graphql-http 0.2.0 → 1.2.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.
@@ -0,0 +1,279 @@
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
+ readonly body: string | Record<string, unknown> | null;
36
+ /**
37
+ * The raw request itself from the implementing server.
38
+ *
39
+ * For example: `express.Request` when using Express, or maybe
40
+ * `http.IncomingMessage` when just using Node with `http.createServer`.
41
+ */
42
+ readonly raw: RawRequest;
43
+ /**
44
+ * Context value about the incoming request, you're free to pass any information here.
45
+ */
46
+ readonly context: Context;
47
+ }
48
+ /**
49
+ * The response headers that get returned from graphql-http.
50
+ *
51
+ * @category Common
52
+ */
53
+ export declare type ResponseHeaders = {
54
+ accept?: string;
55
+ allow?: string;
56
+ 'content-type'?: string;
57
+ } & Record<string, string>;
58
+ /**
59
+ * Server agnostic response body returned from `graphql-http` needing
60
+ * to be coerced to the server implementation in use.
61
+ *
62
+ * @category Common
63
+ */
64
+ export declare type ResponseBody = string;
65
+ /**
66
+ * Server agnostic response options (ex. status and headers) returned from
67
+ * `graphql-http` needing to be coerced to the server implementation in use.
68
+ *
69
+ * @category Common
70
+ */
71
+ export interface ResponseInit {
72
+ readonly status: number;
73
+ readonly statusText: string;
74
+ readonly headers?: ResponseHeaders;
75
+ }
76
+ /**
77
+ * Server agnostic response returned from `graphql-http` containing the
78
+ * body and init options needing to be coerced to the server implementation in use.
79
+ *
80
+ * @category Common
81
+ */
82
+ export declare type Response = readonly [body: ResponseBody | null, init: ResponseInit];
83
+ /**
84
+ * Checks whether the passed value is the `graphql-http` server agnostic response.
85
+ *
86
+ * @category Common
87
+ */
88
+ export declare function isResponse(val: unknown): val is Response;
89
+ /**
90
+ * A concrete GraphQL execution context value type.
91
+ *
92
+ * Mainly used because TypeScript collapes unions
93
+ * with `any` or `unknown` to `any` or `unknown`. So,
94
+ * we use a custom type to allow definitions such as
95
+ * the `context` server option.
96
+ *
97
+ * @category Server
98
+ */
99
+ export declare type ExecutionContext = object | symbol | number | string | boolean | undefined | null;
100
+ /** @category Server */
101
+ export interface HandlerOptions<RawRequest = unknown, Context = unknown> {
102
+ /**
103
+ * The GraphQL schema on which the operations will
104
+ * be executed and validated against.
105
+ *
106
+ * If a function is provided, it will be called on every
107
+ * operation request allowing you to manipulate schema
108
+ * dynamically.
109
+ *
110
+ * If the schema is left undefined, you're trusted to
111
+ * provide one in the returned `ExecutionArgs` from the
112
+ * `onSubscribe` callback.
113
+ *
114
+ * If you want to respond to the client with a custom status and/or body,
115
+ * you should do by returning a `Request` argument which will stop
116
+ * further execution.
117
+ */
118
+ schema?: GraphQLSchema | ((req: Request<RawRequest, Context>, args: Omit<ExecutionArgs, 'schema'>) => Promise<GraphQLSchema | Response> | GraphQLSchema | Response);
119
+ /**
120
+ * A value which is provided to every resolver and holds
121
+ * important contextual information like the currently
122
+ * logged in user, or access to a database.
123
+ */
124
+ context?: ExecutionContext | ((req: Request<RawRequest, Context>, args: ExecutionArgs) => Promise<ExecutionContext | Response> | ExecutionContext | Response);
125
+ /**
126
+ * A custom GraphQL validate function allowing you to apply your
127
+ * own validation rules.
128
+ *
129
+ * Will not be used when implementing a custom `onSubscribe`.
130
+ */
131
+ validate?: typeof graphqlValidate;
132
+ /**
133
+ * Is the `execute` function from GraphQL which is
134
+ * used to execute the query and mutation operations.
135
+ */
136
+ execute?: typeof graphqlExecute;
137
+ /**
138
+ * GraphQL parse function allowing you to apply a custom parser.
139
+ */
140
+ parse?: typeof graphqlParse;
141
+ /**
142
+ * GraphQL operation AST getter used for detecting the operation type.
143
+ */
144
+ getOperationAST?: typeof graphqlGetOperationAST;
145
+ /**
146
+ * The subscribe callback executed right after processing the request
147
+ * before proceeding with the GraphQL operation execution.
148
+ *
149
+ * If you return `ExecutionResult` from the callback, it will be used
150
+ * directly for responding to the request. Useful for implementing a response
151
+ * cache.
152
+ *
153
+ * If you return `ExecutionArgs` from the callback, it will be used instead of
154
+ * trying to build one internally. In this case, you are responsible for providing
155
+ * a ready set of arguments which will be directly plugged in the operation execution.
156
+ *
157
+ * You *must* validate the `ExecutionArgs` yourself if returning them.
158
+ *
159
+ * If you return an array of `GraphQLError` from the callback, they will be reported
160
+ * to the client while complying with the spec.
161
+ *
162
+ * Omitting the fields `contextValue` from the returned `ExecutionArgs` will use the
163
+ * provided `context` option, if available.
164
+ *
165
+ * Useful for preparing the execution arguments following a custom logic. A typical
166
+ * use-case is persisted queries. You can identify the query from the request parameters
167
+ * and supply the appropriate GraphQL operation execution arguments.
168
+ *
169
+ * If you want to respond to the client with a custom status and/or body,
170
+ * you should do by returning a `Request` argument which will stop
171
+ * further execution.
172
+ */
173
+ onSubscribe?: (req: Request<RawRequest, Context>, params: RequestParams) => Promise<ExecutionResult | ExecutionArgs | readonly GraphQLError[] | Response | void> | ExecutionResult | ExecutionArgs | readonly GraphQLError[] | Response | void;
174
+ /**
175
+ * Executed after the operation call resolves.
176
+ *
177
+ * The `OperationResult` argument is the result of operation
178
+ * execution. It can be an iterator or already a value.
179
+ *
180
+ * Use this callback to listen for GraphQL operations and
181
+ * execution result manipulation.
182
+ *
183
+ * If you want to respond to the client with a custom status and/or body,
184
+ * you should do by returning a `Request` argument which will stop
185
+ * further execution.
186
+ */
187
+ onOperation?: (req: Request<RawRequest, Context>, args: ExecutionArgs, result: ExecutionResult) => Promise<ExecutionResult | Response | void> | ExecutionResult | Response | void;
188
+ }
189
+ /**
190
+ * The ready-to-use handler. Simply plug it in your favourite HTTP framework
191
+ * and enjoy.
192
+ *
193
+ * Errors thrown from **any** of the provided options or callbacks (or even due to
194
+ * library misuse or potential bugs) will reject the handler's promise. They are
195
+ * considered internal errors and you should take care of them accordingly.
196
+ *
197
+ * @category Server
198
+ */
199
+ export declare type Handler<RawRequest = unknown, Context = unknown> = (req: Request<RawRequest, Context>) => Promise<Response>;
200
+ /**
201
+ * Makes a GraphQL over HTTP Protocol compliant server handler. The handler can
202
+ * be used with your favourite server library.
203
+ *
204
+ * Beware that the handler resolves only after the whole operation completes.
205
+ *
206
+ * Errors thrown from **any** of the provided options or callbacks (or even due to
207
+ * library misuse or potential bugs) will reject the handler's promise. They are
208
+ * considered internal errors and you should take care of them accordingly.
209
+ *
210
+ * For production environments, its recommended not to transmit the exact internal
211
+ * error details to the client, but instead report to an error logging tool or simply
212
+ * the console.
213
+ *
214
+ * Simple example usage with Node:
215
+ *
216
+ * ```js
217
+ * import http from 'http';
218
+ * import { createHandler } from 'graphql-http';
219
+ * import { schema } from './my-graphql-schema';
220
+ *
221
+ * // Create the GraphQL over HTTP handler
222
+ * const handler = createHandler({ schema });
223
+ *
224
+ * // Create a HTTP server using the handler on `/graphql`
225
+ * const server = http.createServer(async (req, res) => {
226
+ * if (!req.url.startsWith('/graphql')) {
227
+ * return res.writeHead(404).end();
228
+ * }
229
+ *
230
+ * try {
231
+ * const [body, init] = await handler({
232
+ * url: req.url,
233
+ * method: req.method,
234
+ * headers: req.headers,
235
+ * body: await new Promise((resolve) => {
236
+ * let body = '';
237
+ * req.on('data', (chunk) => (body += chunk));
238
+ * req.on('end', () => resolve(body));
239
+ * }),
240
+ * raw: req,
241
+ * });
242
+ * res.writeHead(init.status, init.statusText, init.headers).end(body);
243
+ * } catch (err) {
244
+ * // BEWARE not to transmit the exact internal error message in production environments
245
+ * res.writeHead(500).end(err.message);
246
+ * }
247
+ * });
248
+ *
249
+ * server.listen(4000);
250
+ * console.log('Listening to port 4000');
251
+ * ```
252
+ *
253
+ * @category Server
254
+ */
255
+ export declare function createHandler<RawRequest = unknown, Context = unknown>(options: HandlerOptions<RawRequest, Context>): Handler<RawRequest, Context>;
256
+ /**
257
+ * Request's Media-Type that the server accepts.
258
+ *
259
+ * @category Server
260
+ */
261
+ export declare type AcceptableMediaType = 'application/graphql+json' | 'application/json';
262
+ /**
263
+ * Inspects the request and detects the appropriate/acceptable Media-Type
264
+ * looking at the `Accept` header while complying with the GraphQL over HTTP Protocol.
265
+ *
266
+ * @category Server
267
+ */
268
+ export declare function getAcceptableMediaType(acceptHeader: string | null | undefined): AcceptableMediaType | null;
269
+ /**
270
+ * Creates an appropriate GraphQL over HTTP response following the provided arguments.
271
+ *
272
+ * If the first argument is an `ExecutionResult`, the operation will be treated as "successful".
273
+ *
274
+ * If the first argument is _any_ object without the `data` field, it will be treated as an error (as per the spec)
275
+ * and the response will be constructed with the help of `acceptedMediaType` complying with the GraphQL over HTTP Protocol.
276
+ *
277
+ * @category Server
278
+ */
279
+ export declare function makeResponse(resultOrErrors: Readonly<ExecutionResult> | Readonly<GraphQLError[]> | Readonly<GraphQLError>, acceptedMediaType: AcceptableMediaType): Response;
package/lib/handler.js ADDED
@@ -0,0 +1,353 @@
1
+ "use strict";
2
+ /**
3
+ *
4
+ * handler
5
+ *
6
+ */
7
+ Object.defineProperty(exports, "__esModule", { value: true });
8
+ exports.makeResponse = exports.getAcceptableMediaType = exports.createHandler = exports.isResponse = void 0;
9
+ const graphql_1 = require("graphql");
10
+ const utils_1 = require("./utils");
11
+ /**
12
+ * Checks whether the passed value is the `graphql-http` server agnostic response.
13
+ *
14
+ * @category Common
15
+ */
16
+ function isResponse(val) {
17
+ // TODO: make sure the contents of init match ResponseInit
18
+ return (Array.isArray(val) &&
19
+ (typeof val[0] === 'string' || val[0] === null) &&
20
+ (0, utils_1.isObject)(val[1]));
21
+ }
22
+ exports.isResponse = isResponse;
23
+ /**
24
+ * Makes a GraphQL over HTTP Protocol compliant server handler. The handler can
25
+ * be used with your favourite server library.
26
+ *
27
+ * Beware that the handler resolves only after the whole operation completes.
28
+ *
29
+ * Errors thrown from **any** of the provided options or callbacks (or even due to
30
+ * library misuse or potential bugs) will reject the handler's promise. They are
31
+ * considered internal errors and you should take care of them accordingly.
32
+ *
33
+ * For production environments, its recommended not to transmit the exact internal
34
+ * error details to the client, but instead report to an error logging tool or simply
35
+ * the console.
36
+ *
37
+ * Simple example usage with Node:
38
+ *
39
+ * ```js
40
+ * import http from 'http';
41
+ * import { createHandler } from 'graphql-http';
42
+ * import { schema } from './my-graphql-schema';
43
+ *
44
+ * // Create the GraphQL over HTTP handler
45
+ * const handler = createHandler({ schema });
46
+ *
47
+ * // Create a HTTP server using the handler on `/graphql`
48
+ * const server = http.createServer(async (req, res) => {
49
+ * if (!req.url.startsWith('/graphql')) {
50
+ * return res.writeHead(404).end();
51
+ * }
52
+ *
53
+ * try {
54
+ * const [body, init] = await handler({
55
+ * url: req.url,
56
+ * method: req.method,
57
+ * headers: req.headers,
58
+ * body: await new Promise((resolve) => {
59
+ * let body = '';
60
+ * req.on('data', (chunk) => (body += chunk));
61
+ * req.on('end', () => resolve(body));
62
+ * }),
63
+ * raw: req,
64
+ * });
65
+ * res.writeHead(init.status, init.statusText, init.headers).end(body);
66
+ * } catch (err) {
67
+ * // BEWARE not to transmit the exact internal error message in production environments
68
+ * res.writeHead(500).end(err.message);
69
+ * }
70
+ * });
71
+ *
72
+ * server.listen(4000);
73
+ * console.log('Listening to port 4000');
74
+ * ```
75
+ *
76
+ * @category Server
77
+ */
78
+ function createHandler(options) {
79
+ const { schema, context, validate = graphql_1.validate, execute = graphql_1.execute, parse = graphql_1.parse, getOperationAST = graphql_1.getOperationAST, onSubscribe, onOperation, } = options;
80
+ return async function handler(req) {
81
+ var _a, _b;
82
+ const method = req.method;
83
+ if (method !== 'GET' && method !== 'POST') {
84
+ return [
85
+ null,
86
+ {
87
+ status: 405,
88
+ statusText: 'Method Not Allowed',
89
+ headers: {
90
+ allow: 'GET, POST',
91
+ },
92
+ },
93
+ ];
94
+ }
95
+ const acceptedMediaType = getAcceptableMediaType(req.headers.accept);
96
+ if (!acceptedMediaType) {
97
+ return [
98
+ null,
99
+ {
100
+ status: 406,
101
+ statusText: 'Not Acceptable',
102
+ headers: {
103
+ accept: 'application/graphql+json; charset=utf-8, application/json; charset=utf-8',
104
+ },
105
+ },
106
+ ];
107
+ }
108
+ // TODO: should graphql-http care about content-encoding? I'd say unzipping should happen before handler is reached
109
+ 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)
110
+ ] = (req.headers['content-type'] || '')
111
+ .replace(/\s/g, '')
112
+ .toLowerCase()
113
+ .split(';');
114
+ let params;
115
+ try {
116
+ const partParams = {};
117
+ switch (true) {
118
+ case method === 'GET': {
119
+ // TODO: what if content-type is specified and is not application/x-www-form-urlencoded?
120
+ try {
121
+ const [, search] = req.url.split('?');
122
+ const searchParams = new URLSearchParams(search);
123
+ partParams.operationName =
124
+ (_a = searchParams.get('operationName')) !== null && _a !== void 0 ? _a : undefined;
125
+ partParams.query = (_b = searchParams.get('query')) !== null && _b !== void 0 ? _b : undefined;
126
+ const variables = searchParams.get('variables');
127
+ if (variables)
128
+ partParams.variables = JSON.parse(variables);
129
+ const extensions = searchParams.get('extensions');
130
+ if (extensions)
131
+ partParams.extensions = JSON.parse(extensions);
132
+ }
133
+ catch (_c) {
134
+ throw new Error('Unparsable URL');
135
+ }
136
+ break;
137
+ }
138
+ case method === 'POST' &&
139
+ mediaType === 'application/json' &&
140
+ charset === 'charset=utf-8':
141
+ {
142
+ if (!req.body) {
143
+ throw new Error('Missing body');
144
+ }
145
+ try {
146
+ const data = typeof req.body === 'string' ? JSON.parse(req.body) : req.body;
147
+ partParams.operationName = data.operationName;
148
+ partParams.query = data.query;
149
+ partParams.variables = data.variables;
150
+ partParams.extensions = data.extensions;
151
+ }
152
+ catch (_d) {
153
+ throw new Error('Unparsable JSON body');
154
+ }
155
+ break;
156
+ }
157
+ default: // graphql-http doesnt support any other content type
158
+ return [
159
+ null,
160
+ {
161
+ status: 415,
162
+ statusText: 'Unsupported Media Type',
163
+ },
164
+ ];
165
+ }
166
+ if (partParams.query == null)
167
+ throw new Error('Missing query');
168
+ if (typeof partParams.query !== 'string')
169
+ throw new Error('Invalid query');
170
+ if (partParams.variables != null &&
171
+ (typeof partParams.variables !== 'object' ||
172
+ Array.isArray(partParams.variables))) {
173
+ throw new Error('Invalid variables');
174
+ }
175
+ if (partParams.extensions != null &&
176
+ (typeof partParams.extensions !== 'object' ||
177
+ Array.isArray(partParams.extensions))) {
178
+ throw new Error('Invalid extensions');
179
+ }
180
+ // request parameters are checked and now complete
181
+ params = partParams;
182
+ }
183
+ catch (err) {
184
+ return makeResponse(new graphql_1.GraphQLError(err.message), acceptedMediaType);
185
+ }
186
+ let args;
187
+ const maybeResErrsOrArgs = await (onSubscribe === null || onSubscribe === void 0 ? void 0 : onSubscribe(req, params));
188
+ if (isResponse(maybeResErrsOrArgs))
189
+ return maybeResErrsOrArgs;
190
+ else if ((0, utils_1.isExecutionResult)(maybeResErrsOrArgs) ||
191
+ (0, utils_1.areGraphQLErrors)(maybeResErrsOrArgs))
192
+ return makeResponse(maybeResErrsOrArgs, acceptedMediaType);
193
+ else if (maybeResErrsOrArgs)
194
+ args = maybeResErrsOrArgs;
195
+ else {
196
+ if (!schema)
197
+ throw new Error('The GraphQL schema is not provided');
198
+ const { operationName, query, variables } = params;
199
+ let document;
200
+ try {
201
+ document = parse(query);
202
+ }
203
+ catch (err) {
204
+ return makeResponse(err, acceptedMediaType);
205
+ }
206
+ const argsWithoutSchema = {
207
+ operationName,
208
+ document,
209
+ variableValues: variables,
210
+ };
211
+ if (typeof schema === 'function') {
212
+ const resOrSchema = await schema(req, argsWithoutSchema);
213
+ if (isResponse(resOrSchema))
214
+ return resOrSchema;
215
+ args = Object.assign(Object.assign({}, argsWithoutSchema), { schema: resOrSchema });
216
+ }
217
+ else {
218
+ args = Object.assign(Object.assign({}, argsWithoutSchema), { schema });
219
+ }
220
+ const validationErrs = validate(args.schema, args.document);
221
+ if (validationErrs.length) {
222
+ return makeResponse(validationErrs, acceptedMediaType);
223
+ }
224
+ }
225
+ let operation;
226
+ try {
227
+ const ast = getOperationAST(args.document, args.operationName);
228
+ if (!ast)
229
+ throw null;
230
+ operation = ast.operation;
231
+ }
232
+ catch (_e) {
233
+ return makeResponse(new graphql_1.GraphQLError('Unable to detect operation AST'), acceptedMediaType);
234
+ }
235
+ if (operation === 'subscription') {
236
+ return makeResponse(new graphql_1.GraphQLError('Subscriptions are not supported'), acceptedMediaType);
237
+ }
238
+ // mutations cannot happen over GETs
239
+ // https://graphql.github.io/graphql-over-http/draft/#sel-CALFJRPAAELBAAxwP
240
+ if (operation === 'mutation' && method === 'GET') {
241
+ return [
242
+ JSON.stringify({
243
+ errors: [new graphql_1.GraphQLError('Cannot perform mutations over GET')],
244
+ }),
245
+ {
246
+ status: 405,
247
+ statusText: 'Method Not Allowed',
248
+ headers: {
249
+ allow: 'POST',
250
+ },
251
+ },
252
+ ];
253
+ }
254
+ if (!('contextValue' in args)) {
255
+ const maybeResOrContext = typeof context === 'function' ? await context(req, args) : context;
256
+ if (isResponse(maybeResOrContext))
257
+ return maybeResOrContext;
258
+ args.contextValue = maybeResOrContext;
259
+ }
260
+ let result = await execute(args);
261
+ const maybeResponseOrResult = await (onOperation === null || onOperation === void 0 ? void 0 : onOperation(req, args, result));
262
+ if (isResponse(maybeResponseOrResult))
263
+ return maybeResponseOrResult;
264
+ else if (maybeResponseOrResult)
265
+ result = maybeResponseOrResult;
266
+ if ((0, utils_1.isAsyncIterable)(result)) {
267
+ return makeResponse(new graphql_1.GraphQLError('Subscriptions are not supported'), acceptedMediaType);
268
+ }
269
+ return makeResponse(result, acceptedMediaType);
270
+ };
271
+ }
272
+ exports.createHandler = createHandler;
273
+ /**
274
+ * Inspects the request and detects the appropriate/acceptable Media-Type
275
+ * looking at the `Accept` header while complying with the GraphQL over HTTP Protocol.
276
+ *
277
+ * @category Server
278
+ */
279
+ function getAcceptableMediaType(acceptHeader) {
280
+ let acceptedMediaType = null;
281
+ const accepts = (acceptHeader || '*/*')
282
+ .replace(/\s/g, '')
283
+ .toLowerCase()
284
+ .split(',');
285
+ for (const accept of accepts) {
286
+ // accept-charset became obsolete, shouldnt be used (https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept-Charset)
287
+ // TODO: handle the weight parameter "q"
288
+ const [mediaType, ...params] = accept.split(';');
289
+ const charset = (params === null || params === void 0 ? void 0 : params.find((param) => param.includes('charset='))) || 'charset=utf8'; // utf-8 is assumed when not specified;
290
+ if (mediaType === 'application/json' && charset === 'charset=utf8') {
291
+ acceptedMediaType = 'application/json';
292
+ break;
293
+ }
294
+ if ((mediaType === 'application/graphql+json' ||
295
+ mediaType === 'application/*' ||
296
+ mediaType === '*/*') &&
297
+ charset === 'charset=utf8') {
298
+ acceptedMediaType = 'application/graphql+json';
299
+ break;
300
+ }
301
+ }
302
+ return acceptedMediaType;
303
+ }
304
+ exports.getAcceptableMediaType = getAcceptableMediaType;
305
+ /**
306
+ * Creates an appropriate GraphQL over HTTP response following the provided arguments.
307
+ *
308
+ * If the first argument is an `ExecutionResult`, the operation will be treated as "successful".
309
+ *
310
+ * If the first argument is _any_ object without the `data` field, it will be treated as an error (as per the spec)
311
+ * and the response will be constructed with the help of `acceptedMediaType` complying with the GraphQL over HTTP Protocol.
312
+ *
313
+ * @category Server
314
+ */
315
+ function makeResponse(resultOrErrors, acceptedMediaType) {
316
+ if ((0, utils_1.isExecutionResult)(resultOrErrors)) {
317
+ return [
318
+ JSON.stringify(resultOrErrors),
319
+ {
320
+ status: 200,
321
+ statusText: 'OK',
322
+ headers: {
323
+ 'content-type': acceptedMediaType === 'application/json'
324
+ ? 'application/json; charset=utf-8'
325
+ : 'application/graphql+json; charset=utf-8',
326
+ },
327
+ },
328
+ ];
329
+ }
330
+ return [
331
+ JSON.stringify({
332
+ errors: Array.isArray(resultOrErrors)
333
+ ? (0, utils_1.isObject)(resultOrErrors)
334
+ ? resultOrErrors
335
+ : new graphql_1.GraphQLError(String(resultOrErrors))
336
+ : [resultOrErrors],
337
+ }),
338
+ Object.assign(Object.assign({}, (acceptedMediaType === 'application/json'
339
+ ? {
340
+ status: 200,
341
+ statusText: 'OK',
342
+ }
343
+ : {
344
+ status: 400,
345
+ statusText: 'Bad Request',
346
+ })), { headers: {
347
+ 'content-type': acceptedMediaType === 'application/json'
348
+ ? 'application/json; charset=utf-8'
349
+ : 'application/graphql+json; charset=utf-8',
350
+ } }),
351
+ ];
352
+ }
353
+ exports.makeResponse = makeResponse;