graphql 16.11.0 → 16.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 +49 -6
- package/execution/execute.d.ts +14 -1
- package/execution/execute.js +72 -13
- package/execution/execute.mjs +72 -13
- package/execution/subscribe.js +1 -0
- package/execution/subscribe.mjs +2 -0
- package/index.d.ts +11 -0
- package/index.js +24 -0
- package/index.mjs +6 -2
- package/language/ast.d.ts +45 -1
- package/language/ast.js +14 -1
- package/language/ast.mjs +14 -1
- package/language/index.d.ts +14 -1
- package/language/index.js +12 -0
- package/language/index.mjs +8 -1
- package/language/kinds.d.ts +6 -0
- package/language/kinds.js +5 -0
- package/language/kinds.mjs +5 -0
- package/language/lexer.d.ts +52 -1
- package/language/lexer.js +10 -0
- package/language/lexer.mjs +17 -4
- package/language/parser.d.ts +30 -3
- package/language/parser.js +129 -13
- package/language/parser.mjs +123 -11
- package/language/predicates.d.ts +4 -0
- package/language/predicates.js +11 -0
- package/language/predicates.mjs +9 -0
- package/language/printer.js +42 -13
- package/language/printer.mjs +42 -13
- package/language/schemaCoordinateLexer.d.ts +43 -0
- package/language/schemaCoordinateLexer.js +171 -0
- package/language/schemaCoordinateLexer.mjs +122 -0
- package/language/tokenKind.d.ts +1 -0
- package/language/tokenKind.js +1 -0
- package/language/tokenKind.mjs +1 -0
- package/package.json +1 -1
- package/utilities/index.d.ts +5 -0
- package/utilities/index.js +14 -0
- package/utilities/index.mjs +5 -0
- package/utilities/resolveSchemaCoordinate.d.ts +80 -0
- package/utilities/resolveSchemaCoordinate.js +260 -0
- package/utilities/resolveSchemaCoordinate.mjs +243 -0
- package/validation/rules/ValuesOfCorrectTypeRule.js +7 -36
- package/validation/rules/ValuesOfCorrectTypeRule.mjs +7 -35
- package/validation/validate.js +12 -0
- package/validation/validate.mjs +13 -2
- package/version.js +2 -2
- package/version.mjs +2 -2
package/language/parser.js
CHANGED
|
@@ -6,6 +6,7 @@ Object.defineProperty(exports, '__esModule', {
|
|
|
6
6
|
exports.Parser = void 0;
|
|
7
7
|
exports.parse = parse;
|
|
8
8
|
exports.parseConstValue = parseConstValue;
|
|
9
|
+
exports.parseSchemaCoordinate = parseSchemaCoordinate;
|
|
9
10
|
exports.parseType = parseType;
|
|
10
11
|
exports.parseValue = parseValue;
|
|
11
12
|
|
|
@@ -19,6 +20,8 @@ var _kinds = require('./kinds.js');
|
|
|
19
20
|
|
|
20
21
|
var _lexer = require('./lexer.js');
|
|
21
22
|
|
|
23
|
+
var _schemaCoordinateLexer = require('./schemaCoordinateLexer.js');
|
|
24
|
+
|
|
22
25
|
var _source = require('./source.js');
|
|
23
26
|
|
|
24
27
|
var _tokenKind = require('./tokenKind.js');
|
|
@@ -84,6 +87,29 @@ function parseType(source, options) {
|
|
|
84
87
|
parser.expectToken(_tokenKind.TokenKind.EOF);
|
|
85
88
|
return type;
|
|
86
89
|
}
|
|
90
|
+
/**
|
|
91
|
+
* Given a string containing a GraphQL Schema Coordinate (ex. `Type.field`),
|
|
92
|
+
* parse the AST for that schema coordinate.
|
|
93
|
+
* Throws GraphQLError if a syntax error is encountered.
|
|
94
|
+
*
|
|
95
|
+
* Consider providing the results to the utility function:
|
|
96
|
+
* resolveASTSchemaCoordinate(). Or calling resolveSchemaCoordinate() directly
|
|
97
|
+
* with an unparsed source.
|
|
98
|
+
*/
|
|
99
|
+
|
|
100
|
+
function parseSchemaCoordinate(source) {
|
|
101
|
+
const sourceObj = (0, _source.isSource)(source)
|
|
102
|
+
? source
|
|
103
|
+
: new _source.Source(source);
|
|
104
|
+
const lexer = new _schemaCoordinateLexer.SchemaCoordinateLexer(sourceObj);
|
|
105
|
+
const parser = new Parser(source, {
|
|
106
|
+
lexer,
|
|
107
|
+
});
|
|
108
|
+
parser.expectToken(_tokenKind.TokenKind.SOF);
|
|
109
|
+
const coordinate = parser.parseSchemaCoordinate();
|
|
110
|
+
parser.expectToken(_tokenKind.TokenKind.EOF);
|
|
111
|
+
return coordinate;
|
|
112
|
+
}
|
|
87
113
|
/**
|
|
88
114
|
* This class is exported only to assist people in implementing their own parsers
|
|
89
115
|
* without duplicating too much code and should be used only as last resort for cases
|
|
@@ -98,11 +124,18 @@ function parseType(source, options) {
|
|
|
98
124
|
|
|
99
125
|
class Parser {
|
|
100
126
|
constructor(source, options = {}) {
|
|
101
|
-
const
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
127
|
+
const { lexer, ..._options } = options;
|
|
128
|
+
|
|
129
|
+
if (lexer) {
|
|
130
|
+
this._lexer = lexer;
|
|
131
|
+
} else {
|
|
132
|
+
const sourceObj = (0, _source.isSource)(source)
|
|
133
|
+
? source
|
|
134
|
+
: new _source.Source(source);
|
|
135
|
+
this._lexer = new _lexer.Lexer(sourceObj);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
this._options = _options;
|
|
106
139
|
this._tokenCounter = 0;
|
|
107
140
|
}
|
|
108
141
|
|
|
@@ -169,6 +202,14 @@ class Parser {
|
|
|
169
202
|
? this._lexer.lookahead()
|
|
170
203
|
: this._lexer.token;
|
|
171
204
|
|
|
205
|
+
if (hasDescription && keywordToken.kind === _tokenKind.TokenKind.BRACE_L) {
|
|
206
|
+
throw (0, _syntaxError.syntaxError)(
|
|
207
|
+
this._lexer.source,
|
|
208
|
+
this._lexer.token.start,
|
|
209
|
+
'Unexpected description, descriptions are not supported on shorthand queries.',
|
|
210
|
+
);
|
|
211
|
+
}
|
|
212
|
+
|
|
172
213
|
if (keywordToken.kind === _tokenKind.TokenKind.NAME) {
|
|
173
214
|
switch (keywordToken.value) {
|
|
174
215
|
case 'schema':
|
|
@@ -196,14 +237,6 @@ class Parser {
|
|
|
196
237
|
return this.parseDirectiveDefinition();
|
|
197
238
|
}
|
|
198
239
|
|
|
199
|
-
if (hasDescription) {
|
|
200
|
-
throw (0, _syntaxError.syntaxError)(
|
|
201
|
-
this._lexer.source,
|
|
202
|
-
this._lexer.token.start,
|
|
203
|
-
'Unexpected description, descriptions are supported only on type definitions.',
|
|
204
|
-
);
|
|
205
|
-
}
|
|
206
|
-
|
|
207
240
|
switch (keywordToken.value) {
|
|
208
241
|
case 'query':
|
|
209
242
|
case 'mutation':
|
|
@@ -212,7 +245,17 @@ class Parser {
|
|
|
212
245
|
|
|
213
246
|
case 'fragment':
|
|
214
247
|
return this.parseFragmentDefinition();
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
if (hasDescription) {
|
|
251
|
+
throw (0, _syntaxError.syntaxError)(
|
|
252
|
+
this._lexer.source,
|
|
253
|
+
this._lexer.token.start,
|
|
254
|
+
'Unexpected description, only GraphQL definitions support descriptions.',
|
|
255
|
+
);
|
|
256
|
+
}
|
|
215
257
|
|
|
258
|
+
switch (keywordToken.value) {
|
|
216
259
|
case 'extend':
|
|
217
260
|
return this.parseTypeSystemExtension();
|
|
218
261
|
}
|
|
@@ -234,6 +277,7 @@ class Parser {
|
|
|
234
277
|
return this.node(start, {
|
|
235
278
|
kind: _kinds.Kind.OPERATION_DEFINITION,
|
|
236
279
|
operation: _ast.OperationTypeNode.QUERY,
|
|
280
|
+
description: undefined,
|
|
237
281
|
name: undefined,
|
|
238
282
|
variableDefinitions: [],
|
|
239
283
|
directives: [],
|
|
@@ -241,6 +285,7 @@ class Parser {
|
|
|
241
285
|
});
|
|
242
286
|
}
|
|
243
287
|
|
|
288
|
+
const description = this.parseDescription();
|
|
244
289
|
const operation = this.parseOperationType();
|
|
245
290
|
let name;
|
|
246
291
|
|
|
@@ -251,6 +296,7 @@ class Parser {
|
|
|
251
296
|
return this.node(start, {
|
|
252
297
|
kind: _kinds.Kind.OPERATION_DEFINITION,
|
|
253
298
|
operation,
|
|
299
|
+
description,
|
|
254
300
|
name,
|
|
255
301
|
variableDefinitions: this.parseVariableDefinitions(),
|
|
256
302
|
directives: this.parseDirectives(false),
|
|
@@ -295,6 +341,7 @@ class Parser {
|
|
|
295
341
|
parseVariableDefinition() {
|
|
296
342
|
return this.node(this._lexer.token, {
|
|
297
343
|
kind: _kinds.Kind.VARIABLE_DEFINITION,
|
|
344
|
+
description: this.parseDescription(),
|
|
298
345
|
variable: this.parseVariable(),
|
|
299
346
|
type:
|
|
300
347
|
(this.expectToken(_tokenKind.TokenKind.COLON),
|
|
@@ -443,6 +490,7 @@ class Parser {
|
|
|
443
490
|
|
|
444
491
|
parseFragmentDefinition() {
|
|
445
492
|
const start = this._lexer.token;
|
|
493
|
+
const description = this.parseDescription();
|
|
446
494
|
this.expectKeyword('fragment'); // Legacy support for defining variables within fragments changes
|
|
447
495
|
// the grammar of FragmentDefinition:
|
|
448
496
|
// - fragment FragmentName VariableDefinitions? on TypeCondition Directives? SelectionSet
|
|
@@ -450,6 +498,7 @@ class Parser {
|
|
|
450
498
|
if (this._options.allowLegacyFragmentVariables === true) {
|
|
451
499
|
return this.node(start, {
|
|
452
500
|
kind: _kinds.Kind.FRAGMENT_DEFINITION,
|
|
501
|
+
description,
|
|
453
502
|
name: this.parseFragmentName(),
|
|
454
503
|
variableDefinitions: this.parseVariableDefinitions(),
|
|
455
504
|
typeCondition: (this.expectKeyword('on'), this.parseNamedType()),
|
|
@@ -460,6 +509,7 @@ class Parser {
|
|
|
460
509
|
|
|
461
510
|
return this.node(start, {
|
|
462
511
|
kind: _kinds.Kind.FRAGMENT_DEFINITION,
|
|
512
|
+
description,
|
|
463
513
|
name: this.parseFragmentName(),
|
|
464
514
|
typeCondition: (this.expectKeyword('on'), this.parseNamedType()),
|
|
465
515
|
directives: this.parseDirectives(false),
|
|
@@ -1364,6 +1414,72 @@ class Parser {
|
|
|
1364
1414
|
}
|
|
1365
1415
|
|
|
1366
1416
|
throw this.unexpected(start);
|
|
1417
|
+
} // Schema Coordinates
|
|
1418
|
+
|
|
1419
|
+
/**
|
|
1420
|
+
* SchemaCoordinate :
|
|
1421
|
+
* - Name
|
|
1422
|
+
* - Name . Name
|
|
1423
|
+
* - Name . Name ( Name : )
|
|
1424
|
+
* - \@ Name
|
|
1425
|
+
* - \@ Name ( Name : )
|
|
1426
|
+
*/
|
|
1427
|
+
|
|
1428
|
+
parseSchemaCoordinate() {
|
|
1429
|
+
const start = this._lexer.token;
|
|
1430
|
+
const ofDirective = this.expectOptionalToken(_tokenKind.TokenKind.AT);
|
|
1431
|
+
const name = this.parseName();
|
|
1432
|
+
let memberName;
|
|
1433
|
+
|
|
1434
|
+
if (!ofDirective && this.expectOptionalToken(_tokenKind.TokenKind.DOT)) {
|
|
1435
|
+
memberName = this.parseName();
|
|
1436
|
+
}
|
|
1437
|
+
|
|
1438
|
+
let argumentName;
|
|
1439
|
+
|
|
1440
|
+
if (
|
|
1441
|
+
(ofDirective || memberName) &&
|
|
1442
|
+
this.expectOptionalToken(_tokenKind.TokenKind.PAREN_L)
|
|
1443
|
+
) {
|
|
1444
|
+
argumentName = this.parseName();
|
|
1445
|
+
this.expectToken(_tokenKind.TokenKind.COLON);
|
|
1446
|
+
this.expectToken(_tokenKind.TokenKind.PAREN_R);
|
|
1447
|
+
}
|
|
1448
|
+
|
|
1449
|
+
if (ofDirective) {
|
|
1450
|
+
if (argumentName) {
|
|
1451
|
+
return this.node(start, {
|
|
1452
|
+
kind: _kinds.Kind.DIRECTIVE_ARGUMENT_COORDINATE,
|
|
1453
|
+
name,
|
|
1454
|
+
argumentName,
|
|
1455
|
+
});
|
|
1456
|
+
}
|
|
1457
|
+
|
|
1458
|
+
return this.node(start, {
|
|
1459
|
+
kind: _kinds.Kind.DIRECTIVE_COORDINATE,
|
|
1460
|
+
name,
|
|
1461
|
+
});
|
|
1462
|
+
} else if (memberName) {
|
|
1463
|
+
if (argumentName) {
|
|
1464
|
+
return this.node(start, {
|
|
1465
|
+
kind: _kinds.Kind.ARGUMENT_COORDINATE,
|
|
1466
|
+
name,
|
|
1467
|
+
fieldName: memberName,
|
|
1468
|
+
argumentName,
|
|
1469
|
+
});
|
|
1470
|
+
}
|
|
1471
|
+
|
|
1472
|
+
return this.node(start, {
|
|
1473
|
+
kind: _kinds.Kind.MEMBER_COORDINATE,
|
|
1474
|
+
name,
|
|
1475
|
+
memberName,
|
|
1476
|
+
});
|
|
1477
|
+
}
|
|
1478
|
+
|
|
1479
|
+
return this.node(start, {
|
|
1480
|
+
kind: _kinds.Kind.TYPE_COORDINATE,
|
|
1481
|
+
name,
|
|
1482
|
+
});
|
|
1367
1483
|
} // Core parsing utility functions
|
|
1368
1484
|
|
|
1369
1485
|
/**
|
package/language/parser.mjs
CHANGED
|
@@ -3,6 +3,7 @@ import { Location, OperationTypeNode } from './ast.mjs';
|
|
|
3
3
|
import { DirectiveLocation } from './directiveLocation.mjs';
|
|
4
4
|
import { Kind } from './kinds.mjs';
|
|
5
5
|
import { isPunctuatorTokenKind, Lexer } from './lexer.mjs';
|
|
6
|
+
import { SchemaCoordinateLexer } from './schemaCoordinateLexer.mjs';
|
|
6
7
|
import { isSource, Source } from './source.mjs';
|
|
7
8
|
import { TokenKind } from './tokenKind.mjs';
|
|
8
9
|
/**
|
|
@@ -70,6 +71,27 @@ export function parseType(source, options) {
|
|
|
70
71
|
parser.expectToken(TokenKind.EOF);
|
|
71
72
|
return type;
|
|
72
73
|
}
|
|
74
|
+
/**
|
|
75
|
+
* Given a string containing a GraphQL Schema Coordinate (ex. `Type.field`),
|
|
76
|
+
* parse the AST for that schema coordinate.
|
|
77
|
+
* Throws GraphQLError if a syntax error is encountered.
|
|
78
|
+
*
|
|
79
|
+
* Consider providing the results to the utility function:
|
|
80
|
+
* resolveASTSchemaCoordinate(). Or calling resolveSchemaCoordinate() directly
|
|
81
|
+
* with an unparsed source.
|
|
82
|
+
*/
|
|
83
|
+
|
|
84
|
+
export function parseSchemaCoordinate(source) {
|
|
85
|
+
const sourceObj = isSource(source) ? source : new Source(source);
|
|
86
|
+
const lexer = new SchemaCoordinateLexer(sourceObj);
|
|
87
|
+
const parser = new Parser(source, {
|
|
88
|
+
lexer,
|
|
89
|
+
});
|
|
90
|
+
parser.expectToken(TokenKind.SOF);
|
|
91
|
+
const coordinate = parser.parseSchemaCoordinate();
|
|
92
|
+
parser.expectToken(TokenKind.EOF);
|
|
93
|
+
return coordinate;
|
|
94
|
+
}
|
|
73
95
|
/**
|
|
74
96
|
* This class is exported only to assist people in implementing their own parsers
|
|
75
97
|
* without duplicating too much code and should be used only as last resort for cases
|
|
@@ -84,9 +106,16 @@ export function parseType(source, options) {
|
|
|
84
106
|
|
|
85
107
|
export class Parser {
|
|
86
108
|
constructor(source, options = {}) {
|
|
87
|
-
const
|
|
88
|
-
|
|
89
|
-
|
|
109
|
+
const { lexer, ..._options } = options;
|
|
110
|
+
|
|
111
|
+
if (lexer) {
|
|
112
|
+
this._lexer = lexer;
|
|
113
|
+
} else {
|
|
114
|
+
const sourceObj = isSource(source) ? source : new Source(source);
|
|
115
|
+
this._lexer = new Lexer(sourceObj);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
this._options = _options;
|
|
90
119
|
this._tokenCounter = 0;
|
|
91
120
|
}
|
|
92
121
|
|
|
@@ -153,6 +182,14 @@ export class Parser {
|
|
|
153
182
|
? this._lexer.lookahead()
|
|
154
183
|
: this._lexer.token;
|
|
155
184
|
|
|
185
|
+
if (hasDescription && keywordToken.kind === TokenKind.BRACE_L) {
|
|
186
|
+
throw syntaxError(
|
|
187
|
+
this._lexer.source,
|
|
188
|
+
this._lexer.token.start,
|
|
189
|
+
'Unexpected description, descriptions are not supported on shorthand queries.',
|
|
190
|
+
);
|
|
191
|
+
}
|
|
192
|
+
|
|
156
193
|
if (keywordToken.kind === TokenKind.NAME) {
|
|
157
194
|
switch (keywordToken.value) {
|
|
158
195
|
case 'schema':
|
|
@@ -180,14 +217,6 @@ export class Parser {
|
|
|
180
217
|
return this.parseDirectiveDefinition();
|
|
181
218
|
}
|
|
182
219
|
|
|
183
|
-
if (hasDescription) {
|
|
184
|
-
throw syntaxError(
|
|
185
|
-
this._lexer.source,
|
|
186
|
-
this._lexer.token.start,
|
|
187
|
-
'Unexpected description, descriptions are supported only on type definitions.',
|
|
188
|
-
);
|
|
189
|
-
}
|
|
190
|
-
|
|
191
220
|
switch (keywordToken.value) {
|
|
192
221
|
case 'query':
|
|
193
222
|
case 'mutation':
|
|
@@ -196,7 +225,17 @@ export class Parser {
|
|
|
196
225
|
|
|
197
226
|
case 'fragment':
|
|
198
227
|
return this.parseFragmentDefinition();
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
if (hasDescription) {
|
|
231
|
+
throw syntaxError(
|
|
232
|
+
this._lexer.source,
|
|
233
|
+
this._lexer.token.start,
|
|
234
|
+
'Unexpected description, only GraphQL definitions support descriptions.',
|
|
235
|
+
);
|
|
236
|
+
}
|
|
199
237
|
|
|
238
|
+
switch (keywordToken.value) {
|
|
200
239
|
case 'extend':
|
|
201
240
|
return this.parseTypeSystemExtension();
|
|
202
241
|
}
|
|
@@ -218,6 +257,7 @@ export class Parser {
|
|
|
218
257
|
return this.node(start, {
|
|
219
258
|
kind: Kind.OPERATION_DEFINITION,
|
|
220
259
|
operation: OperationTypeNode.QUERY,
|
|
260
|
+
description: undefined,
|
|
221
261
|
name: undefined,
|
|
222
262
|
variableDefinitions: [],
|
|
223
263
|
directives: [],
|
|
@@ -225,6 +265,7 @@ export class Parser {
|
|
|
225
265
|
});
|
|
226
266
|
}
|
|
227
267
|
|
|
268
|
+
const description = this.parseDescription();
|
|
228
269
|
const operation = this.parseOperationType();
|
|
229
270
|
let name;
|
|
230
271
|
|
|
@@ -235,6 +276,7 @@ export class Parser {
|
|
|
235
276
|
return this.node(start, {
|
|
236
277
|
kind: Kind.OPERATION_DEFINITION,
|
|
237
278
|
operation,
|
|
279
|
+
description,
|
|
238
280
|
name,
|
|
239
281
|
variableDefinitions: this.parseVariableDefinitions(),
|
|
240
282
|
directives: this.parseDirectives(false),
|
|
@@ -279,6 +321,7 @@ export class Parser {
|
|
|
279
321
|
parseVariableDefinition() {
|
|
280
322
|
return this.node(this._lexer.token, {
|
|
281
323
|
kind: Kind.VARIABLE_DEFINITION,
|
|
324
|
+
description: this.parseDescription(),
|
|
282
325
|
variable: this.parseVariable(),
|
|
283
326
|
type: (this.expectToken(TokenKind.COLON), this.parseTypeReference()),
|
|
284
327
|
defaultValue: this.expectOptionalToken(TokenKind.EQUALS)
|
|
@@ -421,6 +464,7 @@ export class Parser {
|
|
|
421
464
|
|
|
422
465
|
parseFragmentDefinition() {
|
|
423
466
|
const start = this._lexer.token;
|
|
467
|
+
const description = this.parseDescription();
|
|
424
468
|
this.expectKeyword('fragment'); // Legacy support for defining variables within fragments changes
|
|
425
469
|
// the grammar of FragmentDefinition:
|
|
426
470
|
// - fragment FragmentName VariableDefinitions? on TypeCondition Directives? SelectionSet
|
|
@@ -428,6 +472,7 @@ export class Parser {
|
|
|
428
472
|
if (this._options.allowLegacyFragmentVariables === true) {
|
|
429
473
|
return this.node(start, {
|
|
430
474
|
kind: Kind.FRAGMENT_DEFINITION,
|
|
475
|
+
description,
|
|
431
476
|
name: this.parseFragmentName(),
|
|
432
477
|
variableDefinitions: this.parseVariableDefinitions(),
|
|
433
478
|
typeCondition: (this.expectKeyword('on'), this.parseNamedType()),
|
|
@@ -438,6 +483,7 @@ export class Parser {
|
|
|
438
483
|
|
|
439
484
|
return this.node(start, {
|
|
440
485
|
kind: Kind.FRAGMENT_DEFINITION,
|
|
486
|
+
description,
|
|
441
487
|
name: this.parseFragmentName(),
|
|
442
488
|
typeCondition: (this.expectKeyword('on'), this.parseNamedType()),
|
|
443
489
|
directives: this.parseDirectives(false),
|
|
@@ -1323,6 +1369,72 @@ export class Parser {
|
|
|
1323
1369
|
}
|
|
1324
1370
|
|
|
1325
1371
|
throw this.unexpected(start);
|
|
1372
|
+
} // Schema Coordinates
|
|
1373
|
+
|
|
1374
|
+
/**
|
|
1375
|
+
* SchemaCoordinate :
|
|
1376
|
+
* - Name
|
|
1377
|
+
* - Name . Name
|
|
1378
|
+
* - Name . Name ( Name : )
|
|
1379
|
+
* - \@ Name
|
|
1380
|
+
* - \@ Name ( Name : )
|
|
1381
|
+
*/
|
|
1382
|
+
|
|
1383
|
+
parseSchemaCoordinate() {
|
|
1384
|
+
const start = this._lexer.token;
|
|
1385
|
+
const ofDirective = this.expectOptionalToken(TokenKind.AT);
|
|
1386
|
+
const name = this.parseName();
|
|
1387
|
+
let memberName;
|
|
1388
|
+
|
|
1389
|
+
if (!ofDirective && this.expectOptionalToken(TokenKind.DOT)) {
|
|
1390
|
+
memberName = this.parseName();
|
|
1391
|
+
}
|
|
1392
|
+
|
|
1393
|
+
let argumentName;
|
|
1394
|
+
|
|
1395
|
+
if (
|
|
1396
|
+
(ofDirective || memberName) &&
|
|
1397
|
+
this.expectOptionalToken(TokenKind.PAREN_L)
|
|
1398
|
+
) {
|
|
1399
|
+
argumentName = this.parseName();
|
|
1400
|
+
this.expectToken(TokenKind.COLON);
|
|
1401
|
+
this.expectToken(TokenKind.PAREN_R);
|
|
1402
|
+
}
|
|
1403
|
+
|
|
1404
|
+
if (ofDirective) {
|
|
1405
|
+
if (argumentName) {
|
|
1406
|
+
return this.node(start, {
|
|
1407
|
+
kind: Kind.DIRECTIVE_ARGUMENT_COORDINATE,
|
|
1408
|
+
name,
|
|
1409
|
+
argumentName,
|
|
1410
|
+
});
|
|
1411
|
+
}
|
|
1412
|
+
|
|
1413
|
+
return this.node(start, {
|
|
1414
|
+
kind: Kind.DIRECTIVE_COORDINATE,
|
|
1415
|
+
name,
|
|
1416
|
+
});
|
|
1417
|
+
} else if (memberName) {
|
|
1418
|
+
if (argumentName) {
|
|
1419
|
+
return this.node(start, {
|
|
1420
|
+
kind: Kind.ARGUMENT_COORDINATE,
|
|
1421
|
+
name,
|
|
1422
|
+
fieldName: memberName,
|
|
1423
|
+
argumentName,
|
|
1424
|
+
});
|
|
1425
|
+
}
|
|
1426
|
+
|
|
1427
|
+
return this.node(start, {
|
|
1428
|
+
kind: Kind.MEMBER_COORDINATE,
|
|
1429
|
+
name,
|
|
1430
|
+
memberName,
|
|
1431
|
+
});
|
|
1432
|
+
}
|
|
1433
|
+
|
|
1434
|
+
return this.node(start, {
|
|
1435
|
+
kind: Kind.TYPE_COORDINATE,
|
|
1436
|
+
name,
|
|
1437
|
+
});
|
|
1326
1438
|
} // Core parsing utility functions
|
|
1327
1439
|
|
|
1328
1440
|
/**
|
package/language/predicates.d.ts
CHANGED
|
@@ -3,6 +3,7 @@ import type {
|
|
|
3
3
|
ConstValueNode,
|
|
4
4
|
DefinitionNode,
|
|
5
5
|
ExecutableDefinitionNode,
|
|
6
|
+
SchemaCoordinateNode,
|
|
6
7
|
SelectionNode,
|
|
7
8
|
TypeDefinitionNode,
|
|
8
9
|
TypeExtensionNode,
|
|
@@ -31,3 +32,6 @@ export declare function isTypeSystemExtensionNode(
|
|
|
31
32
|
export declare function isTypeExtensionNode(
|
|
32
33
|
node: ASTNode,
|
|
33
34
|
): node is TypeExtensionNode;
|
|
35
|
+
export declare function isSchemaCoordinateNode(
|
|
36
|
+
node: ASTNode,
|
|
37
|
+
): node is SchemaCoordinateNode;
|
package/language/predicates.js
CHANGED
|
@@ -6,6 +6,7 @@ Object.defineProperty(exports, '__esModule', {
|
|
|
6
6
|
exports.isConstValueNode = isConstValueNode;
|
|
7
7
|
exports.isDefinitionNode = isDefinitionNode;
|
|
8
8
|
exports.isExecutableDefinitionNode = isExecutableDefinitionNode;
|
|
9
|
+
exports.isSchemaCoordinateNode = isSchemaCoordinateNode;
|
|
9
10
|
exports.isSelectionNode = isSelectionNode;
|
|
10
11
|
exports.isTypeDefinitionNode = isTypeDefinitionNode;
|
|
11
12
|
exports.isTypeExtensionNode = isTypeExtensionNode;
|
|
@@ -107,3 +108,13 @@ function isTypeExtensionNode(node) {
|
|
|
107
108
|
node.kind === _kinds.Kind.INPUT_OBJECT_TYPE_EXTENSION
|
|
108
109
|
);
|
|
109
110
|
}
|
|
111
|
+
|
|
112
|
+
function isSchemaCoordinateNode(node) {
|
|
113
|
+
return (
|
|
114
|
+
node.kind === _kinds.Kind.TYPE_COORDINATE ||
|
|
115
|
+
node.kind === _kinds.Kind.MEMBER_COORDINATE ||
|
|
116
|
+
node.kind === _kinds.Kind.ARGUMENT_COORDINATE ||
|
|
117
|
+
node.kind === _kinds.Kind.DIRECTIVE_COORDINATE ||
|
|
118
|
+
node.kind === _kinds.Kind.DIRECTIVE_ARGUMENT_COORDINATE
|
|
119
|
+
);
|
|
120
|
+
}
|
package/language/predicates.mjs
CHANGED
|
@@ -79,3 +79,12 @@ export function isTypeExtensionNode(node) {
|
|
|
79
79
|
node.kind === Kind.INPUT_OBJECT_TYPE_EXTENSION
|
|
80
80
|
);
|
|
81
81
|
}
|
|
82
|
+
export function isSchemaCoordinateNode(node) {
|
|
83
|
+
return (
|
|
84
|
+
node.kind === Kind.TYPE_COORDINATE ||
|
|
85
|
+
node.kind === Kind.MEMBER_COORDINATE ||
|
|
86
|
+
node.kind === Kind.ARGUMENT_COORDINATE ||
|
|
87
|
+
node.kind === Kind.DIRECTIVE_COORDINATE ||
|
|
88
|
+
node.kind === Kind.DIRECTIVE_ARGUMENT_COORDINATE
|
|
89
|
+
);
|
|
90
|
+
}
|
package/language/printer.js
CHANGED
|
@@ -33,22 +33,27 @@ const printDocASTReducer = {
|
|
|
33
33
|
},
|
|
34
34
|
OperationDefinition: {
|
|
35
35
|
leave(node) {
|
|
36
|
-
const varDefs =
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
36
|
+
const varDefs = hasMultilineItems(node.variableDefinitions)
|
|
37
|
+
? wrap('(\n', join(node.variableDefinitions, '\n'), '\n)')
|
|
38
|
+
: wrap('(', join(node.variableDefinitions, ', '), ')');
|
|
39
|
+
const prefix =
|
|
40
|
+
wrap('', node.description, '\n') +
|
|
41
|
+
join(
|
|
42
|
+
[
|
|
43
|
+
node.operation,
|
|
44
|
+
join([node.name, varDefs]),
|
|
45
|
+
join(node.directives, ' '),
|
|
46
|
+
],
|
|
47
|
+
' ',
|
|
48
|
+
); // Anonymous queries with no directives or variable definitions can use
|
|
45
49
|
// the query short form.
|
|
46
50
|
|
|
47
51
|
return (prefix === 'query' ? '' : prefix + ' ') + node.selectionSet;
|
|
48
52
|
},
|
|
49
53
|
},
|
|
50
54
|
VariableDefinition: {
|
|
51
|
-
leave: ({ variable, type, defaultValue, directives }) =>
|
|
55
|
+
leave: ({ variable, type, defaultValue, directives, description }) =>
|
|
56
|
+
wrap('', description, '\n') +
|
|
52
57
|
variable +
|
|
53
58
|
': ' +
|
|
54
59
|
type +
|
|
@@ -91,9 +96,15 @@ const printDocASTReducer = {
|
|
|
91
96
|
),
|
|
92
97
|
},
|
|
93
98
|
FragmentDefinition: {
|
|
94
|
-
leave: (
|
|
95
|
-
|
|
96
|
-
|
|
99
|
+
leave: ({
|
|
100
|
+
name,
|
|
101
|
+
typeCondition,
|
|
102
|
+
variableDefinitions,
|
|
103
|
+
directives,
|
|
104
|
+
selectionSet,
|
|
105
|
+
description,
|
|
106
|
+
}) =>
|
|
107
|
+
wrap('', description, '\n') + // Note: fragment variable definitions are experimental and may be changed
|
|
97
108
|
// or removed in the future.
|
|
98
109
|
`fragment ${name}${wrap('(', join(variableDefinitions, ', '), ')')} ` +
|
|
99
110
|
`on ${typeCondition} ${wrap('', join(directives, ' '), ' ')}` +
|
|
@@ -297,6 +308,24 @@ const printDocASTReducer = {
|
|
|
297
308
|
leave: ({ name, directives, fields }) =>
|
|
298
309
|
join(['extend input', name, join(directives, ' '), block(fields)], ' '),
|
|
299
310
|
},
|
|
311
|
+
// Schema Coordinates
|
|
312
|
+
TypeCoordinate: {
|
|
313
|
+
leave: ({ name }) => name,
|
|
314
|
+
},
|
|
315
|
+
MemberCoordinate: {
|
|
316
|
+
leave: ({ name, memberName }) => join([name, wrap('.', memberName)]),
|
|
317
|
+
},
|
|
318
|
+
ArgumentCoordinate: {
|
|
319
|
+
leave: ({ name, fieldName, argumentName }) =>
|
|
320
|
+
join([name, wrap('.', fieldName), wrap('(', argumentName, ':)')]),
|
|
321
|
+
},
|
|
322
|
+
DirectiveCoordinate: {
|
|
323
|
+
leave: ({ name }) => join(['@', name]),
|
|
324
|
+
},
|
|
325
|
+
DirectiveArgumentCoordinate: {
|
|
326
|
+
leave: ({ name, argumentName }) =>
|
|
327
|
+
join(['@', name, wrap('(', argumentName, ':)')]),
|
|
328
|
+
},
|
|
300
329
|
};
|
|
301
330
|
/**
|
|
302
331
|
* Given maybeArray, print an empty string if it is null or empty, otherwise
|
package/language/printer.mjs
CHANGED
|
@@ -23,22 +23,27 @@ const printDocASTReducer = {
|
|
|
23
23
|
},
|
|
24
24
|
OperationDefinition: {
|
|
25
25
|
leave(node) {
|
|
26
|
-
const varDefs =
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
26
|
+
const varDefs = hasMultilineItems(node.variableDefinitions)
|
|
27
|
+
? wrap('(\n', join(node.variableDefinitions, '\n'), '\n)')
|
|
28
|
+
: wrap('(', join(node.variableDefinitions, ', '), ')');
|
|
29
|
+
const prefix =
|
|
30
|
+
wrap('', node.description, '\n') +
|
|
31
|
+
join(
|
|
32
|
+
[
|
|
33
|
+
node.operation,
|
|
34
|
+
join([node.name, varDefs]),
|
|
35
|
+
join(node.directives, ' '),
|
|
36
|
+
],
|
|
37
|
+
' ',
|
|
38
|
+
); // Anonymous queries with no directives or variable definitions can use
|
|
35
39
|
// the query short form.
|
|
36
40
|
|
|
37
41
|
return (prefix === 'query' ? '' : prefix + ' ') + node.selectionSet;
|
|
38
42
|
},
|
|
39
43
|
},
|
|
40
44
|
VariableDefinition: {
|
|
41
|
-
leave: ({ variable, type, defaultValue, directives }) =>
|
|
45
|
+
leave: ({ variable, type, defaultValue, directives, description }) =>
|
|
46
|
+
wrap('', description, '\n') +
|
|
42
47
|
variable +
|
|
43
48
|
': ' +
|
|
44
49
|
type +
|
|
@@ -81,9 +86,15 @@ const printDocASTReducer = {
|
|
|
81
86
|
),
|
|
82
87
|
},
|
|
83
88
|
FragmentDefinition: {
|
|
84
|
-
leave: (
|
|
85
|
-
|
|
86
|
-
|
|
89
|
+
leave: ({
|
|
90
|
+
name,
|
|
91
|
+
typeCondition,
|
|
92
|
+
variableDefinitions,
|
|
93
|
+
directives,
|
|
94
|
+
selectionSet,
|
|
95
|
+
description,
|
|
96
|
+
}) =>
|
|
97
|
+
wrap('', description, '\n') + // Note: fragment variable definitions are experimental and may be changed
|
|
87
98
|
// or removed in the future.
|
|
88
99
|
`fragment ${name}${wrap('(', join(variableDefinitions, ', '), ')')} ` +
|
|
89
100
|
`on ${typeCondition} ${wrap('', join(directives, ' '), ' ')}` +
|
|
@@ -285,6 +296,24 @@ const printDocASTReducer = {
|
|
|
285
296
|
leave: ({ name, directives, fields }) =>
|
|
286
297
|
join(['extend input', name, join(directives, ' '), block(fields)], ' '),
|
|
287
298
|
},
|
|
299
|
+
// Schema Coordinates
|
|
300
|
+
TypeCoordinate: {
|
|
301
|
+
leave: ({ name }) => name,
|
|
302
|
+
},
|
|
303
|
+
MemberCoordinate: {
|
|
304
|
+
leave: ({ name, memberName }) => join([name, wrap('.', memberName)]),
|
|
305
|
+
},
|
|
306
|
+
ArgumentCoordinate: {
|
|
307
|
+
leave: ({ name, fieldName, argumentName }) =>
|
|
308
|
+
join([name, wrap('.', fieldName), wrap('(', argumentName, ':)')]),
|
|
309
|
+
},
|
|
310
|
+
DirectiveCoordinate: {
|
|
311
|
+
leave: ({ name }) => join(['@', name]),
|
|
312
|
+
},
|
|
313
|
+
DirectiveArgumentCoordinate: {
|
|
314
|
+
leave: ({ name, argumentName }) =>
|
|
315
|
+
join(['@', name, wrap('(', argumentName, ':)')]),
|
|
316
|
+
},
|
|
288
317
|
};
|
|
289
318
|
/**
|
|
290
319
|
* Given maybeArray, print an empty string if it is null or empty, otherwise
|