graphql-http 1.20.0 → 1.22.0

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.
Files changed (48) hide show
  1. package/README.md +13 -1
  2. package/lib/handler.d.mts +19 -2
  3. package/lib/handler.d.ts +19 -2
  4. package/lib/handler.js +145 -115
  5. package/lib/handler.mjs +137 -108
  6. package/lib/use/@netlify/functions.d.mts +14 -0
  7. package/lib/use/@netlify/functions.d.ts +14 -0
  8. package/lib/use/@netlify/functions.js +37 -0
  9. package/lib/use/@netlify/functions.mjs +33 -0
  10. package/lib/use/express.d.mts +41 -0
  11. package/lib/use/express.d.ts +41 -0
  12. package/lib/use/express.js +72 -19
  13. package/lib/use/express.mjs +71 -19
  14. package/lib/use/fastify.d.mts +42 -1
  15. package/lib/use/fastify.d.ts +42 -1
  16. package/lib/use/fastify.js +68 -11
  17. package/lib/use/fastify.mjs +67 -11
  18. package/lib/use/fetch.d.mts +50 -0
  19. package/lib/use/fetch.d.ts +50 -0
  20. package/lib/use/fetch.js +74 -9
  21. package/lib/use/fetch.mjs +73 -9
  22. package/lib/use/http.d.mts +44 -0
  23. package/lib/use/http.d.ts +44 -0
  24. package/lib/use/http.js +75 -13
  25. package/lib/use/http.mjs +74 -13
  26. package/lib/use/http2.d.mts +56 -0
  27. package/lib/use/http2.d.ts +56 -0
  28. package/lib/use/http2.js +93 -13
  29. package/lib/use/http2.mjs +92 -13
  30. package/lib/use/koa.d.mts +47 -1
  31. package/lib/use/koa.d.ts +47 -1
  32. package/lib/use/koa.js +84 -1
  33. package/lib/use/koa.mjs +83 -1
  34. package/lib/use/uWebSockets.d.mts +55 -0
  35. package/lib/use/uWebSockets.d.ts +55 -0
  36. package/lib/use/uWebSockets.js +109 -31
  37. package/lib/use/uWebSockets.mjs +108 -31
  38. package/lib/utils.d.mts +0 -7
  39. package/lib/utils.d.ts +0 -7
  40. package/lib/utils.js +1 -31
  41. package/lib/utils.mjs +0 -27
  42. package/package.json +28 -32
  43. package/umd/graphql-http-audits.js +2 -2
  44. package/umd/graphql-http-audits.min.js +1 -1
  45. package/umd/graphql-http-audits.min.js.gz +0 -0
  46. package/umd/graphql-http.js +3 -2
  47. package/umd/graphql-http.min.js +1 -1
  48. package/umd/graphql-http.min.js.gz +0 -0
@@ -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,23 @@ 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.on('data', (chunk) => (body += chunk));
98
+ req.on('end', () => resolve(body));
99
+ });
100
+ },
101
+ raw: req,
102
+ context: { res },
103
+ };
104
+ }
@@ -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();
@@ -1,5 +1,6 @@
1
1
  import type { FastifyRequest, FastifyReply, RouteHandler } from 'fastify';
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
  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';
25
66
  *
26
67
  * const fastify = Fastify();
@@ -1,14 +1,68 @@
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 `FastifyReply` 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 Fastify from 'fastify'; // yarn add fastify
16
+ * import { parseRequestParams } from 'graphql-http/lib/use/fastify';
17
+ *
18
+ * const fastify = Fastify();
19
+ * fastify.all('/graphql', async (req, reply) => {
20
+ * try {
21
+ * const maybeParams = await parseRequestParams(req, reply);
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
+ * reply.status(200).send(JSON.stringify(maybeParams, null, ' '));
31
+ * } catch (err) {
32
+ * // well-formatted GraphQL over HTTP request,
33
+ * // but with invalid parameters
34
+ * reply.status(400).send(err.message);
35
+ * }
36
+ * });
37
+ *
38
+ * fastify.listen({ port: 4000 });
39
+ * console.log('Listening to port 4000');
40
+ * ```
41
+ *
42
+ * @category Server/fastify
43
+ */
44
+ async function parseRequestParams(req, reply) {
45
+ const rawReq = toRequest(req, reply);
46
+ const paramsOrRes = await (0, handler_1.parseRequestParams)(rawReq);
47
+ if (!('query' in paramsOrRes)) {
48
+ const [body, init] = paramsOrRes;
49
+ reply
50
+ .status(init.status)
51
+ .headers(init.headers || {})
52
+ // "or undefined" because `null` will be JSON stringified
53
+ .send(body || undefined);
54
+ return null;
55
+ }
56
+ return paramsOrRes;
57
+ }
58
+ exports.parseRequestParams = parseRequestParams;
5
59
  /**
6
60
  * Create a GraphQL over HTTP spec compliant request handler for
7
61
  * the fastify framework.
8
62
  *
9
63
  * ```js
10
64
  * import Fastify from 'fastify'; // yarn add fastify
11
- * import { createHandler } from 'graphql-http/lib/use/express';
65
+ * import { createHandler } from 'graphql-http/lib/use/fastify';
12
66
  * import { schema } from './my-graphql-schema';
13
67
  *
14
68
  * const fastify = Fastify();
@@ -24,15 +78,7 @@ function createHandler(options) {
24
78
  const handle = (0, handler_1.createHandler)(options);
25
79
  return async function requestListener(req, reply) {
26
80
  try {
27
- const [body, init] = await handle({
28
- url: req.url,
29
- method: req.method,
30
- headers: req.headers,
31
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
32
- body: req.body,
33
- raw: req,
34
- context: { reply },
35
- });
81
+ const [body, init] = await handle(toRequest(req, reply));
36
82
  reply
37
83
  .status(init.status)
38
84
  .headers(init.headers || {})
@@ -49,3 +95,14 @@ function createHandler(options) {
49
95
  };
50
96
  }
51
97
  exports.createHandler = createHandler;
98
+ function toRequest(req, reply) {
99
+ return {
100
+ url: req.url,
101
+ method: req.method,
102
+ headers: req.headers,
103
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
104
+ body: req.body,
105
+ raw: req,
106
+ context: { reply },
107
+ };
108
+ }
@@ -1,11 +1,64 @@
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 `FastifyReply` 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 Fastify from 'fastify'; // yarn add fastify
13
+ * import { parseRequestParams } from 'graphql-http/lib/use/fastify';
14
+ *
15
+ * const fastify = Fastify();
16
+ * fastify.all('/graphql', async (req, reply) => {
17
+ * try {
18
+ * const maybeParams = await parseRequestParams(req, reply);
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
+ * reply.status(200).send(JSON.stringify(maybeParams, null, ' '));
28
+ * } catch (err) {
29
+ * // well-formatted GraphQL over HTTP request,
30
+ * // but with invalid parameters
31
+ * reply.status(400).send(err.message);
32
+ * }
33
+ * });
34
+ *
35
+ * fastify.listen({ port: 4000 });
36
+ * console.log('Listening to port 4000');
37
+ * ```
38
+ *
39
+ * @category Server/fastify
40
+ */
41
+ export async function parseRequestParams(req, reply) {
42
+ const rawReq = toRequest(req, reply);
43
+ const paramsOrRes = await rawParseRequestParams(rawReq);
44
+ if (!('query' in paramsOrRes)) {
45
+ const [body, init] = paramsOrRes;
46
+ reply
47
+ .status(init.status)
48
+ .headers(init.headers || {})
49
+ // "or undefined" because `null` will be JSON stringified
50
+ .send(body || undefined);
51
+ return null;
52
+ }
53
+ return paramsOrRes;
54
+ }
2
55
  /**
3
56
  * Create a GraphQL over HTTP spec compliant request handler for
4
57
  * the fastify framework.
5
58
  *
6
59
  * ```js
7
60
  * import Fastify from 'fastify'; // yarn add fastify
8
- * import { createHandler } from 'graphql-http/lib/use/express';
61
+ * import { createHandler } from 'graphql-http/lib/use/fastify';
9
62
  * import { schema } from './my-graphql-schema/index.mjs';
10
63
  *
11
64
  * const fastify = Fastify();
@@ -21,15 +74,7 @@ export function createHandler(options) {
21
74
  const handle = createRawHandler(options);
22
75
  return async function requestListener(req, reply) {
23
76
  try {
24
- const [body, init] = await handle({
25
- url: req.url,
26
- method: req.method,
27
- headers: req.headers,
28
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
29
- body: req.body,
30
- raw: req,
31
- context: { reply },
32
- });
77
+ const [body, init] = await handle(toRequest(req, reply));
33
78
  reply
34
79
  .status(init.status)
35
80
  .headers(init.headers || {})
@@ -45,3 +90,14 @@ export function createHandler(options) {
45
90
  }
46
91
  };
47
92
  }
93
+ function toRequest(req, reply) {
94
+ return {
95
+ url: req.url,
96
+ method: req.method,
97
+ headers: req.headers,
98
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
99
+ body: req.body,
100
+ raw: req,
101
+ context: { reply },
102
+ };
103
+ }
@@ -1,4 +1,5 @@
1
1
  import { HandlerOptions as RawHandlerOptions, OperationContext } from '../handler.mjs';
2
+ import { RequestParams } from '../common.mjs';
2
3
  /**
3
4
  * The necessary API from the fetch environment for the handler.
4
5
  *
@@ -9,6 +10,55 @@ export interface FetchAPI {
9
10
  ReadableStream: typeof ReadableStream;
10
11
  TextEncoder: typeof TextEncoder;
11
12
  }
13
+ /**
14
+ * The GraphQL over HTTP spec compliant request parser for an incoming GraphQL request.
15
+ *
16
+ * It is important to pass in the `abortedRef` so that the parser does not perform any
17
+ * operations on a disposed request (see example).
18
+ *
19
+ * 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 return a `Response`.
20
+ *
21
+ * 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,
22
+ * the function will throw an error and it is up to the user to handle and respond as they see fit.
23
+ *
24
+ * ```js
25
+ * import http from 'http';
26
+ * import { createServerAdapter } from '@whatwg-node/server'; // yarn add @whatwg-node/server
27
+ * import { parseRequestParams } from 'graphql-http/lib/use/fetch';
28
+ *
29
+ * // Use this adapter in _any_ environment.
30
+ * const adapter = createServerAdapter({
31
+ * handleRequest: async (req) => {
32
+ * try {
33
+ * const paramsOrResponse = await parseRequestParams(req);
34
+ * if (paramsOrResponse instanceof Response) {
35
+ * // not a well-formatted GraphQL over HTTP request,
36
+ * // parser created a response object to use
37
+ * return paramsOrResponse;
38
+ * }
39
+ *
40
+ * // well-formatted GraphQL over HTTP request,
41
+ * // with valid parameters
42
+ * return new Response(JSON.stringify(paramsOrResponse, null, ' '), {
43
+ * status: 200,
44
+ * });
45
+ * } catch (err) {
46
+ * // well-formatted GraphQL over HTTP request,
47
+ * // but with invalid parameters
48
+ * return new Response(err.message, { status: 400 });
49
+ * }
50
+ * },
51
+ * });
52
+ *
53
+ * const server = http.createServer(adapter);
54
+ *
55
+ * server.listen(4000);
56
+ * console.log('Listening to port 4000');
57
+ * ```
58
+ *
59
+ * @category Server/fetch
60
+ */
61
+ export declare function parseRequestParams(req: Request, api?: Partial<FetchAPI>): Promise<RequestParams | Response>;
12
62
  /**
13
63
  * Handler options when using the fetch adapter.
14
64
  *
@@ -1,4 +1,5 @@
1
1
  import { HandlerOptions as RawHandlerOptions, OperationContext } from '../handler';
2
+ import { RequestParams } from '../common';
2
3
  /**
3
4
  * The necessary API from the fetch environment for the handler.
4
5
  *
@@ -9,6 +10,55 @@ export interface FetchAPI {
9
10
  ReadableStream: typeof ReadableStream;
10
11
  TextEncoder: typeof TextEncoder;
11
12
  }
13
+ /**
14
+ * The GraphQL over HTTP spec compliant request parser for an incoming GraphQL request.
15
+ *
16
+ * It is important to pass in the `abortedRef` so that the parser does not perform any
17
+ * operations on a disposed request (see example).
18
+ *
19
+ * 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 return a `Response`.
20
+ *
21
+ * 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,
22
+ * the function will throw an error and it is up to the user to handle and respond as they see fit.
23
+ *
24
+ * ```js
25
+ * import http from 'http';
26
+ * import { createServerAdapter } from '@whatwg-node/server'; // yarn add @whatwg-node/server
27
+ * import { parseRequestParams } from 'graphql-http/lib/use/fetch';
28
+ *
29
+ * // Use this adapter in _any_ environment.
30
+ * const adapter = createServerAdapter({
31
+ * handleRequest: async (req) => {
32
+ * try {
33
+ * const paramsOrResponse = await parseRequestParams(req);
34
+ * if (paramsOrResponse instanceof Response) {
35
+ * // not a well-formatted GraphQL over HTTP request,
36
+ * // parser created a response object to use
37
+ * return paramsOrResponse;
38
+ * }
39
+ *
40
+ * // well-formatted GraphQL over HTTP request,
41
+ * // with valid parameters
42
+ * return new Response(JSON.stringify(paramsOrResponse, null, ' '), {
43
+ * status: 200,
44
+ * });
45
+ * } catch (err) {
46
+ * // well-formatted GraphQL over HTTP request,
47
+ * // but with invalid parameters
48
+ * return new Response(err.message, { status: 400 });
49
+ * }
50
+ * },
51
+ * });
52
+ *
53
+ * const server = http.createServer(adapter);
54
+ *
55
+ * server.listen(4000);
56
+ * console.log('Listening to port 4000');
57
+ * ```
58
+ *
59
+ * @category Server/fetch
60
+ */
61
+ export declare function parseRequestParams(req: Request, api?: Partial<FetchAPI>): Promise<RequestParams | Response>;
12
62
  /**
13
63
  * Handler options when using the fetch adapter.
14
64
  *
package/lib/use/fetch.js CHANGED
@@ -1,7 +1,65 @@
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
+ * It is important to pass in the `abortedRef` so that the parser does not perform any
9
+ * operations on a disposed request (see example).
10
+ *
11
+ * 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 return a `Response`.
12
+ *
13
+ * 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,
14
+ * the function will throw an error and it is up to the user to handle and respond as they see fit.
15
+ *
16
+ * ```js
17
+ * import http from 'http';
18
+ * import { createServerAdapter } from '@whatwg-node/server'; // yarn add @whatwg-node/server
19
+ * import { parseRequestParams } from 'graphql-http/lib/use/fetch';
20
+ *
21
+ * // Use this adapter in _any_ environment.
22
+ * const adapter = createServerAdapter({
23
+ * handleRequest: async (req) => {
24
+ * try {
25
+ * const paramsOrResponse = await parseRequestParams(req);
26
+ * if (paramsOrResponse instanceof Response) {
27
+ * // not a well-formatted GraphQL over HTTP request,
28
+ * // parser created a response object to use
29
+ * return paramsOrResponse;
30
+ * }
31
+ *
32
+ * // well-formatted GraphQL over HTTP request,
33
+ * // with valid parameters
34
+ * return new Response(JSON.stringify(paramsOrResponse, null, ' '), {
35
+ * status: 200,
36
+ * });
37
+ * } catch (err) {
38
+ * // well-formatted GraphQL over HTTP request,
39
+ * // but with invalid parameters
40
+ * return new Response(err.message, { status: 400 });
41
+ * }
42
+ * },
43
+ * });
44
+ *
45
+ * const server = http.createServer(adapter);
46
+ *
47
+ * server.listen(4000);
48
+ * console.log('Listening to port 4000');
49
+ * ```
50
+ *
51
+ * @category Server/fetch
52
+ */
53
+ async function parseRequestParams(req, api = {}) {
54
+ const rawReq = toRequest(req, api);
55
+ const paramsOrRes = await (0, handler_1.parseRequestParams)(rawReq);
56
+ if (!('query' in paramsOrRes)) {
57
+ const [body, init] = paramsOrRes;
58
+ return new (api.Response || Response)(body, init);
59
+ }
60
+ return paramsOrRes;
61
+ }
62
+ exports.parseRequestParams = parseRequestParams;
5
63
  /**
6
64
  * Create a GraphQL over HTTP spec compliant request handler for
7
65
  * a fetch environment like Deno, Bun, CloudFlare Workers, Lambdas, etc.
@@ -39,14 +97,7 @@ function createHandler(options, reqCtx = {}) {
39
97
  const handler = (0, handler_1.createHandler)(options);
40
98
  return async function handleRequest(req) {
41
99
  try {
42
- const [body, init] = await handler({
43
- method: req.method,
44
- url: req.url,
45
- headers: req.headers,
46
- body: () => req.text(),
47
- raw: req,
48
- context: api,
49
- });
100
+ const [body, init] = await handler(toRequest(req, api));
50
101
  return new api.Response(body, init);
51
102
  }
52
103
  catch (err) {
@@ -59,3 +110,17 @@ function createHandler(options, reqCtx = {}) {
59
110
  };
60
111
  }
61
112
  exports.createHandler = createHandler;
113
+ function toRequest(req, api = {}) {
114
+ return {
115
+ method: req.method,
116
+ url: req.url,
117
+ headers: req.headers,
118
+ body: () => req.text(),
119
+ raw: req,
120
+ context: {
121
+ Response: api.Response || Response,
122
+ TextEncoder: api.TextEncoder || TextEncoder,
123
+ ReadableStream: api.ReadableStream || ReadableStream,
124
+ },
125
+ };
126
+ }