Skip to content
This repository has been archived by the owner on Mar 20, 2023. It is now read-only.

Add support for customParseFn option #484

Merged
merged 4 commits into from
May 11, 2019
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,9 @@ The `graphqlHTTP` function accepts the following options:
errors produced by fulfilling a GraphQL operation. If no function is
provided, GraphQL's default spec-compliant [`formatError`][] function will be used.

* **`customParseFn`**: An optional function which will be used to create a document
instead of the default `parse` from `graphql-js`.

* **`formatError`**: is deprecated and replaced by `customFormatErrorFn`. It will be
removed in version 1.0.0.

Expand Down
52 changes: 52 additions & 0 deletions src/__tests__/http-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,10 @@ import {
GraphQLString,
GraphQLError,
BREAK,
Source,
validate,
execute,
parse,
} from 'graphql';
import graphqlHTTP from '../';

Expand Down Expand Up @@ -2032,6 +2034,56 @@ describe('test harness', () => {
});
});

describe('Custom parse function', () => {
it('can replace default parse functionality', async () => {
const app = server();

let seenParseArgs;

get(
app,
urlString(),
graphqlHTTP(() => {
return {
schema: TestSchema,
customParseFn(args) {
seenParseArgs = args;
return parse(new Source('{test}', 'Custom parse function'));
},
};
}),
);

const response = await request(app).get(urlString({ query: '----' }));

expect(response.status).to.equal(200);
expect(response.text).to.equal('{"data":{"test":"Hello World"}}');
expect(seenParseArgs).property('body', '----');
});
it('can throw errors', async () => {
const app = server();
get(
app,
urlString(),
graphqlHTTP(() => {
return {
schema: TestSchema,
customParseFn() {
throw new GraphQLError('my custom parse error');
},
};
}),
);

const response = await request(app).get(urlString({ query: '----' }));

expect(response.status).to.equal(400);
expect(response.text).to.equal(
'{"errors":[{"message":"my custom parse error"}]}',
);
});
});

describe('Custom result extensions', () => {
it('allows for adding extensions', async () => {
const app = server();
Expand Down
12 changes: 10 additions & 2 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,12 @@ export type OptionsData = {
*/
customFormatErrorFn?: ?(error: GraphQLError) => mixed,

/**
* An optional function which will be used to create a document instead of
* the default `parse` from `graphql-js`.
*/
customParseFn?: ?(source: Source) => DocumentNode,

/**
* `formatError` is deprecated and replaced by `customFormatErrorFn`. It will
* be removed in version 1.0.0.
Expand Down Expand Up @@ -186,6 +192,7 @@ function graphqlHTTP(options: Options): Middleware {
let formatErrorFn = formatError;
let validateFn = validate;
let executeFn = execute;
let parseFn = parse;
let extensionsFn;
let showGraphiQL;
let query;
Expand Down Expand Up @@ -265,11 +272,11 @@ function graphqlHTTP(options: Options): Middleware {
}

// GraphQL source.
const source = new Source(query, 'GraphQL request');
const source = new Source(query);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@williambailey Can you please revert this line?


// Parse source to AST, reporting any syntax error.
try {
documentAST = parse(source);
documentAST = parseFn(source);
} catch (syntaxError) {
// Return 400: Bad Request if any syntax errors errors exist.
response.statusCode = 400;
Expand Down Expand Up @@ -418,6 +425,7 @@ function graphqlHTTP(options: Options): Middleware {

validateFn = optionsData.customValidateFn || validateFn;
executeFn = optionsData.customExecuteFn || executeFn;
parseFn = optionsData.customParseFn || parseFn;
formatErrorFn =
optionsData.customFormatErrorFn ||
optionsData.formatError ||
Expand Down