graphql-http 1.19.0 → 1.21.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.
package/lib/handler.mjs CHANGED
@@ -4,13 +4,9 @@
4
4
  *
5
5
  */
6
6
  import { validate as graphqlValidate, specifiedRules, execute as graphqlExecute, parse as graphqlParse, getOperationAST as graphqlGetOperationAST, GraphQLError, } from 'graphql';
7
- import { areGraphQLErrors, isAsyncIterable, isExecutionResult, isGraphQLError, isObject, jsonErrorReplacer, } from './utils.mjs';
8
- /**
9
- * Checks whether the passed value is the `graphql-http` server agnostic response.
10
- *
11
- * @category Server
12
- */
13
- export function isResponse(val) {
7
+ import { isAsyncIterable, isExecutionResult, isObject } from './utils.mjs';
8
+ /** Checks whether the passed value is the `graphql-http` server agnostic response. */
9
+ function isResponse(val) {
14
10
  // TODO: make sure the contents of init match ResponseInit
15
11
  return (Array.isArray(val) &&
16
12
  (typeof val[0] === 'string' || val[0] === null) &&
@@ -18,7 +14,7 @@ export function isResponse(val) {
18
14
  }
19
15
  /**
20
16
  * Makes a GraphQL over HTTP spec compliant server handler. The handler can
21
- * be used with your favourite server library.
17
+ * be used with your favorite server library.
22
18
  *
23
19
  * Beware that the handler resolves only after the whole operation completes.
24
20
  *
@@ -72,23 +68,32 @@ export function isResponse(val) {
72
68
  * @category Server
73
69
  */
74
70
  export function createHandler(options) {
75
- const { schema, context, validate = graphqlValidate, validationRules = [], execute = graphqlExecute, parse = graphqlParse, getOperationAST = graphqlGetOperationAST, rootValue, onSubscribe, onOperation, formatError = (err) => err, } = options;
71
+ const { schema, context, validate = graphqlValidate, validationRules = [], execute = graphqlExecute, parse = graphqlParse, getOperationAST = graphqlGetOperationAST, rootValue, onSubscribe, onOperation, formatError = (err) => err, parseRequestParams = defaultParseRequestParams, } = options;
76
72
  return async function handler(req) {
77
- var _a, _b;
78
- const method = req.method;
79
- if (method !== 'GET' && method !== 'POST') {
80
- return [
81
- null,
82
- {
83
- status: 405,
84
- statusText: 'Method Not Allowed',
85
- headers: {
86
- allow: 'GET, POST',
87
- },
88
- },
89
- ];
73
+ let acceptedMediaType = null;
74
+ const accepts = (getHeader(req, 'accept') || '*/*')
75
+ .replace(/\s/g, '')
76
+ .toLowerCase()
77
+ .split(',');
78
+ for (const accept of accepts) {
79
+ // accept-charset became obsolete, shouldnt be used (https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept-Charset)
80
+ // TODO: handle the weight parameter "q"
81
+ 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;
83
+ if (mediaType === 'application/graphql-response+json' &&
84
+ charset === 'charset=utf8') {
85
+ acceptedMediaType = 'application/graphql-response+json';
86
+ break;
87
+ }
88
+ // application/json should be the default until watershed
89
+ if ((mediaType === 'application/json' ||
90
+ mediaType === 'application/*' ||
91
+ mediaType === '*/*') &&
92
+ charset === 'charset=utf8') {
93
+ acceptedMediaType = 'application/json';
94
+ break;
95
+ }
90
96
  }
91
- const acceptedMediaType = getAcceptableMediaType(getHeader(req, 'accept'));
92
97
  if (!acceptedMediaType) {
93
98
  return [
94
99
  null,
@@ -101,89 +106,14 @@ export function createHandler(options) {
101
106
  },
102
107
  ];
103
108
  }
104
- // TODO: should graphql-http care about content-encoding? I'd say unzipping should happen before handler is reached
105
- 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)
106
- ] = (getHeader(req, 'content-type') || '')
107
- .replace(/\s/g, '')
108
- .toLowerCase()
109
- .split(';');
110
109
  let params;
111
110
  try {
112
- const partParams = {};
113
- switch (true) {
114
- case method === 'GET': {
115
- // TODO: what if content-type is specified and is not application/x-www-form-urlencoded?
116
- try {
117
- const [, search] = req.url.split('?');
118
- const searchParams = new URLSearchParams(search);
119
- partParams.operationName =
120
- (_a = searchParams.get('operationName')) !== null && _a !== void 0 ? _a : undefined;
121
- partParams.query = (_b = searchParams.get('query')) !== null && _b !== void 0 ? _b : undefined;
122
- const variables = searchParams.get('variables');
123
- if (variables)
124
- partParams.variables = JSON.parse(variables);
125
- const extensions = searchParams.get('extensions');
126
- if (extensions)
127
- partParams.extensions = JSON.parse(extensions);
128
- }
129
- catch (_c) {
130
- throw new Error('Unparsable URL');
131
- }
132
- break;
133
- }
134
- case method === 'POST' &&
135
- mediaType === 'application/json' &&
136
- charset === 'charset=utf-8':
137
- {
138
- if (!req.body) {
139
- throw new Error('Missing body');
140
- }
141
- let data;
142
- try {
143
- const body = typeof req.body === 'function' ? await req.body() : req.body;
144
- data = typeof body === 'string' ? JSON.parse(body) : body;
145
- }
146
- catch (err) {
147
- throw new Error('Unparsable JSON body');
148
- }
149
- if (!isObject(data)) {
150
- throw new Error('JSON body must be an object');
151
- }
152
- partParams.operationName = data.operationName;
153
- partParams.query = data.query;
154
- partParams.variables = data.variables;
155
- partParams.extensions = data.extensions;
156
- break;
157
- }
158
- default: // graphql-http doesnt support any other content type
159
- return [
160
- null,
161
- {
162
- status: 415,
163
- statusText: 'Unsupported Media Type',
164
- },
165
- ];
166
- }
167
- if (partParams.query == null)
168
- throw new Error('Missing query');
169
- if (typeof partParams.query !== 'string')
170
- throw new Error('Invalid query');
171
- if (partParams.variables != null &&
172
- (typeof partParams.variables !== 'object' ||
173
- Array.isArray(partParams.variables))) {
174
- throw new Error('Invalid variables');
175
- }
176
- if (partParams.operationName != null &&
177
- typeof partParams.operationName !== 'string') {
178
- throw new Error('Invalid operationName');
179
- }
180
- if (partParams.extensions != null &&
181
- (typeof partParams.extensions !== 'object' ||
182
- Array.isArray(partParams.extensions))) {
183
- throw new Error('Invalid extensions');
184
- }
185
- // request parameters are checked and now complete
186
- params = partParams;
111
+ let paramsOrRes = await parseRequestParams(req);
112
+ if (!paramsOrRes)
113
+ paramsOrRes = await defaultParseRequestParams(req);
114
+ if (isResponse(paramsOrRes))
115
+ return paramsOrRes;
116
+ params = paramsOrRes;
187
117
  }
188
118
  catch (err) {
189
119
  return makeResponse(err, acceptedMediaType, formatError);
@@ -245,7 +175,7 @@ export function createHandler(options) {
245
175
  throw null;
246
176
  operation = ast.operation;
247
177
  }
248
- catch (_d) {
178
+ catch (_a) {
249
179
  return makeResponse(new GraphQLError('Unable to detect operation AST'), acceptedMediaType, formatError);
250
180
  }
251
181
  if (operation === 'subscription') {
@@ -253,7 +183,7 @@ export function createHandler(options) {
253
183
  }
254
184
  // mutations cannot happen over GETs
255
185
  // https://graphql.github.io/graphql-over-http/draft/#sel-CALFJRPAAELBAAxwP
256
- if (operation === 'mutation' && method === 'GET') {
186
+ if (operation === 'mutation' && req.method === 'GET') {
257
187
  return [
258
188
  JSON.stringify({
259
189
  errors: [new GraphQLError('Cannot perform mutations over GET')],
@@ -289,36 +219,108 @@ export function createHandler(options) {
289
219
  };
290
220
  }
291
221
  /**
292
- * Inspects the request and detects the appropriate/acceptable Media-Type
293
- * looking at the `Accept` header while complying with the GraphQL over HTTP spec.
222
+ * The default request params parser. Used when no custom one is provided or if it
223
+ * returns nothing.
294
224
  *
295
- * @category Server
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
296
228
  */
297
- export function getAcceptableMediaType(acceptHeader) {
298
- let acceptedMediaType = null;
299
- const accepts = (acceptHeader || '*/*')
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') || '')
300
246
  .replace(/\s/g, '')
301
247
  .toLowerCase()
302
- .split(',');
303
- for (const accept of accepts) {
304
- // accept-charset became obsolete, shouldnt be used (https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept-Charset)
305
- // TODO: handle the weight parameter "q"
306
- const [mediaType, ...params] = accept.split(';');
307
- const charset = (params === null || params === void 0 ? void 0 : params.find((param) => param.includes('charset='))) || 'charset=utf8'; // utf-8 is assumed when not specified;
308
- if (mediaType === 'application/graphql-response+json' &&
309
- charset === 'charset=utf8') {
310
- acceptedMediaType = 'application/graphql-response+json';
311
- break;
312
- }
313
- if ((mediaType === 'application/json' ||
314
- mediaType === 'application/*' ||
315
- mediaType === '*/*') &&
316
- charset === 'charset=utf8') {
317
- acceptedMediaType = 'application/json';
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
+ }
318
269
  break;
319
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');
320
316
  }
321
- return acceptedMediaType;
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;
322
324
  }
323
325
  /**
324
326
  * Creates an appropriate GraphQL over HTTP response following the provided arguments.
@@ -330,10 +332,8 @@ export function getAcceptableMediaType(acceptHeader) {
330
332
  *
331
333
  * If the first argument is an `Error`, the operation will be treated as a bad request responding with `400: Bad Request` and the
332
334
  * error will be present in the `ExecutionResult` style.
333
- *
334
- * @category Server
335
335
  */
336
- export function makeResponse(resultOrErrors, acceptedMediaType, formatError) {
336
+ function makeResponse(resultOrErrors, acceptedMediaType, formatError) {
337
337
  if (resultOrErrors instanceof Error &&
338
338
  // because GraphQLError extends the Error class
339
339
  !isGraphQLError(resultOrErrors)) {
@@ -391,3 +391,26 @@ function getHeader(req, key) {
391
391
  }
392
392
  return Object(req.headers)[key];
393
393
  }
394
+ function areGraphQLErrors(obj) {
395
+ return (Array.isArray(obj) &&
396
+ obj.length > 0 &&
397
+ // if one item in the array is a GraphQLError, we're good
398
+ obj.some(isGraphQLError));
399
+ }
400
+ function isGraphQLError(obj) {
401
+ return obj instanceof GraphQLError;
402
+ }
403
+ function jsonErrorReplacer(_key,
404
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
405
+ val) {
406
+ if (val instanceof Error &&
407
+ // GraphQL errors implement their own stringer
408
+ !isGraphQLError(val)) {
409
+ return {
410
+ // name: val.name, name is included in message
411
+ message: val.message,
412
+ // stack: val.stack, can leak sensitive details
413
+ };
414
+ }
415
+ return val;
416
+ }
@@ -0,0 +1,14 @@
1
+ import { HandlerOptions as RawHandlerOptions, OperationContext } from '../../handler.mjs';
2
+ import type { Handler as NetlifyHandler, HandlerEvent as NetlifyHandlerEvent, HandlerContext as NetlifyHandlerContext } from '@netlify/functions';
3
+ /**
4
+ * Handler options when using the netlify adapter
5
+ *
6
+ * @category Server/@netlify/functions
7
+ */
8
+ export type HandlerOptions<Context extends OperationContext = undefined> = RawHandlerOptions<NetlifyHandlerEvent, NetlifyHandlerContext, Context>;
9
+ /**
10
+ * Create a GraphQL over HTTP spec compliant request handler for netlify functions
11
+ *
12
+ * @category Server/@netlify/functions
13
+ */
14
+ export declare function createHandler<Context extends OperationContext = undefined>(options: HandlerOptions<Context>): NetlifyHandler;
@@ -0,0 +1,14 @@
1
+ import { HandlerOptions as RawHandlerOptions, OperationContext } from '../../handler';
2
+ import type { Handler as NetlifyHandler, HandlerEvent as NetlifyHandlerEvent, HandlerContext as NetlifyHandlerContext } from '@netlify/functions';
3
+ /**
4
+ * Handler options when using the netlify adapter
5
+ *
6
+ * @category Server/@netlify/functions
7
+ */
8
+ export type HandlerOptions<Context extends OperationContext = undefined> = RawHandlerOptions<NetlifyHandlerEvent, NetlifyHandlerContext, Context>;
9
+ /**
10
+ * Create a GraphQL over HTTP spec compliant request handler for netlify functions
11
+ *
12
+ * @category Server/@netlify/functions
13
+ */
14
+ export declare function createHandler<Context extends OperationContext = undefined>(options: HandlerOptions<Context>): NetlifyHandler;
@@ -0,0 +1,37 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createHandler = void 0;
4
+ const handler_1 = require("../../handler");
5
+ /**
6
+ * Create a GraphQL over HTTP spec compliant request handler for netlify functions
7
+ *
8
+ * @category Server/@netlify/functions
9
+ */
10
+ function createHandler(options) {
11
+ const handler = (0, handler_1.createHandler)(options);
12
+ return async function handleRequest(req, ctx) {
13
+ try {
14
+ const [body, init] = await handler({
15
+ method: req.httpMethod,
16
+ url: req.rawUrl,
17
+ headers: req.headers,
18
+ body: req.body,
19
+ raw: req,
20
+ context: ctx,
21
+ });
22
+ return {
23
+ // if body is null, return undefined
24
+ body: body !== null && body !== void 0 ? body : undefined,
25
+ statusCode: init.status,
26
+ };
27
+ }
28
+ catch (err) {
29
+ // The handler shouldnt throw errors.
30
+ // If you wish to handle them differently, consider implementing your own request handler.
31
+ console.error('Internal error occurred during request handling. ' +
32
+ 'Please check your implementation.', err);
33
+ return { statusCode: 500 };
34
+ }
35
+ };
36
+ }
37
+ exports.createHandler = createHandler;
@@ -0,0 +1,33 @@
1
+ import { createHandler as createRawHandler, } from '../../handler.mjs';
2
+ /**
3
+ * Create a GraphQL over HTTP spec compliant request handler for netlify functions
4
+ *
5
+ * @category Server/@netlify/functions
6
+ */
7
+ export function createHandler(options) {
8
+ const handler = createRawHandler(options);
9
+ return async function handleRequest(req, ctx) {
10
+ try {
11
+ const [body, init] = await handler({
12
+ method: req.httpMethod,
13
+ url: req.rawUrl,
14
+ headers: req.headers,
15
+ body: req.body,
16
+ raw: req,
17
+ context: ctx,
18
+ });
19
+ return {
20
+ // if body is null, return undefined
21
+ body: body !== null && body !== void 0 ? body : undefined,
22
+ statusCode: init.status,
23
+ };
24
+ }
25
+ catch (err) {
26
+ // The handler shouldnt throw errors.
27
+ // If you wish to handle them differently, consider implementing your own request handler.
28
+ console.error('Internal error occurred during request handling. ' +
29
+ 'Please check your implementation.', err);
30
+ return { statusCode: 500 };
31
+ }
32
+ };
33
+ }
package/lib/utils.d.mts CHANGED
@@ -4,18 +4,11 @@
4
4
  *
5
5
  */
6
6
  import type { ExecutionResult } from 'graphql';
7
- import { GraphQLError } from 'graphql';
8
7
  /** @private */
9
8
  export declare function extendedTypeof(val: unknown): 'string' | 'number' | 'bigint' | 'boolean' | 'symbol' | 'undefined' | 'object' | 'function' | 'array' | 'null';
10
9
  /** @private */
11
10
  export declare function isObject(val: unknown): val is Record<PropertyKey, any>;
12
11
  /** @private */
13
- export declare function areGraphQLErrors(obj: unknown): obj is readonly GraphQLError[];
14
- /** @private */
15
- export declare function isGraphQLError(obj: unknown): obj is GraphQLError;
16
- /** @private */
17
12
  export declare function isExecutionResult(val: unknown): val is ExecutionResult;
18
13
  /** @private */
19
14
  export declare function isAsyncIterable<T = unknown>(val: unknown): val is AsyncIterable<T>;
20
- /** @private */
21
- export declare function jsonErrorReplacer(_key: string, val: any): any;
package/lib/utils.d.ts CHANGED
@@ -4,18 +4,11 @@
4
4
  *
5
5
  */
6
6
  import type { ExecutionResult } from 'graphql';
7
- import { GraphQLError } from 'graphql';
8
7
  /** @private */
9
8
  export declare function extendedTypeof(val: unknown): 'string' | 'number' | 'bigint' | 'boolean' | 'symbol' | 'undefined' | 'object' | 'function' | 'array' | 'null';
10
9
  /** @private */
11
10
  export declare function isObject(val: unknown): val is Record<PropertyKey, any>;
12
11
  /** @private */
13
- export declare function areGraphQLErrors(obj: unknown): obj is readonly GraphQLError[];
14
- /** @private */
15
- export declare function isGraphQLError(obj: unknown): obj is GraphQLError;
16
- /** @private */
17
12
  export declare function isExecutionResult(val: unknown): val is ExecutionResult;
18
13
  /** @private */
19
14
  export declare function isAsyncIterable<T = unknown>(val: unknown): val is AsyncIterable<T>;
20
- /** @private */
21
- export declare function jsonErrorReplacer(_key: string, val: any): any;
package/lib/utils.js CHANGED
@@ -5,8 +5,7 @@
5
5
  *
6
6
  */
7
7
  Object.defineProperty(exports, "__esModule", { value: true });
8
- exports.jsonErrorReplacer = exports.isAsyncIterable = exports.isExecutionResult = exports.isGraphQLError = exports.areGraphQLErrors = exports.isObject = exports.extendedTypeof = void 0;
9
- const graphql_1 = require("graphql");
8
+ exports.isAsyncIterable = exports.isExecutionResult = exports.isObject = exports.extendedTypeof = void 0;
10
9
  /** @private */
11
10
  function extendedTypeof(val) {
12
11
  if (val === null) {
@@ -24,19 +23,6 @@ function isObject(val) {
24
23
  }
25
24
  exports.isObject = isObject;
26
25
  /** @private */
27
- function areGraphQLErrors(obj) {
28
- return (Array.isArray(obj) &&
29
- obj.length > 0 &&
30
- // if one item in the array is a GraphQLError, we're good
31
- obj.some(isGraphQLError));
32
- }
33
- exports.areGraphQLErrors = areGraphQLErrors;
34
- /** @private */
35
- function isGraphQLError(obj) {
36
- return obj instanceof graphql_1.GraphQLError;
37
- }
38
- exports.isGraphQLError = isGraphQLError;
39
- /** @private */
40
26
  function isExecutionResult(val) {
41
27
  return (isObject(val) &&
42
28
  ('data' in val || ('data' in val && val.data == null && 'errors' in val)));
@@ -47,17 +33,3 @@ function isAsyncIterable(val) {
47
33
  return typeof Object(val)[Symbol.asyncIterator] === 'function';
48
34
  }
49
35
  exports.isAsyncIterable = isAsyncIterable;
50
- /** @private */
51
- function jsonErrorReplacer(_key, val) {
52
- if (val instanceof Error &&
53
- // GraphQL errors implement their own stringer
54
- !isGraphQLError(val)) {
55
- return {
56
- // name: val.name, name is included in message
57
- message: val.message,
58
- // stack: val.stack, can leak sensitive details
59
- };
60
- }
61
- return val;
62
- }
63
- exports.jsonErrorReplacer = jsonErrorReplacer;
package/lib/utils.mjs CHANGED
@@ -3,7 +3,6 @@
3
3
  * utils
4
4
  *
5
5
  */
6
- import { GraphQLError } from 'graphql';
7
6
  /** @private */
8
7
  export function extendedTypeof(val) {
9
8
  if (val === null) {
@@ -19,17 +18,6 @@ export function isObject(val) {
19
18
  return typeof val === 'object' && val !== null;
20
19
  }
21
20
  /** @private */
22
- export function areGraphQLErrors(obj) {
23
- return (Array.isArray(obj) &&
24
- obj.length > 0 &&
25
- // if one item in the array is a GraphQLError, we're good
26
- obj.some(isGraphQLError));
27
- }
28
- /** @private */
29
- export function isGraphQLError(obj) {
30
- return obj instanceof GraphQLError;
31
- }
32
- /** @private */
33
21
  export function isExecutionResult(val) {
34
22
  return (isObject(val) &&
35
23
  ('data' in val || ('data' in val && val.data == null && 'errors' in val)));
@@ -38,16 +26,3 @@ export function isExecutionResult(val) {
38
26
  export function isAsyncIterable(val) {
39
27
  return typeof Object(val)[Symbol.asyncIterator] === 'function';
40
28
  }
41
- /** @private */
42
- export function jsonErrorReplacer(_key, val) {
43
- if (val instanceof Error &&
44
- // GraphQL errors implement their own stringer
45
- !isGraphQLError(val)) {
46
- return {
47
- // name: val.name, name is included in message
48
- message: val.message,
49
- // stack: val.stack, can leak sensitive details
50
- };
51
- }
52
- return val;
53
- }