graphql-http 1.21.0 → 1.22.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/handler.mjs CHANGED
@@ -12,6 +12,116 @@ function isResponse(val) {
12
12
  (typeof val[0] === 'string' || val[0] === null) &&
13
13
  isObject(val[1]));
14
14
  }
15
+ /**
16
+ * The GraphQL over HTTP spec compliant request parser for an incoming GraphQL request.
17
+ * It parses and validates the request itself, including the request method and the
18
+ * content-type of the body.
19
+ *
20
+ * If the HTTP request itself is invalid or malformed, the function will return an
21
+ * appropriate {@link Response}.
22
+ *
23
+ * If the HTTP request is valid, but is not a well-formatted GraphQL request, the
24
+ * function will throw an error and it is up to the user to handle and respond as
25
+ * they see fit.
26
+ *
27
+ * @category Server
28
+ */
29
+ export async function parseRequestParams(req) {
30
+ var _a, _b;
31
+ const method = req.method;
32
+ if (method !== 'GET' && method !== 'POST') {
33
+ return [
34
+ null,
35
+ {
36
+ status: 405,
37
+ statusText: 'Method Not Allowed',
38
+ headers: {
39
+ allow: 'GET, POST',
40
+ },
41
+ },
42
+ ];
43
+ }
44
+ const [mediaType, charset = 'charset=utf-8', // utf-8 is assumed when not specified. this parameter is either "charset" or "boundary" (https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Length)
45
+ ] = (getHeader(req, 'content-type') || '')
46
+ .replace(/\s/g, '')
47
+ .toLowerCase()
48
+ .split(';');
49
+ const partParams = {};
50
+ switch (true) {
51
+ case method === 'GET': {
52
+ // TODO: what if content-type is specified and is not application/x-www-form-urlencoded?
53
+ try {
54
+ const [, search] = req.url.split('?');
55
+ const searchParams = new URLSearchParams(search);
56
+ partParams.operationName =
57
+ (_a = searchParams.get('operationName')) !== null && _a !== void 0 ? _a : undefined;
58
+ partParams.query = (_b = searchParams.get('query')) !== null && _b !== void 0 ? _b : undefined;
59
+ const variables = searchParams.get('variables');
60
+ if (variables)
61
+ partParams.variables = JSON.parse(variables);
62
+ const extensions = searchParams.get('extensions');
63
+ if (extensions)
64
+ partParams.extensions = JSON.parse(extensions);
65
+ }
66
+ catch (_c) {
67
+ throw new Error('Unparsable URL');
68
+ }
69
+ break;
70
+ }
71
+ case method === 'POST' &&
72
+ mediaType === 'application/json' &&
73
+ charset === 'charset=utf-8':
74
+ {
75
+ if (!req.body) {
76
+ throw new Error('Missing body');
77
+ }
78
+ let data;
79
+ try {
80
+ const body = typeof req.body === 'function' ? await req.body() : req.body;
81
+ data = typeof body === 'string' ? JSON.parse(body) : body;
82
+ }
83
+ catch (err) {
84
+ throw new Error('Unparsable JSON body');
85
+ }
86
+ if (!isObject(data)) {
87
+ throw new Error('JSON body must be an object');
88
+ }
89
+ partParams.operationName = data.operationName;
90
+ partParams.query = data.query;
91
+ partParams.variables = data.variables;
92
+ partParams.extensions = data.extensions;
93
+ break;
94
+ }
95
+ default: // graphql-http doesnt support any other content type
96
+ return [
97
+ null,
98
+ {
99
+ status: 415,
100
+ statusText: 'Unsupported Media Type',
101
+ },
102
+ ];
103
+ }
104
+ if (partParams.query == null)
105
+ throw new Error('Missing query');
106
+ if (typeof partParams.query !== 'string')
107
+ throw new Error('Invalid query');
108
+ if (partParams.variables != null &&
109
+ (typeof partParams.variables !== 'object' ||
110
+ Array.isArray(partParams.variables))) {
111
+ throw new Error('Invalid variables');
112
+ }
113
+ if (partParams.operationName != null &&
114
+ typeof partParams.operationName !== 'string') {
115
+ throw new Error('Invalid operationName');
116
+ }
117
+ if (partParams.extensions != null &&
118
+ (typeof partParams.extensions !== 'object' ||
119
+ Array.isArray(partParams.extensions))) {
120
+ throw new Error('Invalid extensions');
121
+ }
122
+ // request parameters are checked and now complete
123
+ return partParams;
124
+ }
15
125
  /**
16
126
  * Makes a GraphQL over HTTP spec compliant server handler. The handler can
17
127
  * be used with your favorite server library.
@@ -68,7 +178,7 @@ function isResponse(val) {
68
178
  * @category Server
69
179
  */
70
180
  export function createHandler(options) {
71
- const { schema, context, validate = graphqlValidate, validationRules = [], execute = graphqlExecute, parse = graphqlParse, getOperationAST = graphqlGetOperationAST, rootValue, onSubscribe, onOperation, formatError = (err) => err, parseRequestParams = defaultParseRequestParams, } = options;
181
+ const { schema, context, validate = graphqlValidate, validationRules = [], execute = graphqlExecute, parse = graphqlParse, getOperationAST = graphqlGetOperationAST, rootValue, onSubscribe, onOperation, formatError = (err) => err, parseRequestParams: optionsParseRequestParams = parseRequestParams, } = options;
72
182
  return async function handler(req) {
73
183
  let acceptedMediaType = null;
74
184
  const accepts = (getHeader(req, 'accept') || '*/*')
@@ -79,9 +189,9 @@ export function createHandler(options) {
79
189
  // accept-charset became obsolete, shouldnt be used (https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept-Charset)
80
190
  // TODO: handle the weight parameter "q"
81
191
  const [mediaType, ...params] = accept.split(';');
82
- const charset = (params === null || params === void 0 ? void 0 : params.find((param) => param.includes('charset='))) || 'charset=utf8'; // utf-8 is assumed when not specified;
192
+ const charset = (params === null || params === void 0 ? void 0 : params.find((param) => param.includes('charset='))) || 'charset=utf-8'; // utf-8 is assumed when not specified;
83
193
  if (mediaType === 'application/graphql-response+json' &&
84
- charset === 'charset=utf8') {
194
+ charset === 'charset=utf-8') {
85
195
  acceptedMediaType = 'application/graphql-response+json';
86
196
  break;
87
197
  }
@@ -89,7 +199,7 @@ export function createHandler(options) {
89
199
  if ((mediaType === 'application/json' ||
90
200
  mediaType === 'application/*' ||
91
201
  mediaType === '*/*') &&
92
- charset === 'charset=utf8') {
202
+ (charset === 'charset=utf-8' || charset === 'charset=utf8')) {
93
203
  acceptedMediaType = 'application/json';
94
204
  break;
95
205
  }
@@ -108,9 +218,9 @@ export function createHandler(options) {
108
218
  }
109
219
  let params;
110
220
  try {
111
- let paramsOrRes = await parseRequestParams(req);
221
+ let paramsOrRes = await optionsParseRequestParams(req);
112
222
  if (!paramsOrRes)
113
- paramsOrRes = await defaultParseRequestParams(req);
223
+ paramsOrRes = await parseRequestParams(req);
114
224
  if (isResponse(paramsOrRes))
115
225
  return paramsOrRes;
116
226
  params = paramsOrRes;
@@ -218,110 +328,6 @@ export function createHandler(options) {
218
328
  return makeResponse(result, acceptedMediaType, formatError);
219
329
  };
220
330
  }
221
- /**
222
- * The default request params parser. Used when no custom one is provided or if it
223
- * returns nothing.
224
- *
225
- * Read more about it in {@link ParseRequestParams}.
226
- *
227
- * TODO: should graphql-http itself care about content-encoding? I'd say unzipping should happen before handler is reached
228
- */
229
- async function defaultParseRequestParams(req) {
230
- var _a, _b;
231
- const method = req.method;
232
- if (method !== 'GET' && method !== 'POST') {
233
- return [
234
- null,
235
- {
236
- status: 405,
237
- statusText: 'Method Not Allowed',
238
- headers: {
239
- allow: 'GET, POST',
240
- },
241
- },
242
- ];
243
- }
244
- const [mediaType, charset = 'charset=utf-8', // utf-8 is assumed when not specified. this parameter is either "charset" or "boundary" (https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Length)
245
- ] = (getHeader(req, 'content-type') || '')
246
- .replace(/\s/g, '')
247
- .toLowerCase()
248
- .split(';');
249
- const partParams = {};
250
- switch (true) {
251
- case method === 'GET': {
252
- // TODO: what if content-type is specified and is not application/x-www-form-urlencoded?
253
- try {
254
- const [, search] = req.url.split('?');
255
- const searchParams = new URLSearchParams(search);
256
- partParams.operationName =
257
- (_a = searchParams.get('operationName')) !== null && _a !== void 0 ? _a : undefined;
258
- partParams.query = (_b = searchParams.get('query')) !== null && _b !== void 0 ? _b : undefined;
259
- const variables = searchParams.get('variables');
260
- if (variables)
261
- partParams.variables = JSON.parse(variables);
262
- const extensions = searchParams.get('extensions');
263
- if (extensions)
264
- partParams.extensions = JSON.parse(extensions);
265
- }
266
- catch (_c) {
267
- throw new Error('Unparsable URL');
268
- }
269
- break;
270
- }
271
- case method === 'POST' &&
272
- mediaType === 'application/json' &&
273
- charset === 'charset=utf-8':
274
- {
275
- if (!req.body) {
276
- throw new Error('Missing body');
277
- }
278
- let data;
279
- try {
280
- const body = typeof req.body === 'function' ? await req.body() : req.body;
281
- data = typeof body === 'string' ? JSON.parse(body) : body;
282
- }
283
- catch (err) {
284
- throw new Error('Unparsable JSON body');
285
- }
286
- if (!isObject(data)) {
287
- throw new Error('JSON body must be an object');
288
- }
289
- partParams.operationName = data.operationName;
290
- partParams.query = data.query;
291
- partParams.variables = data.variables;
292
- partParams.extensions = data.extensions;
293
- break;
294
- }
295
- default: // graphql-http doesnt support any other content type
296
- return [
297
- null,
298
- {
299
- status: 415,
300
- statusText: 'Unsupported Media Type',
301
- },
302
- ];
303
- }
304
- if (partParams.query == null)
305
- throw new Error('Missing query');
306
- if (typeof partParams.query !== 'string')
307
- throw new Error('Invalid query');
308
- if (partParams.variables != null &&
309
- (typeof partParams.variables !== 'object' ||
310
- Array.isArray(partParams.variables))) {
311
- throw new Error('Invalid variables');
312
- }
313
- if (partParams.operationName != null &&
314
- typeof partParams.operationName !== 'string') {
315
- throw new Error('Invalid operationName');
316
- }
317
- if (partParams.extensions != null &&
318
- (typeof partParams.extensions !== 'object' ||
319
- Array.isArray(partParams.extensions))) {
320
- throw new Error('Invalid extensions');
321
- }
322
- // request parameters are checked and now complete
323
- return partParams;
324
- }
325
331
  /**
326
332
  * Creates an appropriate GraphQL over HTTP response following the provided arguments.
327
333
  *
@@ -1,5 +1,6 @@
1
1
  import type { Request, Response, Handler } from 'express';
2
2
  import { HandlerOptions as RawHandlerOptions, OperationContext } from '../handler.mjs';
3
+ import { RequestParams } from '../common.mjs';
3
4
  /**
4
5
  * The context in the request for the handler.
5
6
  *
@@ -8,6 +9,46 @@ import { HandlerOptions as RawHandlerOptions, OperationContext } from '../handle
8
9
  export interface RequestContext {
9
10
  res: Response;
10
11
  }
12
+ /**
13
+ * The GraphQL over HTTP spec compliant request parser for an incoming GraphQL request.
14
+ *
15
+ * If the HTTP request _is not_ a [well-formatted GraphQL over HTTP request](https://graphql.github.io/graphql-over-http/draft/#sec-Request), the function will respond
16
+ * on the `Response` argument and return `null`.
17
+ *
18
+ * If the HTTP request _is_ a [well-formatted GraphQL over HTTP request](https://graphql.github.io/graphql-over-http/draft/#sec-Request), but is invalid or malformed,
19
+ * the function will throw an error and it is up to the user to handle and respond as they see fit.
20
+ *
21
+ * ```js
22
+ * import express from 'express'; // yarn add express
23
+ * import { parseRequestParams } from 'graphql-http/lib/use/express';
24
+ *
25
+ * const app = express();
26
+ * app.all('/graphql', async (req, res) => {
27
+ * try {
28
+ * const maybeParams = await parseRequestParams(req, res);
29
+ * if (!maybeParams) {
30
+ * // not a well-formatted GraphQL over HTTP request,
31
+ * // parser responded and there's nothing else to do
32
+ * return;
33
+ * }
34
+ *
35
+ * // well-formatted GraphQL over HTTP request,
36
+ * // with valid parameters
37
+ * res.writeHead(200).end(JSON.stringify(maybeParams, null, ' '));
38
+ * } catch (err) {
39
+ * // well-formatted GraphQL over HTTP request,
40
+ * // but with invalid parameters
41
+ * res.writeHead(400).end(err.message);
42
+ * }
43
+ * });
44
+ *
45
+ * app.listen({ port: 4000 });
46
+ * console.log('Listening to port 4000');
47
+ * ```
48
+ *
49
+ * @category Server/express
50
+ */
51
+ export declare function parseRequestParams(req: Request, res: Response): Promise<RequestParams | null>;
11
52
  /**
12
53
  * Handler options when using the express adapter.
13
54
  *
@@ -1,5 +1,6 @@
1
1
  import type { Request, Response, Handler } from 'express';
2
2
  import { HandlerOptions as RawHandlerOptions, OperationContext } from '../handler';
3
+ import { RequestParams } from '../common';
3
4
  /**
4
5
  * The context in the request for the handler.
5
6
  *
@@ -8,6 +9,46 @@ import { HandlerOptions as RawHandlerOptions, OperationContext } from '../handle
8
9
  export interface RequestContext {
9
10
  res: Response;
10
11
  }
12
+ /**
13
+ * The GraphQL over HTTP spec compliant request parser for an incoming GraphQL request.
14
+ *
15
+ * If the HTTP request _is not_ a [well-formatted GraphQL over HTTP request](https://graphql.github.io/graphql-over-http/draft/#sec-Request), the function will respond
16
+ * on the `Response` argument and return `null`.
17
+ *
18
+ * If the HTTP request _is_ a [well-formatted GraphQL over HTTP request](https://graphql.github.io/graphql-over-http/draft/#sec-Request), but is invalid or malformed,
19
+ * the function will throw an error and it is up to the user to handle and respond as they see fit.
20
+ *
21
+ * ```js
22
+ * import express from 'express'; // yarn add express
23
+ * import { parseRequestParams } from 'graphql-http/lib/use/express';
24
+ *
25
+ * const app = express();
26
+ * app.all('/graphql', async (req, res) => {
27
+ * try {
28
+ * const maybeParams = await parseRequestParams(req, res);
29
+ * if (!maybeParams) {
30
+ * // not a well-formatted GraphQL over HTTP request,
31
+ * // parser responded and there's nothing else to do
32
+ * return;
33
+ * }
34
+ *
35
+ * // well-formatted GraphQL over HTTP request,
36
+ * // with valid parameters
37
+ * res.writeHead(200).end(JSON.stringify(maybeParams, null, ' '));
38
+ * } catch (err) {
39
+ * // well-formatted GraphQL over HTTP request,
40
+ * // but with invalid parameters
41
+ * res.writeHead(400).end(err.message);
42
+ * }
43
+ * });
44
+ *
45
+ * app.listen({ port: 4000 });
46
+ * console.log('Listening to port 4000');
47
+ * ```
48
+ *
49
+ * @category Server/express
50
+ */
51
+ export declare function parseRequestParams(req: Request, res: Response): Promise<RequestParams | null>;
11
52
  /**
12
53
  * Handler options when using the express adapter.
13
54
  *
@@ -1,7 +1,57 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.createHandler = void 0;
3
+ exports.createHandler = exports.parseRequestParams = void 0;
4
4
  const handler_1 = require("../handler");
5
+ /**
6
+ * The GraphQL over HTTP spec compliant request parser for an incoming GraphQL request.
7
+ *
8
+ * If the HTTP request _is not_ a [well-formatted GraphQL over HTTP request](https://graphql.github.io/graphql-over-http/draft/#sec-Request), the function will respond
9
+ * on the `Response` argument and return `null`.
10
+ *
11
+ * If the HTTP request _is_ a [well-formatted GraphQL over HTTP request](https://graphql.github.io/graphql-over-http/draft/#sec-Request), but is invalid or malformed,
12
+ * the function will throw an error and it is up to the user to handle and respond as they see fit.
13
+ *
14
+ * ```js
15
+ * import express from 'express'; // yarn add express
16
+ * import { parseRequestParams } from 'graphql-http/lib/use/express';
17
+ *
18
+ * const app = express();
19
+ * app.all('/graphql', async (req, res) => {
20
+ * try {
21
+ * const maybeParams = await parseRequestParams(req, res);
22
+ * if (!maybeParams) {
23
+ * // not a well-formatted GraphQL over HTTP request,
24
+ * // parser responded and there's nothing else to do
25
+ * return;
26
+ * }
27
+ *
28
+ * // well-formatted GraphQL over HTTP request,
29
+ * // with valid parameters
30
+ * res.writeHead(200).end(JSON.stringify(maybeParams, null, ' '));
31
+ * } catch (err) {
32
+ * // well-formatted GraphQL over HTTP request,
33
+ * // but with invalid parameters
34
+ * res.writeHead(400).end(err.message);
35
+ * }
36
+ * });
37
+ *
38
+ * app.listen({ port: 4000 });
39
+ * console.log('Listening to port 4000');
40
+ * ```
41
+ *
42
+ * @category Server/express
43
+ */
44
+ async function parseRequestParams(req, res) {
45
+ const rawReq = toRequest(req, res);
46
+ const paramsOrRes = await (0, handler_1.parseRequestParams)(rawReq);
47
+ if (!('query' in paramsOrRes)) {
48
+ const [body, init] = paramsOrRes;
49
+ res.writeHead(init.status, init.statusText, init.headers).end(body);
50
+ return null;
51
+ }
52
+ return paramsOrRes;
53
+ }
54
+ exports.parseRequestParams = parseRequestParams;
5
55
  /**
6
56
  * Create a GraphQL over HTTP spec compliant request handler for
7
57
  * the express framework.
@@ -24,24 +74,7 @@ function createHandler(options) {
24
74
  const handle = (0, handler_1.createHandler)(options);
25
75
  return async function requestListener(req, res) {
26
76
  try {
27
- const [body, init] = await handle({
28
- url: req.url,
29
- method: req.method,
30
- headers: req.headers,
31
- body: () => {
32
- if (req.body) {
33
- // in case express has a body parser
34
- return req.body;
35
- }
36
- return new Promise((resolve) => {
37
- let body = '';
38
- req.on('data', (chunk) => (body += chunk));
39
- req.on('end', () => resolve(body));
40
- });
41
- },
42
- raw: req,
43
- context: { res },
44
- });
77
+ const [body, init] = await handle(toRequest(req, res));
45
78
  res.writeHead(init.status, init.statusText, init.headers).end(body);
46
79
  }
47
80
  catch (err) {
@@ -54,3 +87,24 @@ function createHandler(options) {
54
87
  };
55
88
  }
56
89
  exports.createHandler = createHandler;
90
+ function toRequest(req, res) {
91
+ return {
92
+ url: req.url,
93
+ method: req.method,
94
+ headers: req.headers,
95
+ body: () => {
96
+ if (req.body) {
97
+ // in case express has a body parser
98
+ return req.body;
99
+ }
100
+ return new Promise((resolve) => {
101
+ let body = '';
102
+ req.setEncoding('utf-8');
103
+ req.on('data', (chunk) => (body += chunk));
104
+ req.on('end', () => resolve(body));
105
+ });
106
+ },
107
+ raw: req,
108
+ context: { res },
109
+ };
110
+ }
@@ -1,4 +1,53 @@
1
- import { createHandler as createRawHandler, } from '../handler.mjs';
1
+ import { createHandler as createRawHandler, parseRequestParams as rawParseRequestParams, } from '../handler.mjs';
2
+ /**
3
+ * The GraphQL over HTTP spec compliant request parser for an incoming GraphQL request.
4
+ *
5
+ * If the HTTP request _is not_ a [well-formatted GraphQL over HTTP request](https://graphql.github.io/graphql-over-http/draft/#sec-Request), the function will respond
6
+ * on the `Response` argument and return `null`.
7
+ *
8
+ * If the HTTP request _is_ a [well-formatted GraphQL over HTTP request](https://graphql.github.io/graphql-over-http/draft/#sec-Request), but is invalid or malformed,
9
+ * the function will throw an error and it is up to the user to handle and respond as they see fit.
10
+ *
11
+ * ```js
12
+ * import express from 'express'; // yarn add express
13
+ * import { parseRequestParams } from 'graphql-http/lib/use/express';
14
+ *
15
+ * const app = express();
16
+ * app.all('/graphql', async (req, res) => {
17
+ * try {
18
+ * const maybeParams = await parseRequestParams(req, res);
19
+ * if (!maybeParams) {
20
+ * // not a well-formatted GraphQL over HTTP request,
21
+ * // parser responded and there's nothing else to do
22
+ * return;
23
+ * }
24
+ *
25
+ * // well-formatted GraphQL over HTTP request,
26
+ * // with valid parameters
27
+ * res.writeHead(200).end(JSON.stringify(maybeParams, null, ' '));
28
+ * } catch (err) {
29
+ * // well-formatted GraphQL over HTTP request,
30
+ * // but with invalid parameters
31
+ * res.writeHead(400).end(err.message);
32
+ * }
33
+ * });
34
+ *
35
+ * app.listen({ port: 4000 });
36
+ * console.log('Listening to port 4000');
37
+ * ```
38
+ *
39
+ * @category Server/express
40
+ */
41
+ export async function parseRequestParams(req, res) {
42
+ const rawReq = toRequest(req, res);
43
+ const paramsOrRes = await rawParseRequestParams(rawReq);
44
+ if (!('query' in paramsOrRes)) {
45
+ const [body, init] = paramsOrRes;
46
+ res.writeHead(init.status, init.statusText, init.headers).end(body);
47
+ return null;
48
+ }
49
+ return paramsOrRes;
50
+ }
2
51
  /**
3
52
  * Create a GraphQL over HTTP spec compliant request handler for
4
53
  * the express framework.
@@ -21,24 +70,7 @@ export function createHandler(options) {
21
70
  const handle = createRawHandler(options);
22
71
  return async function requestListener(req, res) {
23
72
  try {
24
- const [body, init] = await handle({
25
- url: req.url,
26
- method: req.method,
27
- headers: req.headers,
28
- body: () => {
29
- if (req.body) {
30
- // in case express has a body parser
31
- return req.body;
32
- }
33
- return new Promise((resolve) => {
34
- let body = '';
35
- req.on('data', (chunk) => (body += chunk));
36
- req.on('end', () => resolve(body));
37
- });
38
- },
39
- raw: req,
40
- context: { res },
41
- });
73
+ const [body, init] = await handle(toRequest(req, res));
42
74
  res.writeHead(init.status, init.statusText, init.headers).end(body);
43
75
  }
44
76
  catch (err) {
@@ -50,3 +82,24 @@ export function createHandler(options) {
50
82
  }
51
83
  };
52
84
  }
85
+ function toRequest(req, res) {
86
+ return {
87
+ url: req.url,
88
+ method: req.method,
89
+ headers: req.headers,
90
+ body: () => {
91
+ if (req.body) {
92
+ // in case express has a body parser
93
+ return req.body;
94
+ }
95
+ return new Promise((resolve) => {
96
+ let body = '';
97
+ req.setEncoding('utf-8');
98
+ req.on('data', (chunk) => (body += chunk));
99
+ req.on('end', () => resolve(body));
100
+ });
101
+ },
102
+ raw: req,
103
+ context: { res },
104
+ };
105
+ }
@@ -1,5 +1,6 @@
1
1
  import type { FastifyRequest, FastifyReply, RouteHandler } from 'fastify';
2
2
  import { HandlerOptions as RawHandlerOptions, OperationContext } from '../handler.mjs';
3
+ import { RequestParams } from '../common.mjs';
3
4
  /**
4
5
  * The context in the request for the handler.
5
6
  *
@@ -8,6 +9,46 @@ import { HandlerOptions as RawHandlerOptions, OperationContext } from '../handle
8
9
  export interface RequestContext {
9
10
  reply: FastifyReply;
10
11
  }
12
+ /**
13
+ * The GraphQL over HTTP spec compliant request parser for an incoming GraphQL request.
14
+ *
15
+ * If the HTTP request _is not_ a [well-formatted GraphQL over HTTP request](https://graphql.github.io/graphql-over-http/draft/#sec-Request), the function will respond
16
+ * on the `FastifyReply` argument and return `null`.
17
+ *
18
+ * If the HTTP request _is_ a [well-formatted GraphQL over HTTP request](https://graphql.github.io/graphql-over-http/draft/#sec-Request), but is invalid or malformed,
19
+ * the function will throw an error and it is up to the user to handle and respond as they see fit.
20
+ *
21
+ * ```js
22
+ * import Fastify from 'fastify'; // yarn add fastify
23
+ * import { parseRequestParams } from 'graphql-http/lib/use/fastify';
24
+ *
25
+ * const fastify = Fastify();
26
+ * fastify.all('/graphql', async (req, reply) => {
27
+ * try {
28
+ * const maybeParams = await parseRequestParams(req, reply);
29
+ * if (!maybeParams) {
30
+ * // not a well-formatted GraphQL over HTTP request,
31
+ * // parser responded and there's nothing else to do
32
+ * return;
33
+ * }
34
+ *
35
+ * // well-formatted GraphQL over HTTP request,
36
+ * // with valid parameters
37
+ * reply.status(200).send(JSON.stringify(maybeParams, null, ' '));
38
+ * } catch (err) {
39
+ * // well-formatted GraphQL over HTTP request,
40
+ * // but with invalid parameters
41
+ * reply.status(400).send(err.message);
42
+ * }
43
+ * });
44
+ *
45
+ * fastify.listen({ port: 4000 });
46
+ * console.log('Listening to port 4000');
47
+ * ```
48
+ *
49
+ * @category Server/fastify
50
+ */
51
+ export declare function parseRequestParams(req: FastifyRequest, reply: FastifyReply): Promise<RequestParams | null>;
11
52
  /**
12
53
  * Handler options when using the fastify adapter.
13
54
  *
@@ -20,7 +61,7 @@ export type HandlerOptions<Context extends OperationContext = undefined> = RawHa
20
61
  *
21
62
  * ```js
22
63
  * import Fastify from 'fastify'; // yarn add fastify
23
- * import { createHandler } from 'graphql-http/lib/use/express';
64
+ * import { createHandler } from 'graphql-http/lib/use/fastify';
24
65
  * import { schema } from './my-graphql-schema/index.mjs';
25
66
  *
26
67
  * const fastify = Fastify();