graphql-http 1.11.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 -7
- package/lib/audits/common.d.mts +16 -0
- package/lib/audits/common.d.ts +16 -0
- package/lib/audits/server.js +126 -149
- package/lib/audits/server.mjs +127 -150
- package/lib/audits/utils.d.mts +35 -16
- package/lib/audits/utils.d.ts +35 -16
- package/lib/audits/utils.js +90 -59
- package/lib/audits/utils.mjs +88 -57
- package/lib/handler.js +24 -25
- package/lib/handler.mjs +25 -26
- package/lib/utils.d.mts +4 -1
- package/lib/utils.d.ts +4 -1
- package/lib/utils.js +9 -4
- package/lib/utils.mjs +7 -3
- package/package.json +20 -20
- package/umd/graphql-http.js +2 -2
- package/umd/graphql-http.min.js +1 -1
- package/umd/graphql-http.min.js.gz +0 -0
package/lib/audits/utils.d.mts
CHANGED
|
@@ -11,27 +11,46 @@ 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
|
-
*
|
|
17
|
-
*
|
|
18
|
-
* All fatal problems will throw an instance of Error.
|
|
16
|
+
* Error thrown when an assertion test fails.
|
|
19
17
|
*
|
|
20
18
|
* @private
|
|
21
19
|
*/
|
|
22
|
-
export declare
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
20
|
+
export declare class AuditError {
|
|
21
|
+
/**
|
|
22
|
+
* Response from the server.
|
|
23
|
+
*/
|
|
24
|
+
response: Response;
|
|
25
|
+
/**
|
|
26
|
+
* Reason for the failing audit.
|
|
27
|
+
*/
|
|
28
|
+
reason: string;
|
|
29
|
+
constructor(response: Response, reason: string);
|
|
30
|
+
}
|
|
30
31
|
/**
|
|
31
|
-
*
|
|
32
|
+
* Will throw an AuditError if the assertion on Response fails.
|
|
33
|
+
*
|
|
34
|
+
* All fatal problems will throw an instance of an Error.
|
|
32
35
|
*
|
|
33
|
-
*
|
|
36
|
+
* The name "ressert" is a wordplay combining "response" and "assert".
|
|
34
37
|
*
|
|
35
38
|
* @private
|
|
36
|
-
|
|
37
|
-
export declare function
|
|
39
|
+
*/
|
|
40
|
+
export declare function ressert(res: Response): {
|
|
41
|
+
status: {
|
|
42
|
+
toBe(code: number): void;
|
|
43
|
+
toBeBetween: (min: number, max: number) => void;
|
|
44
|
+
};
|
|
45
|
+
header(key: 'content-type'): {
|
|
46
|
+
toContain(part: string): void;
|
|
47
|
+
notToContain(part: string): void;
|
|
48
|
+
};
|
|
49
|
+
bodyAsExecutionResult: {
|
|
50
|
+
data: {
|
|
51
|
+
toBe(val: ExecutionResult['data']): Promise<void>;
|
|
52
|
+
};
|
|
53
|
+
toHaveProperty(key: keyof ExecutionResult): Promise<void>;
|
|
54
|
+
notToHaveProperty(key: keyof ExecutionResult): Promise<void>;
|
|
55
|
+
};
|
|
56
|
+
};
|
package/lib/audits/utils.d.ts
CHANGED
|
@@ -11,27 +11,46 @@ 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
|
-
*
|
|
17
|
-
*
|
|
18
|
-
* All fatal problems will throw an instance of Error.
|
|
16
|
+
* Error thrown when an assertion test fails.
|
|
19
17
|
*
|
|
20
18
|
* @private
|
|
21
19
|
*/
|
|
22
|
-
export declare
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
20
|
+
export declare class AuditError {
|
|
21
|
+
/**
|
|
22
|
+
* Response from the server.
|
|
23
|
+
*/
|
|
24
|
+
response: Response;
|
|
25
|
+
/**
|
|
26
|
+
* Reason for the failing audit.
|
|
27
|
+
*/
|
|
28
|
+
reason: string;
|
|
29
|
+
constructor(response: Response, reason: string);
|
|
30
|
+
}
|
|
30
31
|
/**
|
|
31
|
-
*
|
|
32
|
+
* Will throw an AuditError if the assertion on Response fails.
|
|
33
|
+
*
|
|
34
|
+
* All fatal problems will throw an instance of an Error.
|
|
32
35
|
*
|
|
33
|
-
*
|
|
36
|
+
* The name "ressert" is a wordplay combining "response" and "assert".
|
|
34
37
|
*
|
|
35
38
|
* @private
|
|
36
|
-
|
|
37
|
-
export declare function
|
|
39
|
+
*/
|
|
40
|
+
export declare function ressert(res: Response): {
|
|
41
|
+
status: {
|
|
42
|
+
toBe(code: number): void;
|
|
43
|
+
toBeBetween: (min: number, max: number) => void;
|
|
44
|
+
};
|
|
45
|
+
header(key: 'content-type'): {
|
|
46
|
+
toContain(part: string): void;
|
|
47
|
+
notToContain(part: string): void;
|
|
48
|
+
};
|
|
49
|
+
bodyAsExecutionResult: {
|
|
50
|
+
data: {
|
|
51
|
+
toBe(val: ExecutionResult['data']): Promise<void>;
|
|
52
|
+
};
|
|
53
|
+
toHaveProperty(key: keyof ExecutionResult): Promise<void>;
|
|
54
|
+
notToHaveProperty(key: keyof ExecutionResult): Promise<void>;
|
|
55
|
+
};
|
|
56
|
+
};
|
package/lib/audits/utils.js
CHANGED
|
@@ -19,37 +19,41 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
19
19
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
20
20
|
};
|
|
21
21
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
22
|
-
exports.
|
|
22
|
+
exports.ressert = exports.AuditError = exports.audit = void 0;
|
|
23
23
|
__exportStar(require("../utils"), exports);
|
|
24
24
|
/**
|
|
25
25
|
* Wrap and prepare an audit for testing.
|
|
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
|
};
|
|
39
41
|
}
|
|
40
|
-
catch (
|
|
41
|
-
if (
|
|
42
|
-
// anything thrown that is not an assertion
|
|
43
|
-
throw
|
|
42
|
+
catch (err) {
|
|
43
|
+
if (!(err instanceof AuditError)) {
|
|
44
|
+
// anything thrown that is not an assertion error is considered fatal
|
|
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
|
|
49
52
|
'error'
|
|
50
53
|
: // everything else is optional and considered a warning
|
|
51
54
|
'warn',
|
|
52
|
-
reason:
|
|
55
|
+
reason: err.reason,
|
|
56
|
+
response: err.response,
|
|
53
57
|
};
|
|
54
58
|
}
|
|
55
59
|
},
|
|
@@ -57,71 +61,98 @@ function audit(name, fn) {
|
|
|
57
61
|
}
|
|
58
62
|
exports.audit = audit;
|
|
59
63
|
/**
|
|
60
|
-
*
|
|
64
|
+
* Error thrown when an assertion test fails.
|
|
61
65
|
*
|
|
62
|
-
*
|
|
66
|
+
* @private
|
|
67
|
+
*/
|
|
68
|
+
class AuditError {
|
|
69
|
+
constructor(response, reason) {
|
|
70
|
+
this.response = response;
|
|
71
|
+
this.reason = reason;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
exports.AuditError = AuditError;
|
|
75
|
+
/**
|
|
76
|
+
* Will throw an AuditError if the assertion on Response fails.
|
|
77
|
+
*
|
|
78
|
+
* All fatal problems will throw an instance of an Error.
|
|
79
|
+
*
|
|
80
|
+
* The name "ressert" is a wordplay combining "response" and "assert".
|
|
63
81
|
*
|
|
64
82
|
* @private
|
|
65
83
|
*/
|
|
66
|
-
function
|
|
84
|
+
function ressert(res) {
|
|
67
85
|
return {
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
// @ts-expect-error types will match, otherwise never
|
|
80
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
81
|
-
if (!actual.includes(expected)) {
|
|
82
|
-
throw `${name} ${JSON.stringify(actual)} does not contain ${JSON.stringify(expected)}`;
|
|
83
|
-
}
|
|
84
|
-
},
|
|
85
|
-
notToContain: (expected) => {
|
|
86
|
-
// @ts-expect-error types will match, otherwise never
|
|
87
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
88
|
-
if (actual.includes(expected)) {
|
|
89
|
-
throw `${name} ${JSON.stringify(actual)} contains ${JSON.stringify(expected)}`;
|
|
90
|
-
}
|
|
86
|
+
status: {
|
|
87
|
+
toBe(code) {
|
|
88
|
+
if (res.status !== code) {
|
|
89
|
+
throw new AuditError(res, `Response status code is not ${code}`);
|
|
90
|
+
}
|
|
91
|
+
},
|
|
92
|
+
toBeBetween: (min, max) => {
|
|
93
|
+
if (!(min <= res.status && res.status <= max)) {
|
|
94
|
+
throw new AuditError(res, `Response status is not between ${min} and ${max}`);
|
|
95
|
+
}
|
|
96
|
+
},
|
|
91
97
|
},
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
98
|
+
header(key) {
|
|
99
|
+
return {
|
|
100
|
+
toContain(part) {
|
|
101
|
+
var _a;
|
|
102
|
+
if (!((_a = res.headers.get(key)) === null || _a === void 0 ? void 0 : _a.includes(part))) {
|
|
103
|
+
throw new AuditError(res, `Response header ${key} does not contain ${part}`);
|
|
104
|
+
}
|
|
105
|
+
},
|
|
106
|
+
notToContain(part) {
|
|
107
|
+
var _a;
|
|
108
|
+
if ((_a = res.headers.get(key)) === null || _a === void 0 ? void 0 : _a.includes(part)) {
|
|
109
|
+
throw new AuditError(res, `Response header ${key} contains ${part}`);
|
|
110
|
+
}
|
|
111
|
+
},
|
|
112
|
+
};
|
|
99
113
|
},
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
114
|
+
bodyAsExecutionResult: {
|
|
115
|
+
data: {
|
|
116
|
+
async toBe(val) {
|
|
117
|
+
const body = await assertBodyAsExecutionResult(res);
|
|
118
|
+
if (body.data !== val) {
|
|
119
|
+
throw new AuditError(res, `Response body execution result data is not "${val}"`);
|
|
120
|
+
}
|
|
121
|
+
},
|
|
122
|
+
},
|
|
123
|
+
async toHaveProperty(key) {
|
|
124
|
+
const body = await assertBodyAsExecutionResult(res);
|
|
125
|
+
if (!(key in body)) {
|
|
126
|
+
throw new AuditError(res, `Response body execution result does not have a property "${key}"`);
|
|
127
|
+
}
|
|
128
|
+
},
|
|
129
|
+
async notToHaveProperty(key) {
|
|
130
|
+
const body = await assertBodyAsExecutionResult(res);
|
|
131
|
+
if (key in body) {
|
|
132
|
+
throw new AuditError(res, `Response body execution result has a property "${key}"`);
|
|
133
|
+
}
|
|
134
|
+
},
|
|
107
135
|
},
|
|
108
136
|
};
|
|
109
137
|
}
|
|
110
|
-
exports.
|
|
111
|
-
/**
|
|
112
|
-
* Parses the string as JSON and safely reports parsing issues for audits.
|
|
113
|
-
*
|
|
114
|
-
* Assumes the parsed JSON will be an `ExecutionResult`.
|
|
115
|
-
*
|
|
116
|
-
* @private
|
|
117
|
-
* */
|
|
138
|
+
exports.ressert = ressert;
|
|
139
|
+
/** @private */
|
|
118
140
|
async function assertBodyAsExecutionResult(res) {
|
|
119
|
-
|
|
141
|
+
let decoded;
|
|
142
|
+
try {
|
|
143
|
+
const decoder = new TextDecoder('utf-8');
|
|
144
|
+
const buff = await res.arrayBuffer();
|
|
145
|
+
decoded = decoder.decode(buff);
|
|
146
|
+
}
|
|
147
|
+
catch (err) {
|
|
148
|
+
throw new AuditError(res, 'Response body is not UTF-8 encoded');
|
|
149
|
+
}
|
|
150
|
+
let body;
|
|
120
151
|
try {
|
|
121
|
-
|
|
152
|
+
body = JSON.parse(decoded);
|
|
122
153
|
}
|
|
123
154
|
catch (err) {
|
|
124
|
-
throw
|
|
155
|
+
throw new AuditError(res, 'Response body is not valid JSON');
|
|
125
156
|
}
|
|
157
|
+
return body;
|
|
126
158
|
}
|
|
127
|
-
exports.assertBodyAsExecutionResult = assertBodyAsExecutionResult;
|
package/lib/audits/utils.mjs
CHANGED
|
@@ -9,99 +9,130 @@ 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
|
};
|
|
22
24
|
}
|
|
23
|
-
catch (
|
|
24
|
-
if (
|
|
25
|
-
// anything thrown that is not an assertion
|
|
26
|
-
throw
|
|
25
|
+
catch (err) {
|
|
26
|
+
if (!(err instanceof AuditError)) {
|
|
27
|
+
// anything thrown that is not an assertion error is considered fatal
|
|
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
|
|
32
35
|
'error'
|
|
33
36
|
: // everything else is optional and considered a warning
|
|
34
37
|
'warn',
|
|
35
|
-
reason:
|
|
38
|
+
reason: err.reason,
|
|
39
|
+
response: err.response,
|
|
36
40
|
};
|
|
37
41
|
}
|
|
38
42
|
},
|
|
39
43
|
};
|
|
40
44
|
}
|
|
41
45
|
/**
|
|
42
|
-
*
|
|
46
|
+
* Error thrown when an assertion test fails.
|
|
43
47
|
*
|
|
44
|
-
*
|
|
48
|
+
* @private
|
|
49
|
+
*/
|
|
50
|
+
export class AuditError {
|
|
51
|
+
constructor(response, reason) {
|
|
52
|
+
this.response = response;
|
|
53
|
+
this.reason = reason;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Will throw an AuditError if the assertion on Response fails.
|
|
58
|
+
*
|
|
59
|
+
* All fatal problems will throw an instance of an Error.
|
|
60
|
+
*
|
|
61
|
+
* The name "ressert" is a wordplay combining "response" and "assert".
|
|
45
62
|
*
|
|
46
63
|
* @private
|
|
47
64
|
*/
|
|
48
|
-
export function
|
|
65
|
+
export function ressert(res) {
|
|
49
66
|
return {
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
// @ts-expect-error types will match, otherwise never
|
|
62
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
63
|
-
if (!actual.includes(expected)) {
|
|
64
|
-
throw `${name} ${JSON.stringify(actual)} does not contain ${JSON.stringify(expected)}`;
|
|
65
|
-
}
|
|
66
|
-
},
|
|
67
|
-
notToContain: (expected) => {
|
|
68
|
-
// @ts-expect-error types will match, otherwise never
|
|
69
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
70
|
-
if (actual.includes(expected)) {
|
|
71
|
-
throw `${name} ${JSON.stringify(actual)} contains ${JSON.stringify(expected)}`;
|
|
72
|
-
}
|
|
67
|
+
status: {
|
|
68
|
+
toBe(code) {
|
|
69
|
+
if (res.status !== code) {
|
|
70
|
+
throw new AuditError(res, `Response status code is not ${code}`);
|
|
71
|
+
}
|
|
72
|
+
},
|
|
73
|
+
toBeBetween: (min, max) => {
|
|
74
|
+
if (!(min <= res.status && res.status <= max)) {
|
|
75
|
+
throw new AuditError(res, `Response status is not between ${min} and ${max}`);
|
|
76
|
+
}
|
|
77
|
+
},
|
|
73
78
|
},
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
79
|
+
header(key) {
|
|
80
|
+
return {
|
|
81
|
+
toContain(part) {
|
|
82
|
+
var _a;
|
|
83
|
+
if (!((_a = res.headers.get(key)) === null || _a === void 0 ? void 0 : _a.includes(part))) {
|
|
84
|
+
throw new AuditError(res, `Response header ${key} does not contain ${part}`);
|
|
85
|
+
}
|
|
86
|
+
},
|
|
87
|
+
notToContain(part) {
|
|
88
|
+
var _a;
|
|
89
|
+
if ((_a = res.headers.get(key)) === null || _a === void 0 ? void 0 : _a.includes(part)) {
|
|
90
|
+
throw new AuditError(res, `Response header ${key} contains ${part}`);
|
|
91
|
+
}
|
|
92
|
+
},
|
|
93
|
+
};
|
|
81
94
|
},
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
95
|
+
bodyAsExecutionResult: {
|
|
96
|
+
data: {
|
|
97
|
+
async toBe(val) {
|
|
98
|
+
const body = await assertBodyAsExecutionResult(res);
|
|
99
|
+
if (body.data !== val) {
|
|
100
|
+
throw new AuditError(res, `Response body execution result data is not "${val}"`);
|
|
101
|
+
}
|
|
102
|
+
},
|
|
103
|
+
},
|
|
104
|
+
async toHaveProperty(key) {
|
|
105
|
+
const body = await assertBodyAsExecutionResult(res);
|
|
106
|
+
if (!(key in body)) {
|
|
107
|
+
throw new AuditError(res, `Response body execution result does not have a property "${key}"`);
|
|
108
|
+
}
|
|
109
|
+
},
|
|
110
|
+
async notToHaveProperty(key) {
|
|
111
|
+
const body = await assertBodyAsExecutionResult(res);
|
|
112
|
+
if (key in body) {
|
|
113
|
+
throw new AuditError(res, `Response body execution result has a property "${key}"`);
|
|
114
|
+
}
|
|
115
|
+
},
|
|
89
116
|
},
|
|
90
117
|
};
|
|
91
118
|
}
|
|
92
|
-
/**
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
119
|
+
/** @private */
|
|
120
|
+
async function assertBodyAsExecutionResult(res) {
|
|
121
|
+
let decoded;
|
|
122
|
+
try {
|
|
123
|
+
const decoder = new TextDecoder('utf-8');
|
|
124
|
+
const buff = await res.arrayBuffer();
|
|
125
|
+
decoded = decoder.decode(buff);
|
|
126
|
+
}
|
|
127
|
+
catch (err) {
|
|
128
|
+
throw new AuditError(res, 'Response body is not UTF-8 encoded');
|
|
129
|
+
}
|
|
130
|
+
let body;
|
|
101
131
|
try {
|
|
102
|
-
|
|
132
|
+
body = JSON.parse(decoded);
|
|
103
133
|
}
|
|
104
134
|
catch (err) {
|
|
105
|
-
throw
|
|
135
|
+
throw new AuditError(res, 'Response body is not valid JSON');
|
|
106
136
|
}
|
|
137
|
+
return body;
|
|
107
138
|
}
|
package/lib/handler.js
CHANGED
|
@@ -326,41 +326,40 @@ exports.getAcceptableMediaType = getAcceptableMediaType;
|
|
|
326
326
|
* @category Server
|
|
327
327
|
*/
|
|
328
328
|
function makeResponse(resultOrErrors, acceptedMediaType) {
|
|
329
|
-
|
|
329
|
+
const errors = (0, utils_1.isGraphQLError)(resultOrErrors)
|
|
330
|
+
? [resultOrErrors]
|
|
331
|
+
: (0, utils_1.areGraphQLErrors)(resultOrErrors)
|
|
332
|
+
? resultOrErrors
|
|
333
|
+
: null;
|
|
334
|
+
if (errors) {
|
|
330
335
|
return [
|
|
331
|
-
JSON.stringify(
|
|
332
|
-
{
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
+
JSON.stringify({ errors }),
|
|
337
|
+
Object.assign(Object.assign({}, (acceptedMediaType === 'application/json'
|
|
338
|
+
? {
|
|
339
|
+
status: 200,
|
|
340
|
+
statusText: 'OK',
|
|
341
|
+
}
|
|
342
|
+
: {
|
|
343
|
+
status: 400,
|
|
344
|
+
statusText: 'Bad Request',
|
|
345
|
+
})), { headers: {
|
|
336
346
|
'content-type': acceptedMediaType === 'application/json'
|
|
337
347
|
? 'application/json; charset=utf-8'
|
|
338
348
|
: 'application/graphql-response+json; charset=utf-8',
|
|
339
|
-
},
|
|
340
|
-
},
|
|
349
|
+
} }),
|
|
341
350
|
];
|
|
342
351
|
}
|
|
343
352
|
return [
|
|
344
|
-
JSON.stringify(
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
: [resultOrErrors],
|
|
350
|
-
}),
|
|
351
|
-
Object.assign(Object.assign({}, (acceptedMediaType === 'application/json'
|
|
352
|
-
? {
|
|
353
|
-
status: 200,
|
|
354
|
-
statusText: 'OK',
|
|
355
|
-
}
|
|
356
|
-
: {
|
|
357
|
-
status: 400,
|
|
358
|
-
statusText: 'Bad Request',
|
|
359
|
-
})), { headers: {
|
|
353
|
+
JSON.stringify(resultOrErrors),
|
|
354
|
+
{
|
|
355
|
+
status: 200,
|
|
356
|
+
statusText: 'OK',
|
|
357
|
+
headers: {
|
|
360
358
|
'content-type': acceptedMediaType === 'application/json'
|
|
361
359
|
? 'application/json; charset=utf-8'
|
|
362
360
|
: 'application/graphql-response+json; charset=utf-8',
|
|
363
|
-
}
|
|
361
|
+
},
|
|
362
|
+
},
|
|
364
363
|
];
|
|
365
364
|
}
|
|
366
365
|
exports.makeResponse = makeResponse;
|
package/lib/handler.mjs
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
*
|
|
5
5
|
*/
|
|
6
6
|
import { validate as graphqlValidate, execute as graphqlExecute, parse as graphqlParse, getOperationAST as graphqlGetOperationAST, GraphQLError, } from 'graphql';
|
|
7
|
-
import { areGraphQLErrors, isAsyncIterable, isExecutionResult, isObject, } from './utils.mjs';
|
|
7
|
+
import { areGraphQLErrors, isAsyncIterable, isExecutionResult, isGraphQLError, isObject, } from './utils.mjs';
|
|
8
8
|
/**
|
|
9
9
|
* Checks whether the passed value is the `graphql-http` server agnostic response.
|
|
10
10
|
*
|
|
@@ -320,41 +320,40 @@ export function getAcceptableMediaType(acceptHeader) {
|
|
|
320
320
|
* @category Server
|
|
321
321
|
*/
|
|
322
322
|
export function makeResponse(resultOrErrors, acceptedMediaType) {
|
|
323
|
-
|
|
323
|
+
const errors = isGraphQLError(resultOrErrors)
|
|
324
|
+
? [resultOrErrors]
|
|
325
|
+
: areGraphQLErrors(resultOrErrors)
|
|
326
|
+
? resultOrErrors
|
|
327
|
+
: null;
|
|
328
|
+
if (errors) {
|
|
324
329
|
return [
|
|
325
|
-
JSON.stringify(
|
|
326
|
-
{
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
+
JSON.stringify({ errors }),
|
|
331
|
+
Object.assign(Object.assign({}, (acceptedMediaType === 'application/json'
|
|
332
|
+
? {
|
|
333
|
+
status: 200,
|
|
334
|
+
statusText: 'OK',
|
|
335
|
+
}
|
|
336
|
+
: {
|
|
337
|
+
status: 400,
|
|
338
|
+
statusText: 'Bad Request',
|
|
339
|
+
})), { headers: {
|
|
330
340
|
'content-type': acceptedMediaType === 'application/json'
|
|
331
341
|
? 'application/json; charset=utf-8'
|
|
332
342
|
: 'application/graphql-response+json; charset=utf-8',
|
|
333
|
-
},
|
|
334
|
-
},
|
|
343
|
+
} }),
|
|
335
344
|
];
|
|
336
345
|
}
|
|
337
346
|
return [
|
|
338
|
-
JSON.stringify(
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
: [resultOrErrors],
|
|
344
|
-
}),
|
|
345
|
-
Object.assign(Object.assign({}, (acceptedMediaType === 'application/json'
|
|
346
|
-
? {
|
|
347
|
-
status: 200,
|
|
348
|
-
statusText: 'OK',
|
|
349
|
-
}
|
|
350
|
-
: {
|
|
351
|
-
status: 400,
|
|
352
|
-
statusText: 'Bad Request',
|
|
353
|
-
})), { headers: {
|
|
347
|
+
JSON.stringify(resultOrErrors),
|
|
348
|
+
{
|
|
349
|
+
status: 200,
|
|
350
|
+
statusText: 'OK',
|
|
351
|
+
headers: {
|
|
354
352
|
'content-type': acceptedMediaType === 'application/json'
|
|
355
353
|
? 'application/json; charset=utf-8'
|
|
356
354
|
: 'application/graphql-response+json; charset=utf-8',
|
|
357
|
-
}
|
|
355
|
+
},
|
|
356
|
+
},
|
|
358
357
|
];
|
|
359
358
|
}
|
|
360
359
|
function getHeader(req, key) {
|