graphql-http 1.12.0 → 1.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +15 -9
- package/lib/audits/common.d.mts +15 -0
- package/lib/audits/common.d.ts +15 -0
- package/lib/audits/server.js +54 -65
- package/lib/audits/server.mjs +54 -65
- package/lib/audits/utils.d.mts +1 -1
- package/lib/audits/utils.d.ts +1 -1
- package/lib/audits/utils.js +4 -1
- package/lib/audits/utils.mjs +4 -1
- package/package.json +12 -12
- package/umd/graphql-http.min.js.gz +0 -0
package/README.md
CHANGED
|
@@ -744,15 +744,21 @@ Having said this, graphql-http is mostly aimed for library authors and simple se
|
|
|
744
744
|
|
|
745
745
|
If you want a feature-full server with bleeding edge technologies, you're recommended to use one of the following.
|
|
746
746
|
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
|
750
|
-
|
|
751
|
-
| [
|
|
752
|
-
| [
|
|
753
|
-
| [
|
|
754
|
-
| [
|
|
755
|
-
| [
|
|
747
|
+
<!-- <ServersTable> -->
|
|
748
|
+
<!-- prettier-ignore-start -->
|
|
749
|
+
| Name | Audit |
|
|
750
|
+
|------|-------|
|
|
751
|
+
| [apollo-server](https://www.apollographql.com/docs/apollo-server) | [✅ Compliant](/implementations/apollo-server/README.md) |
|
|
752
|
+
| [deno](https://deno.com/blog/build-a-graphql-server-with-deno) | [✅ Compliant](/implementations/deno/README.md) |
|
|
753
|
+
| [graph-client](https://github.com/graphprotocol/graph-client) | [✅ Compliant](/implementations/graph-client/README.md) |
|
|
754
|
+
| [graphql-helix](https://www.graphql-helix.com) | [✅ Compliant](/implementations/graphql-helix/README.md) |
|
|
755
|
+
| [graphql-yoga](https://www.the-guild.dev/graphql/yoga-server) | [✅ Compliant](/implementations/graphql-yoga/README.md) |
|
|
756
|
+
| [hotchocolate](https://chillicream.com/docs/hotchocolate) | [✅ Compliant](/implementations/hotchocolate/README.md) |
|
|
757
|
+
| [pioneer](https://pioneer.dexclaimation.com) | [✅ Compliant](/implementations/pioneer/README.md) |
|
|
758
|
+
| [postgraphile](https://www.graphile.org/postgraphile) | [✅ Compliant](/implementations/postgraphile/README.md) |
|
|
759
|
+
<!-- prettier-ignore-end -->
|
|
760
|
+
|
|
761
|
+
<!-- </ServersTable> -->
|
|
756
762
|
|
|
757
763
|
## [Documentation](docs/)
|
|
758
764
|
|
package/lib/audits/common.d.mts
CHANGED
|
@@ -23,6 +23,11 @@ export type AuditName = `${AuditRequirement} ${string}`;
|
|
|
23
23
|
* @category Audits
|
|
24
24
|
*/
|
|
25
25
|
export interface Audit {
|
|
26
|
+
/**
|
|
27
|
+
* Uniquely represents the audit. Helps with pinning audits
|
|
28
|
+
* without depending on the human readable audit name.
|
|
29
|
+
*/
|
|
30
|
+
id: string;
|
|
26
31
|
name: AuditName;
|
|
27
32
|
fn: () => Promise<AuditResult>;
|
|
28
33
|
}
|
|
@@ -32,6 +37,11 @@ export interface Audit {
|
|
|
32
37
|
* @category Audits
|
|
33
38
|
*/
|
|
34
39
|
export interface AuditOk {
|
|
40
|
+
/**
|
|
41
|
+
* Uniquely represents the passing audit. Helps with pinning audits
|
|
42
|
+
* without depending on the human readable audit name.
|
|
43
|
+
*/
|
|
44
|
+
id: string;
|
|
35
45
|
name: AuditName;
|
|
36
46
|
status: 'ok';
|
|
37
47
|
}
|
|
@@ -46,6 +56,11 @@ export interface AuditOk {
|
|
|
46
56
|
* @category Audits
|
|
47
57
|
*/
|
|
48
58
|
export interface AuditFail {
|
|
59
|
+
/**
|
|
60
|
+
* Uniquely represents the failing audit. Helps with pinning audits
|
|
61
|
+
* without depending on the human readable audit name.
|
|
62
|
+
*/
|
|
63
|
+
id: string;
|
|
49
64
|
name: AuditName;
|
|
50
65
|
status: 'warn' | 'error';
|
|
51
66
|
reason: string;
|
package/lib/audits/common.d.ts
CHANGED
|
@@ -23,6 +23,11 @@ export type AuditName = `${AuditRequirement} ${string}`;
|
|
|
23
23
|
* @category Audits
|
|
24
24
|
*/
|
|
25
25
|
export interface Audit {
|
|
26
|
+
/**
|
|
27
|
+
* Uniquely represents the audit. Helps with pinning audits
|
|
28
|
+
* without depending on the human readable audit name.
|
|
29
|
+
*/
|
|
30
|
+
id: string;
|
|
26
31
|
name: AuditName;
|
|
27
32
|
fn: () => Promise<AuditResult>;
|
|
28
33
|
}
|
|
@@ -32,6 +37,11 @@ export interface Audit {
|
|
|
32
37
|
* @category Audits
|
|
33
38
|
*/
|
|
34
39
|
export interface AuditOk {
|
|
40
|
+
/**
|
|
41
|
+
* Uniquely represents the passing audit. Helps with pinning audits
|
|
42
|
+
* without depending on the human readable audit name.
|
|
43
|
+
*/
|
|
44
|
+
id: string;
|
|
35
45
|
name: AuditName;
|
|
36
46
|
status: 'ok';
|
|
37
47
|
}
|
|
@@ -46,6 +56,11 @@ export interface AuditOk {
|
|
|
46
56
|
* @category Audits
|
|
47
57
|
*/
|
|
48
58
|
export interface AuditFail {
|
|
59
|
+
/**
|
|
60
|
+
* Uniquely represents the failing audit. Helps with pinning audits
|
|
61
|
+
* without depending on the human readable audit name.
|
|
62
|
+
*/
|
|
63
|
+
id: string;
|
|
49
64
|
name: AuditName;
|
|
50
65
|
status: 'warn' | 'error';
|
|
51
66
|
reason: string;
|
package/lib/audits/server.js
CHANGED
|
@@ -18,7 +18,7 @@ function serverAudits(opts) {
|
|
|
18
18
|
// Media Types
|
|
19
19
|
(0, utils_1.audit)(
|
|
20
20
|
// TODO: convert to MUST after watershed
|
|
21
|
-
'SHOULD accept application/graphql-response+json and match the content-type', async () => {
|
|
21
|
+
'22EB', 'SHOULD accept application/graphql-response+json and match the content-type', async () => {
|
|
22
22
|
const res = await fetchFn(await getUrl(opts.url), {
|
|
23
23
|
method: 'POST',
|
|
24
24
|
headers: {
|
|
@@ -32,7 +32,7 @@ function serverAudits(opts) {
|
|
|
32
32
|
.header('content-type')
|
|
33
33
|
.toContain('application/graphql-response+json');
|
|
34
34
|
}),
|
|
35
|
-
(0, utils_1.audit)('MUST accept application/json and match the content-type', async () => {
|
|
35
|
+
(0, utils_1.audit)('4655', 'MUST accept application/json and match the content-type', async () => {
|
|
36
36
|
const res = await fetchFn(await getUrl(opts.url), {
|
|
37
37
|
method: 'POST',
|
|
38
38
|
headers: {
|
|
@@ -44,7 +44,7 @@ function serverAudits(opts) {
|
|
|
44
44
|
(0, utils_1.ressert)(res).status.toBe(200);
|
|
45
45
|
(0, utils_1.ressert)(res).header('content-type').toContain('application/json');
|
|
46
46
|
}),
|
|
47
|
-
(0, utils_1.audit)('SHOULD accept */* and use application/json for the content-type', async () => {
|
|
47
|
+
(0, utils_1.audit)('47DE', 'SHOULD accept */* and use application/json for the content-type', async () => {
|
|
48
48
|
const res = await fetchFn(await getUrl(opts.url), {
|
|
49
49
|
method: 'POST',
|
|
50
50
|
headers: {
|
|
@@ -56,14 +56,14 @@ function serverAudits(opts) {
|
|
|
56
56
|
(0, utils_1.ressert)(res).status.toBe(200);
|
|
57
57
|
(0, utils_1.ressert)(res).header('content-type').toContain('application/json');
|
|
58
58
|
}),
|
|
59
|
-
(0, utils_1.audit)('SHOULD assume application/json content-type when accept is missing', async () => {
|
|
59
|
+
(0, utils_1.audit)('80D8', 'SHOULD assume application/json content-type when accept is missing', async () => {
|
|
60
60
|
const url = new URL(await getUrl(opts.url));
|
|
61
61
|
url.searchParams.set('query', '{ __typename }');
|
|
62
62
|
const res = await fetchFn(url.toString());
|
|
63
63
|
(0, utils_1.ressert)(res).status.toBe(200);
|
|
64
64
|
(0, utils_1.ressert)(res).header('content-type').toContain('application/json');
|
|
65
65
|
}),
|
|
66
|
-
(0, utils_1.audit)('MUST use utf-8 encoding when responding', async () => {
|
|
66
|
+
(0, utils_1.audit)('82A3', 'MUST use utf-8 encoding when responding', async () => {
|
|
67
67
|
const res = await fetchFn(await getUrl(opts.url), {
|
|
68
68
|
method: 'POST',
|
|
69
69
|
headers: {
|
|
@@ -80,7 +80,7 @@ function serverAudits(opts) {
|
|
|
80
80
|
throw new utils_1.AuditError(res, 'Response body is not UTF-8 encoded');
|
|
81
81
|
}
|
|
82
82
|
}),
|
|
83
|
-
(0, utils_1.audit)('MUST accept utf-8 encoded request', async () => {
|
|
83
|
+
(0, utils_1.audit)('BF61', 'MUST accept utf-8 encoded request', async () => {
|
|
84
84
|
const res = await fetchFn(await getUrl(opts.url), {
|
|
85
85
|
method: 'POST',
|
|
86
86
|
headers: {
|
|
@@ -90,7 +90,7 @@ function serverAudits(opts) {
|
|
|
90
90
|
});
|
|
91
91
|
(0, utils_1.ressert)(res).status.toBe(200);
|
|
92
92
|
}),
|
|
93
|
-
(0, utils_1.audit)('MUST assume utf-8 in request if encoding is unspecified', async () => {
|
|
93
|
+
(0, utils_1.audit)('78D5', 'MUST assume utf-8 in request if encoding is unspecified', async () => {
|
|
94
94
|
const res = await fetchFn(await getUrl(opts.url), {
|
|
95
95
|
method: 'POST',
|
|
96
96
|
headers: {
|
|
@@ -101,7 +101,7 @@ function serverAudits(opts) {
|
|
|
101
101
|
(0, utils_1.ressert)(res).status.toBe(200);
|
|
102
102
|
}),
|
|
103
103
|
// Request
|
|
104
|
-
(0, utils_1.audit)('MUST accept POST requests', async () => {
|
|
104
|
+
(0, utils_1.audit)('2C94', 'MUST accept POST requests', async () => {
|
|
105
105
|
const res = await fetchFn(await getUrl(opts.url), {
|
|
106
106
|
method: 'POST',
|
|
107
107
|
headers: { 'content-type': 'application/json' },
|
|
@@ -109,7 +109,7 @@ function serverAudits(opts) {
|
|
|
109
109
|
});
|
|
110
110
|
(0, utils_1.ressert)(res).status.toBe(200);
|
|
111
111
|
}),
|
|
112
|
-
(0, utils_1.audit)('MAY accept application/x-www-form-urlencoded formatted GET requests', async () => {
|
|
112
|
+
(0, utils_1.audit)('5A70', 'MAY accept application/x-www-form-urlencoded formatted GET requests', async () => {
|
|
113
113
|
const url = new URL(await getUrl(opts.url));
|
|
114
114
|
url.searchParams.set('query', '{ __typename }');
|
|
115
115
|
const res = await fetchFn(url.toString());
|
|
@@ -117,7 +117,7 @@ function serverAudits(opts) {
|
|
|
117
117
|
}),
|
|
118
118
|
// Request GET
|
|
119
119
|
// TODO: this is a MUST if the server supports GET requests
|
|
120
|
-
(0, utils_1.audit)('MAY NOT allow executing mutations on GET requests', async () => {
|
|
120
|
+
(0, utils_1.audit)('9C48', 'MAY NOT allow executing mutations on GET requests', async () => {
|
|
121
121
|
const url = new URL(await getUrl(opts.url));
|
|
122
122
|
url.searchParams.set('query', 'mutation { __typename }');
|
|
123
123
|
const res = await fetchFn(url.toString(), {
|
|
@@ -128,13 +128,13 @@ function serverAudits(opts) {
|
|
|
128
128
|
(0, utils_1.ressert)(res).status.toBeBetween(400, 499);
|
|
129
129
|
}),
|
|
130
130
|
// Request POST
|
|
131
|
-
(0, utils_1.audit)('SHOULD respond with 4xx status code if content-type is not supplied on POST requests', async () => {
|
|
131
|
+
(0, utils_1.audit)('9ABE', 'SHOULD respond with 4xx status code if content-type is not supplied on POST requests', async () => {
|
|
132
132
|
const res = await fetchFn(await getUrl(opts.url), {
|
|
133
133
|
method: 'POST',
|
|
134
134
|
});
|
|
135
135
|
(0, utils_1.ressert)(res).status.toBeBetween(400, 499);
|
|
136
136
|
}),
|
|
137
|
-
(0, utils_1.audit)('MUST accept application/json POST requests', async () => {
|
|
137
|
+
(0, utils_1.audit)('03D4', 'MUST accept application/json POST requests', async () => {
|
|
138
138
|
const res = await fetchFn(await getUrl(opts.url), {
|
|
139
139
|
method: 'POST',
|
|
140
140
|
headers: { 'content-type': 'application/json' },
|
|
@@ -142,7 +142,7 @@ function serverAudits(opts) {
|
|
|
142
142
|
});
|
|
143
143
|
(0, utils_1.ressert)(res).status.toBe(200);
|
|
144
144
|
}),
|
|
145
|
-
(0, utils_1.audit)('MUST require a request body on POST', async () => {
|
|
145
|
+
(0, utils_1.audit)('7267', 'MUST require a request body on POST', async () => {
|
|
146
146
|
var _a;
|
|
147
147
|
const res = await fetchFn(await getUrl(opts.url), {
|
|
148
148
|
method: 'POST',
|
|
@@ -158,7 +158,7 @@ function serverAudits(opts) {
|
|
|
158
158
|
// Request Parameters
|
|
159
159
|
(0, utils_1.audit)(
|
|
160
160
|
// TODO: convert to MUST after watershed
|
|
161
|
-
'SHOULD use 400 status code on missing {query} parameter when accepting application/graphql-response+json', async () => {
|
|
161
|
+
'6610', 'SHOULD use 400 status code on missing {query} parameter when accepting application/graphql-response+json', async () => {
|
|
162
162
|
const res = await fetchFn(await getUrl(opts.url), {
|
|
163
163
|
method: 'POST',
|
|
164
164
|
headers: {
|
|
@@ -169,7 +169,7 @@ function serverAudits(opts) {
|
|
|
169
169
|
});
|
|
170
170
|
(0, utils_1.ressert)(res).status.toBe(400);
|
|
171
171
|
}),
|
|
172
|
-
(0, utils_1.audit)('SHOULD use 200 status code with errors field on missing {query} parameter when accepting application/json', async () => {
|
|
172
|
+
(0, utils_1.audit)('3715', 'SHOULD use 200 status code with errors field on missing {query} parameter when accepting application/json', async () => {
|
|
173
173
|
const res = await fetchFn(await getUrl(opts.url), {
|
|
174
174
|
method: 'POST',
|
|
175
175
|
headers: {
|
|
@@ -181,7 +181,7 @@ function serverAudits(opts) {
|
|
|
181
181
|
(0, utils_1.ressert)(res).status.toBe(200);
|
|
182
182
|
await (0, utils_1.ressert)(res).bodyAsExecutionResult.toHaveProperty('errors');
|
|
183
183
|
}),
|
|
184
|
-
...[{ obj: 'ect' }, 0, false, ['array']].map((invalid) => (0, utils_1.audit)(
|
|
184
|
+
...[{ obj: 'ect' }, 0, false, ['array']].map((invalid, index) => (0, utils_1.audit)(`4F5${index}`,
|
|
185
185
|
// TODO: convert to MUST after watershed
|
|
186
186
|
`SHOULD use 400 status code on ${(0, utils_1.extendedTypeof)(invalid)} {query} parameter when accepting application/graphql-response+json`, async () => {
|
|
187
187
|
const res = await fetchFn(await getUrl(opts.url), {
|
|
@@ -196,7 +196,7 @@ function serverAudits(opts) {
|
|
|
196
196
|
});
|
|
197
197
|
(0, utils_1.ressert)(res).status.toBe(400);
|
|
198
198
|
})),
|
|
199
|
-
...[{ obj: 'ect' }, 0, false, ['array']].map((invalid) => (0, utils_1.audit)(`SHOULD use 200 status code with errors field on ${(0, utils_1.extendedTypeof)(invalid)} {query} parameter when accepting application/json`, async () => {
|
|
199
|
+
...[{ 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 () => {
|
|
200
200
|
const res = await fetchFn(await getUrl(opts.url), {
|
|
201
201
|
method: 'POST',
|
|
202
202
|
headers: {
|
|
@@ -212,7 +212,7 @@ function serverAudits(opts) {
|
|
|
212
212
|
})),
|
|
213
213
|
(0, utils_1.audit)(
|
|
214
214
|
// TODO: convert to MUST after watershed
|
|
215
|
-
'SHOULD allow string {query} parameter when accepting application/graphql-response+json', async () => {
|
|
215
|
+
'34A2', 'SHOULD allow string {query} parameter when accepting application/graphql-response+json', async () => {
|
|
216
216
|
const res = await fetchFn(await getUrl(opts.url), {
|
|
217
217
|
method: 'POST',
|
|
218
218
|
headers: {
|
|
@@ -225,7 +225,7 @@ function serverAudits(opts) {
|
|
|
225
225
|
});
|
|
226
226
|
(0, utils_1.ressert)(res).status.toBe(200);
|
|
227
227
|
}),
|
|
228
|
-
(0, utils_1.audit)('MUST allow string {query} parameter when accepting application/json', async () => {
|
|
228
|
+
(0, utils_1.audit)('13EE', 'MUST allow string {query} parameter when accepting application/json', async () => {
|
|
229
229
|
const res = await fetchFn(await getUrl(opts.url), {
|
|
230
230
|
method: 'POST',
|
|
231
231
|
headers: {
|
|
@@ -239,7 +239,7 @@ function serverAudits(opts) {
|
|
|
239
239
|
(0, utils_1.ressert)(res).status.toBe(200);
|
|
240
240
|
await (0, utils_1.ressert)(res).bodyAsExecutionResult.notToHaveProperty('errors');
|
|
241
241
|
}),
|
|
242
|
-
...[{ obj: 'ect' }, 0, false, ['array']].map((invalid) => (0, utils_1.audit)(
|
|
242
|
+
...[{ obj: 'ect' }, 0, false, ['array']].map((invalid, index) => (0, utils_1.audit)(`E3E${index}`,
|
|
243
243
|
// TODO: convert to MUST after watershed
|
|
244
244
|
`SHOULD use 400 status code on ${(0, utils_1.extendedTypeof)(invalid)} {operationName} parameter when accepting application/graphql-response+json`, async () => {
|
|
245
245
|
const res = await fetchFn(await getUrl(opts.url), {
|
|
@@ -255,7 +255,7 @@ function serverAudits(opts) {
|
|
|
255
255
|
});
|
|
256
256
|
(0, utils_1.ressert)(res).status.toBe(400);
|
|
257
257
|
})),
|
|
258
|
-
...[{ obj: 'ect' }, 0, false, ['array']].map((invalid) => (0, utils_1.audit)(`SHOULD use 200 status code with errors field on ${(0, utils_1.extendedTypeof)(invalid)} {operationName} parameter when accepting application/json`, async () => {
|
|
258
|
+
...[{ 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 () => {
|
|
259
259
|
const res = await fetchFn(await getUrl(opts.url), {
|
|
260
260
|
method: 'POST',
|
|
261
261
|
headers: {
|
|
@@ -272,7 +272,7 @@ function serverAudits(opts) {
|
|
|
272
272
|
})),
|
|
273
273
|
(0, utils_1.audit)(
|
|
274
274
|
// TODO: convert to MUST after watershed
|
|
275
|
-
'SHOULD allow string {operationName} parameter when accepting application/graphql-response+json', async () => {
|
|
275
|
+
'8161', 'SHOULD allow string {operationName} parameter when accepting application/graphql-response+json', async () => {
|
|
276
276
|
const res = await fetchFn(await getUrl(opts.url), {
|
|
277
277
|
method: 'POST',
|
|
278
278
|
headers: {
|
|
@@ -286,7 +286,7 @@ function serverAudits(opts) {
|
|
|
286
286
|
});
|
|
287
287
|
(0, utils_1.ressert)(res).status.toBe(200);
|
|
288
288
|
}),
|
|
289
|
-
(0, utils_1.audit)('MUST allow string {operationName} parameter when accepting application/json', async () => {
|
|
289
|
+
(0, utils_1.audit)('B8B3', 'MUST allow string {operationName} parameter when accepting application/json', async () => {
|
|
290
290
|
const res = await fetchFn(await getUrl(opts.url), {
|
|
291
291
|
method: 'POST',
|
|
292
292
|
headers: {
|
|
@@ -301,8 +301,8 @@ function serverAudits(opts) {
|
|
|
301
301
|
(0, utils_1.ressert)(res).status.toBe(200);
|
|
302
302
|
await (0, utils_1.ressert)(res).bodyAsExecutionResult.notToHaveProperty('errors');
|
|
303
303
|
}),
|
|
304
|
-
...['variables', 'operationName', 'extensions'].flatMap((parameter) => [
|
|
305
|
-
(0, utils_1.audit)(
|
|
304
|
+
...['variables', 'operationName', 'extensions'].flatMap((parameter, index) => [
|
|
305
|
+
(0, utils_1.audit)(`94B${index}`,
|
|
306
306
|
// TODO: convert to MUST after watershed
|
|
307
307
|
`SHOULD allow null {${parameter}} parameter when accepting application/graphql-response+json`, async () => {
|
|
308
308
|
const res = await fetchFn(await getUrl(opts.url), {
|
|
@@ -319,7 +319,7 @@ function serverAudits(opts) {
|
|
|
319
319
|
(0, utils_1.ressert)(res).status.toBe(200);
|
|
320
320
|
await (0, utils_1.ressert)(res).bodyAsExecutionResult.notToHaveProperty('errors');
|
|
321
321
|
}),
|
|
322
|
-
(0, utils_1.audit)(`MUST allow null {${parameter}} parameter when accepting application/json`, async () => {
|
|
322
|
+
(0, utils_1.audit)(`022${index}`, `MUST allow null {${parameter}} parameter when accepting application/json`, async () => {
|
|
323
323
|
const res = await fetchFn(await getUrl(opts.url), {
|
|
324
324
|
method: 'POST',
|
|
325
325
|
headers: {
|
|
@@ -335,7 +335,7 @@ function serverAudits(opts) {
|
|
|
335
335
|
await (0, utils_1.ressert)(res).bodyAsExecutionResult.notToHaveProperty('errors');
|
|
336
336
|
}),
|
|
337
337
|
]),
|
|
338
|
-
...['string', 0, false, ['array']].map((invalid) => (0, utils_1.audit)(
|
|
338
|
+
...['string', 0, false, ['array']].map((invalid, index) => (0, utils_1.audit)(`69B${index}`,
|
|
339
339
|
// TODO: convert to MUST after watershed
|
|
340
340
|
`SHOULD use 400 status code on ${(0, utils_1.extendedTypeof)(invalid)} {variables} parameter when accepting application/graphql-response+json`, async () => {
|
|
341
341
|
const res = await fetchFn(await getUrl(opts.url), {
|
|
@@ -351,7 +351,7 @@ function serverAudits(opts) {
|
|
|
351
351
|
});
|
|
352
352
|
(0, utils_1.ressert)(res).status.toBe(400);
|
|
353
353
|
})),
|
|
354
|
-
...['string', 0, false, ['array']].map((invalid) => (0, utils_1.audit)(`SHOULD use 200 status code with errors field on ${(0, utils_1.extendedTypeof)(invalid)} {variables} parameter when accepting application/json`, async () => {
|
|
354
|
+
...['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 () => {
|
|
355
355
|
const res = await fetchFn(await getUrl(opts.url), {
|
|
356
356
|
method: 'POST',
|
|
357
357
|
headers: {
|
|
@@ -368,7 +368,7 @@ function serverAudits(opts) {
|
|
|
368
368
|
})),
|
|
369
369
|
(0, utils_1.audit)(
|
|
370
370
|
// TODO: convert to MUST after watershed
|
|
371
|
-
'SHOULD allow map {variables} parameter when accepting application/graphql-response+json', async () => {
|
|
371
|
+
'2EA1', 'SHOULD allow map {variables} parameter when accepting application/graphql-response+json', async () => {
|
|
372
372
|
const res = await fetchFn(await getUrl(opts.url), {
|
|
373
373
|
method: 'POST',
|
|
374
374
|
headers: {
|
|
@@ -382,7 +382,7 @@ function serverAudits(opts) {
|
|
|
382
382
|
});
|
|
383
383
|
(0, utils_1.ressert)(res).status.toBe(200);
|
|
384
384
|
}),
|
|
385
|
-
(0, utils_1.audit)('MUST allow map {variables} parameter when accepting application/json', async () => {
|
|
385
|
+
(0, utils_1.audit)('28B9', 'MUST allow map {variables} parameter when accepting application/json', async () => {
|
|
386
386
|
const res = await fetchFn(await getUrl(opts.url), {
|
|
387
387
|
method: 'POST',
|
|
388
388
|
headers: {
|
|
@@ -397,7 +397,7 @@ function serverAudits(opts) {
|
|
|
397
397
|
(0, utils_1.ressert)(res).status.toBe(200);
|
|
398
398
|
await (0, utils_1.ressert)(res).bodyAsExecutionResult.notToHaveProperty('errors');
|
|
399
399
|
}),
|
|
400
|
-
(0, utils_1.audit)('MAY allow URL-encoded JSON string {variables} parameter in GETs when accepting application/graphql-response+json', async () => {
|
|
400
|
+
(0, utils_1.audit)('D6D5', 'MAY allow URL-encoded JSON string {variables} parameter in GETs when accepting application/graphql-response+json', async () => {
|
|
401
401
|
const url = new URL(await getUrl(opts.url));
|
|
402
402
|
url.searchParams.set('query', 'query Type($name: String!) { __type(name: $name) { name } }');
|
|
403
403
|
url.searchParams.set('variables', JSON.stringify({ name: 'sometype' }));
|
|
@@ -409,7 +409,7 @@ function serverAudits(opts) {
|
|
|
409
409
|
});
|
|
410
410
|
(0, utils_1.ressert)(res).status.toBe(200);
|
|
411
411
|
}),
|
|
412
|
-
(0, utils_1.audit)('MAY allow URL-encoded JSON string {variables} parameter in GETs when accepting application/json', async () => {
|
|
412
|
+
(0, utils_1.audit)('6A70', 'MAY allow URL-encoded JSON string {variables} parameter in GETs when accepting application/json', async () => {
|
|
413
413
|
const url = new URL(await getUrl(opts.url));
|
|
414
414
|
url.searchParams.set('query', 'query Type($name: String!) { __type(name: $name) { name } }');
|
|
415
415
|
url.searchParams.set('variables', JSON.stringify({ name: 'sometype' }));
|
|
@@ -422,7 +422,7 @@ function serverAudits(opts) {
|
|
|
422
422
|
(0, utils_1.ressert)(res).status.toBe(200);
|
|
423
423
|
await (0, utils_1.ressert)(res).bodyAsExecutionResult.notToHaveProperty('errors');
|
|
424
424
|
}),
|
|
425
|
-
...['string', 0, false, ['array']].map((invalid) => (0, utils_1.audit)(
|
|
425
|
+
...['string', 0, false, ['array']].map((invalid, index) => (0, utils_1.audit)(`904${index}`,
|
|
426
426
|
// TODO: convert to MUST after watershed
|
|
427
427
|
`SHOULD use 400 status code on ${(0, utils_1.extendedTypeof)(invalid)} {extensions} parameter when accepting application/graphql-response+json`, async () => {
|
|
428
428
|
const res = await fetchFn(await getUrl(opts.url), {
|
|
@@ -438,7 +438,7 @@ function serverAudits(opts) {
|
|
|
438
438
|
});
|
|
439
439
|
(0, utils_1.ressert)(res).status.toBe(400);
|
|
440
440
|
})),
|
|
441
|
-
...['string', 0, false, ['array']].map((invalid) => (0, utils_1.audit)(`SHOULD use 200 status code with errors field on ${(0, utils_1.extendedTypeof)(invalid)} {extensions} parameter when accepting application/json`, async () => {
|
|
441
|
+
...['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 () => {
|
|
442
442
|
const res = await fetchFn(await getUrl(opts.url), {
|
|
443
443
|
method: 'POST',
|
|
444
444
|
headers: {
|
|
@@ -455,7 +455,7 @@ function serverAudits(opts) {
|
|
|
455
455
|
})),
|
|
456
456
|
(0, utils_1.audit)(
|
|
457
457
|
// TODO: convert to MUST after watershed
|
|
458
|
-
'SHOULD allow map {extensions} parameter when accepting application/graphql-response+json', async () => {
|
|
458
|
+
'428F', 'SHOULD allow map {extensions} parameter when accepting application/graphql-response+json', async () => {
|
|
459
459
|
const res = await fetchFn(await getUrl(opts.url), {
|
|
460
460
|
method: 'POST',
|
|
461
461
|
headers: {
|
|
@@ -469,7 +469,7 @@ function serverAudits(opts) {
|
|
|
469
469
|
});
|
|
470
470
|
(0, utils_1.ressert)(res).status.toBe(200);
|
|
471
471
|
}),
|
|
472
|
-
(0, utils_1.audit)('MUST allow map {extensions} parameter when accepting application/json', async () => {
|
|
472
|
+
(0, utils_1.audit)('1B7A', 'MUST allow map {extensions} parameter when accepting application/json', async () => {
|
|
473
473
|
const res = await fetchFn(await getUrl(opts.url), {
|
|
474
474
|
method: 'POST',
|
|
475
475
|
headers: {
|
|
@@ -484,9 +484,9 @@ function serverAudits(opts) {
|
|
|
484
484
|
(0, utils_1.ressert)(res).status.toBe(200);
|
|
485
485
|
await (0, utils_1.ressert)(res).bodyAsExecutionResult.notToHaveProperty('errors');
|
|
486
486
|
}),
|
|
487
|
-
// TODO: audit('MUST accept a map for the {extensions} parameter'),
|
|
487
|
+
// TODO: audit('39AA', 'MUST accept a map for the {extensions} parameter'),
|
|
488
488
|
// Response application/json
|
|
489
|
-
(0, utils_1.audit)('SHOULD use 200 status code on JSON parsing failure when accepting application/json', async () => {
|
|
489
|
+
(0, utils_1.audit)('D477', 'SHOULD use 200 status code on JSON parsing failure when accepting application/json', async () => {
|
|
490
490
|
const res = await fetchFn(await getUrl(opts.url), {
|
|
491
491
|
method: 'POST',
|
|
492
492
|
headers: {
|
|
@@ -497,7 +497,7 @@ function serverAudits(opts) {
|
|
|
497
497
|
});
|
|
498
498
|
(0, utils_1.ressert)(res).status.toBe(200);
|
|
499
499
|
}),
|
|
500
|
-
(0, utils_1.audit)('SHOULD use 200 status code if parameters are invalid when accepting application/json', async () => {
|
|
500
|
+
(0, utils_1.audit)('F5AF', 'SHOULD use 200 status code if parameters are invalid when accepting application/json', async () => {
|
|
501
501
|
const res = await fetchFn(await getUrl(opts.url), {
|
|
502
502
|
method: 'POST',
|
|
503
503
|
headers: {
|
|
@@ -510,7 +510,7 @@ function serverAudits(opts) {
|
|
|
510
510
|
});
|
|
511
511
|
(0, utils_1.ressert)(res).status.toBe(200);
|
|
512
512
|
}),
|
|
513
|
-
(0, utils_1.audit)('SHOULD use 200 status code on document parsing failure when accepting application/json', async () => {
|
|
513
|
+
(0, utils_1.audit)('572B', 'SHOULD use 200 status code on document parsing failure when accepting application/json', async () => {
|
|
514
514
|
const res = await fetchFn(await getUrl(opts.url), {
|
|
515
515
|
method: 'POST',
|
|
516
516
|
headers: {
|
|
@@ -521,7 +521,7 @@ function serverAudits(opts) {
|
|
|
521
521
|
});
|
|
522
522
|
(0, utils_1.ressert)(res).status.toBe(200);
|
|
523
523
|
}),
|
|
524
|
-
(0, utils_1.audit)('SHOULD use 200 status code on document validation failure when accepting application/json', async () => {
|
|
524
|
+
(0, utils_1.audit)('FDE2', 'SHOULD use 200 status code on document validation failure when accepting application/json', async () => {
|
|
525
525
|
const res = await fetchFn(await getUrl(opts.url), {
|
|
526
526
|
method: 'POST',
|
|
527
527
|
headers: {
|
|
@@ -537,7 +537,7 @@ function serverAudits(opts) {
|
|
|
537
537
|
// Response application/graphql-response+json
|
|
538
538
|
(0, utils_1.audit)(
|
|
539
539
|
// TODO: convert to MUST after watershed
|
|
540
|
-
'SHOULD use 4xx or 5xx status codes on JSON parsing failure when accepting application/graphql-response+json', async () => {
|
|
540
|
+
'60AA', 'SHOULD use 4xx or 5xx status codes on JSON parsing failure when accepting application/graphql-response+json', async () => {
|
|
541
541
|
const res = await fetchFn(await getUrl(opts.url), {
|
|
542
542
|
method: 'POST',
|
|
543
543
|
headers: {
|
|
@@ -548,7 +548,7 @@ function serverAudits(opts) {
|
|
|
548
548
|
});
|
|
549
549
|
(0, utils_1.ressert)(res).status.toBeBetween(400, 499);
|
|
550
550
|
}),
|
|
551
|
-
(0, utils_1.audit)('SHOULD use 400 status code on JSON parsing failure when accepting application/graphql-response+json', async () => {
|
|
551
|
+
(0, utils_1.audit)('2163', 'SHOULD use 400 status code on JSON parsing failure when accepting application/graphql-response+json', async () => {
|
|
552
552
|
const res = await fetchFn(await getUrl(opts.url), {
|
|
553
553
|
method: 'POST',
|
|
554
554
|
headers: {
|
|
@@ -559,20 +559,9 @@ function serverAudits(opts) {
|
|
|
559
559
|
});
|
|
560
560
|
(0, utils_1.ressert)(res).status.toBe(400);
|
|
561
561
|
}),
|
|
562
|
-
(0, utils_1.audit)('SHOULD not contain the data entry on JSON parsing failure when accepting application/graphql-response+json', async () => {
|
|
563
|
-
const res = await fetchFn(await getUrl(opts.url), {
|
|
564
|
-
method: 'POST',
|
|
565
|
-
headers: {
|
|
566
|
-
'content-type': 'application/json',
|
|
567
|
-
accept: 'application/graphql-response+json',
|
|
568
|
-
},
|
|
569
|
-
body: '{ "not a JSON',
|
|
570
|
-
});
|
|
571
|
-
await (0, utils_1.ressert)(res).bodyAsExecutionResult.data.toBe(undefined);
|
|
572
|
-
}),
|
|
573
562
|
(0, utils_1.audit)(
|
|
574
563
|
// TODO: convert to MUST after watershed
|
|
575
|
-
'SHOULD use 4xx or 5xx status codes if parameters are invalid when accepting application/graphql-response+json', async () => {
|
|
564
|
+
'3E36', 'SHOULD use 4xx or 5xx status codes if parameters are invalid when accepting application/graphql-response+json', async () => {
|
|
576
565
|
const res = await fetchFn(await getUrl(opts.url), {
|
|
577
566
|
method: 'POST',
|
|
578
567
|
headers: {
|
|
@@ -585,7 +574,7 @@ function serverAudits(opts) {
|
|
|
585
574
|
});
|
|
586
575
|
(0, utils_1.ressert)(res).status.toBeBetween(400, 599);
|
|
587
576
|
}),
|
|
588
|
-
(0, utils_1.audit)('SHOULD use 400 status code if parameters are invalid when accepting application/graphql-response+json', async () => {
|
|
577
|
+
(0, utils_1.audit)('17C5', 'SHOULD use 400 status code if parameters are invalid when accepting application/graphql-response+json', async () => {
|
|
589
578
|
const res = await fetchFn(await getUrl(opts.url), {
|
|
590
579
|
method: 'POST',
|
|
591
580
|
headers: {
|
|
@@ -598,7 +587,7 @@ function serverAudits(opts) {
|
|
|
598
587
|
});
|
|
599
588
|
(0, utils_1.ressert)(res).status.toBe(400);
|
|
600
589
|
}),
|
|
601
|
-
(0, utils_1.audit)('SHOULD not contain the data entry if parameters are invalid when accepting application/graphql-response+json', async () => {
|
|
590
|
+
(0, utils_1.audit)('34D6', 'SHOULD not contain the data entry if parameters are invalid when accepting application/graphql-response+json', async () => {
|
|
602
591
|
const res = await fetchFn(await getUrl(opts.url), {
|
|
603
592
|
method: 'POST',
|
|
604
593
|
headers: {
|
|
@@ -613,7 +602,7 @@ function serverAudits(opts) {
|
|
|
613
602
|
}),
|
|
614
603
|
(0, utils_1.audit)(
|
|
615
604
|
// TODO: convert to MUST after watershed
|
|
616
|
-
'SHOULD use 4xx or 5xx status codes on document parsing failure when accepting application/graphql-response+json', async () => {
|
|
605
|
+
'865D', 'SHOULD use 4xx or 5xx status codes on document parsing failure when accepting application/graphql-response+json', async () => {
|
|
617
606
|
const res = await fetchFn(await getUrl(opts.url), {
|
|
618
607
|
method: 'POST',
|
|
619
608
|
headers: {
|
|
@@ -626,7 +615,7 @@ function serverAudits(opts) {
|
|
|
626
615
|
});
|
|
627
616
|
(0, utils_1.ressert)(res).status.toBeBetween(400, 599);
|
|
628
617
|
}),
|
|
629
|
-
(0, utils_1.audit)('SHOULD use 400 status code on document parsing failure when accepting application/graphql-response+json', async () => {
|
|
618
|
+
(0, utils_1.audit)('556A', 'SHOULD use 400 status code on document parsing failure when accepting application/graphql-response+json', async () => {
|
|
630
619
|
const res = await fetchFn(await getUrl(opts.url), {
|
|
631
620
|
method: 'POST',
|
|
632
621
|
headers: {
|
|
@@ -639,7 +628,7 @@ function serverAudits(opts) {
|
|
|
639
628
|
});
|
|
640
629
|
(0, utils_1.ressert)(res).status.toBe(400);
|
|
641
630
|
}),
|
|
642
|
-
(0, utils_1.audit)('SHOULD not contain the data entry on document parsing failure when accepting application/graphql-response+json', async () => {
|
|
631
|
+
(0, utils_1.audit)('D586', 'SHOULD not contain the data entry on document parsing failure when accepting application/graphql-response+json', async () => {
|
|
643
632
|
const res = await fetchFn(await getUrl(opts.url), {
|
|
644
633
|
method: 'POST',
|
|
645
634
|
headers: {
|
|
@@ -654,7 +643,7 @@ function serverAudits(opts) {
|
|
|
654
643
|
}),
|
|
655
644
|
(0, utils_1.audit)(
|
|
656
645
|
// TODO: convert to MUST after watershed
|
|
657
|
-
'SHOULD use 4xx or 5xx status codes on document validation failure when accepting application/graphql-response+json', async () => {
|
|
646
|
+
'51FE', 'SHOULD use 4xx or 5xx status codes on document validation failure when accepting application/graphql-response+json', async () => {
|
|
658
647
|
const res = await fetchFn(await getUrl(opts.url), {
|
|
659
648
|
method: 'POST',
|
|
660
649
|
headers: {
|
|
@@ -667,7 +656,7 @@ function serverAudits(opts) {
|
|
|
667
656
|
});
|
|
668
657
|
(0, utils_1.ressert)(res).status.toBeBetween(400, 599);
|
|
669
658
|
}),
|
|
670
|
-
(0, utils_1.audit)('SHOULD use 400 status code on document validation failure when accepting application/graphql-response+json', async () => {
|
|
659
|
+
(0, utils_1.audit)('74FF', 'SHOULD use 400 status code on document validation failure when accepting application/graphql-response+json', async () => {
|
|
671
660
|
const res = await fetchFn(await getUrl(opts.url), {
|
|
672
661
|
method: 'POST',
|
|
673
662
|
headers: {
|
|
@@ -680,7 +669,7 @@ function serverAudits(opts) {
|
|
|
680
669
|
});
|
|
681
670
|
(0, utils_1.ressert)(res).status.toBe(400);
|
|
682
671
|
}),
|
|
683
|
-
(0, utils_1.audit)('SHOULD not contain the data entry on document validation failure when accepting application/graphql-response+json', async () => {
|
|
672
|
+
(0, utils_1.audit)('5E5B', 'SHOULD not contain the data entry on document validation failure when accepting application/graphql-response+json', async () => {
|
|
684
673
|
const res = await fetchFn(await getUrl(opts.url), {
|
|
685
674
|
method: 'POST',
|
|
686
675
|
headers: {
|
|
@@ -694,10 +683,10 @@ function serverAudits(opts) {
|
|
|
694
683
|
await (0, utils_1.ressert)(res).bodyAsExecutionResult.data.toBe(undefined);
|
|
695
684
|
}),
|
|
696
685
|
// TODO: how to fail and have the data entry?
|
|
697
|
-
// audit('MUST use 2xx status code if response contains the data entry and it is not null when accepting application/graphql-response+json'),
|
|
686
|
+
// audit('EE52', 'MUST use 2xx status code if response contains the data entry and it is not null when accepting application/graphql-response+json'),
|
|
698
687
|
// TODO: how to make an unauthorized request?
|
|
699
688
|
// https://graphql.github.io/graphql-over-http/draft/#sel-EANNNDTAAEVBAAqqc
|
|
700
|
-
// audit('SHOULD use 401 or 403 status codes when the request is not permitted')
|
|
689
|
+
// audit('BC58', 'SHOULD use 401 or 403 status codes when the request is not permitted')
|
|
701
690
|
];
|
|
702
691
|
}
|
|
703
692
|
exports.serverAudits = serverAudits;
|
package/lib/audits/server.mjs
CHANGED
|
@@ -15,7 +15,7 @@ export function serverAudits(opts) {
|
|
|
15
15
|
// Media Types
|
|
16
16
|
audit(
|
|
17
17
|
// TODO: convert to MUST after watershed
|
|
18
|
-
'SHOULD accept application/graphql-response+json and match the content-type', async () => {
|
|
18
|
+
'22EB', 'SHOULD accept application/graphql-response+json and match the content-type', async () => {
|
|
19
19
|
const res = await fetchFn(await getUrl(opts.url), {
|
|
20
20
|
method: 'POST',
|
|
21
21
|
headers: {
|
|
@@ -29,7 +29,7 @@ export function serverAudits(opts) {
|
|
|
29
29
|
.header('content-type')
|
|
30
30
|
.toContain('application/graphql-response+json');
|
|
31
31
|
}),
|
|
32
|
-
audit('MUST accept application/json and match the content-type', async () => {
|
|
32
|
+
audit('4655', 'MUST accept application/json and match the content-type', async () => {
|
|
33
33
|
const res = await fetchFn(await getUrl(opts.url), {
|
|
34
34
|
method: 'POST',
|
|
35
35
|
headers: {
|
|
@@ -41,7 +41,7 @@ export function serverAudits(opts) {
|
|
|
41
41
|
ressert(res).status.toBe(200);
|
|
42
42
|
ressert(res).header('content-type').toContain('application/json');
|
|
43
43
|
}),
|
|
44
|
-
audit('SHOULD accept */* and use application/json for the content-type', async () => {
|
|
44
|
+
audit('47DE', 'SHOULD accept */* and use application/json for the content-type', async () => {
|
|
45
45
|
const res = await fetchFn(await getUrl(opts.url), {
|
|
46
46
|
method: 'POST',
|
|
47
47
|
headers: {
|
|
@@ -53,14 +53,14 @@ export function serverAudits(opts) {
|
|
|
53
53
|
ressert(res).status.toBe(200);
|
|
54
54
|
ressert(res).header('content-type').toContain('application/json');
|
|
55
55
|
}),
|
|
56
|
-
audit('SHOULD assume application/json content-type when accept is missing', async () => {
|
|
56
|
+
audit('80D8', 'SHOULD assume application/json content-type when accept is missing', async () => {
|
|
57
57
|
const url = new URL(await getUrl(opts.url));
|
|
58
58
|
url.searchParams.set('query', '{ __typename }');
|
|
59
59
|
const res = await fetchFn(url.toString());
|
|
60
60
|
ressert(res).status.toBe(200);
|
|
61
61
|
ressert(res).header('content-type').toContain('application/json');
|
|
62
62
|
}),
|
|
63
|
-
audit('MUST use utf-8 encoding when responding', async () => {
|
|
63
|
+
audit('82A3', 'MUST use utf-8 encoding when responding', async () => {
|
|
64
64
|
const res = await fetchFn(await getUrl(opts.url), {
|
|
65
65
|
method: 'POST',
|
|
66
66
|
headers: {
|
|
@@ -77,7 +77,7 @@ export function serverAudits(opts) {
|
|
|
77
77
|
throw new AuditError(res, 'Response body is not UTF-8 encoded');
|
|
78
78
|
}
|
|
79
79
|
}),
|
|
80
|
-
audit('MUST accept utf-8 encoded request', async () => {
|
|
80
|
+
audit('BF61', 'MUST accept utf-8 encoded request', async () => {
|
|
81
81
|
const res = await fetchFn(await getUrl(opts.url), {
|
|
82
82
|
method: 'POST',
|
|
83
83
|
headers: {
|
|
@@ -87,7 +87,7 @@ export function serverAudits(opts) {
|
|
|
87
87
|
});
|
|
88
88
|
ressert(res).status.toBe(200);
|
|
89
89
|
}),
|
|
90
|
-
audit('MUST assume utf-8 in request if encoding is unspecified', async () => {
|
|
90
|
+
audit('78D5', 'MUST assume utf-8 in request if encoding is unspecified', async () => {
|
|
91
91
|
const res = await fetchFn(await getUrl(opts.url), {
|
|
92
92
|
method: 'POST',
|
|
93
93
|
headers: {
|
|
@@ -98,7 +98,7 @@ export function serverAudits(opts) {
|
|
|
98
98
|
ressert(res).status.toBe(200);
|
|
99
99
|
}),
|
|
100
100
|
// Request
|
|
101
|
-
audit('MUST accept POST requests', async () => {
|
|
101
|
+
audit('2C94', 'MUST accept POST requests', async () => {
|
|
102
102
|
const res = await fetchFn(await getUrl(opts.url), {
|
|
103
103
|
method: 'POST',
|
|
104
104
|
headers: { 'content-type': 'application/json' },
|
|
@@ -106,7 +106,7 @@ export function serverAudits(opts) {
|
|
|
106
106
|
});
|
|
107
107
|
ressert(res).status.toBe(200);
|
|
108
108
|
}),
|
|
109
|
-
audit('MAY accept application/x-www-form-urlencoded formatted GET requests', async () => {
|
|
109
|
+
audit('5A70', 'MAY accept application/x-www-form-urlencoded formatted GET requests', async () => {
|
|
110
110
|
const url = new URL(await getUrl(opts.url));
|
|
111
111
|
url.searchParams.set('query', '{ __typename }');
|
|
112
112
|
const res = await fetchFn(url.toString());
|
|
@@ -114,7 +114,7 @@ export function serverAudits(opts) {
|
|
|
114
114
|
}),
|
|
115
115
|
// Request GET
|
|
116
116
|
// TODO: this is a MUST if the server supports GET requests
|
|
117
|
-
audit('MAY NOT allow executing mutations on GET requests', async () => {
|
|
117
|
+
audit('9C48', 'MAY NOT allow executing mutations on GET requests', async () => {
|
|
118
118
|
const url = new URL(await getUrl(opts.url));
|
|
119
119
|
url.searchParams.set('query', 'mutation { __typename }');
|
|
120
120
|
const res = await fetchFn(url.toString(), {
|
|
@@ -125,13 +125,13 @@ export function serverAudits(opts) {
|
|
|
125
125
|
ressert(res).status.toBeBetween(400, 499);
|
|
126
126
|
}),
|
|
127
127
|
// Request POST
|
|
128
|
-
audit('SHOULD respond with 4xx status code if content-type is not supplied on POST requests', async () => {
|
|
128
|
+
audit('9ABE', 'SHOULD respond with 4xx status code if content-type is not supplied on POST requests', async () => {
|
|
129
129
|
const res = await fetchFn(await getUrl(opts.url), {
|
|
130
130
|
method: 'POST',
|
|
131
131
|
});
|
|
132
132
|
ressert(res).status.toBeBetween(400, 499);
|
|
133
133
|
}),
|
|
134
|
-
audit('MUST accept application/json POST requests', async () => {
|
|
134
|
+
audit('03D4', 'MUST accept application/json POST requests', async () => {
|
|
135
135
|
const res = await fetchFn(await getUrl(opts.url), {
|
|
136
136
|
method: 'POST',
|
|
137
137
|
headers: { 'content-type': 'application/json' },
|
|
@@ -139,7 +139,7 @@ export function serverAudits(opts) {
|
|
|
139
139
|
});
|
|
140
140
|
ressert(res).status.toBe(200);
|
|
141
141
|
}),
|
|
142
|
-
audit('MUST require a request body on POST', async () => {
|
|
142
|
+
audit('7267', 'MUST require a request body on POST', async () => {
|
|
143
143
|
var _a;
|
|
144
144
|
const res = await fetchFn(await getUrl(opts.url), {
|
|
145
145
|
method: 'POST',
|
|
@@ -155,7 +155,7 @@ export function serverAudits(opts) {
|
|
|
155
155
|
// Request Parameters
|
|
156
156
|
audit(
|
|
157
157
|
// TODO: convert to MUST after watershed
|
|
158
|
-
'SHOULD use 400 status code on missing {query} parameter when accepting application/graphql-response+json', async () => {
|
|
158
|
+
'6610', 'SHOULD use 400 status code on missing {query} parameter when accepting application/graphql-response+json', async () => {
|
|
159
159
|
const res = await fetchFn(await getUrl(opts.url), {
|
|
160
160
|
method: 'POST',
|
|
161
161
|
headers: {
|
|
@@ -166,7 +166,7 @@ export function serverAudits(opts) {
|
|
|
166
166
|
});
|
|
167
167
|
ressert(res).status.toBe(400);
|
|
168
168
|
}),
|
|
169
|
-
audit('SHOULD use 200 status code with errors field on missing {query} parameter when accepting application/json', async () => {
|
|
169
|
+
audit('3715', 'SHOULD use 200 status code with errors field on missing {query} parameter when accepting application/json', async () => {
|
|
170
170
|
const res = await fetchFn(await getUrl(opts.url), {
|
|
171
171
|
method: 'POST',
|
|
172
172
|
headers: {
|
|
@@ -178,7 +178,7 @@ export function serverAudits(opts) {
|
|
|
178
178
|
ressert(res).status.toBe(200);
|
|
179
179
|
await ressert(res).bodyAsExecutionResult.toHaveProperty('errors');
|
|
180
180
|
}),
|
|
181
|
-
...[{ obj: 'ect' }, 0, false, ['array']].map((invalid) => audit(
|
|
181
|
+
...[{ obj: 'ect' }, 0, false, ['array']].map((invalid, index) => audit(`4F5${index}`,
|
|
182
182
|
// TODO: convert to MUST after watershed
|
|
183
183
|
`SHOULD use 400 status code on ${extendedTypeof(invalid)} {query} parameter when accepting application/graphql-response+json`, async () => {
|
|
184
184
|
const res = await fetchFn(await getUrl(opts.url), {
|
|
@@ -193,7 +193,7 @@ export function serverAudits(opts) {
|
|
|
193
193
|
});
|
|
194
194
|
ressert(res).status.toBe(400);
|
|
195
195
|
})),
|
|
196
|
-
...[{ obj: 'ect' }, 0, false, ['array']].map((invalid) => audit(`SHOULD use 200 status code with errors field on ${extendedTypeof(invalid)} {query} parameter when accepting application/json`, async () => {
|
|
196
|
+
...[{ obj: 'ect' }, 0, false, ['array']].map((invalid, index) => audit(`9FE${index}`, `SHOULD use 200 status code with errors field on ${extendedTypeof(invalid)} {query} parameter when accepting application/json`, async () => {
|
|
197
197
|
const res = await fetchFn(await getUrl(opts.url), {
|
|
198
198
|
method: 'POST',
|
|
199
199
|
headers: {
|
|
@@ -209,7 +209,7 @@ export function serverAudits(opts) {
|
|
|
209
209
|
})),
|
|
210
210
|
audit(
|
|
211
211
|
// TODO: convert to MUST after watershed
|
|
212
|
-
'SHOULD allow string {query} parameter when accepting application/graphql-response+json', async () => {
|
|
212
|
+
'34A2', 'SHOULD allow string {query} parameter when accepting application/graphql-response+json', async () => {
|
|
213
213
|
const res = await fetchFn(await getUrl(opts.url), {
|
|
214
214
|
method: 'POST',
|
|
215
215
|
headers: {
|
|
@@ -222,7 +222,7 @@ export function serverAudits(opts) {
|
|
|
222
222
|
});
|
|
223
223
|
ressert(res).status.toBe(200);
|
|
224
224
|
}),
|
|
225
|
-
audit('MUST allow string {query} parameter when accepting application/json', async () => {
|
|
225
|
+
audit('13EE', 'MUST allow string {query} parameter when accepting application/json', async () => {
|
|
226
226
|
const res = await fetchFn(await getUrl(opts.url), {
|
|
227
227
|
method: 'POST',
|
|
228
228
|
headers: {
|
|
@@ -236,7 +236,7 @@ export function serverAudits(opts) {
|
|
|
236
236
|
ressert(res).status.toBe(200);
|
|
237
237
|
await ressert(res).bodyAsExecutionResult.notToHaveProperty('errors');
|
|
238
238
|
}),
|
|
239
|
-
...[{ obj: 'ect' }, 0, false, ['array']].map((invalid) => audit(
|
|
239
|
+
...[{ obj: 'ect' }, 0, false, ['array']].map((invalid, index) => audit(`E3E${index}`,
|
|
240
240
|
// TODO: convert to MUST after watershed
|
|
241
241
|
`SHOULD use 400 status code on ${extendedTypeof(invalid)} {operationName} parameter when accepting application/graphql-response+json`, async () => {
|
|
242
242
|
const res = await fetchFn(await getUrl(opts.url), {
|
|
@@ -252,7 +252,7 @@ export function serverAudits(opts) {
|
|
|
252
252
|
});
|
|
253
253
|
ressert(res).status.toBe(400);
|
|
254
254
|
})),
|
|
255
|
-
...[{ obj: 'ect' }, 0, false, ['array']].map((invalid) => audit(`SHOULD use 200 status code with errors field on ${extendedTypeof(invalid)} {operationName} parameter when accepting application/json`, async () => {
|
|
255
|
+
...[{ obj: 'ect' }, 0, false, ['array']].map((invalid, index) => audit(`FB9${index}`, `SHOULD use 200 status code with errors field on ${extendedTypeof(invalid)} {operationName} parameter when accepting application/json`, async () => {
|
|
256
256
|
const res = await fetchFn(await getUrl(opts.url), {
|
|
257
257
|
method: 'POST',
|
|
258
258
|
headers: {
|
|
@@ -269,7 +269,7 @@ export function serverAudits(opts) {
|
|
|
269
269
|
})),
|
|
270
270
|
audit(
|
|
271
271
|
// TODO: convert to MUST after watershed
|
|
272
|
-
'SHOULD allow string {operationName} parameter when accepting application/graphql-response+json', async () => {
|
|
272
|
+
'8161', 'SHOULD allow string {operationName} parameter when accepting application/graphql-response+json', async () => {
|
|
273
273
|
const res = await fetchFn(await getUrl(opts.url), {
|
|
274
274
|
method: 'POST',
|
|
275
275
|
headers: {
|
|
@@ -283,7 +283,7 @@ export function serverAudits(opts) {
|
|
|
283
283
|
});
|
|
284
284
|
ressert(res).status.toBe(200);
|
|
285
285
|
}),
|
|
286
|
-
audit('MUST allow string {operationName} parameter when accepting application/json', async () => {
|
|
286
|
+
audit('B8B3', 'MUST allow string {operationName} parameter when accepting application/json', async () => {
|
|
287
287
|
const res = await fetchFn(await getUrl(opts.url), {
|
|
288
288
|
method: 'POST',
|
|
289
289
|
headers: {
|
|
@@ -298,8 +298,8 @@ export function serverAudits(opts) {
|
|
|
298
298
|
ressert(res).status.toBe(200);
|
|
299
299
|
await ressert(res).bodyAsExecutionResult.notToHaveProperty('errors');
|
|
300
300
|
}),
|
|
301
|
-
...['variables', 'operationName', 'extensions'].flatMap((parameter) => [
|
|
302
|
-
audit(
|
|
301
|
+
...['variables', 'operationName', 'extensions'].flatMap((parameter, index) => [
|
|
302
|
+
audit(`94B${index}`,
|
|
303
303
|
// TODO: convert to MUST after watershed
|
|
304
304
|
`SHOULD allow null {${parameter}} parameter when accepting application/graphql-response+json`, async () => {
|
|
305
305
|
const res = await fetchFn(await getUrl(opts.url), {
|
|
@@ -316,7 +316,7 @@ export function serverAudits(opts) {
|
|
|
316
316
|
ressert(res).status.toBe(200);
|
|
317
317
|
await ressert(res).bodyAsExecutionResult.notToHaveProperty('errors');
|
|
318
318
|
}),
|
|
319
|
-
audit(`MUST allow null {${parameter}} parameter when accepting application/json`, async () => {
|
|
319
|
+
audit(`022${index}`, `MUST allow null {${parameter}} parameter when accepting application/json`, async () => {
|
|
320
320
|
const res = await fetchFn(await getUrl(opts.url), {
|
|
321
321
|
method: 'POST',
|
|
322
322
|
headers: {
|
|
@@ -332,7 +332,7 @@ export function serverAudits(opts) {
|
|
|
332
332
|
await ressert(res).bodyAsExecutionResult.notToHaveProperty('errors');
|
|
333
333
|
}),
|
|
334
334
|
]),
|
|
335
|
-
...['string', 0, false, ['array']].map((invalid) => audit(
|
|
335
|
+
...['string', 0, false, ['array']].map((invalid, index) => audit(`69B${index}`,
|
|
336
336
|
// TODO: convert to MUST after watershed
|
|
337
337
|
`SHOULD use 400 status code on ${extendedTypeof(invalid)} {variables} parameter when accepting application/graphql-response+json`, async () => {
|
|
338
338
|
const res = await fetchFn(await getUrl(opts.url), {
|
|
@@ -348,7 +348,7 @@ export function serverAudits(opts) {
|
|
|
348
348
|
});
|
|
349
349
|
ressert(res).status.toBe(400);
|
|
350
350
|
})),
|
|
351
|
-
...['string', 0, false, ['array']].map((invalid) => audit(`SHOULD use 200 status code with errors field on ${extendedTypeof(invalid)} {variables} parameter when accepting application/json`, async () => {
|
|
351
|
+
...['string', 0, false, ['array']].map((invalid, index) => audit(`F05${index}`, `SHOULD use 200 status code with errors field on ${extendedTypeof(invalid)} {variables} parameter when accepting application/json`, async () => {
|
|
352
352
|
const res = await fetchFn(await getUrl(opts.url), {
|
|
353
353
|
method: 'POST',
|
|
354
354
|
headers: {
|
|
@@ -365,7 +365,7 @@ export function serverAudits(opts) {
|
|
|
365
365
|
})),
|
|
366
366
|
audit(
|
|
367
367
|
// TODO: convert to MUST after watershed
|
|
368
|
-
'SHOULD allow map {variables} parameter when accepting application/graphql-response+json', async () => {
|
|
368
|
+
'2EA1', 'SHOULD allow map {variables} parameter when accepting application/graphql-response+json', async () => {
|
|
369
369
|
const res = await fetchFn(await getUrl(opts.url), {
|
|
370
370
|
method: 'POST',
|
|
371
371
|
headers: {
|
|
@@ -379,7 +379,7 @@ export function serverAudits(opts) {
|
|
|
379
379
|
});
|
|
380
380
|
ressert(res).status.toBe(200);
|
|
381
381
|
}),
|
|
382
|
-
audit('MUST allow map {variables} parameter when accepting application/json', async () => {
|
|
382
|
+
audit('28B9', 'MUST allow map {variables} parameter when accepting application/json', async () => {
|
|
383
383
|
const res = await fetchFn(await getUrl(opts.url), {
|
|
384
384
|
method: 'POST',
|
|
385
385
|
headers: {
|
|
@@ -394,7 +394,7 @@ export function serverAudits(opts) {
|
|
|
394
394
|
ressert(res).status.toBe(200);
|
|
395
395
|
await ressert(res).bodyAsExecutionResult.notToHaveProperty('errors');
|
|
396
396
|
}),
|
|
397
|
-
audit('MAY allow URL-encoded JSON string {variables} parameter in GETs when accepting application/graphql-response+json', async () => {
|
|
397
|
+
audit('D6D5', 'MAY allow URL-encoded JSON string {variables} parameter in GETs when accepting application/graphql-response+json', async () => {
|
|
398
398
|
const url = new URL(await getUrl(opts.url));
|
|
399
399
|
url.searchParams.set('query', 'query Type($name: String!) { __type(name: $name) { name } }');
|
|
400
400
|
url.searchParams.set('variables', JSON.stringify({ name: 'sometype' }));
|
|
@@ -406,7 +406,7 @@ export function serverAudits(opts) {
|
|
|
406
406
|
});
|
|
407
407
|
ressert(res).status.toBe(200);
|
|
408
408
|
}),
|
|
409
|
-
audit('MAY allow URL-encoded JSON string {variables} parameter in GETs when accepting application/json', async () => {
|
|
409
|
+
audit('6A70', 'MAY allow URL-encoded JSON string {variables} parameter in GETs when accepting application/json', async () => {
|
|
410
410
|
const url = new URL(await getUrl(opts.url));
|
|
411
411
|
url.searchParams.set('query', 'query Type($name: String!) { __type(name: $name) { name } }');
|
|
412
412
|
url.searchParams.set('variables', JSON.stringify({ name: 'sometype' }));
|
|
@@ -419,7 +419,7 @@ export function serverAudits(opts) {
|
|
|
419
419
|
ressert(res).status.toBe(200);
|
|
420
420
|
await ressert(res).bodyAsExecutionResult.notToHaveProperty('errors');
|
|
421
421
|
}),
|
|
422
|
-
...['string', 0, false, ['array']].map((invalid) => audit(
|
|
422
|
+
...['string', 0, false, ['array']].map((invalid, index) => audit(`904${index}`,
|
|
423
423
|
// TODO: convert to MUST after watershed
|
|
424
424
|
`SHOULD use 400 status code on ${extendedTypeof(invalid)} {extensions} parameter when accepting application/graphql-response+json`, async () => {
|
|
425
425
|
const res = await fetchFn(await getUrl(opts.url), {
|
|
@@ -435,7 +435,7 @@ export function serverAudits(opts) {
|
|
|
435
435
|
});
|
|
436
436
|
ressert(res).status.toBe(400);
|
|
437
437
|
})),
|
|
438
|
-
...['string', 0, false, ['array']].map((invalid) => audit(`SHOULD use 200 status code with errors field on ${extendedTypeof(invalid)} {extensions} parameter when accepting application/json`, async () => {
|
|
438
|
+
...['string', 0, false, ['array']].map((invalid, index) => audit(`368${index}`, `SHOULD use 200 status code with errors field on ${extendedTypeof(invalid)} {extensions} parameter when accepting application/json`, async () => {
|
|
439
439
|
const res = await fetchFn(await getUrl(opts.url), {
|
|
440
440
|
method: 'POST',
|
|
441
441
|
headers: {
|
|
@@ -452,7 +452,7 @@ export function serverAudits(opts) {
|
|
|
452
452
|
})),
|
|
453
453
|
audit(
|
|
454
454
|
// TODO: convert to MUST after watershed
|
|
455
|
-
'SHOULD allow map {extensions} parameter when accepting application/graphql-response+json', async () => {
|
|
455
|
+
'428F', 'SHOULD allow map {extensions} parameter when accepting application/graphql-response+json', async () => {
|
|
456
456
|
const res = await fetchFn(await getUrl(opts.url), {
|
|
457
457
|
method: 'POST',
|
|
458
458
|
headers: {
|
|
@@ -466,7 +466,7 @@ export function serverAudits(opts) {
|
|
|
466
466
|
});
|
|
467
467
|
ressert(res).status.toBe(200);
|
|
468
468
|
}),
|
|
469
|
-
audit('MUST allow map {extensions} parameter when accepting application/json', async () => {
|
|
469
|
+
audit('1B7A', 'MUST allow map {extensions} parameter when accepting application/json', async () => {
|
|
470
470
|
const res = await fetchFn(await getUrl(opts.url), {
|
|
471
471
|
method: 'POST',
|
|
472
472
|
headers: {
|
|
@@ -481,9 +481,9 @@ export function serverAudits(opts) {
|
|
|
481
481
|
ressert(res).status.toBe(200);
|
|
482
482
|
await ressert(res).bodyAsExecutionResult.notToHaveProperty('errors');
|
|
483
483
|
}),
|
|
484
|
-
// TODO: audit('MUST accept a map for the {extensions} parameter'),
|
|
484
|
+
// TODO: audit('39AA', 'MUST accept a map for the {extensions} parameter'),
|
|
485
485
|
// Response application/json
|
|
486
|
-
audit('SHOULD use 200 status code on JSON parsing failure when accepting application/json', async () => {
|
|
486
|
+
audit('D477', 'SHOULD use 200 status code on JSON parsing failure when accepting application/json', async () => {
|
|
487
487
|
const res = await fetchFn(await getUrl(opts.url), {
|
|
488
488
|
method: 'POST',
|
|
489
489
|
headers: {
|
|
@@ -494,7 +494,7 @@ export function serverAudits(opts) {
|
|
|
494
494
|
});
|
|
495
495
|
ressert(res).status.toBe(200);
|
|
496
496
|
}),
|
|
497
|
-
audit('SHOULD use 200 status code if parameters are invalid when accepting application/json', async () => {
|
|
497
|
+
audit('F5AF', 'SHOULD use 200 status code if parameters are invalid when accepting application/json', async () => {
|
|
498
498
|
const res = await fetchFn(await getUrl(opts.url), {
|
|
499
499
|
method: 'POST',
|
|
500
500
|
headers: {
|
|
@@ -507,7 +507,7 @@ export function serverAudits(opts) {
|
|
|
507
507
|
});
|
|
508
508
|
ressert(res).status.toBe(200);
|
|
509
509
|
}),
|
|
510
|
-
audit('SHOULD use 200 status code on document parsing failure when accepting application/json', async () => {
|
|
510
|
+
audit('572B', 'SHOULD use 200 status code on document parsing failure when accepting application/json', async () => {
|
|
511
511
|
const res = await fetchFn(await getUrl(opts.url), {
|
|
512
512
|
method: 'POST',
|
|
513
513
|
headers: {
|
|
@@ -518,7 +518,7 @@ export function serverAudits(opts) {
|
|
|
518
518
|
});
|
|
519
519
|
ressert(res).status.toBe(200);
|
|
520
520
|
}),
|
|
521
|
-
audit('SHOULD use 200 status code on document validation failure when accepting application/json', async () => {
|
|
521
|
+
audit('FDE2', 'SHOULD use 200 status code on document validation failure when accepting application/json', async () => {
|
|
522
522
|
const res = await fetchFn(await getUrl(opts.url), {
|
|
523
523
|
method: 'POST',
|
|
524
524
|
headers: {
|
|
@@ -534,7 +534,7 @@ export function serverAudits(opts) {
|
|
|
534
534
|
// Response application/graphql-response+json
|
|
535
535
|
audit(
|
|
536
536
|
// TODO: convert to MUST after watershed
|
|
537
|
-
'SHOULD use 4xx or 5xx status codes on JSON parsing failure when accepting application/graphql-response+json', async () => {
|
|
537
|
+
'60AA', 'SHOULD use 4xx or 5xx status codes on JSON parsing failure when accepting application/graphql-response+json', async () => {
|
|
538
538
|
const res = await fetchFn(await getUrl(opts.url), {
|
|
539
539
|
method: 'POST',
|
|
540
540
|
headers: {
|
|
@@ -545,7 +545,7 @@ export function serverAudits(opts) {
|
|
|
545
545
|
});
|
|
546
546
|
ressert(res).status.toBeBetween(400, 499);
|
|
547
547
|
}),
|
|
548
|
-
audit('SHOULD use 400 status code on JSON parsing failure when accepting application/graphql-response+json', async () => {
|
|
548
|
+
audit('2163', 'SHOULD use 400 status code on JSON parsing failure when accepting application/graphql-response+json', async () => {
|
|
549
549
|
const res = await fetchFn(await getUrl(opts.url), {
|
|
550
550
|
method: 'POST',
|
|
551
551
|
headers: {
|
|
@@ -556,20 +556,9 @@ export function serverAudits(opts) {
|
|
|
556
556
|
});
|
|
557
557
|
ressert(res).status.toBe(400);
|
|
558
558
|
}),
|
|
559
|
-
audit('SHOULD not contain the data entry on JSON parsing failure when accepting application/graphql-response+json', async () => {
|
|
560
|
-
const res = await fetchFn(await getUrl(opts.url), {
|
|
561
|
-
method: 'POST',
|
|
562
|
-
headers: {
|
|
563
|
-
'content-type': 'application/json',
|
|
564
|
-
accept: 'application/graphql-response+json',
|
|
565
|
-
},
|
|
566
|
-
body: '{ "not a JSON',
|
|
567
|
-
});
|
|
568
|
-
await ressert(res).bodyAsExecutionResult.data.toBe(undefined);
|
|
569
|
-
}),
|
|
570
559
|
audit(
|
|
571
560
|
// TODO: convert to MUST after watershed
|
|
572
|
-
'SHOULD use 4xx or 5xx status codes if parameters are invalid when accepting application/graphql-response+json', async () => {
|
|
561
|
+
'3E36', 'SHOULD use 4xx or 5xx status codes if parameters are invalid when accepting application/graphql-response+json', async () => {
|
|
573
562
|
const res = await fetchFn(await getUrl(opts.url), {
|
|
574
563
|
method: 'POST',
|
|
575
564
|
headers: {
|
|
@@ -582,7 +571,7 @@ export function serverAudits(opts) {
|
|
|
582
571
|
});
|
|
583
572
|
ressert(res).status.toBeBetween(400, 599);
|
|
584
573
|
}),
|
|
585
|
-
audit('SHOULD use 400 status code if parameters are invalid when accepting application/graphql-response+json', async () => {
|
|
574
|
+
audit('17C5', 'SHOULD use 400 status code if parameters are invalid when accepting application/graphql-response+json', async () => {
|
|
586
575
|
const res = await fetchFn(await getUrl(opts.url), {
|
|
587
576
|
method: 'POST',
|
|
588
577
|
headers: {
|
|
@@ -595,7 +584,7 @@ export function serverAudits(opts) {
|
|
|
595
584
|
});
|
|
596
585
|
ressert(res).status.toBe(400);
|
|
597
586
|
}),
|
|
598
|
-
audit('SHOULD not contain the data entry if parameters are invalid when accepting application/graphql-response+json', async () => {
|
|
587
|
+
audit('34D6', 'SHOULD not contain the data entry if parameters are invalid when accepting application/graphql-response+json', async () => {
|
|
599
588
|
const res = await fetchFn(await getUrl(opts.url), {
|
|
600
589
|
method: 'POST',
|
|
601
590
|
headers: {
|
|
@@ -610,7 +599,7 @@ export function serverAudits(opts) {
|
|
|
610
599
|
}),
|
|
611
600
|
audit(
|
|
612
601
|
// TODO: convert to MUST after watershed
|
|
613
|
-
'SHOULD use 4xx or 5xx status codes on document parsing failure when accepting application/graphql-response+json', async () => {
|
|
602
|
+
'865D', 'SHOULD use 4xx or 5xx status codes on document parsing failure when accepting application/graphql-response+json', async () => {
|
|
614
603
|
const res = await fetchFn(await getUrl(opts.url), {
|
|
615
604
|
method: 'POST',
|
|
616
605
|
headers: {
|
|
@@ -623,7 +612,7 @@ export function serverAudits(opts) {
|
|
|
623
612
|
});
|
|
624
613
|
ressert(res).status.toBeBetween(400, 599);
|
|
625
614
|
}),
|
|
626
|
-
audit('SHOULD use 400 status code on document parsing failure when accepting application/graphql-response+json', async () => {
|
|
615
|
+
audit('556A', 'SHOULD use 400 status code on document parsing failure when accepting application/graphql-response+json', async () => {
|
|
627
616
|
const res = await fetchFn(await getUrl(opts.url), {
|
|
628
617
|
method: 'POST',
|
|
629
618
|
headers: {
|
|
@@ -636,7 +625,7 @@ export function serverAudits(opts) {
|
|
|
636
625
|
});
|
|
637
626
|
ressert(res).status.toBe(400);
|
|
638
627
|
}),
|
|
639
|
-
audit('SHOULD not contain the data entry on document parsing failure when accepting application/graphql-response+json', async () => {
|
|
628
|
+
audit('D586', 'SHOULD not contain the data entry on document parsing failure when accepting application/graphql-response+json', async () => {
|
|
640
629
|
const res = await fetchFn(await getUrl(opts.url), {
|
|
641
630
|
method: 'POST',
|
|
642
631
|
headers: {
|
|
@@ -651,7 +640,7 @@ export function serverAudits(opts) {
|
|
|
651
640
|
}),
|
|
652
641
|
audit(
|
|
653
642
|
// TODO: convert to MUST after watershed
|
|
654
|
-
'SHOULD use 4xx or 5xx status codes on document validation failure when accepting application/graphql-response+json', async () => {
|
|
643
|
+
'51FE', 'SHOULD use 4xx or 5xx status codes on document validation failure when accepting application/graphql-response+json', async () => {
|
|
655
644
|
const res = await fetchFn(await getUrl(opts.url), {
|
|
656
645
|
method: 'POST',
|
|
657
646
|
headers: {
|
|
@@ -664,7 +653,7 @@ export function serverAudits(opts) {
|
|
|
664
653
|
});
|
|
665
654
|
ressert(res).status.toBeBetween(400, 599);
|
|
666
655
|
}),
|
|
667
|
-
audit('SHOULD use 400 status code on document validation failure when accepting application/graphql-response+json', async () => {
|
|
656
|
+
audit('74FF', 'SHOULD use 400 status code on document validation failure when accepting application/graphql-response+json', async () => {
|
|
668
657
|
const res = await fetchFn(await getUrl(opts.url), {
|
|
669
658
|
method: 'POST',
|
|
670
659
|
headers: {
|
|
@@ -677,7 +666,7 @@ export function serverAudits(opts) {
|
|
|
677
666
|
});
|
|
678
667
|
ressert(res).status.toBe(400);
|
|
679
668
|
}),
|
|
680
|
-
audit('SHOULD not contain the data entry on document validation failure when accepting application/graphql-response+json', async () => {
|
|
669
|
+
audit('5E5B', 'SHOULD not contain the data entry on document validation failure when accepting application/graphql-response+json', async () => {
|
|
681
670
|
const res = await fetchFn(await getUrl(opts.url), {
|
|
682
671
|
method: 'POST',
|
|
683
672
|
headers: {
|
|
@@ -691,10 +680,10 @@ export function serverAudits(opts) {
|
|
|
691
680
|
await ressert(res).bodyAsExecutionResult.data.toBe(undefined);
|
|
692
681
|
}),
|
|
693
682
|
// TODO: how to fail and have the data entry?
|
|
694
|
-
// audit('MUST use 2xx status code if response contains the data entry and it is not null when accepting application/graphql-response+json'),
|
|
683
|
+
// audit('EE52', 'MUST use 2xx status code if response contains the data entry and it is not null when accepting application/graphql-response+json'),
|
|
695
684
|
// TODO: how to make an unauthorized request?
|
|
696
685
|
// https://graphql.github.io/graphql-over-http/draft/#sel-EANNNDTAAEVBAAqqc
|
|
697
|
-
// audit('SHOULD use 401 or 403 status codes when the request is not permitted')
|
|
686
|
+
// audit('BC58', 'SHOULD use 401 or 403 status codes when the request is not permitted')
|
|
698
687
|
];
|
|
699
688
|
}
|
|
700
689
|
/**
|
package/lib/audits/utils.d.mts
CHANGED
|
@@ -11,7 +11,7 @@ export * from '../utils';
|
|
|
11
11
|
*
|
|
12
12
|
* @private
|
|
13
13
|
*/
|
|
14
|
-
export declare function audit(name: AuditName, fn: () => Promise<void>): Audit;
|
|
14
|
+
export declare function audit(id: string, name: AuditName, fn: () => Promise<void>): Audit;
|
|
15
15
|
/**
|
|
16
16
|
* Error thrown when an assertion test fails.
|
|
17
17
|
*
|
package/lib/audits/utils.d.ts
CHANGED
|
@@ -11,7 +11,7 @@ export * from '../utils';
|
|
|
11
11
|
*
|
|
12
12
|
* @private
|
|
13
13
|
*/
|
|
14
|
-
export declare function audit(name: AuditName, fn: () => Promise<void>): Audit;
|
|
14
|
+
export declare function audit(id: string, name: AuditName, fn: () => Promise<void>): Audit;
|
|
15
15
|
/**
|
|
16
16
|
* Error thrown when an assertion test fails.
|
|
17
17
|
*
|
package/lib/audits/utils.js
CHANGED
|
@@ -26,13 +26,15 @@ __exportStar(require("../utils"), exports);
|
|
|
26
26
|
*
|
|
27
27
|
* @private
|
|
28
28
|
*/
|
|
29
|
-
function audit(name, fn) {
|
|
29
|
+
function audit(id, name, fn) {
|
|
30
30
|
return {
|
|
31
|
+
id,
|
|
31
32
|
name,
|
|
32
33
|
fn: async () => {
|
|
33
34
|
try {
|
|
34
35
|
await fn();
|
|
35
36
|
return {
|
|
37
|
+
id,
|
|
36
38
|
name,
|
|
37
39
|
status: 'ok',
|
|
38
40
|
};
|
|
@@ -43,6 +45,7 @@ function audit(name, fn) {
|
|
|
43
45
|
throw err;
|
|
44
46
|
}
|
|
45
47
|
return {
|
|
48
|
+
id,
|
|
46
49
|
name,
|
|
47
50
|
status: name.startsWith('MUST')
|
|
48
51
|
? // only failing MUSTs are considered errors
|
package/lib/audits/utils.mjs
CHANGED
|
@@ -9,13 +9,15 @@ export * from '../utils.mjs';
|
|
|
9
9
|
*
|
|
10
10
|
* @private
|
|
11
11
|
*/
|
|
12
|
-
export function audit(name, fn) {
|
|
12
|
+
export function audit(id, name, fn) {
|
|
13
13
|
return {
|
|
14
|
+
id,
|
|
14
15
|
name,
|
|
15
16
|
fn: async () => {
|
|
16
17
|
try {
|
|
17
18
|
await fn();
|
|
18
19
|
return {
|
|
20
|
+
id,
|
|
19
21
|
name,
|
|
20
22
|
status: 'ok',
|
|
21
23
|
};
|
|
@@ -26,6 +28,7 @@ export function audit(name, fn) {
|
|
|
26
28
|
throw err;
|
|
27
29
|
}
|
|
28
30
|
return {
|
|
31
|
+
id,
|
|
29
32
|
name,
|
|
30
33
|
status: name.startsWith('MUST')
|
|
31
34
|
? // only failing MUSTs are considered errors
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "graphql-http",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.13.0",
|
|
4
4
|
"description": "Simple, pluggable, zero-dependency, GraphQL over HTTP Protocol compliant server and client",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"graphql",
|
|
@@ -102,33 +102,33 @@
|
|
|
102
102
|
"@babel/plugin-proposal-optional-chaining": "^7.20.7",
|
|
103
103
|
"@babel/preset-env": "^7.20.2",
|
|
104
104
|
"@babel/preset-typescript": "^7.18.6",
|
|
105
|
-
"@rollup/plugin-terser": "^0.
|
|
105
|
+
"@rollup/plugin-terser": "^0.4.0",
|
|
106
106
|
"@rollup/plugin-typescript": "^11.0.0",
|
|
107
107
|
"@semantic-release/changelog": "^6.0.2",
|
|
108
108
|
"@semantic-release/git": "^10.0.1",
|
|
109
109
|
"@types/eslint": "^8.4.10",
|
|
110
|
-
"@types/express": "^4.17.
|
|
110
|
+
"@types/express": "^4.17.16",
|
|
111
111
|
"@types/glob": "^8.0.1",
|
|
112
|
-
"@types/jest": "^29.
|
|
112
|
+
"@types/jest": "^29.4.0",
|
|
113
113
|
"@types/koa": "^2.13.5",
|
|
114
114
|
"@types/koa-mount": "^4.0.2",
|
|
115
|
-
"@typescript-eslint/eslint-plugin": "^5.
|
|
116
|
-
"@typescript-eslint/parser": "^5.
|
|
115
|
+
"@typescript-eslint/eslint-plugin": "^5.49.0",
|
|
116
|
+
"@typescript-eslint/parser": "^5.49.0",
|
|
117
117
|
"@whatwg-node/fetch": "^0.6.2",
|
|
118
|
-
"babel-jest": "^29.
|
|
118
|
+
"babel-jest": "^29.4.0",
|
|
119
119
|
"eslint": "^8.32.0",
|
|
120
120
|
"eslint-config-prettier": "^8.6.0",
|
|
121
121
|
"express": "^4.18.2",
|
|
122
|
-
"fastify": "^4.
|
|
122
|
+
"fastify": "^4.12.0",
|
|
123
123
|
"graphql": "^16.6.0",
|
|
124
|
-
"jest": "^29.
|
|
125
|
-
"jest-jasmine2": "^29.
|
|
124
|
+
"jest": "^29.4.0",
|
|
125
|
+
"jest-jasmine2": "^29.4.0",
|
|
126
126
|
"koa": "^2.14.1",
|
|
127
127
|
"koa-mount": "^4.0.0",
|
|
128
128
|
"node-fetch": "^3.3.0",
|
|
129
129
|
"prettier": "^2.8.3",
|
|
130
|
-
"rollup": "^3.
|
|
131
|
-
"semantic-release": "^20.0
|
|
130
|
+
"rollup": "^3.11.0",
|
|
131
|
+
"semantic-release": "^20.1.0",
|
|
132
132
|
"tslib": "^2.4.1",
|
|
133
133
|
"typedoc": "^0.23.24",
|
|
134
134
|
"typedoc-plugin-markdown": "^3.14.0",
|
|
Binary file
|