graphql-http 1.4.0 → 1.6.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.
@@ -0,0 +1,285 @@
1
+ /**
2
+ *
3
+ * handler
4
+ *
5
+ */
6
+ import { ExecutionArgs, ExecutionResult, GraphQLSchema, validate as graphqlValidate, execute as graphqlExecute, parse as graphqlParse, getOperationAST as graphqlGetOperationAST, GraphQLError } from 'graphql';
7
+ import { RequestParams } from './common';
8
+ /**
9
+ * The incoming request headers the implementing server should provide.
10
+ *
11
+ * @category Common
12
+ */
13
+ export interface RequestHeaders {
14
+ accept?: string | undefined;
15
+ allow?: string | undefined;
16
+ 'content-type'?: string | undefined;
17
+ /**
18
+ * Always an array in Node. Duplicates are added to it.
19
+ * Not necessarily true for other environments, make sure
20
+ * to check the type during runtime.
21
+ */
22
+ 'set-cookie'?: string | string[] | undefined;
23
+ [key: string]: string | string[] | undefined;
24
+ }
25
+ /**
26
+ * Server agnostic request interface containing the raw request
27
+ * which is server dependant.
28
+ *
29
+ * @category Common
30
+ */
31
+ export interface Request<RawRequest, Context> {
32
+ readonly method: string;
33
+ readonly url: string;
34
+ readonly headers: RequestHeaders;
35
+ /**
36
+ * Parsed request body or a parser function.
37
+ *
38
+ * If the provided function throws, the error message "Unparsable JSON body" will
39
+ * be in the erroneous response.
40
+ */
41
+ readonly body: string | Record<string, unknown> | null | (() => string | Record<string, unknown> | null | Promise<string | Record<string, unknown> | null>);
42
+ /**
43
+ * The raw request itself from the implementing server.
44
+ *
45
+ * For example: `express.Request` when using Express, or maybe
46
+ * `http.IncomingMessage` when just using Node with `http.createServer`.
47
+ */
48
+ readonly raw: RawRequest;
49
+ /**
50
+ * Context value about the incoming request, you're free to pass any information here.
51
+ */
52
+ readonly context: Context;
53
+ }
54
+ /**
55
+ * The response headers that get returned from graphql-http.
56
+ *
57
+ * @category Common
58
+ */
59
+ export declare type ResponseHeaders = {
60
+ accept?: string;
61
+ allow?: string;
62
+ 'content-type'?: string;
63
+ } & Record<string, string>;
64
+ /**
65
+ * Server agnostic response body returned from `graphql-http` needing
66
+ * to be coerced to the server implementation in use.
67
+ *
68
+ * @category Common
69
+ */
70
+ export declare type ResponseBody = string;
71
+ /**
72
+ * Server agnostic response options (ex. status and headers) returned from
73
+ * `graphql-http` needing to be coerced to the server implementation in use.
74
+ *
75
+ * @category Common
76
+ */
77
+ export interface ResponseInit {
78
+ readonly status: number;
79
+ readonly statusText: string;
80
+ readonly headers?: ResponseHeaders;
81
+ }
82
+ /**
83
+ * Server agnostic response returned from `graphql-http` containing the
84
+ * body and init options needing to be coerced to the server implementation in use.
85
+ *
86
+ * @category Common
87
+ */
88
+ export declare type Response = readonly [body: ResponseBody | null, init: ResponseInit];
89
+ /**
90
+ * Checks whether the passed value is the `graphql-http` server agnostic response.
91
+ *
92
+ * @category Common
93
+ */
94
+ export declare function isResponse(val: unknown): val is Response;
95
+ /**
96
+ * A concrete GraphQL execution context value type.
97
+ *
98
+ * Mainly used because TypeScript collapes unions
99
+ * with `any` or `unknown` to `any` or `unknown`. So,
100
+ * we use a custom type to allow definitions such as
101
+ * the `context` server option.
102
+ *
103
+ * @category Server
104
+ */
105
+ export declare type ExecutionContext = object | symbol | number | string | boolean | undefined | null;
106
+ /** @category Server */
107
+ export interface HandlerOptions<RawRequest = unknown, Context = unknown> {
108
+ /**
109
+ * The GraphQL schema on which the operations will
110
+ * be executed and validated against.
111
+ *
112
+ * If a function is provided, it will be called on every
113
+ * operation request allowing you to manipulate schema
114
+ * dynamically.
115
+ *
116
+ * If the schema is left undefined, you're trusted to
117
+ * provide one in the returned `ExecutionArgs` from the
118
+ * `onSubscribe` callback.
119
+ *
120
+ * If you want to respond to the client with a custom status and/or body,
121
+ * you should do by returning a `Request` argument which will stop
122
+ * further execution.
123
+ */
124
+ schema?: GraphQLSchema | ((req: Request<RawRequest, Context>, args: Omit<ExecutionArgs, 'schema'>) => Promise<GraphQLSchema | Response> | GraphQLSchema | Response);
125
+ /**
126
+ * A value which is provided to every resolver and holds
127
+ * important contextual information like the currently
128
+ * logged in user, or access to a database.
129
+ */
130
+ context?: ExecutionContext | ((req: Request<RawRequest, Context>, args: ExecutionArgs) => Promise<ExecutionContext | Response> | ExecutionContext | Response);
131
+ /**
132
+ * A custom GraphQL validate function allowing you to apply your
133
+ * own validation rules.
134
+ *
135
+ * Will not be used when implementing a custom `onSubscribe`.
136
+ */
137
+ validate?: typeof graphqlValidate;
138
+ /**
139
+ * Is the `execute` function from GraphQL which is
140
+ * used to execute the query and mutation operations.
141
+ */
142
+ execute?: typeof graphqlExecute;
143
+ /**
144
+ * GraphQL parse function allowing you to apply a custom parser.
145
+ */
146
+ parse?: typeof graphqlParse;
147
+ /**
148
+ * GraphQL operation AST getter used for detecting the operation type.
149
+ */
150
+ getOperationAST?: typeof graphqlGetOperationAST;
151
+ /**
152
+ * The subscribe callback executed right after processing the request
153
+ * before proceeding with the GraphQL operation execution.
154
+ *
155
+ * If you return `ExecutionResult` from the callback, it will be used
156
+ * directly for responding to the request. Useful for implementing a response
157
+ * cache.
158
+ *
159
+ * If you return `ExecutionArgs` from the callback, it will be used instead of
160
+ * trying to build one internally. In this case, you are responsible for providing
161
+ * a ready set of arguments which will be directly plugged in the operation execution.
162
+ *
163
+ * You *must* validate the `ExecutionArgs` yourself if returning them.
164
+ *
165
+ * If you return an array of `GraphQLError` from the callback, they will be reported
166
+ * to the client while complying with the spec.
167
+ *
168
+ * Omitting the fields `contextValue` from the returned `ExecutionArgs` will use the
169
+ * provided `context` option, if available.
170
+ *
171
+ * Useful for preparing the execution arguments following a custom logic. A typical
172
+ * use-case is persisted queries. You can identify the query from the request parameters
173
+ * and supply the appropriate GraphQL operation execution arguments.
174
+ *
175
+ * If you want to respond to the client with a custom status and/or body,
176
+ * you should do by returning a `Request` argument which will stop
177
+ * further execution.
178
+ */
179
+ onSubscribe?: (req: Request<RawRequest, Context>, params: RequestParams) => Promise<ExecutionResult | ExecutionArgs | readonly GraphQLError[] | Response | void> | ExecutionResult | ExecutionArgs | readonly GraphQLError[] | Response | void;
180
+ /**
181
+ * Executed after the operation call resolves.
182
+ *
183
+ * The `OperationResult` argument is the result of operation
184
+ * execution. It can be an iterator or already a value.
185
+ *
186
+ * Use this callback to listen for GraphQL operations and
187
+ * execution result manipulation.
188
+ *
189
+ * If you want to respond to the client with a custom status and/or body,
190
+ * you should do by returning a `Request` argument which will stop
191
+ * further execution.
192
+ */
193
+ onOperation?: (req: Request<RawRequest, Context>, args: ExecutionArgs, result: ExecutionResult) => Promise<ExecutionResult | Response | void> | ExecutionResult | Response | void;
194
+ }
195
+ /**
196
+ * The ready-to-use handler. Simply plug it in your favourite HTTP framework
197
+ * and enjoy.
198
+ *
199
+ * Errors thrown from **any** of the provided options or callbacks (or even due to
200
+ * library misuse or potential bugs) will reject the handler's promise. They are
201
+ * considered internal errors and you should take care of them accordingly.
202
+ *
203
+ * @category Server
204
+ */
205
+ export declare type Handler<RawRequest = unknown, Context = unknown> = (req: Request<RawRequest, Context>) => Promise<Response>;
206
+ /**
207
+ * Makes a GraphQL over HTTP Protocol compliant server handler. The handler can
208
+ * be used with your favourite server library.
209
+ *
210
+ * Beware that the handler resolves only after the whole operation completes.
211
+ *
212
+ * Errors thrown from **any** of the provided options or callbacks (or even due to
213
+ * library misuse or potential bugs) will reject the handler's promise. They are
214
+ * considered internal errors and you should take care of them accordingly.
215
+ *
216
+ * For production environments, its recommended not to transmit the exact internal
217
+ * error details to the client, but instead report to an error logging tool or simply
218
+ * the console.
219
+ *
220
+ * Simple example usage with Node:
221
+ *
222
+ * ```js
223
+ * import http from 'http';
224
+ * import { createHandler } from 'graphql-http';
225
+ * import { schema } from './my-graphql-schema';
226
+ *
227
+ * // Create the GraphQL over HTTP handler
228
+ * const handler = createHandler({ schema });
229
+ *
230
+ * // Create a HTTP server using the handler on `/graphql`
231
+ * const server = http.createServer(async (req, res) => {
232
+ * if (!req.url.startsWith('/graphql')) {
233
+ * return res.writeHead(404).end();
234
+ * }
235
+ *
236
+ * try {
237
+ * const [body, init] = await handler({
238
+ * url: req.url,
239
+ * method: req.method,
240
+ * headers: req.headers,
241
+ * body: () => new Promise((resolve) => {
242
+ * let body = '';
243
+ * req.on('data', (chunk) => (body += chunk));
244
+ * req.on('end', () => resolve(body));
245
+ * }),
246
+ * raw: req,
247
+ * });
248
+ * res.writeHead(init.status, init.statusText, init.headers).end(body);
249
+ * } catch (err) {
250
+ * // BEWARE not to transmit the exact internal error message in production environments
251
+ * res.writeHead(500).end(err.message);
252
+ * }
253
+ * });
254
+ *
255
+ * server.listen(4000);
256
+ * console.log('Listening to port 4000');
257
+ * ```
258
+ *
259
+ * @category Server
260
+ */
261
+ export declare function createHandler<RawRequest = unknown, Context = unknown>(options: HandlerOptions<RawRequest, Context>): Handler<RawRequest, Context>;
262
+ /**
263
+ * Request's Media-Type that the server accepts.
264
+ *
265
+ * @category Server
266
+ */
267
+ export declare type AcceptableMediaType = 'application/graphql-response+json' | 'application/json';
268
+ /**
269
+ * Inspects the request and detects the appropriate/acceptable Media-Type
270
+ * looking at the `Accept` header while complying with the GraphQL over HTTP Protocol.
271
+ *
272
+ * @category Server
273
+ */
274
+ export declare function getAcceptableMediaType(acceptHeader: string | null | undefined): AcceptableMediaType | null;
275
+ /**
276
+ * Creates an appropriate GraphQL over HTTP response following the provided arguments.
277
+ *
278
+ * If the first argument is an `ExecutionResult`, the operation will be treated as "successful".
279
+ *
280
+ * If the first argument is _any_ object without the `data` field, it will be treated as an error (as per the spec)
281
+ * and the response will be constructed with the help of `acceptedMediaType` complying with the GraphQL over HTTP Protocol.
282
+ *
283
+ * @category Server
284
+ */
285
+ export declare function makeResponse(resultOrErrors: Readonly<ExecutionResult> | Readonly<GraphQLError[]> | Readonly<GraphQLError>, acceptedMediaType: AcceptableMediaType): Response;
package/lib/handler.d.ts CHANGED
@@ -238,7 +238,7 @@ export declare type Handler<RawRequest = unknown, Context = unknown> = (req: Req
238
238
  * url: req.url,
239
239
  * method: req.method,
240
240
  * headers: req.headers,
241
- * body: await new Promise((resolve) => {
241
+ * body: () => new Promise((resolve) => {
242
242
  * let body = '';
243
243
  * req.on('data', (chunk) => (body += chunk));
244
244
  * req.on('end', () => resolve(body));
package/lib/handler.js CHANGED
@@ -55,7 +55,7 @@ exports.isResponse = isResponse;
55
55
  * url: req.url,
56
56
  * method: req.method,
57
57
  * headers: req.headers,
58
- * body: await new Promise((resolve) => {
58
+ * body: () => new Promise((resolve) => {
59
59
  * let body = '';
60
60
  * req.on('data', (chunk) => (body += chunk));
61
61
  * req.on('end', () => resolve(body));
package/lib/handler.mjs CHANGED
@@ -35,7 +35,7 @@ export function isResponse(val) {
35
35
  * ```js
36
36
  * import http from 'http';
37
37
  * import { createHandler } from 'graphql-http';
38
- * import { schema } from './my-graphql-schema.mjs';
38
+ * import { schema } from './my-graphql-schema/index.mjs';
39
39
  *
40
40
  * // Create the GraphQL over HTTP handler
41
41
  * const handler = createHandler({ schema });
@@ -51,7 +51,7 @@ export function isResponse(val) {
51
51
  * url: req.url,
52
52
  * method: req.method,
53
53
  * headers: req.headers,
54
- * body: await new Promise((resolve) => {
54
+ * body: () => new Promise((resolve) => {
55
55
  * let body = '';
56
56
  * req.on('data', (chunk) => (body += chunk));
57
57
  * req.on('end', () => resolve(body));
@@ -0,0 +1,4 @@
1
+ export * from './common';
2
+ export * from './handler';
3
+ export * from './client';
4
+ export * from './audits';
package/lib/index.d.ts CHANGED
@@ -1,3 +1,4 @@
1
1
  export * from './common';
2
2
  export * from './handler';
3
3
  export * from './client';
4
+ export * from './audits';
package/lib/index.js CHANGED
@@ -17,3 +17,4 @@ Object.defineProperty(exports, "__esModule", { value: true });
17
17
  __exportStar(require("./common"), exports);
18
18
  __exportStar(require("./handler"), exports);
19
19
  __exportStar(require("./client"), exports);
20
+ __exportStar(require("./audits"), exports);
package/lib/index.mjs CHANGED
@@ -1,3 +1,4 @@
1
1
  export * from './common.mjs';
2
2
  export * from './handler.mjs';
3
3
  export * from './client.mjs';
4
+ export * from './audits/index.mjs';
@@ -0,0 +1,16 @@
1
+ /**
2
+ *
3
+ * utils
4
+ *
5
+ */
6
+ import type { ExecutionResult, GraphQLError } from 'graphql';
7
+ /** @private */
8
+ export declare function extendedTypeof(val: unknown): 'string' | 'number' | 'bigint' | 'boolean' | 'symbol' | 'undefined' | 'object' | 'function' | 'array' | 'null';
9
+ /** @private */
10
+ export declare function isObject(val: unknown): val is Record<PropertyKey, any>;
11
+ /** @private */
12
+ export declare function areGraphQLErrors(obj: unknown): obj is readonly GraphQLError[];
13
+ /** @private */
14
+ export declare function isExecutionResult(val: unknown): val is ExecutionResult;
15
+ /** @private */
16
+ export declare function isAsyncIterable<T = unknown>(val: unknown): val is AsyncIterable<T>;
package/lib/utils.d.ts CHANGED
@@ -5,6 +5,8 @@
5
5
  */
6
6
  import type { ExecutionResult, GraphQLError } from 'graphql';
7
7
  /** @private */
8
+ export declare function extendedTypeof(val: unknown): 'string' | 'number' | 'bigint' | 'boolean' | 'symbol' | 'undefined' | 'object' | 'function' | 'array' | 'null';
9
+ /** @private */
8
10
  export declare function isObject(val: unknown): val is Record<PropertyKey, any>;
9
11
  /** @private */
10
12
  export declare function areGraphQLErrors(obj: unknown): obj is readonly GraphQLError[];
package/lib/utils.js CHANGED
@@ -5,7 +5,18 @@
5
5
  *
6
6
  */
7
7
  Object.defineProperty(exports, "__esModule", { value: true });
8
- exports.isAsyncIterable = exports.isExecutionResult = exports.areGraphQLErrors = exports.isObject = void 0;
8
+ exports.isAsyncIterable = exports.isExecutionResult = exports.areGraphQLErrors = exports.isObject = exports.extendedTypeof = void 0;
9
+ /** @private */
10
+ function extendedTypeof(val) {
11
+ if (val === null) {
12
+ return 'null';
13
+ }
14
+ if (Array.isArray(val)) {
15
+ return 'array';
16
+ }
17
+ return typeof val;
18
+ }
19
+ exports.extendedTypeof = extendedTypeof;
9
20
  /** @private */
10
21
  function isObject(val) {
11
22
  return typeof val === 'object' && val !== null;
package/lib/utils.mjs CHANGED
@@ -4,6 +4,16 @@
4
4
  *
5
5
  */
6
6
  /** @private */
7
+ export function extendedTypeof(val) {
8
+ if (val === null) {
9
+ return 'null';
10
+ }
11
+ if (Array.isArray(val)) {
12
+ return 'array';
13
+ }
14
+ return typeof val;
15
+ }
16
+ /** @private */
7
17
  export function isObject(val) {
8
18
  return typeof val === 'object' && val !== null;
9
19
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "graphql-http",
3
- "version": "1.4.0",
3
+ "version": "1.6.1",
4
4
  "description": "Simple, pluggable, zero-dependency, GraphQL over HTTP Protocol compliant server and client",
5
5
  "keywords": [
6
6
  "graphql",
@@ -24,7 +24,7 @@
24
24
  "engines": {
25
25
  "node": ">=12"
26
26
  },
27
- "packageManager": "yarn@3.2.2",
27
+ "packageManager": "yarn@3.2.3",
28
28
  "main": "lib/index.js",
29
29
  "module": "lib/index.mjs",
30
30
  "browser": "umd/graphql-http.js",
@@ -55,45 +55,50 @@
55
55
  "lint": "eslint 'src'",
56
56
  "type-check": "tsc --noEmit",
57
57
  "test": "NODE_OPTIONS=--experimental-vm-modules jest",
58
- "build:esm": "tsc -b tsconfig.esm.json && node scripts/esm-post-process.js",
58
+ "build:esm": "tsc -b tsconfig.esm.json && node scripts/esm-post-process.mjs",
59
59
  "build:cjs": "tsc -b tsconfig.cjs.json",
60
60
  "build:umd": "rollup -c && gzip umd/graphql-http.min.js -c > umd/graphql-http.min.js.gz",
61
61
  "build": "yarn build:esm && yarn build:cjs && yarn build:umd",
62
62
  "release": "semantic-release"
63
63
  },
64
+ "workspaces": [
65
+ "implementations/*"
66
+ ],
64
67
  "peerDependencies": {
65
68
  "graphql": ">=0.11 <=16"
66
69
  },
67
70
  "devDependencies": {
68
- "@babel/core": "^7.18.10",
71
+ "@babel/core": "^7.18.13",
69
72
  "@babel/plugin-proposal-class-properties": "^7.18.6",
70
73
  "@babel/plugin-proposal-nullish-coalescing-operator": "^7.18.6",
71
74
  "@babel/plugin-proposal-object-rest-spread": "^7.18.9",
72
75
  "@babel/plugin-proposal-optional-chaining": "^7.18.9",
73
76
  "@babel/preset-env": "^7.18.10",
74
77
  "@babel/preset-typescript": "^7.18.6",
75
- "@rollup/plugin-typescript": "^8.3.4",
78
+ "@rollup/plugin-typescript": "^8.4.0",
76
79
  "@semantic-release/changelog": "^6.0.1",
77
80
  "@semantic-release/git": "^10.0.1",
78
- "@types/jest": "^28.1.7",
79
- "@typescript-eslint/eslint-plugin": "^5.33.1",
80
- "@typescript-eslint/parser": "^5.33.1",
81
- "babel-jest": "^28.1.3",
82
- "eslint": "^8.22.0",
81
+ "@types/jest": "^29.0.0",
82
+ "@typescript-eslint/eslint-plugin": "^5.36.1",
83
+ "@typescript-eslint/parser": "^5.36.1",
84
+ "babel-jest": "^29.0.1",
85
+ "eslint": "^8.23.0",
83
86
  "eslint-config-prettier": "^8.5.0",
84
87
  "eslint-plugin-prettier": "^4.2.1",
85
- "graphql": "^16.5.0",
86
- "jest": "^28.1.3",
87
- "jest-jasmine2": "^28.1.3",
88
+ "graphql": "^16.6.0",
89
+ "jest": "^29.0.1",
90
+ "jest-jasmine2": "^29.0.1",
88
91
  "node-fetch": "^3.2.10",
89
92
  "prettier": "^2.7.1",
90
- "replacestream": "^4.0.3",
91
- "rollup": "^2.78.0",
93
+ "rollup": "^2.79.0",
92
94
  "rollup-plugin-terser": "^7.0.2",
93
- "semantic-release": "^19.0.3",
95
+ "semantic-release": "^19.0.5",
94
96
  "tslib": "^2.4.0",
95
- "typedoc": "^0.23.10",
96
- "typedoc-plugin-markdown": "^3.13.4",
97
- "typescript": "^4.7.4"
97
+ "typedoc": "^0.23.13",
98
+ "typedoc-plugin-markdown": "^3.13.5",
99
+ "typescript": "^4.8.2"
100
+ },
101
+ "resolutions": {
102
+ "npm/libnpmversion": "^3.0.6"
98
103
  }
99
104
  }
Binary file