graphql-http 1.17.1 → 1.19.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 (47) hide show
  1. package/README.md +17 -1
  2. package/lib/audits/common.d.mts +1 -1
  3. package/lib/audits/common.d.ts +1 -1
  4. package/lib/audits/render.js +15 -0
  5. package/lib/audits/render.mjs +15 -0
  6. package/lib/audits/server.js +42 -172
  7. package/lib/audits/server.mjs +42 -172
  8. package/lib/audits/utils.js +6 -3
  9. package/lib/audits/utils.mjs +6 -3
  10. package/lib/handler.d.mts +20 -3
  11. package/lib/handler.d.ts +20 -3
  12. package/lib/handler.js +36 -14
  13. package/lib/handler.mjs +37 -15
  14. package/lib/use/express.js +1 -18
  15. package/lib/use/express.mjs +1 -18
  16. package/lib/use/fastify.js +1 -19
  17. package/lib/use/fastify.mjs +1 -19
  18. package/lib/use/fetch.d.mts +1 -1
  19. package/lib/use/fetch.d.ts +1 -1
  20. package/lib/use/fetch.js +2 -22
  21. package/lib/use/fetch.mjs +2 -22
  22. package/lib/use/http.d.mts +1 -1
  23. package/lib/use/http.d.ts +1 -1
  24. package/lib/use/http.js +2 -19
  25. package/lib/use/http.mjs +2 -19
  26. package/lib/use/http2.d.mts +1 -1
  27. package/lib/use/http2.d.ts +1 -1
  28. package/lib/use/http2.js +2 -19
  29. package/lib/use/http2.mjs +2 -19
  30. package/lib/use/koa.js +0 -14
  31. package/lib/use/koa.mjs +0 -14
  32. package/lib/use/node.d.mts +1 -1
  33. package/lib/use/node.d.ts +1 -1
  34. package/lib/use/node.js +1 -1
  35. package/lib/use/node.mjs +1 -1
  36. package/lib/use/uWebSockets.d.mts +36 -0
  37. package/lib/use/uWebSockets.d.ts +36 -0
  38. package/lib/use/uWebSockets.js +84 -0
  39. package/lib/use/uWebSockets.mjs +80 -0
  40. package/lib/utils.d.mts +2 -0
  41. package/lib/utils.d.ts +2 -0
  42. package/lib/utils.js +15 -1
  43. package/lib/utils.mjs +13 -0
  44. package/package.json +30 -25
  45. package/umd/graphql-http-audits.js +63 -175
  46. package/umd/graphql-http-audits.min.js +1 -1
  47. package/umd/graphql-http-audits.min.js.gz +0 -0
package/README.md CHANGED
@@ -158,6 +158,21 @@ app.listen({ port: 4000 });
158
158
  console.log('Listening to port 4000');
159
159
  ```
160
160
 
161
+ ##### With [`uWebSockets.js`](https://github.com/uNetworking/uWebSockets.js)
162
+
163
+ ```js
164
+ import uWS from 'uWebSockets.js'; // yarn add uWebSockets.js@uNetworking/uWebSockets.js#<version>
165
+ import { createHandler } from 'graphql-http/lib/use/uWebSockets';
166
+ import { schema } from './previous-step';
167
+
168
+ uWS
169
+ .App()
170
+ .any('/graphql', createHandler({ schema }))
171
+ .listen(4000, () => {
172
+ console.log('Listening to port 4000');
173
+ });
174
+ ```
175
+
161
176
  ##### With [`Deno`](https://deno.land/)
162
177
 
163
178
  ```ts
@@ -768,7 +783,7 @@ Put the above contents in a file and run it with `deno test --allow-net`.
768
783
 
769
784
  ## Only [GraphQL over HTTP](https://graphql.github.io/graphql-over-http/)
770
785
 
771
- This is the official [GraphQL over HTTP spec](https://graphql.github.io/graphql-over-http/) reference implementation and as such follows the specification strictly without any additional features (like file uploads, @stream/@defer directives and subscriptions).
786
+ This is the official [GraphQL over HTTP spec](https://graphql.github.io/graphql-over-http/) reference implementation and as such follows the specification strictly without any additional features (like playgrounds or GUIs, file uploads, @stream/@defer directives and subscriptions).
772
787
 
773
788
  Having said this, graphql-http is mostly aimed for library authors and simple server setups, where the requirements are exact to what the aforementioned spec offers.
774
789
 
@@ -788,6 +803,7 @@ Their compliance with the [GraphQL over HTTP spec](https://graphql.github.io/gra
788
803
  | [graphql-helix](https://www.graphql-helix.com) | [✅ Compliant](/implementations/graphql-helix/README.md) |
789
804
  | [graphql-yoga](https://www.the-guild.dev/graphql/yoga-server) | [✅ Compliant](/implementations/graphql-yoga/README.md) |
790
805
  | [hotchocolate](https://chillicream.com/docs/hotchocolate) | [✅ Compliant](/implementations/hotchocolate/README.md) |
806
+ | [lighthouse](https://lighthouse-php.com) | [✅ Compliant](/implementations/lighthouse/README.md) |
791
807
  | [pioneer](https://pioneer.dexclaimation.com) | [✅ Compliant](/implementations/pioneer/README.md) |
792
808
  | [postgraphile](https://www.graphile.org/postgraphile) | [✅ Compliant](/implementations/postgraphile/README.md) |
793
809
  <!-- prettier-ignore-end -->
@@ -62,7 +62,7 @@ export interface AuditFail {
62
62
  */
63
63
  id: string;
64
64
  name: AuditName;
65
- status: 'warn' | 'error';
65
+ status: 'notice' | 'warn' | 'error';
66
66
  reason: string;
67
67
  response: Response;
68
68
  }
@@ -62,7 +62,7 @@ export interface AuditFail {
62
62
  */
63
63
  id: string;
64
64
  name: AuditName;
65
- status: 'warn' | 'error';
65
+ status: 'notice' | 'warn' | 'error';
66
66
  reason: string;
67
67
  response: Response;
68
68
  }
@@ -11,6 +11,7 @@ async function renderAuditResultsToHTML(results) {
11
11
  const grouped = {
12
12
  total: 0,
13
13
  ok: [],
14
+ notice: [],
14
15
  warn: [],
15
16
  error: [],
16
17
  };
@@ -33,6 +34,9 @@ async function renderAuditResultsToHTML(results) {
33
34
  if (grouped.ok.length) {
34
35
  report += `<li><span style="font-family: monospace">✅</span> <b>${grouped.ok.length}</b> pass</li>\n`;
35
36
  }
37
+ if (grouped.notice.length) {
38
+ report += `<li><span style="font-family: monospace">💡</span> <b>${grouped.notice.length}</b> notices (suggestions)</li>\n`;
39
+ }
36
40
  if (grouped.warn.length) {
37
41
  // TODO: warning sign is rendered as "⚠️" in markdown instead of the emoji
38
42
  report += `<li><span style="font-family: monospace">⚠️</span> <b>${grouped.warn.length}</b> warnings (optional)</li>\n`;
@@ -51,6 +55,17 @@ async function renderAuditResultsToHTML(results) {
51
55
  report += '</ol>\n';
52
56
  report += '\n';
53
57
  }
58
+ if (grouped.notice.length) {
59
+ report += `<h2>Notices</h2>\n`;
60
+ report +=
61
+ 'The server <i>MAY</i> support these, but are truly optional. These are suggestions following recommended conventions.\n';
62
+ report += '<ol>\n';
63
+ for (const [, result] of grouped.notice.entries()) {
64
+ report += await printAuditFail(result);
65
+ }
66
+ report += '</ol>\n';
67
+ report += '\n';
68
+ }
54
69
  if (grouped.warn.length) {
55
70
  report += `<h2>Warnings</h2>\n`;
56
71
  report += 'The server <i>SHOULD</i> support these, but is not required.\n';
@@ -8,6 +8,7 @@ export async function renderAuditResultsToHTML(results) {
8
8
  const grouped = {
9
9
  total: 0,
10
10
  ok: [],
11
+ notice: [],
11
12
  warn: [],
12
13
  error: [],
13
14
  };
@@ -30,6 +31,9 @@ export async function renderAuditResultsToHTML(results) {
30
31
  if (grouped.ok.length) {
31
32
  report += `<li><span style="font-family: monospace">✅</span> <b>${grouped.ok.length}</b> pass</li>\n`;
32
33
  }
34
+ if (grouped.notice.length) {
35
+ report += `<li><span style="font-family: monospace">💡</span> <b>${grouped.notice.length}</b> notices (suggestions)</li>\n`;
36
+ }
33
37
  if (grouped.warn.length) {
34
38
  // TODO: warning sign is rendered as "⚠️" in markdown instead of the emoji
35
39
  report += `<li><span style="font-family: monospace">⚠️</span> <b>${grouped.warn.length}</b> warnings (optional)</li>\n`;
@@ -48,6 +52,17 @@ export async function renderAuditResultsToHTML(results) {
48
52
  report += '</ol>\n';
49
53
  report += '\n';
50
54
  }
55
+ if (grouped.notice.length) {
56
+ report += `<h2>Notices</h2>\n`;
57
+ report +=
58
+ 'The server <i>MAY</i> support these, but are truly optional. These are suggestions following recommended conventions.\n';
59
+ report += '<ol>\n';
60
+ for (const [, result] of grouped.notice.entries()) {
61
+ report += await printAuditFail(result);
62
+ }
63
+ report += '</ol>\n';
64
+ report += '\n';
65
+ }
51
66
  if (grouped.warn.length) {
52
67
  report += `<h2>Warnings</h2>\n`;
53
68
  report += 'The server <i>SHOULD</i> support these, but is not required.\n';
@@ -57,9 +57,13 @@ function serverAudits(opts) {
57
57
  (0, utils_1.ressert)(res).header('content-type').toContain('application/json');
58
58
  }),
59
59
  (0, utils_1.audit)('80D8', 'SHOULD assume application/json content-type when accept is missing', async () => {
60
- const url = new URL(await getUrl(opts.url));
61
- url.searchParams.set('query', '{ __typename }');
62
- const res = await fetchFn(url.toString());
60
+ const res = await fetchFn(await getUrl(opts.url), {
61
+ method: 'POST',
62
+ headers: {
63
+ 'content-type': 'application/json',
64
+ },
65
+ body: JSON.stringify({ query: '{ __typename }' }),
66
+ });
63
67
  (0, utils_1.ressert)(res).status.toBe(200);
64
68
  (0, utils_1.ressert)(res).header('content-type').toContain('application/json');
65
69
  }),
@@ -130,7 +134,7 @@ function serverAudits(opts) {
130
134
  (0, utils_1.ressert)(res).status.toBeBetween(400, 499);
131
135
  }),
132
136
  // Request POST
133
- (0, utils_1.audit)('9ABE', 'SHOULD respond with 4xx status code if content-type is not supplied on POST requests', async () => {
137
+ (0, utils_1.audit)('9ABE', 'MAY respond with 4xx status code if content-type is not supplied on POST requests', async () => {
134
138
  const res = await fetchFn(await getUrl(opts.url), {
135
139
  method: 'POST',
136
140
  });
@@ -144,23 +148,15 @@ function serverAudits(opts) {
144
148
  });
145
149
  (0, utils_1.ressert)(res).status.toBe(200);
146
150
  }),
147
- (0, utils_1.audit)('7267', 'MUST require a request body on POST', async () => {
148
- var _a;
151
+ (0, utils_1.audit)('A5BF', 'MAY use 400 status code when request body is missing on POST', async () => {
149
152
  const res = await fetchFn(await getUrl(opts.url), {
150
153
  method: 'POST',
151
154
  headers: { 'content-type': 'application/json' },
152
155
  });
153
- if ((_a = res.headers.get('content-type')) === null || _a === void 0 ? void 0 : _a.includes('application/json')) {
154
- await (0, utils_1.ressert)(res).bodyAsExecutionResult.toHaveProperty('errors');
155
- }
156
- else {
157
- (0, utils_1.ressert)(res).status.toBe(400);
158
- }
156
+ (0, utils_1.ressert)(res).status.toBe(400);
159
157
  }),
160
158
  // Request Parameters
161
- (0, utils_1.audit)(
162
- // TODO: convert to MUST after watershed
163
- '6610', 'SHOULD use 400 status code on missing {query} parameter when accepting application/graphql-response+json', async () => {
159
+ (0, utils_1.audit)('423L', 'MAY use 400 status code on missing {query} parameter', async () => {
164
160
  const res = await fetchFn(await getUrl(opts.url), {
165
161
  method: 'POST',
166
162
  headers: {
@@ -171,26 +167,11 @@ function serverAudits(opts) {
171
167
  });
172
168
  (0, utils_1.ressert)(res).status.toBe(400);
173
169
  }),
174
- (0, utils_1.audit)('3715', 'SHOULD use 200 status code with errors field on missing {query} parameter when accepting application/json', async () => {
170
+ ...[{ obj: 'ect' }, 0, false, ['array']].map((invalid, index) => (0, utils_1.audit)(`LKJ${index}`, `MAY use 400 status code on ${(0, utils_1.extendedTypeof)(invalid)} {query} parameter`, async () => {
175
171
  const res = await fetchFn(await getUrl(opts.url), {
176
172
  method: 'POST',
177
173
  headers: {
178
174
  'content-type': 'application/json',
179
- accept: 'application/json',
180
- },
181
- body: JSON.stringify({ notquery: '{ __typename }' }),
182
- });
183
- (0, utils_1.ressert)(res).status.toBe(200);
184
- await (0, utils_1.ressert)(res).bodyAsExecutionResult.toHaveProperty('errors');
185
- }),
186
- ...[{ obj: 'ect' }, 0, false, ['array']].map((invalid, index) => (0, utils_1.audit)(`4F5${index}`,
187
- // TODO: convert to MUST after watershed
188
- `SHOULD use 400 status code on ${(0, utils_1.extendedTypeof)(invalid)} {query} parameter when accepting application/graphql-response+json`, async () => {
189
- const res = await fetchFn(await getUrl(opts.url), {
190
- method: 'POST',
191
- headers: {
192
- 'content-type': 'application/json',
193
- accept: 'application/graphql-response+json',
194
175
  },
195
176
  body: JSON.stringify({
196
177
  query: invalid,
@@ -198,20 +179,6 @@ function serverAudits(opts) {
198
179
  });
199
180
  (0, utils_1.ressert)(res).status.toBe(400);
200
181
  })),
201
- ...[{ obj: 'ect' }, 0, false, ['array']].map((invalid, index) => (0, utils_1.audit)(`9FE${index}`, `SHOULD use 200 status code with errors field on ${(0, utils_1.extendedTypeof)(invalid)} {query} parameter when accepting application/json`, async () => {
202
- const res = await fetchFn(await getUrl(opts.url), {
203
- method: 'POST',
204
- headers: {
205
- 'content-type': 'application/json',
206
- accept: 'application/json',
207
- },
208
- body: JSON.stringify({
209
- query: invalid,
210
- }),
211
- });
212
- (0, utils_1.ressert)(res).status.toBe(200);
213
- await (0, utils_1.ressert)(res).bodyAsExecutionResult.toHaveProperty('errors');
214
- })),
215
182
  (0, utils_1.audit)(
216
183
  // TODO: convert to MUST after watershed
217
184
  '34A2', 'SHOULD allow string {query} parameter when accepting application/graphql-response+json', async () => {
@@ -241,14 +208,11 @@ function serverAudits(opts) {
241
208
  (0, utils_1.ressert)(res).status.toBe(200);
242
209
  await (0, utils_1.ressert)(res).bodyAsExecutionResult.notToHaveProperty('errors');
243
210
  }),
244
- ...[{ obj: 'ect' }, 0, false, ['array']].map((invalid, index) => (0, utils_1.audit)(`E3E${index}`,
245
- // TODO: convert to MUST after watershed
246
- `SHOULD use 400 status code on ${(0, utils_1.extendedTypeof)(invalid)} {operationName} parameter when accepting application/graphql-response+json`, async () => {
211
+ ...[{ obj: 'ect' }, 0, false, ['array']].map((invalid, index) => (0, utils_1.audit)(`6C0${index}`, `MAY use 400 status code on ${(0, utils_1.extendedTypeof)(invalid)} {operationName} parameter`, async () => {
247
212
  const res = await fetchFn(await getUrl(opts.url), {
248
213
  method: 'POST',
249
214
  headers: {
250
215
  'content-type': 'application/json',
251
- accept: 'application/graphql-response+json',
252
216
  },
253
217
  body: JSON.stringify({
254
218
  operationName: invalid,
@@ -257,21 +221,6 @@ function serverAudits(opts) {
257
221
  });
258
222
  (0, utils_1.ressert)(res).status.toBe(400);
259
223
  })),
260
- ...[{ obj: 'ect' }, 0, false, ['array']].map((invalid, index) => (0, utils_1.audit)(`FB9${index}`, `SHOULD use 200 status code with errors field on ${(0, utils_1.extendedTypeof)(invalid)} {operationName} parameter when accepting application/json`, async () => {
261
- const res = await fetchFn(await getUrl(opts.url), {
262
- method: 'POST',
263
- headers: {
264
- 'content-type': 'application/json',
265
- accept: 'application/json',
266
- },
267
- body: JSON.stringify({
268
- operationName: invalid,
269
- query: '{ __typename }',
270
- }),
271
- });
272
- (0, utils_1.ressert)(res).status.toBe(200);
273
- await (0, utils_1.ressert)(res).bodyAsExecutionResult.toHaveProperty('errors');
274
- })),
275
224
  (0, utils_1.audit)(
276
225
  // TODO: convert to MUST after watershed
277
226
  '8161', 'SHOULD allow string {operationName} parameter when accepting application/graphql-response+json', async () => {
@@ -337,14 +286,11 @@ function serverAudits(opts) {
337
286
  await (0, utils_1.ressert)(res).bodyAsExecutionResult.notToHaveProperty('errors');
338
287
  }),
339
288
  ]),
340
- ...['string', 0, false, ['array']].map((invalid, index) => (0, utils_1.audit)(`69B${index}`,
341
- // TODO: convert to MUST after watershed
342
- `SHOULD use 400 status code on ${(0, utils_1.extendedTypeof)(invalid)} {variables} parameter when accepting application/graphql-response+json`, async () => {
289
+ ...['string', 0, false, ['array']].map((invalid, index) => (0, utils_1.audit)(`476${index}`, `MAY use 400 status code on ${(0, utils_1.extendedTypeof)(invalid)} {variables} parameter`, async () => {
343
290
  const res = await fetchFn(await getUrl(opts.url), {
344
291
  method: 'POST',
345
292
  headers: {
346
293
  'content-type': 'application/json',
347
- accept: 'application/graphql-response+json',
348
294
  },
349
295
  body: JSON.stringify({
350
296
  query: '{ __typename }',
@@ -353,21 +299,6 @@ function serverAudits(opts) {
353
299
  });
354
300
  (0, utils_1.ressert)(res).status.toBe(400);
355
301
  })),
356
- ...['string', 0, false, ['array']].map((invalid, index) => (0, utils_1.audit)(`F05${index}`, `SHOULD use 200 status code with errors field on ${(0, utils_1.extendedTypeof)(invalid)} {variables} parameter when accepting application/json`, async () => {
357
- const res = await fetchFn(await getUrl(opts.url), {
358
- method: 'POST',
359
- headers: {
360
- 'content-type': 'application/json',
361
- accept: 'application/json',
362
- },
363
- body: JSON.stringify({
364
- query: '{ __typename }',
365
- variables: invalid,
366
- }),
367
- });
368
- (0, utils_1.ressert)(res).status.toBe(200);
369
- await (0, utils_1.ressert)(res).bodyAsExecutionResult.toHaveProperty('errors');
370
- })),
371
302
  (0, utils_1.audit)(
372
303
  // TODO: convert to MUST after watershed
373
304
  '2EA1', 'SHOULD allow map {variables} parameter when accepting application/graphql-response+json', async () => {
@@ -424,14 +355,13 @@ function serverAudits(opts) {
424
355
  (0, utils_1.ressert)(res).status.toBe(200);
425
356
  await (0, utils_1.ressert)(res).bodyAsExecutionResult.notToHaveProperty('errors');
426
357
  }),
427
- ...['string', 0, false, ['array']].map((invalid, index) => (0, utils_1.audit)(`904${index}`,
358
+ ...['string', 0, false, ['array']].map((invalid, index) => (0, utils_1.audit)(`58B${index}`,
428
359
  // TODO: convert to MUST after watershed
429
- `SHOULD use 400 status code on ${(0, utils_1.extendedTypeof)(invalid)} {extensions} parameter when accepting application/graphql-response+json`, async () => {
360
+ `MAY use 400 status code on ${(0, utils_1.extendedTypeof)(invalid)} {extensions} parameter`, async () => {
430
361
  const res = await fetchFn(await getUrl(opts.url), {
431
362
  method: 'POST',
432
363
  headers: {
433
364
  'content-type': 'application/json',
434
- accept: 'application/graphql-response+json',
435
365
  },
436
366
  body: JSON.stringify({
437
367
  query: '{ __typename }',
@@ -440,21 +370,6 @@ function serverAudits(opts) {
440
370
  });
441
371
  (0, utils_1.ressert)(res).status.toBe(400);
442
372
  })),
443
- ...['string', 0, false, ['array']].map((invalid, index) => (0, utils_1.audit)(`368${index}`, `SHOULD use 200 status code with errors field on ${(0, utils_1.extendedTypeof)(invalid)} {extensions} parameter when accepting application/json`, async () => {
444
- const res = await fetchFn(await getUrl(opts.url), {
445
- method: 'POST',
446
- headers: {
447
- 'content-type': 'application/json',
448
- accept: 'application/json',
449
- },
450
- body: JSON.stringify({
451
- query: '{ __typename }',
452
- extensions: invalid,
453
- }),
454
- });
455
- (0, utils_1.ressert)(res).status.toBe(200);
456
- await (0, utils_1.ressert)(res).bodyAsExecutionResult.toHaveProperty('errors');
457
- })),
458
373
  (0, utils_1.audit)(
459
374
  // TODO: convert to MUST after watershed
460
375
  '428F', 'SHOULD allow map {extensions} parameter when accepting application/graphql-response+json', async () => {
@@ -486,136 +401,91 @@ function serverAudits(opts) {
486
401
  (0, utils_1.ressert)(res).status.toBe(200);
487
402
  await (0, utils_1.ressert)(res).bodyAsExecutionResult.notToHaveProperty('errors');
488
403
  }),
489
- // TODO: audit('39AA', 'MUST accept a map for the {extensions} parameter'),
490
- // Response application/json
491
- (0, utils_1.audit)('D477', 'SHOULD use 200 status code on JSON parsing failure when accepting application/json', async () => {
404
+ (0, utils_1.audit)('B6DC', 'MAY use 4xx or 5xx status codes on JSON parsing failure', async () => {
492
405
  const res = await fetchFn(await getUrl(opts.url), {
493
406
  method: 'POST',
494
407
  headers: {
495
408
  'content-type': 'application/json',
496
- accept: 'application/json',
497
409
  },
498
410
  body: '{ "not a JSON',
499
411
  });
500
- (0, utils_1.ressert)(res).status.toBe(200);
501
- }),
502
- (0, utils_1.audit)('F5AF', 'SHOULD use 200 status code if parameters are invalid when accepting application/json', async () => {
503
- const res = await fetchFn(await getUrl(opts.url), {
504
- method: 'POST',
505
- headers: {
506
- 'content-type': 'application/json',
507
- accept: 'application/json',
508
- },
509
- body: JSON.stringify({
510
- qeury: /* typo */ '{ __typename }',
511
- }),
512
- });
513
- (0, utils_1.ressert)(res).status.toBe(200);
412
+ (0, utils_1.ressert)(res).status.toBeBetween(400, 499);
514
413
  }),
515
- (0, utils_1.audit)('572B', 'SHOULD use 200 status code on document parsing failure when accepting application/json', async () => {
414
+ (0, utils_1.audit)('BCF8', 'MAY use 400 status code on JSON parsing failure', async () => {
516
415
  const res = await fetchFn(await getUrl(opts.url), {
517
416
  method: 'POST',
518
417
  headers: {
519
418
  'content-type': 'application/json',
520
- accept: 'application/json',
521
419
  },
522
- body: JSON.stringify({ query: '{' }),
420
+ body: '{ "not a JSON',
523
421
  });
524
- (0, utils_1.ressert)(res).status.toBe(200);
422
+ (0, utils_1.ressert)(res).status.toBe(400);
525
423
  }),
526
- (0, utils_1.audit)('FDE2', 'SHOULD use 200 status code on document validation failure when accepting application/json', async () => {
424
+ (0, utils_1.audit)('8764', 'MAY use 4xx or 5xx status codes if parameters are invalid', async () => {
527
425
  const res = await fetchFn(await getUrl(opts.url), {
528
426
  method: 'POST',
529
427
  headers: {
530
428
  'content-type': 'application/json',
531
- accept: 'application/json',
532
429
  },
533
430
  body: JSON.stringify({
534
- query: '{ 8f31403dfe404bccbb0e835f2629c6a7 }', // making sure the field doesnt exist
431
+ qeury /* typo */: '{ __typename }',
535
432
  }),
536
433
  });
537
- (0, utils_1.ressert)(res).status.toBe(200);
434
+ (0, utils_1.ressert)(res).status.toBeBetween(400, 599);
538
435
  }),
539
- (0, utils_1.audit)('7B9B', 'SHOULD use a status code of 200 on variable coercion failure when accepting application/json', async () => {
436
+ (0, utils_1.audit)('3E3A', 'MAY use 400 status code if parameters are invalid', async () => {
540
437
  const res = await fetchFn(await getUrl(opts.url), {
541
438
  method: 'POST',
542
439
  headers: {
543
440
  'content-type': 'application/json',
544
- accept: 'application/json',
545
441
  },
546
442
  body: JSON.stringify({
547
- query: 'query CoerceFailure($id: ID!){ __typename }',
548
- variables: { id: null },
443
+ qeury: /* typo */ '{ __typename }',
549
444
  }),
550
445
  });
551
- (0, utils_1.ressert)(res).status.toBe(200);
552
- }),
553
- // Response application/graphql-response+json
554
- (0, utils_1.audit)(
555
- // TODO: convert to MUST after watershed
556
- '60AA', 'SHOULD use 4xx or 5xx status codes on JSON parsing failure when accepting application/graphql-response+json', async () => {
557
- const res = await fetchFn(await getUrl(opts.url), {
558
- method: 'POST',
559
- headers: {
560
- 'content-type': 'application/json',
561
- accept: 'application/graphql-response+json',
562
- },
563
- body: '{ "not a JSON',
564
- });
565
- (0, utils_1.ressert)(res).status.toBeBetween(400, 499);
566
- }),
567
- (0, utils_1.audit)('2163', 'SHOULD use 400 status code on JSON parsing failure when accepting application/graphql-response+json', async () => {
568
- const res = await fetchFn(await getUrl(opts.url), {
569
- method: 'POST',
570
- headers: {
571
- 'content-type': 'application/json',
572
- accept: 'application/graphql-response+json',
573
- },
574
- body: '{ "not a JSON',
575
- });
576
446
  (0, utils_1.ressert)(res).status.toBe(400);
577
447
  }),
578
- (0, utils_1.audit)(
579
- // TODO: convert to MUST after watershed
580
- '3E36', 'SHOULD use 4xx or 5xx status codes if parameters are invalid when accepting application/graphql-response+json', async () => {
448
+ // TODO: audit('39AA', 'MUST accept a map for the {extensions} parameter'),
449
+ // Response application/json
450
+ (0, utils_1.audit)('572B', 'SHOULD use 200 status code on document parsing failure when accepting application/json', async () => {
581
451
  const res = await fetchFn(await getUrl(opts.url), {
582
452
  method: 'POST',
583
453
  headers: {
584
454
  'content-type': 'application/json',
585
- accept: 'application/graphql-response+json',
455
+ accept: 'application/json',
586
456
  },
587
- body: JSON.stringify({
588
- qeury /* typo */: '{ __typename }',
589
- }),
457
+ body: JSON.stringify({ query: '{' }),
590
458
  });
591
- (0, utils_1.ressert)(res).status.toBeBetween(400, 599);
459
+ (0, utils_1.ressert)(res).status.toBe(200);
592
460
  }),
593
- (0, utils_1.audit)('17C5', 'SHOULD use 400 status code if parameters are invalid when accepting application/graphql-response+json', async () => {
461
+ (0, utils_1.audit)('FDE2', 'SHOULD use 200 status code on document validation failure when accepting application/json', async () => {
594
462
  const res = await fetchFn(await getUrl(opts.url), {
595
463
  method: 'POST',
596
464
  headers: {
597
465
  'content-type': 'application/json',
598
- accept: 'application/graphql-response+json',
466
+ accept: 'application/json',
599
467
  },
600
468
  body: JSON.stringify({
601
- qeury: /* typo */ '{ __typename }',
469
+ query: '{ 8f31403dfe404bccbb0e835f2629c6a7 }', // making sure the field doesnt exist
602
470
  }),
603
471
  });
604
- (0, utils_1.ressert)(res).status.toBe(400);
472
+ (0, utils_1.ressert)(res).status.toBe(200);
605
473
  }),
606
- (0, utils_1.audit)('34D6', 'SHOULD not contain the data entry if parameters are invalid when accepting application/graphql-response+json', async () => {
474
+ (0, utils_1.audit)('7B9B', 'SHOULD use a status code of 200 on variable coercion failure when accepting application/json', async () => {
607
475
  const res = await fetchFn(await getUrl(opts.url), {
608
476
  method: 'POST',
609
477
  headers: {
610
478
  'content-type': 'application/json',
611
- accept: 'application/graphql-response+json',
479
+ accept: 'application/json',
612
480
  },
613
481
  body: JSON.stringify({
614
- qeury: /* typo */ '{ __typename }',
482
+ query: 'query CoerceFailure($id: ID!){ __typename }',
483
+ variables: { id: null },
615
484
  }),
616
485
  });
617
- await (0, utils_1.ressert)(res).bodyAsExecutionResult.data.toBe(undefined);
486
+ (0, utils_1.ressert)(res).status.toBe(200);
618
487
  }),
488
+ // Response application/graphql-response+json
619
489
  (0, utils_1.audit)(
620
490
  // TODO: convert to MUST after watershed
621
491
  '865D', 'SHOULD use 4xx or 5xx status codes on document parsing failure when accepting application/graphql-response+json', async () => {