graphql-http 1.7.0 → 1.7.2

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/README.md CHANGED
@@ -7,9 +7,9 @@
7
7
 
8
8
  [![Continuous integration](https://github.com/graphql/graphql-http/workflows/Continuous%20integration/badge.svg)](https://github.com/graphql/graphql-http/actions?query=workflow%3A%22Continuous+integration%22) [![graphql-http](https://img.shields.io/npm/v/graphql-http.svg?label=graphql-http&logo=npm)](https://www.npmjs.com/package/graphql-http)
9
9
 
10
- <i>Need subscriptions? Try <b>[graphql-ws](https://github.com/enisdenjo/graphql-ws)</b> or <b>[graphql-sse](https://github.com/enisdenjo/graphql-sse)</b> instead!</i>
10
+ <i>Want a full-featured server? See the <b>[servers section](#servers)</b>!</i>
11
11
 
12
- <i>Want a full-featured server? See the <b>[servers section](#servers)</b></i>!
12
+ <i>Need subscriptions? Try <b>[graphql-ws](https://github.com/enisdenjo/graphql-ws)</b> or <b>[graphql-sse](https://github.com/enisdenjo/graphql-sse)</b> instead!</i>
13
13
 
14
14
  <br />
15
15
  </div>
@@ -729,12 +729,13 @@ Having said this, graphql-http is mostly aimed for library authors and simple se
729
729
 
730
730
  If you want a feature-full server with bleeding edge technologies, you're recommended to use one of the following.
731
731
 
732
- | Name | Audit |
733
- | -------------------------------------------------------------- | ------------------------------------------------------------------ |
734
- | [graphql-yoga](https://www.the-guild.dev/graphql/yoga-server) | [✅ Fully compliant](/implementations/graphql-yoga/README.md) |
735
- | [apollo-server](https://www.the-guild.dev/graphql/yoga-server) | [⚠️ Partially compliant](/implementations/apollo-server/README.md) |
736
- | [mercurius](https://mercurius.dev) | [⚠️ Partially compliant](/implementations/mercurius/README.md) |
737
- | [graphql-helix](https://www.graphql-helix.com/) | [⚠️ Partially compliant](/implementations/graphql-helix/README.md) |
732
+ | Name | Audit |
733
+ | ------------------------------------------------------------------ | -------------------------------------------------------- |
734
+ | [graphql-yoga](https://www.the-guild.dev/graphql/yoga-server) | [✅ Compliant](/implementations/graphql-yoga/README.md) |
735
+ | [hotchocolate](https://chillicream.com/docs/hotchocolate) | [✅ Compliant](/implementations/hotchocolate/README.md) |
736
+ | [postgraphile](https://www.graphile.org/postgraphile/) | [✅ Compliant](/implementations/postgraphile/README.md) |
737
+ | [apollo-server](https://www.apollographql.com/docs/apollo-server/) | [✅ Compliant](/implementations/apollo-server/README.md) |
738
+ | [mercurius](https://mercurius.dev) | [✅ Compliant](/implementations/mercurius/README.md) |
738
739
 
739
740
  ## [Documentation](docs/)
740
741
 
@@ -19,53 +19,56 @@ function serverAudits(opts) {
19
19
  (0, utils_1.audit)(
20
20
  // TODO: convert to MUST after watershed
21
21
  'SHOULD accept application/graphql-response+json and match the content-type', async () => {
22
- const url = new URL(opts.url);
23
- url.searchParams.set('query', '{ __typename }');
24
- const res = await fetchFn(url.toString(), {
22
+ const res = await fetchFn(opts.url, {
23
+ method: 'POST',
25
24
  headers: {
25
+ 'content-type': 'application/json',
26
26
  accept: 'application/graphql-response+json',
27
27
  },
28
+ body: JSON.stringify({ query: '{ __typename }' }),
28
29
  });
29
30
  (0, utils_1.assert)('Status code', res.status).toBe(200);
30
31
  (0, utils_1.assert)('Content-Type header', res.headers.get('content-type')).toContain('application/graphql-response+json');
31
32
  }),
32
33
  (0, utils_1.audit)('MUST accept application/json and match the content-type', async () => {
33
- const url = new URL(opts.url);
34
- url.searchParams.set('query', '{ __typename }');
35
- const res = await fetchFn(url.toString(), {
34
+ const res = await fetchFn(opts.url, {
35
+ method: 'POST',
36
36
  headers: {
37
+ 'content-type': 'application/json',
37
38
  accept: 'application/json',
38
39
  },
40
+ body: JSON.stringify({ query: '{ __typename }' }),
39
41
  });
40
42
  (0, utils_1.assert)('Status code', res.status).toBe(200);
41
43
  (0, utils_1.assert)('Content-Type header', res.headers.get('content-type')).toContain('application/json');
42
44
  }),
43
- (0, utils_1.audit)(
44
- // TODO: convert to MUST after watershed
45
- 'SHOULD accept */* and use application/graphql-response+json for the content-type', async () => {
46
- const url = new URL(opts.url);
47
- url.searchParams.set('query', '{ __typename }');
48
- const res = await fetchFn(url.toString(), {
45
+ (0, utils_1.audit)('SHOULD accept */* and use application/json for the content-type', async () => {
46
+ const res = await fetchFn(opts.url, {
47
+ method: 'POST',
49
48
  headers: {
49
+ 'content-type': 'application/json',
50
50
  accept: '*/*',
51
51
  },
52
+ body: JSON.stringify({ query: '{ __typename }' }),
52
53
  });
53
54
  (0, utils_1.assert)('Status code', res.status).toBe(200);
54
- (0, utils_1.assert)('Content-Type header', res.headers.get('content-type')).toContain('application/graphql-response+json');
55
+ (0, utils_1.assert)('Content-Type header', res.headers.get('content-type')).toContain('application/json');
55
56
  }),
56
- (0, utils_1.audit)(
57
- // TODO: convert to MUST after watershed
58
- 'SHOULD assume application/graphql-response+json content-type when accept is missing', async () => {
57
+ (0, utils_1.audit)('SHOULD assume application/json content-type when accept is missing', async () => {
59
58
  const url = new URL(opts.url);
60
59
  url.searchParams.set('query', '{ __typename }');
61
60
  const res = await fetchFn(url.toString());
62
61
  (0, utils_1.assert)('Status code', res.status).toBe(200);
63
- (0, utils_1.assert)('Content-Type header', res.headers.get('content-type')).toContain('application/graphql-response+json');
62
+ (0, utils_1.assert)('Content-Type header', res.headers.get('content-type')).toContain('application/json');
64
63
  }),
65
64
  (0, utils_1.audit)('MUST use utf-8 encoding when responding', async () => {
66
- const url = new URL(opts.url);
67
- url.searchParams.set('query', '{ __typename }');
68
- const res = await fetchFn(url.toString());
65
+ const res = await fetchFn(opts.url, {
66
+ method: 'POST',
67
+ headers: {
68
+ 'content-type': 'application/json',
69
+ },
70
+ body: JSON.stringify({ query: '{ __typename }' }),
71
+ });
69
72
  (0, utils_1.assert)('Status code', res.status).toBe(200);
70
73
  // has charset set to utf-8
71
74
  try {
@@ -88,23 +91,23 @@ function serverAudits(opts) {
88
91
  }
89
92
  }),
90
93
  (0, utils_1.audit)('MUST accept utf-8 encoding', async () => {
91
- const url = new URL(opts.url);
92
- url.searchParams.set('query', '{ __typename }');
93
- const res = await fetchFn(url.toString(), {
94
+ const res = await fetchFn(opts.url, {
95
+ method: 'POST',
94
96
  headers: {
95
97
  'content-type': 'application/json; charset=utf-8',
96
98
  },
99
+ body: JSON.stringify({ query: '{ __typename }' }),
97
100
  });
98
101
  (0, utils_1.assert)('Status code', res.status).toBe(200);
99
102
  (0, utils_1.assert)('Content-Type header', res.headers.get('content-type')).toContain('utf-8');
100
103
  }),
101
104
  (0, utils_1.audit)('MUST assume utf-8 if encoding is unspecified', async () => {
102
- const url = new URL(opts.url);
103
- url.searchParams.set('query', '{ __typename }');
104
- const res = await fetchFn(url.toString(), {
105
+ const res = await fetchFn(opts.url, {
106
+ method: 'POST',
105
107
  headers: {
106
108
  'content-type': 'application/json',
107
109
  },
110
+ body: JSON.stringify({ query: '{ __typename }' }),
108
111
  });
109
112
  (0, utils_1.assert)('Status code', res.status).toBe(200);
110
113
  (0, utils_1.assert)('Content-Type header', res.headers.get('content-type')).toContain('utf-8');
@@ -125,7 +128,8 @@ function serverAudits(opts) {
125
128
  (0, utils_1.assert)('Status code', res.status).toBe(200);
126
129
  }),
127
130
  // Request GET
128
- (0, utils_1.audit)('MUST NOT allow executing mutations on GET requests', async () => {
131
+ // TODO: this is a MUST if the server supports GET requests
132
+ (0, utils_1.audit)('MAY NOT allow executing mutations on GET requests', async () => {
129
133
  const url = new URL(opts.url);
130
134
  url.searchParams.set('query', 'mutation { __typename }');
131
135
  const res = await fetchFn(url.toString(), {
@@ -133,15 +137,14 @@ function serverAudits(opts) {
133
137
  accept: 'application/graphql-response+json',
134
138
  },
135
139
  });
136
- (0, utils_1.assert)('Status code', res.status).toBe(405);
140
+ (0, utils_1.assert)('Status code', res.status).toBeBetween(400, 499);
137
141
  }),
138
142
  // Request POST
139
143
  (0, utils_1.audit)('SHOULD respond with 4xx status code if content-type is not supplied on POST requests', async () => {
140
144
  const res = await fetchFn(opts.url, {
141
145
  method: 'POST',
142
146
  });
143
- (0, utils_1.assert)('Status code', res.status).toBeGreaterThanOrEqual(400);
144
- (0, utils_1.assert)('Status code', res.status).toBeLessThanOrEqual(499);
147
+ (0, utils_1.assert)('Status code', res.status).toBeBetween(400, 499);
145
148
  }),
146
149
  (0, utils_1.audit)('MUST accept application/json POST requests', async () => {
147
150
  const res = await fetchFn(opts.url, {
@@ -152,11 +155,17 @@ function serverAudits(opts) {
152
155
  (0, utils_1.assert)('Status code', res.status).toBe(200);
153
156
  }),
154
157
  (0, utils_1.audit)('MUST require a request body on POST', async () => {
158
+ var _a;
155
159
  const res = await fetchFn(opts.url, {
156
160
  method: 'POST',
157
161
  headers: { 'content-type': 'application/json' },
158
162
  });
159
- (0, utils_1.assert)('Status code', res.status).toBe(400);
163
+ if ((_a = res.headers.get('content-type')) === null || _a === void 0 ? void 0 : _a.includes('application/json')) {
164
+ (0, utils_1.assert)('Execution result', await (0, utils_1.assertBodyAsExecutionResult)(res)).toHaveProperty('errors');
165
+ }
166
+ else {
167
+ (0, utils_1.assert)('Status code', res.status).toBe(400);
168
+ }
160
169
  }),
161
170
  // Request Parameters
162
171
  (0, utils_1.audit)(
@@ -366,9 +375,7 @@ function serverAudits(opts) {
366
375
  (0, utils_1.assert)('Status code', res.status).toBe(200);
367
376
  (0, utils_1.assert)('Execution result', await (0, utils_1.assertBodyAsExecutionResult)(res)).notToHaveProperty('errors');
368
377
  }),
369
- (0, utils_1.audit)(
370
- // TODO: convert to MUST after watershed
371
- 'SHOULD allow URL-encoded JSON string {variables} parameter in GETs when accepting application/graphql-response+json', async () => {
378
+ (0, utils_1.audit)('MAY allow URL-encoded JSON string {variables} parameter in GETs when accepting application/graphql-response+json', async () => {
372
379
  const url = new URL(opts.url);
373
380
  url.searchParams.set('query', 'query Type($name: String!) { __type(name: $name) { name } }');
374
381
  url.searchParams.set('variables', JSON.stringify({ name: 'sometype' }));
@@ -380,7 +387,7 @@ function serverAudits(opts) {
380
387
  });
381
388
  (0, utils_1.assert)('Status code', res.status).toBe(200);
382
389
  }),
383
- (0, utils_1.audit)('MUST allow URL-encoded JSON string {variables} parameter in GETs when accepting application/json', async () => {
390
+ (0, utils_1.audit)('MAY allow URL-encoded JSON string {variables} parameter in GETs when accepting application/json', async () => {
384
391
  const url = new URL(opts.url);
385
392
  url.searchParams.set('query', 'query Type($name: String!) { __type(name: $name) { name } }');
386
393
  url.searchParams.set('variables', JSON.stringify({ name: 'sometype' }));
@@ -469,29 +476,39 @@ function serverAudits(opts) {
469
476
  (0, utils_1.assert)('Status code', res.status).toBe(200);
470
477
  }),
471
478
  (0, utils_1.audit)('SHOULD use 200 status code if parameters are invalid when accepting application/json', async () => {
472
- const url = new URL(opts.url);
473
- url.searchParams.set('qeury' /* typo */, '{ __typename }');
474
- const res = await fetchFn(url.toString(), {
475
- method: 'GET',
476
- headers: { accept: 'application/json' },
479
+ const res = await fetchFn(opts.url, {
480
+ method: 'POST',
481
+ headers: {
482
+ 'content-type': 'application/json',
483
+ accept: 'application/json',
484
+ },
485
+ body: JSON.stringify({
486
+ qeury: /* typo */ '{ __typename }',
487
+ }),
477
488
  });
478
489
  (0, utils_1.assert)('Status code', res.status).toBe(200);
479
490
  }),
480
491
  (0, utils_1.audit)('SHOULD use 200 status code on document parsing failure when accepting application/json', async () => {
481
- const url = new URL(opts.url);
482
- url.searchParams.set('query', '{');
483
- const res = await fetchFn(url.toString(), {
484
- method: 'GET',
485
- headers: { accept: 'application/json' },
492
+ const res = await fetchFn(opts.url, {
493
+ method: 'POST',
494
+ headers: {
495
+ 'content-type': 'application/json',
496
+ accept: 'application/json',
497
+ },
498
+ body: JSON.stringify({ query: '{' }),
486
499
  });
487
500
  (0, utils_1.assert)('Status code', res.status).toBe(200);
488
501
  }),
489
502
  (0, utils_1.audit)('SHOULD use 200 status code on document validation failure when accepting application/json', async () => {
490
- const url = new URL(opts.url);
491
- url.searchParams.set('query', '{ 8f31403dfe404bccbb0e835f2629c6a7 }'); // making sure the field doesnt exist
492
- const res = await fetchFn(url.toString(), {
493
- method: 'GET',
494
- headers: { accept: 'application/json' },
503
+ const res = await fetchFn(opts.url, {
504
+ method: 'POST',
505
+ headers: {
506
+ 'content-type': 'application/json',
507
+ accept: 'application/json',
508
+ },
509
+ body: JSON.stringify({
510
+ query: '{ 8f31403dfe404bccbb0e835f2629c6a7 }', // making sure the field doesnt exist
511
+ }),
495
512
  });
496
513
  (0, utils_1.assert)('Status code', res.status).toBe(200);
497
514
  }),
@@ -507,8 +524,7 @@ function serverAudits(opts) {
507
524
  },
508
525
  body: '{ "not a JSON',
509
526
  });
510
- (0, utils_1.assert)('Status code', res.status).toBeGreaterThanOrEqual(400);
511
- (0, utils_1.assert)('Status code', res.status).toBeLessThanOrEqual(599);
527
+ (0, utils_1.assert)('Status code', res.status).toBeBetween(400, 499);
512
528
  }),
513
529
  (0, utils_1.audit)('SHOULD use 400 status code on JSON parsing failure when accepting application/graphql-response+json', async () => {
514
530
  const res = await fetchFn(opts.url, {
@@ -535,90 +551,123 @@ function serverAudits(opts) {
535
551
  (0, utils_1.audit)(
536
552
  // TODO: convert to MUST after watershed
537
553
  'SHOULD use 4xx or 5xx status codes if parameters are invalid when accepting application/graphql-response+json', async () => {
538
- const url = new URL(opts.url);
539
- url.searchParams.set('qeury' /* typo */, '{ __typename }');
540
- const res = await fetchFn(url.toString(), {
541
- method: 'GET',
542
- headers: { accept: 'application/graphql-response+json' },
554
+ const res = await fetchFn(opts.url, {
555
+ method: 'POST',
556
+ headers: {
557
+ 'content-type': 'application/json',
558
+ accept: 'application/graphql-response+json',
559
+ },
560
+ body: JSON.stringify({
561
+ qeury /* typo */: '{ __typename }',
562
+ }),
543
563
  });
544
- (0, utils_1.assert)('Status code', res.status).toBeGreaterThanOrEqual(400);
545
- (0, utils_1.assert)('Status code', res.status).toBeLessThanOrEqual(599);
564
+ (0, utils_1.assert)('Status code', res.status).toBeBetween(400, 599);
546
565
  }),
547
566
  (0, utils_1.audit)('SHOULD use 400 status code if parameters are invalid when accepting application/graphql-response+json', async () => {
548
- const url = new URL(opts.url);
549
- url.searchParams.set('qeury' /* typo */, '{ __typename }');
550
- const res = await fetchFn(url.toString(), {
551
- method: 'GET',
552
- headers: { accept: 'application/graphql-response+json' },
567
+ const res = await fetchFn(opts.url, {
568
+ method: 'POST',
569
+ headers: {
570
+ 'content-type': 'application/json',
571
+ accept: 'application/graphql-response+json',
572
+ },
573
+ body: JSON.stringify({
574
+ qeury: /* typo */ '{ __typename }',
575
+ }),
553
576
  });
554
577
  (0, utils_1.assert)('Status code', res.status).toBe(400);
555
578
  }),
556
579
  (0, utils_1.audit)('SHOULD not contain the data entry if parameters are invalid when accepting application/graphql-response+json', async () => {
557
- const url = new URL(opts.url);
558
- url.searchParams.set('qeury' /* typo */, '{ __typename }');
559
- const res = await fetchFn(url.toString(), {
560
- method: 'GET',
561
- headers: { accept: 'application/graphql-response+json' },
580
+ const res = await fetchFn(opts.url, {
581
+ method: 'POST',
582
+ headers: {
583
+ 'content-type': 'application/json',
584
+ accept: 'application/graphql-response+json',
585
+ },
586
+ body: JSON.stringify({
587
+ qeury: /* typo */ '{ __typename }',
588
+ }),
562
589
  });
563
590
  (0, utils_1.assert)('Data entry', (await (0, utils_1.assertBodyAsExecutionResult)(res)).data).toBe(undefined);
564
591
  }),
565
592
  (0, utils_1.audit)(
566
593
  // TODO: convert to MUST after watershed
567
594
  'SHOULD use 4xx or 5xx status codes on document parsing failure when accepting application/graphql-response+json', async () => {
568
- const url = new URL(opts.url);
569
- url.searchParams.set('query', '{');
570
- const res = await fetchFn(url.toString(), {
571
- method: 'GET',
572
- headers: { accept: 'application/graphql-response+json' },
595
+ const res = await fetchFn(opts.url, {
596
+ method: 'POST',
597
+ headers: {
598
+ 'content-type': 'application/json',
599
+ accept: 'application/graphql-response+json',
600
+ },
601
+ body: JSON.stringify({
602
+ query: '{',
603
+ }),
573
604
  });
574
- (0, utils_1.assert)('Status code', res.status).toBeGreaterThanOrEqual(400);
575
- (0, utils_1.assert)('Status code', res.status).toBeLessThanOrEqual(599);
605
+ (0, utils_1.assert)('Status code', res.status).toBeBetween(400, 599);
576
606
  }),
577
607
  (0, utils_1.audit)('SHOULD use 400 status code on document parsing failure when accepting application/graphql-response+json', async () => {
578
- const url = new URL(opts.url);
579
- url.searchParams.set('query', '{');
580
- const res = await fetchFn(url.toString(), {
581
- method: 'GET',
582
- headers: { accept: 'application/graphql-response+json' },
608
+ const res = await fetchFn(opts.url, {
609
+ method: 'POST',
610
+ headers: {
611
+ 'content-type': 'application/json',
612
+ accept: 'application/graphql-response+json',
613
+ },
614
+ body: JSON.stringify({
615
+ query: '{',
616
+ }),
583
617
  });
584
618
  (0, utils_1.assert)('Status code', res.status).toBe(400);
585
619
  }),
586
620
  (0, utils_1.audit)('SHOULD not contain the data entry on document parsing failure when accepting application/graphql-response+json', async () => {
587
- const url = new URL(opts.url);
588
- url.searchParams.set('query', '{');
589
- const res = await fetchFn(url.toString(), {
590
- method: 'GET',
591
- headers: { accept: 'application/graphql-response+json' },
621
+ const res = await fetchFn(opts.url, {
622
+ method: 'POST',
623
+ headers: {
624
+ 'content-type': 'application/json',
625
+ accept: 'application/graphql-response+json',
626
+ },
627
+ body: JSON.stringify({
628
+ query: '{',
629
+ }),
592
630
  });
593
631
  (0, utils_1.assert)('Data entry', (await (0, utils_1.assertBodyAsExecutionResult)(res)).data).toBe(undefined);
594
632
  }),
595
633
  (0, utils_1.audit)(
596
634
  // TODO: convert to MUST after watershed
597
635
  'SHOULD use 4xx or 5xx status codes on document validation failure when accepting application/graphql-response+json', async () => {
598
- const url = new URL(opts.url);
599
- url.searchParams.set('query', '{ 8f31403dfe404bccbb0e835f2629c6a7 }'); // making sure the field doesnt exist
600
- const res = await fetchFn(url.toString(), {
601
- method: 'GET',
602
- headers: { accept: 'application/graphql-response+json' },
636
+ const res = await fetchFn(opts.url, {
637
+ method: 'POST',
638
+ headers: {
639
+ 'content-type': 'application/json',
640
+ accept: 'application/graphql-response+json',
641
+ },
642
+ body: JSON.stringify({
643
+ query: '{ 8f31403dfe404bccbb0e835f2629c6a7 }', // making sure the field doesnt exist
644
+ }),
603
645
  });
604
- (0, utils_1.assert)('Status code', res.status).toBeGreaterThanOrEqual(400);
605
- (0, utils_1.assert)('Status code', res.status).toBeLessThanOrEqual(599);
646
+ (0, utils_1.assert)('Status code', res.status).toBeBetween(400, 599);
606
647
  }),
607
648
  (0, utils_1.audit)('SHOULD use 400 status code on document validation failure when accepting application/graphql-response+json', async () => {
608
- const url = new URL(opts.url);
609
- url.searchParams.set('query', '{ 8f31403dfe404bccbb0e835f2629c6a7 }'); // making sure the field doesnt exist
610
- const res = await fetchFn(url.toString(), {
611
- method: 'GET',
612
- headers: { accept: 'application/graphql-response+json' },
649
+ const res = await fetchFn(opts.url, {
650
+ method: 'POST',
651
+ headers: {
652
+ 'content-type': 'application/json',
653
+ accept: 'application/graphql-response+json',
654
+ },
655
+ body: JSON.stringify({
656
+ query: '{ 8f31403dfe404bccbb0e835f2629c6a7 }', // making sure the field doesnt exist
657
+ }),
613
658
  });
614
659
  (0, utils_1.assert)('Status code', res.status).toBe(400);
615
660
  }),
616
661
  (0, utils_1.audit)('SHOULD not contain the data entry on document validation failure when accepting application/graphql-response+json', async () => {
617
- const url = new URL(opts.url);
618
- url.searchParams.set('query', '{ 8f31403dfe404bccbb0e835f2629c6a7 }'); // making sure the field doesnt exist
619
- const res = await fetchFn(url.toString(), {
620
- method: 'GET',
621
- headers: { accept: 'application/graphql-response+json' },
662
+ const res = await fetchFn(opts.url, {
663
+ method: 'POST',
664
+ headers: {
665
+ 'content-type': 'application/json',
666
+ accept: 'application/graphql-response+json',
667
+ },
668
+ body: JSON.stringify({
669
+ query: '{ 8f31403dfe404bccbb0e835f2629c6a7 }', // making sure the field doesnt exist
670
+ }),
622
671
  });
623
672
  (0, utils_1.assert)('Data entry', (await (0, utils_1.assertBodyAsExecutionResult)(res)).data).toBe(undefined);
624
673
  }),
@@ -16,53 +16,56 @@ export function serverAudits(opts) {
16
16
  audit(
17
17
  // TODO: convert to MUST after watershed
18
18
  'SHOULD accept application/graphql-response+json and match the content-type', async () => {
19
- const url = new URL(opts.url);
20
- url.searchParams.set('query', '{ __typename }');
21
- const res = await fetchFn(url.toString(), {
19
+ const res = await fetchFn(opts.url, {
20
+ method: 'POST',
22
21
  headers: {
22
+ 'content-type': 'application/json',
23
23
  accept: 'application/graphql-response+json',
24
24
  },
25
+ body: JSON.stringify({ query: '{ __typename }' }),
25
26
  });
26
27
  assert('Status code', res.status).toBe(200);
27
28
  assert('Content-Type header', res.headers.get('content-type')).toContain('application/graphql-response+json');
28
29
  }),
29
30
  audit('MUST accept application/json and match the content-type', async () => {
30
- const url = new URL(opts.url);
31
- url.searchParams.set('query', '{ __typename }');
32
- const res = await fetchFn(url.toString(), {
31
+ const res = await fetchFn(opts.url, {
32
+ method: 'POST',
33
33
  headers: {
34
+ 'content-type': 'application/json',
34
35
  accept: 'application/json',
35
36
  },
37
+ body: JSON.stringify({ query: '{ __typename }' }),
36
38
  });
37
39
  assert('Status code', res.status).toBe(200);
38
40
  assert('Content-Type header', res.headers.get('content-type')).toContain('application/json');
39
41
  }),
40
- audit(
41
- // TODO: convert to MUST after watershed
42
- 'SHOULD accept */* and use application/graphql-response+json for the content-type', async () => {
43
- const url = new URL(opts.url);
44
- url.searchParams.set('query', '{ __typename }');
45
- const res = await fetchFn(url.toString(), {
42
+ audit('SHOULD accept */* and use application/json for the content-type', async () => {
43
+ const res = await fetchFn(opts.url, {
44
+ method: 'POST',
46
45
  headers: {
46
+ 'content-type': 'application/json',
47
47
  accept: '*/*',
48
48
  },
49
+ body: JSON.stringify({ query: '{ __typename }' }),
49
50
  });
50
51
  assert('Status code', res.status).toBe(200);
51
- assert('Content-Type header', res.headers.get('content-type')).toContain('application/graphql-response+json');
52
+ assert('Content-Type header', res.headers.get('content-type')).toContain('application/json');
52
53
  }),
53
- audit(
54
- // TODO: convert to MUST after watershed
55
- 'SHOULD assume application/graphql-response+json content-type when accept is missing', async () => {
54
+ audit('SHOULD assume application/json content-type when accept is missing', async () => {
56
55
  const url = new URL(opts.url);
57
56
  url.searchParams.set('query', '{ __typename }');
58
57
  const res = await fetchFn(url.toString());
59
58
  assert('Status code', res.status).toBe(200);
60
- assert('Content-Type header', res.headers.get('content-type')).toContain('application/graphql-response+json');
59
+ assert('Content-Type header', res.headers.get('content-type')).toContain('application/json');
61
60
  }),
62
61
  audit('MUST use utf-8 encoding when responding', async () => {
63
- const url = new URL(opts.url);
64
- url.searchParams.set('query', '{ __typename }');
65
- const res = await fetchFn(url.toString());
62
+ const res = await fetchFn(opts.url, {
63
+ method: 'POST',
64
+ headers: {
65
+ 'content-type': 'application/json',
66
+ },
67
+ body: JSON.stringify({ query: '{ __typename }' }),
68
+ });
66
69
  assert('Status code', res.status).toBe(200);
67
70
  // has charset set to utf-8
68
71
  try {
@@ -85,23 +88,23 @@ export function serverAudits(opts) {
85
88
  }
86
89
  }),
87
90
  audit('MUST accept utf-8 encoding', async () => {
88
- const url = new URL(opts.url);
89
- url.searchParams.set('query', '{ __typename }');
90
- const res = await fetchFn(url.toString(), {
91
+ const res = await fetchFn(opts.url, {
92
+ method: 'POST',
91
93
  headers: {
92
94
  'content-type': 'application/json; charset=utf-8',
93
95
  },
96
+ body: JSON.stringify({ query: '{ __typename }' }),
94
97
  });
95
98
  assert('Status code', res.status).toBe(200);
96
99
  assert('Content-Type header', res.headers.get('content-type')).toContain('utf-8');
97
100
  }),
98
101
  audit('MUST assume utf-8 if encoding is unspecified', async () => {
99
- const url = new URL(opts.url);
100
- url.searchParams.set('query', '{ __typename }');
101
- const res = await fetchFn(url.toString(), {
102
+ const res = await fetchFn(opts.url, {
103
+ method: 'POST',
102
104
  headers: {
103
105
  'content-type': 'application/json',
104
106
  },
107
+ body: JSON.stringify({ query: '{ __typename }' }),
105
108
  });
106
109
  assert('Status code', res.status).toBe(200);
107
110
  assert('Content-Type header', res.headers.get('content-type')).toContain('utf-8');
@@ -122,7 +125,8 @@ export function serverAudits(opts) {
122
125
  assert('Status code', res.status).toBe(200);
123
126
  }),
124
127
  // Request GET
125
- audit('MUST NOT allow executing mutations on GET requests', async () => {
128
+ // TODO: this is a MUST if the server supports GET requests
129
+ audit('MAY NOT allow executing mutations on GET requests', async () => {
126
130
  const url = new URL(opts.url);
127
131
  url.searchParams.set('query', 'mutation { __typename }');
128
132
  const res = await fetchFn(url.toString(), {
@@ -130,15 +134,14 @@ export function serverAudits(opts) {
130
134
  accept: 'application/graphql-response+json',
131
135
  },
132
136
  });
133
- assert('Status code', res.status).toBe(405);
137
+ assert('Status code', res.status).toBeBetween(400, 499);
134
138
  }),
135
139
  // Request POST
136
140
  audit('SHOULD respond with 4xx status code if content-type is not supplied on POST requests', async () => {
137
141
  const res = await fetchFn(opts.url, {
138
142
  method: 'POST',
139
143
  });
140
- assert('Status code', res.status).toBeGreaterThanOrEqual(400);
141
- assert('Status code', res.status).toBeLessThanOrEqual(499);
144
+ assert('Status code', res.status).toBeBetween(400, 499);
142
145
  }),
143
146
  audit('MUST accept application/json POST requests', async () => {
144
147
  const res = await fetchFn(opts.url, {
@@ -149,11 +152,17 @@ export function serverAudits(opts) {
149
152
  assert('Status code', res.status).toBe(200);
150
153
  }),
151
154
  audit('MUST require a request body on POST', async () => {
155
+ var _a;
152
156
  const res = await fetchFn(opts.url, {
153
157
  method: 'POST',
154
158
  headers: { 'content-type': 'application/json' },
155
159
  });
156
- assert('Status code', res.status).toBe(400);
160
+ if ((_a = res.headers.get('content-type')) === null || _a === void 0 ? void 0 : _a.includes('application/json')) {
161
+ assert('Execution result', await assertBodyAsExecutionResult(res)).toHaveProperty('errors');
162
+ }
163
+ else {
164
+ assert('Status code', res.status).toBe(400);
165
+ }
157
166
  }),
158
167
  // Request Parameters
159
168
  audit(
@@ -363,9 +372,7 @@ export function serverAudits(opts) {
363
372
  assert('Status code', res.status).toBe(200);
364
373
  assert('Execution result', await assertBodyAsExecutionResult(res)).notToHaveProperty('errors');
365
374
  }),
366
- audit(
367
- // TODO: convert to MUST after watershed
368
- 'SHOULD allow URL-encoded JSON string {variables} parameter in GETs when accepting application/graphql-response+json', async () => {
375
+ audit('MAY allow URL-encoded JSON string {variables} parameter in GETs when accepting application/graphql-response+json', async () => {
369
376
  const url = new URL(opts.url);
370
377
  url.searchParams.set('query', 'query Type($name: String!) { __type(name: $name) { name } }');
371
378
  url.searchParams.set('variables', JSON.stringify({ name: 'sometype' }));
@@ -377,7 +384,7 @@ export function serverAudits(opts) {
377
384
  });
378
385
  assert('Status code', res.status).toBe(200);
379
386
  }),
380
- audit('MUST allow URL-encoded JSON string {variables} parameter in GETs when accepting application/json', async () => {
387
+ audit('MAY allow URL-encoded JSON string {variables} parameter in GETs when accepting application/json', async () => {
381
388
  const url = new URL(opts.url);
382
389
  url.searchParams.set('query', 'query Type($name: String!) { __type(name: $name) { name } }');
383
390
  url.searchParams.set('variables', JSON.stringify({ name: 'sometype' }));
@@ -466,29 +473,39 @@ export function serverAudits(opts) {
466
473
  assert('Status code', res.status).toBe(200);
467
474
  }),
468
475
  audit('SHOULD use 200 status code if parameters are invalid when accepting application/json', async () => {
469
- const url = new URL(opts.url);
470
- url.searchParams.set('qeury' /* typo */, '{ __typename }');
471
- const res = await fetchFn(url.toString(), {
472
- method: 'GET',
473
- headers: { accept: 'application/json' },
476
+ const res = await fetchFn(opts.url, {
477
+ method: 'POST',
478
+ headers: {
479
+ 'content-type': 'application/json',
480
+ accept: 'application/json',
481
+ },
482
+ body: JSON.stringify({
483
+ qeury: /* typo */ '{ __typename }',
484
+ }),
474
485
  });
475
486
  assert('Status code', res.status).toBe(200);
476
487
  }),
477
488
  audit('SHOULD use 200 status code on document parsing failure when accepting application/json', async () => {
478
- const url = new URL(opts.url);
479
- url.searchParams.set('query', '{');
480
- const res = await fetchFn(url.toString(), {
481
- method: 'GET',
482
- headers: { accept: 'application/json' },
489
+ const res = await fetchFn(opts.url, {
490
+ method: 'POST',
491
+ headers: {
492
+ 'content-type': 'application/json',
493
+ accept: 'application/json',
494
+ },
495
+ body: JSON.stringify({ query: '{' }),
483
496
  });
484
497
  assert('Status code', res.status).toBe(200);
485
498
  }),
486
499
  audit('SHOULD use 200 status code on document validation failure when accepting application/json', async () => {
487
- const url = new URL(opts.url);
488
- url.searchParams.set('query', '{ 8f31403dfe404bccbb0e835f2629c6a7 }'); // making sure the field doesnt exist
489
- const res = await fetchFn(url.toString(), {
490
- method: 'GET',
491
- headers: { accept: 'application/json' },
500
+ const res = await fetchFn(opts.url, {
501
+ method: 'POST',
502
+ headers: {
503
+ 'content-type': 'application/json',
504
+ accept: 'application/json',
505
+ },
506
+ body: JSON.stringify({
507
+ query: '{ 8f31403dfe404bccbb0e835f2629c6a7 }', // making sure the field doesnt exist
508
+ }),
492
509
  });
493
510
  assert('Status code', res.status).toBe(200);
494
511
  }),
@@ -504,8 +521,7 @@ export function serverAudits(opts) {
504
521
  },
505
522
  body: '{ "not a JSON',
506
523
  });
507
- assert('Status code', res.status).toBeGreaterThanOrEqual(400);
508
- assert('Status code', res.status).toBeLessThanOrEqual(599);
524
+ assert('Status code', res.status).toBeBetween(400, 499);
509
525
  }),
510
526
  audit('SHOULD use 400 status code on JSON parsing failure when accepting application/graphql-response+json', async () => {
511
527
  const res = await fetchFn(opts.url, {
@@ -532,90 +548,123 @@ export function serverAudits(opts) {
532
548
  audit(
533
549
  // TODO: convert to MUST after watershed
534
550
  'SHOULD use 4xx or 5xx status codes if parameters are invalid when accepting application/graphql-response+json', async () => {
535
- const url = new URL(opts.url);
536
- url.searchParams.set('qeury' /* typo */, '{ __typename }');
537
- const res = await fetchFn(url.toString(), {
538
- method: 'GET',
539
- headers: { accept: 'application/graphql-response+json' },
551
+ const res = await fetchFn(opts.url, {
552
+ method: 'POST',
553
+ headers: {
554
+ 'content-type': 'application/json',
555
+ accept: 'application/graphql-response+json',
556
+ },
557
+ body: JSON.stringify({
558
+ qeury /* typo */: '{ __typename }',
559
+ }),
540
560
  });
541
- assert('Status code', res.status).toBeGreaterThanOrEqual(400);
542
- assert('Status code', res.status).toBeLessThanOrEqual(599);
561
+ assert('Status code', res.status).toBeBetween(400, 599);
543
562
  }),
544
563
  audit('SHOULD use 400 status code if parameters are invalid when accepting application/graphql-response+json', async () => {
545
- const url = new URL(opts.url);
546
- url.searchParams.set('qeury' /* typo */, '{ __typename }');
547
- const res = await fetchFn(url.toString(), {
548
- method: 'GET',
549
- headers: { accept: 'application/graphql-response+json' },
564
+ const res = await fetchFn(opts.url, {
565
+ method: 'POST',
566
+ headers: {
567
+ 'content-type': 'application/json',
568
+ accept: 'application/graphql-response+json',
569
+ },
570
+ body: JSON.stringify({
571
+ qeury: /* typo */ '{ __typename }',
572
+ }),
550
573
  });
551
574
  assert('Status code', res.status).toBe(400);
552
575
  }),
553
576
  audit('SHOULD not contain the data entry if parameters are invalid when accepting application/graphql-response+json', async () => {
554
- const url = new URL(opts.url);
555
- url.searchParams.set('qeury' /* typo */, '{ __typename }');
556
- const res = await fetchFn(url.toString(), {
557
- method: 'GET',
558
- headers: { accept: 'application/graphql-response+json' },
577
+ const res = await fetchFn(opts.url, {
578
+ method: 'POST',
579
+ headers: {
580
+ 'content-type': 'application/json',
581
+ accept: 'application/graphql-response+json',
582
+ },
583
+ body: JSON.stringify({
584
+ qeury: /* typo */ '{ __typename }',
585
+ }),
559
586
  });
560
587
  assert('Data entry', (await assertBodyAsExecutionResult(res)).data).toBe(undefined);
561
588
  }),
562
589
  audit(
563
590
  // TODO: convert to MUST after watershed
564
591
  'SHOULD use 4xx or 5xx status codes on document parsing failure when accepting application/graphql-response+json', async () => {
565
- const url = new URL(opts.url);
566
- url.searchParams.set('query', '{');
567
- const res = await fetchFn(url.toString(), {
568
- method: 'GET',
569
- headers: { accept: 'application/graphql-response+json' },
592
+ const res = await fetchFn(opts.url, {
593
+ method: 'POST',
594
+ headers: {
595
+ 'content-type': 'application/json',
596
+ accept: 'application/graphql-response+json',
597
+ },
598
+ body: JSON.stringify({
599
+ query: '{',
600
+ }),
570
601
  });
571
- assert('Status code', res.status).toBeGreaterThanOrEqual(400);
572
- assert('Status code', res.status).toBeLessThanOrEqual(599);
602
+ assert('Status code', res.status).toBeBetween(400, 599);
573
603
  }),
574
604
  audit('SHOULD use 400 status code on document parsing failure when accepting application/graphql-response+json', async () => {
575
- const url = new URL(opts.url);
576
- url.searchParams.set('query', '{');
577
- const res = await fetchFn(url.toString(), {
578
- method: 'GET',
579
- headers: { accept: 'application/graphql-response+json' },
605
+ const res = await fetchFn(opts.url, {
606
+ method: 'POST',
607
+ headers: {
608
+ 'content-type': 'application/json',
609
+ accept: 'application/graphql-response+json',
610
+ },
611
+ body: JSON.stringify({
612
+ query: '{',
613
+ }),
580
614
  });
581
615
  assert('Status code', res.status).toBe(400);
582
616
  }),
583
617
  audit('SHOULD not contain the data entry on document parsing failure when accepting application/graphql-response+json', async () => {
584
- const url = new URL(opts.url);
585
- url.searchParams.set('query', '{');
586
- const res = await fetchFn(url.toString(), {
587
- method: 'GET',
588
- headers: { accept: 'application/graphql-response+json' },
618
+ const res = await fetchFn(opts.url, {
619
+ method: 'POST',
620
+ headers: {
621
+ 'content-type': 'application/json',
622
+ accept: 'application/graphql-response+json',
623
+ },
624
+ body: JSON.stringify({
625
+ query: '{',
626
+ }),
589
627
  });
590
628
  assert('Data entry', (await assertBodyAsExecutionResult(res)).data).toBe(undefined);
591
629
  }),
592
630
  audit(
593
631
  // TODO: convert to MUST after watershed
594
632
  'SHOULD use 4xx or 5xx status codes on document validation failure when accepting application/graphql-response+json', async () => {
595
- const url = new URL(opts.url);
596
- url.searchParams.set('query', '{ 8f31403dfe404bccbb0e835f2629c6a7 }'); // making sure the field doesnt exist
597
- const res = await fetchFn(url.toString(), {
598
- method: 'GET',
599
- headers: { accept: 'application/graphql-response+json' },
633
+ const res = await fetchFn(opts.url, {
634
+ method: 'POST',
635
+ headers: {
636
+ 'content-type': 'application/json',
637
+ accept: 'application/graphql-response+json',
638
+ },
639
+ body: JSON.stringify({
640
+ query: '{ 8f31403dfe404bccbb0e835f2629c6a7 }', // making sure the field doesnt exist
641
+ }),
600
642
  });
601
- assert('Status code', res.status).toBeGreaterThanOrEqual(400);
602
- assert('Status code', res.status).toBeLessThanOrEqual(599);
643
+ assert('Status code', res.status).toBeBetween(400, 599);
603
644
  }),
604
645
  audit('SHOULD use 400 status code on document validation failure when accepting application/graphql-response+json', async () => {
605
- const url = new URL(opts.url);
606
- url.searchParams.set('query', '{ 8f31403dfe404bccbb0e835f2629c6a7 }'); // making sure the field doesnt exist
607
- const res = await fetchFn(url.toString(), {
608
- method: 'GET',
609
- headers: { accept: 'application/graphql-response+json' },
646
+ const res = await fetchFn(opts.url, {
647
+ method: 'POST',
648
+ headers: {
649
+ 'content-type': 'application/json',
650
+ accept: 'application/graphql-response+json',
651
+ },
652
+ body: JSON.stringify({
653
+ query: '{ 8f31403dfe404bccbb0e835f2629c6a7 }', // making sure the field doesnt exist
654
+ }),
610
655
  });
611
656
  assert('Status code', res.status).toBe(400);
612
657
  }),
613
658
  audit('SHOULD not contain the data entry on document validation failure when accepting application/graphql-response+json', async () => {
614
- const url = new URL(opts.url);
615
- url.searchParams.set('query', '{ 8f31403dfe404bccbb0e835f2629c6a7 }'); // making sure the field doesnt exist
616
- const res = await fetchFn(url.toString(), {
617
- method: 'GET',
618
- headers: { accept: 'application/graphql-response+json' },
659
+ const res = await fetchFn(opts.url, {
660
+ method: 'POST',
661
+ headers: {
662
+ 'content-type': 'application/json',
663
+ accept: 'application/graphql-response+json',
664
+ },
665
+ body: JSON.stringify({
666
+ query: '{ 8f31403dfe404bccbb0e835f2629c6a7 }', // making sure the field doesnt exist
667
+ }),
619
668
  });
620
669
  assert('Data entry', (await assertBodyAsExecutionResult(res)).data).toBe(undefined);
621
670
  }),
@@ -21,8 +21,7 @@ export declare function audit(name: AuditName, fn: () => Promise<void>): Audit;
21
21
  */
22
22
  export declare function assert<T = unknown>(name: string, actual: T): {
23
23
  toBe: (expected: T) => void;
24
- toBeLessThanOrEqual: (expected: T extends number ? T : never) => void;
25
- toBeGreaterThanOrEqual: (expected: T extends number ? T : never) => void;
24
+ toBeBetween: (min: T extends number ? T : never, max: T extends number ? T : never) => void;
26
25
  toContain: (expected: T extends (infer U)[] ? U : T extends string ? T : never) => void;
27
26
  notToContain: (expected: T extends (infer U_1)[] ? U_1 : T extends string ? T : never) => void;
28
27
  toHaveProperty: (prop: T extends Record<any, any> ? PropertyKey : never) => void;
@@ -21,8 +21,7 @@ export declare function audit(name: AuditName, fn: () => Promise<void>): Audit;
21
21
  */
22
22
  export declare function assert<T = unknown>(name: string, actual: T): {
23
23
  toBe: (expected: T) => void;
24
- toBeLessThanOrEqual: (expected: T extends number ? T : never) => void;
25
- toBeGreaterThanOrEqual: (expected: T extends number ? T : never) => void;
24
+ toBeBetween: (min: T extends number ? T : never, max: T extends number ? T : never) => void;
26
25
  toContain: (expected: T extends (infer U)[] ? U : T extends string ? T : never) => void;
27
26
  notToContain: (expected: T extends (infer U_1)[] ? U_1 : T extends string ? T : never) => void;
28
27
  toHaveProperty: (prop: T extends Record<any, any> ? PropertyKey : never) => void;
@@ -70,14 +70,9 @@ function assert(name, actual) {
70
70
  throw `${name} ${actual} is not ${expected}`;
71
71
  }
72
72
  },
73
- toBeLessThanOrEqual: (expected) => {
74
- if (!(actual <= expected)) {
75
- throw `${name} ${actual} is not less than or equal to ${expected}`;
76
- }
77
- },
78
- toBeGreaterThanOrEqual: (expected) => {
79
- if (!(actual >= expected)) {
80
- throw `${name} ${actual} is not greater than or equal to ${expected}`;
73
+ toBeBetween: (min, max) => {
74
+ if (!(min <= actual && actual <= max)) {
75
+ throw `${name} ${actual} is not between ${min} and ${max}`;
81
76
  }
82
77
  },
83
78
  toContain: (expected) => {
@@ -52,14 +52,9 @@ export function assert(name, actual) {
52
52
  throw `${name} ${actual} is not ${expected}`;
53
53
  }
54
54
  },
55
- toBeLessThanOrEqual: (expected) => {
56
- if (!(actual <= expected)) {
57
- throw `${name} ${actual} is not less than or equal to ${expected}`;
58
- }
59
- },
60
- toBeGreaterThanOrEqual: (expected) => {
61
- if (!(actual >= expected)) {
62
- throw `${name} ${actual} is not greater than or equal to ${expected}`;
55
+ toBeBetween: (min, max) => {
56
+ if (!(min <= actual && actual <= max)) {
57
+ throw `${name} ${actual} is not between ${min} and ${max}`;
63
58
  }
64
59
  },
65
60
  toContain: (expected) => {
package/lib/handler.js CHANGED
@@ -296,15 +296,16 @@ function getAcceptableMediaType(acceptHeader) {
296
296
  // TODO: handle the weight parameter "q"
297
297
  const [mediaType, ...params] = accept.split(';');
298
298
  const charset = (params === null || params === void 0 ? void 0 : params.find((param) => param.includes('charset='))) || 'charset=utf8'; // utf-8 is assumed when not specified;
299
- if (mediaType === 'application/json' && charset === 'charset=utf8') {
300
- acceptedMediaType = 'application/json';
299
+ if (mediaType === 'application/graphql-response+json' &&
300
+ charset === 'charset=utf8') {
301
+ acceptedMediaType = 'application/graphql-response+json';
301
302
  break;
302
303
  }
303
- if ((mediaType === 'application/graphql-response+json' ||
304
+ if ((mediaType === 'application/json' ||
304
305
  mediaType === 'application/*' ||
305
306
  mediaType === '*/*') &&
306
307
  charset === 'charset=utf8') {
307
- acceptedMediaType = 'application/graphql-response+json';
308
+ acceptedMediaType = 'application/json';
308
309
  break;
309
310
  }
310
311
  }
package/lib/handler.mjs CHANGED
@@ -291,15 +291,16 @@ export function getAcceptableMediaType(acceptHeader) {
291
291
  // TODO: handle the weight parameter "q"
292
292
  const [mediaType, ...params] = accept.split(';');
293
293
  const charset = (params === null || params === void 0 ? void 0 : params.find((param) => param.includes('charset='))) || 'charset=utf8'; // utf-8 is assumed when not specified;
294
- if (mediaType === 'application/json' && charset === 'charset=utf8') {
295
- acceptedMediaType = 'application/json';
294
+ if (mediaType === 'application/graphql-response+json' &&
295
+ charset === 'charset=utf8') {
296
+ acceptedMediaType = 'application/graphql-response+json';
296
297
  break;
297
298
  }
298
- if ((mediaType === 'application/graphql-response+json' ||
299
+ if ((mediaType === 'application/json' ||
299
300
  mediaType === 'application/*' ||
300
301
  mediaType === '*/*') &&
301
302
  charset === 'charset=utf8') {
302
- acceptedMediaType = 'application/graphql-response+json';
303
+ acceptedMediaType = 'application/json';
303
304
  break;
304
305
  }
305
306
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "graphql-http",
3
- "version": "1.7.0",
3
+ "version": "1.7.2",
4
4
  "description": "Simple, pluggable, zero-dependency, GraphQL over HTTP Protocol compliant server and client",
5
5
  "keywords": [
6
6
  "graphql",
@@ -82,7 +82,7 @@
82
82
  "release": "semantic-release"
83
83
  },
84
84
  "workspaces": [
85
- "implementations/*"
85
+ "implementations/**/*"
86
86
  ],
87
87
  "peerDependencies": {
88
88
  "graphql": ">=0.11 <=16"
Binary file