graphql 16.11.0 → 16.12.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.
Files changed (43) hide show
  1. package/README.md +49 -6
  2. package/execution/execute.js +9 -0
  3. package/execution/execute.mjs +9 -0
  4. package/index.d.ts +11 -0
  5. package/index.js +24 -0
  6. package/index.mjs +6 -2
  7. package/language/ast.d.ts +45 -1
  8. package/language/ast.js +14 -1
  9. package/language/ast.mjs +14 -1
  10. package/language/index.d.ts +14 -1
  11. package/language/index.js +12 -0
  12. package/language/index.mjs +8 -1
  13. package/language/kinds.d.ts +6 -0
  14. package/language/kinds.js +5 -0
  15. package/language/kinds.mjs +5 -0
  16. package/language/lexer.d.ts +52 -1
  17. package/language/lexer.js +10 -0
  18. package/language/lexer.mjs +17 -4
  19. package/language/parser.d.ts +30 -3
  20. package/language/parser.js +129 -13
  21. package/language/parser.mjs +123 -11
  22. package/language/predicates.d.ts +4 -0
  23. package/language/predicates.js +11 -0
  24. package/language/predicates.mjs +9 -0
  25. package/language/printer.js +42 -13
  26. package/language/printer.mjs +42 -13
  27. package/language/schemaCoordinateLexer.d.ts +43 -0
  28. package/language/schemaCoordinateLexer.js +171 -0
  29. package/language/schemaCoordinateLexer.mjs +122 -0
  30. package/language/tokenKind.d.ts +1 -0
  31. package/language/tokenKind.js +1 -0
  32. package/language/tokenKind.mjs +1 -0
  33. package/package.json +1 -1
  34. package/utilities/index.d.ts +5 -0
  35. package/utilities/index.js +14 -0
  36. package/utilities/index.mjs +5 -0
  37. package/utilities/resolveSchemaCoordinate.d.ts +80 -0
  38. package/utilities/resolveSchemaCoordinate.js +260 -0
  39. package/utilities/resolveSchemaCoordinate.mjs +243 -0
  40. package/validation/rules/ValuesOfCorrectTypeRule.js +2 -36
  41. package/validation/rules/ValuesOfCorrectTypeRule.mjs +2 -35
  42. package/version.js +2 -2
  43. package/version.mjs +2 -2
@@ -3,6 +3,13 @@ import { Token } from './ast.mjs';
3
3
  import { dedentBlockStringLines } from './blockString.mjs';
4
4
  import { isDigit, isNameContinue, isNameStart } from './characterClasses.mjs';
5
5
  import { TokenKind } from './tokenKind.mjs';
6
+ /**
7
+ * A Lexer interface which provides common properties and methods required for
8
+ * lexing GraphQL source.
9
+ *
10
+ * @internal
11
+ */
12
+
6
13
  /**
7
14
  * Given a Source object, creates a Lexer for that source.
8
15
  * A Lexer is a stateful stream generator in that every time
@@ -11,7 +18,6 @@ import { TokenKind } from './tokenKind.mjs';
11
18
  * EOF, after which the lexer will repeatedly return the same EOF token
12
19
  * whenever called.
13
20
  */
14
-
15
21
  export class Lexer {
16
22
  /**
17
23
  * The previously focused non-ignored token.
@@ -87,6 +93,7 @@ export function isPunctuatorTokenKind(kind) {
87
93
  kind === TokenKind.AMP ||
88
94
  kind === TokenKind.PAREN_L ||
89
95
  kind === TokenKind.PAREN_R ||
96
+ kind === TokenKind.DOT ||
90
97
  kind === TokenKind.SPREAD ||
91
98
  kind === TokenKind.COLON ||
92
99
  kind === TokenKind.EQUALS ||
@@ -141,9 +148,11 @@ function isTrailingSurrogate(code) {
141
148
  *
142
149
  * Printable ASCII is printed quoted, while other points are printed in Unicode
143
150
  * code point form (ie. U+1234).
151
+ *
152
+ * @internal
144
153
  */
145
154
 
146
- function printCodePointAt(lexer, location) {
155
+ export function printCodePointAt(lexer, location) {
147
156
  const code = lexer.source.body.codePointAt(location);
148
157
 
149
158
  if (code === undefined) {
@@ -158,9 +167,11 @@ function printCodePointAt(lexer, location) {
158
167
  }
159
168
  /**
160
169
  * Create a token with line and column location information.
170
+ *
171
+ * @internal
161
172
  */
162
173
 
163
- function createToken(lexer, kind, start, end, value) {
174
+ export function createToken(lexer, kind, start, end, value) {
164
175
  const line = lexer.line;
165
176
  const col = 1 + start - lexer.lineStart;
166
177
  return new Token(kind, start, end, line, col, value);
@@ -875,9 +886,11 @@ function readBlockString(lexer, start) {
875
886
  * Name ::
876
887
  * - NameStart NameContinue* [lookahead != NameContinue]
877
888
  * ```
889
+ *
890
+ * @internal
878
891
  */
879
892
 
880
- function readName(lexer, start) {
893
+ export function readName(lexer, start) {
881
894
  const body = lexer.source.body;
882
895
  const bodyLength = body.length;
883
896
  let position = start + 1;
@@ -36,6 +36,7 @@ import type {
36
36
  OperationTypeDefinitionNode,
37
37
  ScalarTypeDefinitionNode,
38
38
  ScalarTypeExtensionNode,
39
+ SchemaCoordinateNode,
39
40
  SchemaDefinitionNode,
40
41
  SchemaExtensionNode,
41
42
  SelectionNode,
@@ -51,7 +52,7 @@ import type {
51
52
  VariableNode,
52
53
  } from './ast';
53
54
  import { Location, OperationTypeNode } from './ast';
54
- import { Lexer } from './lexer';
55
+ import type { LexerInterface } from './lexer';
55
56
  import { Source } from './source';
56
57
  import { TokenKind } from './tokenKind';
57
58
  /**
@@ -88,6 +89,11 @@ export interface ParseOptions {
88
89
  * ```
89
90
  */
90
91
  allowLegacyFragmentVariables?: boolean;
92
+ /**
93
+ * You may override the Lexer class used to lex the source; this is used by
94
+ * schema coordinates to introduce a lexer with a restricted syntax.
95
+ */
96
+ lexer?: LexerInterface | undefined;
91
97
  }
92
98
  /**
93
99
  * Given a GraphQL source, parses it into a Document.
@@ -133,6 +139,18 @@ export declare function parseType(
133
139
  source: string | Source,
134
140
  options?: ParseOptions | undefined,
135
141
  ): TypeNode;
142
+ /**
143
+ * Given a string containing a GraphQL Schema Coordinate (ex. `Type.field`),
144
+ * parse the AST for that schema coordinate.
145
+ * Throws GraphQLError if a syntax error is encountered.
146
+ *
147
+ * Consider providing the results to the utility function:
148
+ * resolveASTSchemaCoordinate(). Or calling resolveSchemaCoordinate() directly
149
+ * with an unparsed source.
150
+ */
151
+ export declare function parseSchemaCoordinate(
152
+ source: string | Source,
153
+ ): SchemaCoordinateNode;
136
154
  /**
137
155
  * This class is exported only to assist people in implementing their own parsers
138
156
  * without duplicating too much code and should be used only as last resort for cases
@@ -145,8 +163,8 @@ export declare function parseType(
145
163
  * @internal
146
164
  */
147
165
  export declare class Parser {
148
- protected _options: ParseOptions;
149
- protected _lexer: Lexer;
166
+ protected _options: Omit<ParseOptions, 'lexer'>;
167
+ protected _lexer: LexerInterface;
150
168
  protected _tokenCounter: number;
151
169
  constructor(source: string | Source, options?: ParseOptions);
152
170
  get tokenCount(): number;
@@ -490,6 +508,15 @@ export declare class Parser {
490
508
  */
491
509
  parseDirectiveLocations(): Array<NameNode>;
492
510
  parseDirectiveLocation(): NameNode;
511
+ /**
512
+ * SchemaCoordinate :
513
+ * - Name
514
+ * - Name . Name
515
+ * - Name . Name ( Name : )
516
+ * - \@ Name
517
+ * - \@ Name ( Name : )
518
+ */
519
+ parseSchemaCoordinate(): SchemaCoordinateNode;
493
520
  /**
494
521
  * Returns a node that, if configured to do so, sets a "loc" field as a
495
522
  * location object, used to identify the place in the source that created a
@@ -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 sourceObj = (0, _source.isSource)(source)
102
- ? source
103
- : new _source.Source(source);
104
- this._lexer = new _lexer.Lexer(sourceObj);
105
- this._options = options;
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
  /**
@@ -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 sourceObj = isSource(source) ? source : new Source(source);
88
- this._lexer = new Lexer(sourceObj);
89
- this._options = options;
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
  /**
@@ -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;
@@ -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
+ }
@@ -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
+ }