+1
-66
alias/error/GraphQLError.mjs
+1
-66
alias/error/GraphQLError.mjs
···
1
-
import { getLocation } from 'graphql/language/location';
2
-
3
-
import { printLocation, printSourceLocation } from '../language/printLocation';
4
-
5
-
export class GraphQLError extends Error {
6
-
constructor(
7
-
message,
8
-
nodes,
9
-
source,
10
-
positions,
11
-
path,
12
-
originalError,
13
-
extensions
14
-
) {
15
-
super(message);
16
-
17
-
this.name = 'GraphQLError';
18
-
this.message = message;
19
-
20
-
if (path) this.path = path;
21
-
if (nodes) this.nodes = nodes;
22
-
if (source) this.source = source;
23
-
if (positions) this.positions = positions;
24
-
if (originalError) this.originalError = originalError;
25
-
26
-
let _extensions = extensions;
27
-
if (_extensions == null && originalError != null) {
28
-
const originalExtensions = originalError.extensions;
29
-
if (isObjectLike(originalExtensions)) {
30
-
_extensions = originalExtensions;
31
-
}
32
-
}
33
-
34
-
if (_extensions) {
35
-
this.extensions = _extensions;
36
-
}
37
-
}
38
-
39
-
toJSON() {
40
-
const formattedError = { message: this.message };
41
-
42
-
if (this.locations != null) formattedError.locations = this.locations;
43
-
if (this.path != null) formattedError.path = this.path;
44
-
if (this.extensions != null && Object.keys(this.extensions).length > 0)
45
-
formattedError.extensions = this.extensions;
46
-
return formattedError;
47
-
}
48
-
49
-
toString() {
50
-
let output = error.message;
51
-
52
-
if (error.nodes) {
53
-
for (const node of error.nodes) {
54
-
if (node.loc) {
55
-
output += '\n\n' + printLocation(node.loc);
56
-
}
57
-
}
58
-
} else if (error.source && error.locations) {
59
-
for (const location of error.locations) {
60
-
output += '\n\n' + printSourceLocation(error.source, location);
61
-
}
62
-
}
63
-
64
-
return output;
65
-
}
66
-
}
67
68
/**
69
* Prints a GraphQLError to a string, representing useful location information
+1
-3
alias/language/blockString.mjs
+1
-3
alias/language/blockString.mjs
+1
alias/language/kinds.mjs
+1
alias/language/kinds.mjs
···
···
1
+
export { Kind } from '@0no-co/graphql.web';
+1
-339
alias/language/parser.mjs
+1
-339
alias/language/parser.mjs
···
1
-
/**
2
-
* This is a spec-compliant implementation of a GraphQL query language parser,
3
-
* up-to-date with the June 2018 Edition. Unlike the reference implementation
4
-
* in graphql.js it will only parse the query language, but not the schema
5
-
* language.
6
-
*/
7
-
import { Kind } from 'graphql';
8
-
import { GraphQLError } from '../error/GraphQLError';
9
-
import { match, parse as makeParser } from 'reghex';
10
-
11
-
// 2.1.7: Includes commas, and line comments
12
-
const ignored = /([\s,]|#[^\n\r]+)+/;
13
-
14
-
// 2.1.9: Limited to ASCII character set, so regex shortcodes are fine
15
-
const name = match(Kind.NAME, (x) => ({
16
-
kind: x.tag,
17
-
value: x[0],
18
-
}))`
19
-
${/[_\w][_\d\w]*/}
20
-
`;
21
-
22
-
const null_ = match(Kind.NULL, (x) => ({
23
-
kind: x.tag,
24
-
}))`
25
-
${'null'}
26
-
`;
27
-
28
-
const bool = match(Kind.BOOLEAN, (x) => ({
29
-
kind: x.tag,
30
-
value: x[0] === 'true',
31
-
}))`
32
-
${/true|false/}
33
-
`;
34
-
35
-
const variable = match(Kind.VARIABLE, (x) => ({
36
-
kind: x.tag,
37
-
name: x[0],
38
-
}))`
39
-
:${'$'} ${name}
40
-
`;
41
-
42
-
// 2.9.6: Technically, this parser doesn't need to check that true, false, and null
43
-
// aren't used as enums, but this prevents mistakes and follows the spec closely
44
-
const enum_ = match(Kind.ENUM, (x) => ({
45
-
kind: x.tag,
46
-
value: x[0].value,
47
-
}))`
48
-
${name}
49
-
`;
50
-
51
-
// 2.9.1-2: These combine both number values for the sake of simplicity.
52
-
// It allows for leading zeroes, unlike graphql.js, which shouldn't matter;
53
-
const number = match(null, (x) => ({
54
-
kind: x.length === 1 ? Kind.INT : Kind.FLOAT,
55
-
value: x.join(''),
56
-
}))`
57
-
${/[-]?\d+/}
58
-
${/[.]\d+/}?
59
-
${/[eE][+-]?\d+/}?
60
-
`;
61
-
62
-
// 2.9.4: Notably, this skips checks for unicode escape sequences and escaped quotes.
63
-
const string = match(Kind.STRING, (x) => ({
64
-
kind: x.tag,
65
-
value: x[0],
66
-
}))`
67
-
(:${'"""'} ${/[\s\S]+?(?=""")/} :${'"""'})
68
-
| (:${'"'} ${/[^"\r\n]*/} :${'"'})
69
-
`;
70
-
71
-
const list = match(Kind.LIST, (x) => ({
72
-
kind: x.tag,
73
-
values: x.slice(),
74
-
}))`
75
-
:${'['}
76
-
${() => value}*
77
-
(?: ${ignored}? ${']'} ${ignored}?)
78
-
`;
79
-
80
-
const objectField = match(Kind.OBJECT_FIELD, (x) => ({
81
-
kind: x.tag,
82
-
name: x[0],
83
-
value: x[1],
84
-
}))`
85
-
:${ignored}?
86
-
${name}
87
-
(?: ${ignored}? ${':'})
88
-
${() => value}
89
-
`;
90
-
91
-
const object = match(Kind.OBJECT, (x) => ({
92
-
kind: x.tag,
93
-
fields: x.slice(),
94
-
}))`
95
-
:${'{'}
96
-
${objectField}*
97
-
(?: ${'}'} ${ignored}?)
98
-
`;
99
-
100
-
// 2.9: This matches the spec closely and is complete
101
-
const value = match(null, (x) => x[0])`
102
-
:${ignored}?
103
-
(
104
-
${null_}
105
-
| ${bool}
106
-
| ${variable}
107
-
| ${string}
108
-
| ${number}
109
-
| ${enum_}
110
-
| ${list}
111
-
| ${object}
112
-
)
113
-
:${ignored}?
114
-
`;
115
-
116
-
const arg = match(Kind.ARGUMENT, (x) => ({
117
-
kind: x.tag,
118
-
name: x[0],
119
-
value: x[1],
120
-
}))`
121
-
${name}
122
-
(?: ${ignored}? ${':'} ${ignored}?)
123
-
${value}
124
-
`;
125
-
126
-
const args = match()`
127
-
:${ignored}?
128
-
(
129
-
(?: ${'('} ${ignored}?)
130
-
${arg}+
131
-
(?: ${')'} ${ignored}?)
132
-
)?
133
-
`;
134
-
135
-
const directive = match(Kind.DIRECTIVE, (x) => ({
136
-
kind: x.tag,
137
-
name: x[0],
138
-
arguments: x[1],
139
-
}))`
140
-
:${'@'} ${name} :${ignored}?
141
-
${args}?
142
-
:${ignored}?
143
-
`;
144
-
145
-
const directives = match()`
146
-
:${ignored}?
147
-
${directive}*
148
-
`;
149
-
150
-
const field = match(Kind.FIELD, (x) => {
151
-
let i = 0;
152
-
return {
153
-
kind: x.tag,
154
-
alias: x[1].kind === Kind.NAME ? x[i++] : undefined,
155
-
name: x[i++],
156
-
arguments: x[i++],
157
-
directives: x[i++],
158
-
selectionSet: x[i++],
159
-
};
160
-
})`
161
-
:${ignored}?
162
-
${name}
163
-
(
164
-
(?: ${ignored}? ${':'} ${ignored}?)
165
-
${name}
166
-
)?
167
-
${args}
168
-
${directives}
169
-
${() => selectionSet}?
170
-
`;
171
-
172
-
// 2.11: The type declarations may be simplified since there's little room
173
-
// for error in this limited type system.
174
-
const type = match(null, (x) => {
175
-
const node =
176
-
x[0].kind === 'Name'
177
-
? { kind: Kind.NAMED_TYPE, name: x[0] }
178
-
: { kind: Kind.LIST_TYPE, type: x[0] };
179
-
return x[1] === '!' ? { kind: Kind.NON_NULL_TYPE, type: node } : node;
180
-
})`
181
-
(
182
-
(
183
-
(?: ${'['} ${ignored}?)
184
-
${() => type}
185
-
(?: ${ignored}? ${']'} ${ignored}?)
186
-
) | ${name}
187
-
)
188
-
${'!'}?
189
-
:${ignored}?
190
-
`;
191
-
192
-
const typeCondition = match(null, (x) => ({
193
-
kind: Kind.NAMED_TYPE,
194
-
name: x[0],
195
-
}))`
196
-
(?: ${ignored}? ${'on'} ${ignored})
197
-
${name}
198
-
:${ignored}?
199
-
`;
200
-
201
-
const inlineFragment = match(Kind.INLINE_FRAGMENT, (x) => {
202
-
let i = 0;
203
-
return {
204
-
kind: x.tag,
205
-
typeCondition: x[i].kind === Kind.NAMED_TYPE ? x[i++] : undefined,
206
-
directives: x[i++],
207
-
selectionSet: x[i],
208
-
};
209
-
})`
210
-
:${'...'}
211
-
${typeCondition}?
212
-
${directives}
213
-
${() => selectionSet}
214
-
`;
215
-
216
-
const fragmentSpread = match(Kind.FRAGMENT_SPREAD, (x) => ({
217
-
kind: x.tag,
218
-
name: x[0],
219
-
directives: x[1],
220
-
}))`
221
-
(?: ${'...'} ${ignored}?)
222
-
!${'on'}
223
-
${name}
224
-
:${ignored}?
225
-
${directives}
226
-
`;
227
-
228
-
const selectionSet = match(Kind.SELECTION_SET, (x) => ({
229
-
kind: x.tag,
230
-
selections: x.slice(),
231
-
}))`
232
-
:${ignored}?
233
-
(?: ${'{'} ${ignored}?)
234
-
(
235
-
${inlineFragment} |
236
-
${fragmentSpread} |
237
-
${field}
238
-
)+
239
-
(?: ${'}'} ${ignored}?)
240
-
`;
241
-
242
-
const varDefinitionDefault = match(null, (x) => x[0])`
243
-
(?: ${'='} ${ignored}?)
244
-
${value}
245
-
`;
246
-
247
-
const varDefinition = match(Kind.VARIABLE_DEFINITION, (x) => ({
248
-
kind: x.tag,
249
-
variable: x[0],
250
-
type: x[1],
251
-
defaultValue: x[2].kind ? x[2] : undefined,
252
-
directives: !x[2].kind ? x[2] : x[3],
253
-
}))`
254
-
${variable}
255
-
(?: ${ignored}? ${':'} ${ignored}?)
256
-
${type}
257
-
${varDefinitionDefault}?
258
-
${directives}
259
-
:${ignored}?
260
-
`;
261
-
262
-
const varDefinitions = match('vars')`
263
-
:${ignored}?
264
-
(?: ${'('} ${ignored}?)
265
-
${varDefinition}+
266
-
(?: ${')'} ${ignored}?)
267
-
`;
268
-
269
-
const fragmentDefinition = match(Kind.FRAGMENT_DEFINITION, (x) => ({
270
-
kind: x.tag,
271
-
name: x[0],
272
-
typeCondition: x[1],
273
-
directives: x[2],
274
-
selectionSet: x[3],
275
-
}))`
276
-
(?: ${ignored}? ${'fragment'} ${ignored})
277
-
${name}
278
-
${typeCondition}
279
-
${directives}
280
-
${selectionSet}
281
-
`;
282
-
283
-
const operationDefinition = match(Kind.OPERATION_DEFINITION, (x) => {
284
-
let i = 1;
285
-
return {
286
-
kind: x.tag,
287
-
operation: x[0],
288
-
name: x[i].kind === Kind.NAME ? x[i++] : undefined,
289
-
variableDefinitions: x[i].tag === 'vars' ? x[i++].slice() : [],
290
-
directives: x[i++],
291
-
selectionSet: x[i],
292
-
};
293
-
})`
294
-
:${ignored}?
295
-
${/query|mutation|subscription/}
296
-
(:${ignored} ${name})?
297
-
${varDefinitions}?
298
-
${directives}
299
-
${selectionSet}
300
-
`;
301
-
302
-
const queryShorthand = match(Kind.OPERATION_DEFINITION, (x) => ({
303
-
kind: x.tag,
304
-
operation: 'query',
305
-
name: undefined,
306
-
variableDefinitions: [],
307
-
directives: [],
308
-
selectionSet: x[0],
309
-
}))`
310
-
${selectionSet}
311
-
`;
312
-
313
-
const root = match(Kind.DOCUMENT, (x) =>
314
-
x.length ? { kind: x.tag, definitions: x.slice() } : undefined
315
-
)`
316
-
(${queryShorthand} | ${operationDefinition} | ${fragmentDefinition})*
317
-
`;
318
-
319
-
const _parse = makeParser(root);
320
-
const _parseValue = makeParser(value);
321
-
const _parseType = makeParser(type);
322
-
323
-
export function parse(input) {
324
-
const result = _parse(input);
325
-
if (result == null) throw new GraphQLError('Syntax Error');
326
-
return result;
327
-
}
328
-
329
-
export function parseValue(input) {
330
-
const result = _parseValue(input);
331
-
if (result == null) throw new GraphQLError('Syntax Error');
332
-
return result;
333
-
}
334
-
335
-
export function parseType(input) {
336
-
const result = _parseType(input);
337
-
if (result == null) throw new GraphQLError('Syntax Error');
338
-
return result;
339
-
}
+1
-1
alias/language/printString.mjs
+1
-1
alias/language/printString.mjs
+1
-141
alias/language/printer.mjs
+1
-141
alias/language/printer.mjs
···
1
-
import { Kind } from 'graphql';
2
-
import { printBlockString } from './blockString';
3
-
import { printString } from './printString';
4
-
5
-
export function print(node) {
6
-
if (Array.isArray(node)) {
7
-
return node.map(print);
8
-
} else if (node == null || typeof node !== 'object') {
9
-
return node ? '' + node : '';
10
-
}
11
-
12
-
switch (node.kind) {
13
-
case 'OperationDefinition': {
14
-
const prefix = join(
15
-
[
16
-
node.operation,
17
-
print(node.name) +
18
-
wrap('(', join(print(node.variableDefinitions), ', '), ')'),
19
-
join(print(node.directives), ' '),
20
-
],
21
-
' '
22
-
);
23
-
24
-
return (
25
-
(prefix === 'query' ? '' : prefix + ' ') + print(node.selectionSet)
26
-
);
27
-
}
28
-
29
-
case 'VariableDefinition':
30
-
return (
31
-
print(node.variable) +
32
-
': ' +
33
-
print(node.type) +
34
-
wrap(' = ', print(node.defaultValue)) +
35
-
wrap(' ', join(print(node.directives), ' '))
36
-
);
37
-
38
-
case 'Field':
39
-
return join(
40
-
[
41
-
wrap('', print(node.alias), ': ') +
42
-
print(node.name) +
43
-
wrap('(', join(print(node.arguments), ', '), ')'),
44
-
join(print(node.directives), ' '),
45
-
print(node.selectionSet),
46
-
],
47
-
' '
48
-
);
49
-
50
-
case 'StringValue':
51
-
return node.isBlockString
52
-
? printBlockString(node.value)
53
-
: printString(node.value);
54
-
55
-
case 'BooleanValue':
56
-
return node.value ? 'true' : 'false';
57
-
58
-
case 'NullValue':
59
-
return 'null';
60
-
61
-
case 'IntValue':
62
-
case 'FloatValue':
63
-
case 'EnumValue':
64
-
case 'Name':
65
-
return node.value;
66
-
67
-
case 'ListValue':
68
-
return '[' + join(print(node.values), ', ') + ']';
69
-
70
-
case 'ObjectValue':
71
-
return '{' + join(print(node.fields), ', ') + '}';
72
-
73
-
case 'ObjectField':
74
-
return node.name.value + ': ' + print(node.value);
75
-
76
-
case 'Variable':
77
-
return '$' + node.name.value;
78
-
case 'Document':
79
-
return join(print(node.definitions), '\n\n') + '\n';
80
-
case 'SelectionSet':
81
-
return block(print(node.selections));
82
-
case 'Argument':
83
-
return node.name.value + ': ' + print(node.value);
84
-
85
-
case 'FragmentSpread':
86
-
return (
87
-
'...' + print(node.name) + wrap(' ', join(print(node.directives), ' '))
88
-
);
89
-
90
-
case 'InlineFragment':
91
-
return join(
92
-
[
93
-
'...',
94
-
wrap('on ', print(node.typeCondition)),
95
-
join(print(node.directives), ' '),
96
-
print(node.selectionSet),
97
-
],
98
-
' '
99
-
);
100
-
101
-
case 'FragmentDefinition':
102
-
return (
103
-
'fragment ' +
104
-
node.name.value +
105
-
wrap('(', join(print(node.variableDefinitions), ', '), ')') +
106
-
' ' +
107
-
'on ' +
108
-
print(node.typeCondition) +
109
-
' ' +
110
-
wrap('', join(print(node.directives), ' '), ' ') +
111
-
print(node.selectionSet)
112
-
);
113
-
114
-
case 'Directive':
115
-
return (
116
-
'@' +
117
-
node.name.value +
118
-
wrap('(', join(print(node.arguments), ', '), ')')
119
-
);
120
-
121
-
case 'NamedType':
122
-
return node.name.value;
123
-
124
-
case 'ListType':
125
-
return '[' + print(node.type) + ']';
126
-
127
-
case 'NonNullType':
128
-
return print(node.type) + '!';
129
-
130
-
default:
131
-
return '';
132
-
}
133
-
}
134
-
135
-
const join = (array, separator) =>
136
-
(array && array.filter((x) => x).join(separator || '')) || '';
137
-
138
-
const block = (array) =>
139
-
wrap('{\n ', join(array, '\n').replace(/\n/g, '\n '), '\n}');
140
-
141
-
const wrap = (start, value, end) => (value ? start + value + (end || '') : '');
+2
-87
alias/language/visitor.mjs
+2
-87
alias/language/visitor.mjs
···
1
-
import {
2
getEnterLeaveForKind,
3
getVisitFn,
4
visitInParallel,
5
-
BREAK,
6
} from 'graphql/language/visitor';
7
8
-
export { getEnterLeaveForKind, getVisitFn, visitInParallel, BREAK };
9
-
10
-
export function visit(node, visitor) {
11
-
const path = [];
12
-
const ancestors = [];
13
-
14
-
function traverse(node, key, parent) {
15
-
let hasEdited = false;
16
-
17
-
const enter = getVisitFn(visitor, node.kind, false);
18
-
const resultEnter =
19
-
enter && enter.call(visitor, node, key, parent, path, ancestors);
20
-
if (resultEnter === false) {
21
-
return node;
22
-
} else if (resultEnter === null) {
23
-
return null;
24
-
} else if (resultEnter === BREAK) {
25
-
throw BREAK;
26
-
} else if (resultEnter && typeof resultEnter.kind === 'string') {
27
-
hasEdited = resultEnter !== node;
28
-
node = resultEnter;
29
-
}
30
-
31
-
if (parent) ancestors.push(parent);
32
-
33
-
let result;
34
-
const copy = { ...node };
35
-
for (const nodeKey in node) {
36
-
path.push(nodeKey);
37
-
let value = node[nodeKey];
38
-
if (Array.isArray(value)) {
39
-
const newValue = [];
40
-
for (let index = 0; index < value.length; index++) {
41
-
if (value[index] != null && typeof value[index].kind === 'string') {
42
-
ancestors.push(node);
43
-
path.push(index);
44
-
result = traverse(value[index], index, value);
45
-
path.pop();
46
-
ancestors.pop();
47
-
if (result === undefined) {
48
-
newValue.push(value[index]);
49
-
} else if (result === null) {
50
-
hasEdited = true;
51
-
} else {
52
-
hasEdited = hasEdited || result !== value[index];
53
-
newValue.push(result);
54
-
}
55
-
}
56
-
}
57
-
value = newValue;
58
-
} else if (value != null && typeof value.kind === 'string') {
59
-
result = traverse(value, nodeKey, node);
60
-
if (result !== undefined) {
61
-
hasEdited = hasEdited || value !== result;
62
-
value = result;
63
-
}
64
-
}
65
-
66
-
path.pop();
67
-
if (hasEdited) copy[nodeKey] = value;
68
-
}
69
-
70
-
if (parent) ancestors.pop();
71
-
const leave = getVisitFn(visitor, node.kind, true);
72
-
const resultLeave =
73
-
leave && leave.call(visitor, node, key, parent, path, ancestors);
74
-
if (resultLeave === BREAK) {
75
-
throw BREAK;
76
-
} else if (resultLeave !== undefined) {
77
-
return resultLeave;
78
-
} else if (resultEnter !== undefined) {
79
-
return hasEdited ? copy : resultEnter;
80
-
} else {
81
-
return hasEdited ? copy : node;
82
-
}
83
-
}
84
-
85
-
try {
86
-
const result = traverse(node);
87
-
return result !== undefined && result !== false ? result : node;
88
-
} catch (error) {
89
-
if (error !== BREAK) throw error;
90
-
return node;
91
-
}
92
-
}
+1
package.json
+1
package.json
+11
tsconfig.json
+11
tsconfig.json
+5
yarn.lock
+5
yarn.lock
···
2
# yarn lockfile v1
3
4
5
+
"@0no-co/graphql.web@^0.1.2":
6
+
version "0.1.2"
7
+
resolved "https://registry.yarnpkg.com/@0no-co/graphql.web/-/graphql.web-0.1.2.tgz#6a8f71bad35e1db0f1c464bc5aaf7a8d02c03b23"
8
+
integrity sha512-Jgn4aaiXit6yDL4tBZvv1wV2x9rCEsElqpeNxO80NHUNOPP+QY9VxA1dq9RTSaeaeN6/i994gNV+UvRIX3gQLQ==
9
+
10
"@babel/code-frame@7.12.11":
11
version "7.12.11"
12
resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.12.11.tgz#f4ad435aa263db935b8f10f2c552d23fb716a63f"