UNPKG

40.1 kBJavaScriptView Raw
1import inspect from '../jsutils/inspect';
2import devAssert from '../jsutils/devAssert';
3import defineToJSON from '../jsutils/defineToJSON';
4import { syntaxError } from '../error/syntaxError';
5import { Kind } from './kinds';
6import { Source } from './source';
7import { createLexer } from './lexer';
8import { DirectiveLocation } from './directiveLocation';
9import { TokenKind } from './tokenKind';
10
11/**
12 * Given a GraphQL source, parses it into a Document.
13 * Throws GraphQLError if a syntax error is encountered.
14 */
15export function parse(source, options) {
16 var parser = new Parser(source, options);
17 return parser.parseDocument();
18}
19/**
20 * Given a string containing a GraphQL value (ex. `[42]`), parse the AST for
21 * that value.
22 * Throws GraphQLError if a syntax error is encountered.
23 *
24 * This is useful within tools that operate upon GraphQL Values directly and
25 * in isolation of complete GraphQL documents.
26 *
27 * Consider providing the results to the utility function: valueFromAST().
28 */
29
30export function parseValue(source, options) {
31 var parser = new Parser(source, options);
32 parser.expectToken(TokenKind.SOF);
33 var value = parser.parseValueLiteral(false);
34 parser.expectToken(TokenKind.EOF);
35 return value;
36}
37/**
38 * Given a string containing a GraphQL Type (ex. `[Int!]`), parse the AST for
39 * that type.
40 * Throws GraphQLError if a syntax error is encountered.
41 *
42 * This is useful within tools that operate upon GraphQL Types directly and
43 * in isolation of complete GraphQL documents.
44 *
45 * Consider providing the results to the utility function: typeFromAST().
46 */
47
48export function parseType(source, options) {
49 var parser = new Parser(source, options);
50 parser.expectToken(TokenKind.SOF);
51 var type = parser.parseTypeReference();
52 parser.expectToken(TokenKind.EOF);
53 return type;
54}
55
56var Parser =
57/*#__PURE__*/
58function () {
59 function Parser(source, options) {
60 var sourceObj = typeof source === 'string' ? new Source(source) : source;
61 sourceObj instanceof Source || devAssert(0, "Must provide Source. Received: ".concat(inspect(sourceObj)));
62 this._lexer = createLexer(sourceObj);
63 this._options = options || {};
64 }
65 /**
66 * Converts a name lex token into a name parse node.
67 */
68
69
70 var _proto = Parser.prototype;
71
72 _proto.parseName = function parseName() {
73 var token = this.expectToken(TokenKind.NAME);
74 return {
75 kind: Kind.NAME,
76 value: token.value,
77 loc: this.loc(token)
78 };
79 } // Implements the parsing rules in the Document section.
80
81 /**
82 * Document : Definition+
83 */
84 ;
85
86 _proto.parseDocument = function parseDocument() {
87 var start = this._lexer.token;
88 return {
89 kind: Kind.DOCUMENT,
90 definitions: this.many(TokenKind.SOF, this.parseDefinition, TokenKind.EOF),
91 loc: this.loc(start)
92 };
93 }
94 /**
95 * Definition :
96 * - ExecutableDefinition
97 * - TypeSystemDefinition
98 * - TypeSystemExtension
99 *
100 * ExecutableDefinition :
101 * - OperationDefinition
102 * - FragmentDefinition
103 */
104 ;
105
106 _proto.parseDefinition = function parseDefinition() {
107 if (this.peek(TokenKind.NAME)) {
108 switch (this._lexer.token.value) {
109 case 'query':
110 case 'mutation':
111 case 'subscription':
112 return this.parseOperationDefinition();
113
114 case 'fragment':
115 return this.parseFragmentDefinition();
116
117 case 'schema':
118 case 'scalar':
119 case 'type':
120 case 'interface':
121 case 'union':
122 case 'enum':
123 case 'input':
124 case 'directive':
125 return this.parseTypeSystemDefinition();
126
127 case 'extend':
128 return this.parseTypeSystemExtension();
129 }
130 } else if (this.peek(TokenKind.BRACE_L)) {
131 return this.parseOperationDefinition();
132 } else if (this.peekDescription()) {
133 return this.parseTypeSystemDefinition();
134 }
135
136 throw this.unexpected();
137 } // Implements the parsing rules in the Operations section.
138
139 /**
140 * OperationDefinition :
141 * - SelectionSet
142 * - OperationType Name? VariableDefinitions? Directives? SelectionSet
143 */
144 ;
145
146 _proto.parseOperationDefinition = function parseOperationDefinition() {
147 var start = this._lexer.token;
148
149 if (this.peek(TokenKind.BRACE_L)) {
150 return {
151 kind: Kind.OPERATION_DEFINITION,
152 operation: 'query',
153 name: undefined,
154 variableDefinitions: [],
155 directives: [],
156 selectionSet: this.parseSelectionSet(),
157 loc: this.loc(start)
158 };
159 }
160
161 var operation = this.parseOperationType();
162 var name;
163
164 if (this.peek(TokenKind.NAME)) {
165 name = this.parseName();
166 }
167
168 return {
169 kind: Kind.OPERATION_DEFINITION,
170 operation: operation,
171 name: name,
172 variableDefinitions: this.parseVariableDefinitions(),
173 directives: this.parseDirectives(false),
174 selectionSet: this.parseSelectionSet(),
175 loc: this.loc(start)
176 };
177 }
178 /**
179 * OperationType : one of query mutation subscription
180 */
181 ;
182
183 _proto.parseOperationType = function parseOperationType() {
184 var operationToken = this.expectToken(TokenKind.NAME);
185
186 switch (operationToken.value) {
187 case 'query':
188 return 'query';
189
190 case 'mutation':
191 return 'mutation';
192
193 case 'subscription':
194 return 'subscription';
195 }
196
197 throw this.unexpected(operationToken);
198 }
199 /**
200 * VariableDefinitions : ( VariableDefinition+ )
201 */
202 ;
203
204 _proto.parseVariableDefinitions = function parseVariableDefinitions() {
205 return this.optionalMany(TokenKind.PAREN_L, this.parseVariableDefinition, TokenKind.PAREN_R);
206 }
207 /**
208 * VariableDefinition : Variable : Type DefaultValue? Directives[Const]?
209 */
210 ;
211
212 _proto.parseVariableDefinition = function parseVariableDefinition() {
213 var start = this._lexer.token;
214 return {
215 kind: Kind.VARIABLE_DEFINITION,
216 variable: this.parseVariable(),
217 type: (this.expectToken(TokenKind.COLON), this.parseTypeReference()),
218 defaultValue: this.expectOptionalToken(TokenKind.EQUALS) ? this.parseValueLiteral(true) : undefined,
219 directives: this.parseDirectives(true),
220 loc: this.loc(start)
221 };
222 }
223 /**
224 * Variable : $ Name
225 */
226 ;
227
228 _proto.parseVariable = function parseVariable() {
229 var start = this._lexer.token;
230 this.expectToken(TokenKind.DOLLAR);
231 return {
232 kind: Kind.VARIABLE,
233 name: this.parseName(),
234 loc: this.loc(start)
235 };
236 }
237 /**
238 * SelectionSet : { Selection+ }
239 */
240 ;
241
242 _proto.parseSelectionSet = function parseSelectionSet() {
243 var start = this._lexer.token;
244 return {
245 kind: Kind.SELECTION_SET,
246 selections: this.many(TokenKind.BRACE_L, this.parseSelection, TokenKind.BRACE_R),
247 loc: this.loc(start)
248 };
249 }
250 /**
251 * Selection :
252 * - Field
253 * - FragmentSpread
254 * - InlineFragment
255 */
256 ;
257
258 _proto.parseSelection = function parseSelection() {
259 return this.peek(TokenKind.SPREAD) ? this.parseFragment() : this.parseField();
260 }
261 /**
262 * Field : Alias? Name Arguments? Directives? SelectionSet?
263 *
264 * Alias : Name :
265 */
266 ;
267
268 _proto.parseField = function parseField() {
269 var start = this._lexer.token;
270 var nameOrAlias = this.parseName();
271 var alias;
272 var name;
273
274 if (this.expectOptionalToken(TokenKind.COLON)) {
275 alias = nameOrAlias;
276 name = this.parseName();
277 } else {
278 name = nameOrAlias;
279 }
280
281 return {
282 kind: Kind.FIELD,
283 alias: alias,
284 name: name,
285 arguments: this.parseArguments(false),
286 directives: this.parseDirectives(false),
287 selectionSet: this.peek(TokenKind.BRACE_L) ? this.parseSelectionSet() : undefined,
288 loc: this.loc(start)
289 };
290 }
291 /**
292 * Arguments[Const] : ( Argument[?Const]+ )
293 */
294 ;
295
296 _proto.parseArguments = function parseArguments(isConst) {
297 var item = isConst ? this.parseConstArgument : this.parseArgument;
298 return this.optionalMany(TokenKind.PAREN_L, item, TokenKind.PAREN_R);
299 }
300 /**
301 * Argument[Const] : Name : Value[?Const]
302 */
303 ;
304
305 _proto.parseArgument = function parseArgument() {
306 var start = this._lexer.token;
307 var name = this.parseName();
308 this.expectToken(TokenKind.COLON);
309 return {
310 kind: Kind.ARGUMENT,
311 name: name,
312 value: this.parseValueLiteral(false),
313 loc: this.loc(start)
314 };
315 };
316
317 _proto.parseConstArgument = function parseConstArgument() {
318 var start = this._lexer.token;
319 return {
320 kind: Kind.ARGUMENT,
321 name: this.parseName(),
322 value: (this.expectToken(TokenKind.COLON), this.parseValueLiteral(true)),
323 loc: this.loc(start)
324 };
325 } // Implements the parsing rules in the Fragments section.
326
327 /**
328 * Corresponds to both FragmentSpread and InlineFragment in the spec.
329 *
330 * FragmentSpread : ... FragmentName Directives?
331 *
332 * InlineFragment : ... TypeCondition? Directives? SelectionSet
333 */
334 ;
335
336 _proto.parseFragment = function parseFragment() {
337 var start = this._lexer.token;
338 this.expectToken(TokenKind.SPREAD);
339 var hasTypeCondition = this.expectOptionalKeyword('on');
340
341 if (!hasTypeCondition && this.peek(TokenKind.NAME)) {
342 return {
343 kind: Kind.FRAGMENT_SPREAD,
344 name: this.parseFragmentName(),
345 directives: this.parseDirectives(false),
346 loc: this.loc(start)
347 };
348 }
349
350 return {
351 kind: Kind.INLINE_FRAGMENT,
352 typeCondition: hasTypeCondition ? this.parseNamedType() : undefined,
353 directives: this.parseDirectives(false),
354 selectionSet: this.parseSelectionSet(),
355 loc: this.loc(start)
356 };
357 }
358 /**
359 * FragmentDefinition :
360 * - fragment FragmentName on TypeCondition Directives? SelectionSet
361 *
362 * TypeCondition : NamedType
363 */
364 ;
365
366 _proto.parseFragmentDefinition = function parseFragmentDefinition() {
367 var start = this._lexer.token;
368 this.expectKeyword('fragment'); // Experimental support for defining variables within fragments changes
369 // the grammar of FragmentDefinition:
370 // - fragment FragmentName VariableDefinitions? on TypeCondition Directives? SelectionSet
371
372 if (this._options.experimentalFragmentVariables) {
373 return {
374 kind: Kind.FRAGMENT_DEFINITION,
375 name: this.parseFragmentName(),
376 variableDefinitions: this.parseVariableDefinitions(),
377 typeCondition: (this.expectKeyword('on'), this.parseNamedType()),
378 directives: this.parseDirectives(false),
379 selectionSet: this.parseSelectionSet(),
380 loc: this.loc(start)
381 };
382 }
383
384 return {
385 kind: Kind.FRAGMENT_DEFINITION,
386 name: this.parseFragmentName(),
387 typeCondition: (this.expectKeyword('on'), this.parseNamedType()),
388 directives: this.parseDirectives(false),
389 selectionSet: this.parseSelectionSet(),
390 loc: this.loc(start)
391 };
392 }
393 /**
394 * FragmentName : Name but not `on`
395 */
396 ;
397
398 _proto.parseFragmentName = function parseFragmentName() {
399 if (this._lexer.token.value === 'on') {
400 throw this.unexpected();
401 }
402
403 return this.parseName();
404 } // Implements the parsing rules in the Values section.
405
406 /**
407 * Value[Const] :
408 * - [~Const] Variable
409 * - IntValue
410 * - FloatValue
411 * - StringValue
412 * - BooleanValue
413 * - NullValue
414 * - EnumValue
415 * - ListValue[?Const]
416 * - ObjectValue[?Const]
417 *
418 * BooleanValue : one of `true` `false`
419 *
420 * NullValue : `null`
421 *
422 * EnumValue : Name but not `true`, `false` or `null`
423 */
424 ;
425
426 _proto.parseValueLiteral = function parseValueLiteral(isConst) {
427 var token = this._lexer.token;
428
429 switch (token.kind) {
430 case TokenKind.BRACKET_L:
431 return this.parseList(isConst);
432
433 case TokenKind.BRACE_L:
434 return this.parseObject(isConst);
435
436 case TokenKind.INT:
437 this._lexer.advance();
438
439 return {
440 kind: Kind.INT,
441 value: token.value,
442 loc: this.loc(token)
443 };
444
445 case TokenKind.FLOAT:
446 this._lexer.advance();
447
448 return {
449 kind: Kind.FLOAT,
450 value: token.value,
451 loc: this.loc(token)
452 };
453
454 case TokenKind.STRING:
455 case TokenKind.BLOCK_STRING:
456 return this.parseStringLiteral();
457
458 case TokenKind.NAME:
459 if (token.value === 'true' || token.value === 'false') {
460 this._lexer.advance();
461
462 return {
463 kind: Kind.BOOLEAN,
464 value: token.value === 'true',
465 loc: this.loc(token)
466 };
467 } else if (token.value === 'null') {
468 this._lexer.advance();
469
470 return {
471 kind: Kind.NULL,
472 loc: this.loc(token)
473 };
474 }
475
476 this._lexer.advance();
477
478 return {
479 kind: Kind.ENUM,
480 value: token.value,
481 loc: this.loc(token)
482 };
483
484 case TokenKind.DOLLAR:
485 if (!isConst) {
486 return this.parseVariable();
487 }
488
489 break;
490 }
491
492 throw this.unexpected();
493 };
494
495 _proto.parseStringLiteral = function parseStringLiteral() {
496 var token = this._lexer.token;
497
498 this._lexer.advance();
499
500 return {
501 kind: Kind.STRING,
502 value: token.value,
503 block: token.kind === TokenKind.BLOCK_STRING,
504 loc: this.loc(token)
505 };
506 }
507 /**
508 * ListValue[Const] :
509 * - [ ]
510 * - [ Value[?Const]+ ]
511 */
512 ;
513
514 _proto.parseList = function parseList(isConst) {
515 var _this = this;
516
517 var start = this._lexer.token;
518
519 var item = function item() {
520 return _this.parseValueLiteral(isConst);
521 };
522
523 return {
524 kind: Kind.LIST,
525 values: this.any(TokenKind.BRACKET_L, item, TokenKind.BRACKET_R),
526 loc: this.loc(start)
527 };
528 }
529 /**
530 * ObjectValue[Const] :
531 * - { }
532 * - { ObjectField[?Const]+ }
533 */
534 ;
535
536 _proto.parseObject = function parseObject(isConst) {
537 var _this2 = this;
538
539 var start = this._lexer.token;
540
541 var item = function item() {
542 return _this2.parseObjectField(isConst);
543 };
544
545 return {
546 kind: Kind.OBJECT,
547 fields: this.any(TokenKind.BRACE_L, item, TokenKind.BRACE_R),
548 loc: this.loc(start)
549 };
550 }
551 /**
552 * ObjectField[Const] : Name : Value[?Const]
553 */
554 ;
555
556 _proto.parseObjectField = function parseObjectField(isConst) {
557 var start = this._lexer.token;
558 var name = this.parseName();
559 this.expectToken(TokenKind.COLON);
560 return {
561 kind: Kind.OBJECT_FIELD,
562 name: name,
563 value: this.parseValueLiteral(isConst),
564 loc: this.loc(start)
565 };
566 } // Implements the parsing rules in the Directives section.
567
568 /**
569 * Directives[Const] : Directive[?Const]+
570 */
571 ;
572
573 _proto.parseDirectives = function parseDirectives(isConst) {
574 var directives = [];
575
576 while (this.peek(TokenKind.AT)) {
577 directives.push(this.parseDirective(isConst));
578 }
579
580 return directives;
581 }
582 /**
583 * Directive[Const] : @ Name Arguments[?Const]?
584 */
585 ;
586
587 _proto.parseDirective = function parseDirective(isConst) {
588 var start = this._lexer.token;
589 this.expectToken(TokenKind.AT);
590 return {
591 kind: Kind.DIRECTIVE,
592 name: this.parseName(),
593 arguments: this.parseArguments(isConst),
594 loc: this.loc(start)
595 };
596 } // Implements the parsing rules in the Types section.
597
598 /**
599 * Type :
600 * - NamedType
601 * - ListType
602 * - NonNullType
603 */
604 ;
605
606 _proto.parseTypeReference = function parseTypeReference() {
607 var start = this._lexer.token;
608 var type;
609
610 if (this.expectOptionalToken(TokenKind.BRACKET_L)) {
611 type = this.parseTypeReference();
612 this.expectToken(TokenKind.BRACKET_R);
613 type = {
614 kind: Kind.LIST_TYPE,
615 type: type,
616 loc: this.loc(start)
617 };
618 } else {
619 type = this.parseNamedType();
620 }
621
622 if (this.expectOptionalToken(TokenKind.BANG)) {
623 return {
624 kind: Kind.NON_NULL_TYPE,
625 type: type,
626 loc: this.loc(start)
627 };
628 }
629
630 return type;
631 }
632 /**
633 * NamedType : Name
634 */
635 ;
636
637 _proto.parseNamedType = function parseNamedType() {
638 var start = this._lexer.token;
639 return {
640 kind: Kind.NAMED_TYPE,
641 name: this.parseName(),
642 loc: this.loc(start)
643 };
644 } // Implements the parsing rules in the Type Definition section.
645
646 /**
647 * TypeSystemDefinition :
648 * - SchemaDefinition
649 * - TypeDefinition
650 * - DirectiveDefinition
651 *
652 * TypeDefinition :
653 * - ScalarTypeDefinition
654 * - ObjectTypeDefinition
655 * - InterfaceTypeDefinition
656 * - UnionTypeDefinition
657 * - EnumTypeDefinition
658 * - InputObjectTypeDefinition
659 */
660 ;
661
662 _proto.parseTypeSystemDefinition = function parseTypeSystemDefinition() {
663 // Many definitions begin with a description and require a lookahead.
664 var keywordToken = this.peekDescription() ? this._lexer.lookahead() : this._lexer.token;
665
666 if (keywordToken.kind === TokenKind.NAME) {
667 switch (keywordToken.value) {
668 case 'schema':
669 return this.parseSchemaDefinition();
670
671 case 'scalar':
672 return this.parseScalarTypeDefinition();
673
674 case 'type':
675 return this.parseObjectTypeDefinition();
676
677 case 'interface':
678 return this.parseInterfaceTypeDefinition();
679
680 case 'union':
681 return this.parseUnionTypeDefinition();
682
683 case 'enum':
684 return this.parseEnumTypeDefinition();
685
686 case 'input':
687 return this.parseInputObjectTypeDefinition();
688
689 case 'directive':
690 return this.parseDirectiveDefinition();
691 }
692 }
693
694 throw this.unexpected(keywordToken);
695 };
696
697 _proto.peekDescription = function peekDescription() {
698 return this.peek(TokenKind.STRING) || this.peek(TokenKind.BLOCK_STRING);
699 }
700 /**
701 * Description : StringValue
702 */
703 ;
704
705 _proto.parseDescription = function parseDescription() {
706 if (this.peekDescription()) {
707 return this.parseStringLiteral();
708 }
709 }
710 /**
711 * SchemaDefinition : schema Directives[Const]? { OperationTypeDefinition+ }
712 */
713 ;
714
715 _proto.parseSchemaDefinition = function parseSchemaDefinition() {
716 var start = this._lexer.token;
717 this.expectKeyword('schema');
718 var directives = this.parseDirectives(true);
719 var operationTypes = this.many(TokenKind.BRACE_L, this.parseOperationTypeDefinition, TokenKind.BRACE_R);
720 return {
721 kind: Kind.SCHEMA_DEFINITION,
722 directives: directives,
723 operationTypes: operationTypes,
724 loc: this.loc(start)
725 };
726 }
727 /**
728 * OperationTypeDefinition : OperationType : NamedType
729 */
730 ;
731
732 _proto.parseOperationTypeDefinition = function parseOperationTypeDefinition() {
733 var start = this._lexer.token;
734 var operation = this.parseOperationType();
735 this.expectToken(TokenKind.COLON);
736 var type = this.parseNamedType();
737 return {
738 kind: Kind.OPERATION_TYPE_DEFINITION,
739 operation: operation,
740 type: type,
741 loc: this.loc(start)
742 };
743 }
744 /**
745 * ScalarTypeDefinition : Description? scalar Name Directives[Const]?
746 */
747 ;
748
749 _proto.parseScalarTypeDefinition = function parseScalarTypeDefinition() {
750 var start = this._lexer.token;
751 var description = this.parseDescription();
752 this.expectKeyword('scalar');
753 var name = this.parseName();
754 var directives = this.parseDirectives(true);
755 return {
756 kind: Kind.SCALAR_TYPE_DEFINITION,
757 description: description,
758 name: name,
759 directives: directives,
760 loc: this.loc(start)
761 };
762 }
763 /**
764 * ObjectTypeDefinition :
765 * Description?
766 * type Name ImplementsInterfaces? Directives[Const]? FieldsDefinition?
767 */
768 ;
769
770 _proto.parseObjectTypeDefinition = function parseObjectTypeDefinition() {
771 var start = this._lexer.token;
772 var description = this.parseDescription();
773 this.expectKeyword('type');
774 var name = this.parseName();
775 var interfaces = this.parseImplementsInterfaces();
776 var directives = this.parseDirectives(true);
777 var fields = this.parseFieldsDefinition();
778 return {
779 kind: Kind.OBJECT_TYPE_DEFINITION,
780 description: description,
781 name: name,
782 interfaces: interfaces,
783 directives: directives,
784 fields: fields,
785 loc: this.loc(start)
786 };
787 }
788 /**
789 * ImplementsInterfaces :
790 * - implements `&`? NamedType
791 * - ImplementsInterfaces & NamedType
792 */
793 ;
794
795 _proto.parseImplementsInterfaces = function parseImplementsInterfaces() {
796 var types = [];
797
798 if (this.expectOptionalKeyword('implements')) {
799 // Optional leading ampersand
800 this.expectOptionalToken(TokenKind.AMP);
801
802 do {
803 types.push(this.parseNamedType());
804 } while (this.expectOptionalToken(TokenKind.AMP) || // Legacy support for the SDL?
805 this._options.allowLegacySDLImplementsInterfaces && this.peek(TokenKind.NAME));
806 }
807
808 return types;
809 }
810 /**
811 * FieldsDefinition : { FieldDefinition+ }
812 */
813 ;
814
815 _proto.parseFieldsDefinition = function parseFieldsDefinition() {
816 // Legacy support for the SDL?
817 if (this._options.allowLegacySDLEmptyFields && this.peek(TokenKind.BRACE_L) && this._lexer.lookahead().kind === TokenKind.BRACE_R) {
818 this._lexer.advance();
819
820 this._lexer.advance();
821
822 return [];
823 }
824
825 return this.optionalMany(TokenKind.BRACE_L, this.parseFieldDefinition, TokenKind.BRACE_R);
826 }
827 /**
828 * FieldDefinition :
829 * - Description? Name ArgumentsDefinition? : Type Directives[Const]?
830 */
831 ;
832
833 _proto.parseFieldDefinition = function parseFieldDefinition() {
834 var start = this._lexer.token;
835 var description = this.parseDescription();
836 var name = this.parseName();
837 var args = this.parseArgumentDefs();
838 this.expectToken(TokenKind.COLON);
839 var type = this.parseTypeReference();
840 var directives = this.parseDirectives(true);
841 return {
842 kind: Kind.FIELD_DEFINITION,
843 description: description,
844 name: name,
845 arguments: args,
846 type: type,
847 directives: directives,
848 loc: this.loc(start)
849 };
850 }
851 /**
852 * ArgumentsDefinition : ( InputValueDefinition+ )
853 */
854 ;
855
856 _proto.parseArgumentDefs = function parseArgumentDefs() {
857 return this.optionalMany(TokenKind.PAREN_L, this.parseInputValueDef, TokenKind.PAREN_R);
858 }
859 /**
860 * InputValueDefinition :
861 * - Description? Name : Type DefaultValue? Directives[Const]?
862 */
863 ;
864
865 _proto.parseInputValueDef = function parseInputValueDef() {
866 var start = this._lexer.token;
867 var description = this.parseDescription();
868 var name = this.parseName();
869 this.expectToken(TokenKind.COLON);
870 var type = this.parseTypeReference();
871 var defaultValue;
872
873 if (this.expectOptionalToken(TokenKind.EQUALS)) {
874 defaultValue = this.parseValueLiteral(true);
875 }
876
877 var directives = this.parseDirectives(true);
878 return {
879 kind: Kind.INPUT_VALUE_DEFINITION,
880 description: description,
881 name: name,
882 type: type,
883 defaultValue: defaultValue,
884 directives: directives,
885 loc: this.loc(start)
886 };
887 }
888 /**
889 * InterfaceTypeDefinition :
890 * - Description? interface Name Directives[Const]? FieldsDefinition?
891 */
892 ;
893
894 _proto.parseInterfaceTypeDefinition = function parseInterfaceTypeDefinition() {
895 var start = this._lexer.token;
896 var description = this.parseDescription();
897 this.expectKeyword('interface');
898 var name = this.parseName();
899 var directives = this.parseDirectives(true);
900 var fields = this.parseFieldsDefinition();
901 return {
902 kind: Kind.INTERFACE_TYPE_DEFINITION,
903 description: description,
904 name: name,
905 directives: directives,
906 fields: fields,
907 loc: this.loc(start)
908 };
909 }
910 /**
911 * UnionTypeDefinition :
912 * - Description? union Name Directives[Const]? UnionMemberTypes?
913 */
914 ;
915
916 _proto.parseUnionTypeDefinition = function parseUnionTypeDefinition() {
917 var start = this._lexer.token;
918 var description = this.parseDescription();
919 this.expectKeyword('union');
920 var name = this.parseName();
921 var directives = this.parseDirectives(true);
922 var types = this.parseUnionMemberTypes();
923 return {
924 kind: Kind.UNION_TYPE_DEFINITION,
925 description: description,
926 name: name,
927 directives: directives,
928 types: types,
929 loc: this.loc(start)
930 };
931 }
932 /**
933 * UnionMemberTypes :
934 * - = `|`? NamedType
935 * - UnionMemberTypes | NamedType
936 */
937 ;
938
939 _proto.parseUnionMemberTypes = function parseUnionMemberTypes() {
940 var types = [];
941
942 if (this.expectOptionalToken(TokenKind.EQUALS)) {
943 // Optional leading pipe
944 this.expectOptionalToken(TokenKind.PIPE);
945
946 do {
947 types.push(this.parseNamedType());
948 } while (this.expectOptionalToken(TokenKind.PIPE));
949 }
950
951 return types;
952 }
953 /**
954 * EnumTypeDefinition :
955 * - Description? enum Name Directives[Const]? EnumValuesDefinition?
956 */
957 ;
958
959 _proto.parseEnumTypeDefinition = function parseEnumTypeDefinition() {
960 var start = this._lexer.token;
961 var description = this.parseDescription();
962 this.expectKeyword('enum');
963 var name = this.parseName();
964 var directives = this.parseDirectives(true);
965 var values = this.parseEnumValuesDefinition();
966 return {
967 kind: Kind.ENUM_TYPE_DEFINITION,
968 description: description,
969 name: name,
970 directives: directives,
971 values: values,
972 loc: this.loc(start)
973 };
974 }
975 /**
976 * EnumValuesDefinition : { EnumValueDefinition+ }
977 */
978 ;
979
980 _proto.parseEnumValuesDefinition = function parseEnumValuesDefinition() {
981 return this.optionalMany(TokenKind.BRACE_L, this.parseEnumValueDefinition, TokenKind.BRACE_R);
982 }
983 /**
984 * EnumValueDefinition : Description? EnumValue Directives[Const]?
985 *
986 * EnumValue : Name
987 */
988 ;
989
990 _proto.parseEnumValueDefinition = function parseEnumValueDefinition() {
991 var start = this._lexer.token;
992 var description = this.parseDescription();
993 var name = this.parseName();
994 var directives = this.parseDirectives(true);
995 return {
996 kind: Kind.ENUM_VALUE_DEFINITION,
997 description: description,
998 name: name,
999 directives: directives,
1000 loc: this.loc(start)
1001 };
1002 }
1003 /**
1004 * InputObjectTypeDefinition :
1005 * - Description? input Name Directives[Const]? InputFieldsDefinition?
1006 */
1007 ;
1008
1009 _proto.parseInputObjectTypeDefinition = function parseInputObjectTypeDefinition() {
1010 var start = this._lexer.token;
1011 var description = this.parseDescription();
1012 this.expectKeyword('input');
1013 var name = this.parseName();
1014 var directives = this.parseDirectives(true);
1015 var fields = this.parseInputFieldsDefinition();
1016 return {
1017 kind: Kind.INPUT_OBJECT_TYPE_DEFINITION,
1018 description: description,
1019 name: name,
1020 directives: directives,
1021 fields: fields,
1022 loc: this.loc(start)
1023 };
1024 }
1025 /**
1026 * InputFieldsDefinition : { InputValueDefinition+ }
1027 */
1028 ;
1029
1030 _proto.parseInputFieldsDefinition = function parseInputFieldsDefinition() {
1031 return this.optionalMany(TokenKind.BRACE_L, this.parseInputValueDef, TokenKind.BRACE_R);
1032 }
1033 /**
1034 * TypeSystemExtension :
1035 * - SchemaExtension
1036 * - TypeExtension
1037 *
1038 * TypeExtension :
1039 * - ScalarTypeExtension
1040 * - ObjectTypeExtension
1041 * - InterfaceTypeExtension
1042 * - UnionTypeExtension
1043 * - EnumTypeExtension
1044 * - InputObjectTypeDefinition
1045 */
1046 ;
1047
1048 _proto.parseTypeSystemExtension = function parseTypeSystemExtension() {
1049 var keywordToken = this._lexer.lookahead();
1050
1051 if (keywordToken.kind === TokenKind.NAME) {
1052 switch (keywordToken.value) {
1053 case 'schema':
1054 return this.parseSchemaExtension();
1055
1056 case 'scalar':
1057 return this.parseScalarTypeExtension();
1058
1059 case 'type':
1060 return this.parseObjectTypeExtension();
1061
1062 case 'interface':
1063 return this.parseInterfaceTypeExtension();
1064
1065 case 'union':
1066 return this.parseUnionTypeExtension();
1067
1068 case 'enum':
1069 return this.parseEnumTypeExtension();
1070
1071 case 'input':
1072 return this.parseInputObjectTypeExtension();
1073 }
1074 }
1075
1076 throw this.unexpected(keywordToken);
1077 }
1078 /**
1079 * SchemaExtension :
1080 * - extend schema Directives[Const]? { OperationTypeDefinition+ }
1081 * - extend schema Directives[Const]
1082 */
1083 ;
1084
1085 _proto.parseSchemaExtension = function parseSchemaExtension() {
1086 var start = this._lexer.token;
1087 this.expectKeyword('extend');
1088 this.expectKeyword('schema');
1089 var directives = this.parseDirectives(true);
1090 var operationTypes = this.optionalMany(TokenKind.BRACE_L, this.parseOperationTypeDefinition, TokenKind.BRACE_R);
1091
1092 if (directives.length === 0 && operationTypes.length === 0) {
1093 throw this.unexpected();
1094 }
1095
1096 return {
1097 kind: Kind.SCHEMA_EXTENSION,
1098 directives: directives,
1099 operationTypes: operationTypes,
1100 loc: this.loc(start)
1101 };
1102 }
1103 /**
1104 * ScalarTypeExtension :
1105 * - extend scalar Name Directives[Const]
1106 */
1107 ;
1108
1109 _proto.parseScalarTypeExtension = function parseScalarTypeExtension() {
1110 var start = this._lexer.token;
1111 this.expectKeyword('extend');
1112 this.expectKeyword('scalar');
1113 var name = this.parseName();
1114 var directives = this.parseDirectives(true);
1115
1116 if (directives.length === 0) {
1117 throw this.unexpected();
1118 }
1119
1120 return {
1121 kind: Kind.SCALAR_TYPE_EXTENSION,
1122 name: name,
1123 directives: directives,
1124 loc: this.loc(start)
1125 };
1126 }
1127 /**
1128 * ObjectTypeExtension :
1129 * - extend type Name ImplementsInterfaces? Directives[Const]? FieldsDefinition
1130 * - extend type Name ImplementsInterfaces? Directives[Const]
1131 * - extend type Name ImplementsInterfaces
1132 */
1133 ;
1134
1135 _proto.parseObjectTypeExtension = function parseObjectTypeExtension() {
1136 var start = this._lexer.token;
1137 this.expectKeyword('extend');
1138 this.expectKeyword('type');
1139 var name = this.parseName();
1140 var interfaces = this.parseImplementsInterfaces();
1141 var directives = this.parseDirectives(true);
1142 var fields = this.parseFieldsDefinition();
1143
1144 if (interfaces.length === 0 && directives.length === 0 && fields.length === 0) {
1145 throw this.unexpected();
1146 }
1147
1148 return {
1149 kind: Kind.OBJECT_TYPE_EXTENSION,
1150 name: name,
1151 interfaces: interfaces,
1152 directives: directives,
1153 fields: fields,
1154 loc: this.loc(start)
1155 };
1156 }
1157 /**
1158 * InterfaceTypeExtension :
1159 * - extend interface Name Directives[Const]? FieldsDefinition
1160 * - extend interface Name Directives[Const]
1161 */
1162 ;
1163
1164 _proto.parseInterfaceTypeExtension = function parseInterfaceTypeExtension() {
1165 var start = this._lexer.token;
1166 this.expectKeyword('extend');
1167 this.expectKeyword('interface');
1168 var name = this.parseName();
1169 var directives = this.parseDirectives(true);
1170 var fields = this.parseFieldsDefinition();
1171
1172 if (directives.length === 0 && fields.length === 0) {
1173 throw this.unexpected();
1174 }
1175
1176 return {
1177 kind: Kind.INTERFACE_TYPE_EXTENSION,
1178 name: name,
1179 directives: directives,
1180 fields: fields,
1181 loc: this.loc(start)
1182 };
1183 }
1184 /**
1185 * UnionTypeExtension :
1186 * - extend union Name Directives[Const]? UnionMemberTypes
1187 * - extend union Name Directives[Const]
1188 */
1189 ;
1190
1191 _proto.parseUnionTypeExtension = function parseUnionTypeExtension() {
1192 var start = this._lexer.token;
1193 this.expectKeyword('extend');
1194 this.expectKeyword('union');
1195 var name = this.parseName();
1196 var directives = this.parseDirectives(true);
1197 var types = this.parseUnionMemberTypes();
1198
1199 if (directives.length === 0 && types.length === 0) {
1200 throw this.unexpected();
1201 }
1202
1203 return {
1204 kind: Kind.UNION_TYPE_EXTENSION,
1205 name: name,
1206 directives: directives,
1207 types: types,
1208 loc: this.loc(start)
1209 };
1210 }
1211 /**
1212 * EnumTypeExtension :
1213 * - extend enum Name Directives[Const]? EnumValuesDefinition
1214 * - extend enum Name Directives[Const]
1215 */
1216 ;
1217
1218 _proto.parseEnumTypeExtension = function parseEnumTypeExtension() {
1219 var start = this._lexer.token;
1220 this.expectKeyword('extend');
1221 this.expectKeyword('enum');
1222 var name = this.parseName();
1223 var directives = this.parseDirectives(true);
1224 var values = this.parseEnumValuesDefinition();
1225
1226 if (directives.length === 0 && values.length === 0) {
1227 throw this.unexpected();
1228 }
1229
1230 return {
1231 kind: Kind.ENUM_TYPE_EXTENSION,
1232 name: name,
1233 directives: directives,
1234 values: values,
1235 loc: this.loc(start)
1236 };
1237 }
1238 /**
1239 * InputObjectTypeExtension :
1240 * - extend input Name Directives[Const]? InputFieldsDefinition
1241 * - extend input Name Directives[Const]
1242 */
1243 ;
1244
1245 _proto.parseInputObjectTypeExtension = function parseInputObjectTypeExtension() {
1246 var start = this._lexer.token;
1247 this.expectKeyword('extend');
1248 this.expectKeyword('input');
1249 var name = this.parseName();
1250 var directives = this.parseDirectives(true);
1251 var fields = this.parseInputFieldsDefinition();
1252
1253 if (directives.length === 0 && fields.length === 0) {
1254 throw this.unexpected();
1255 }
1256
1257 return {
1258 kind: Kind.INPUT_OBJECT_TYPE_EXTENSION,
1259 name: name,
1260 directives: directives,
1261 fields: fields,
1262 loc: this.loc(start)
1263 };
1264 }
1265 /**
1266 * DirectiveDefinition :
1267 * - Description? directive @ Name ArgumentsDefinition? `repeatable`? on DirectiveLocations
1268 */
1269 ;
1270
1271 _proto.parseDirectiveDefinition = function parseDirectiveDefinition() {
1272 var start = this._lexer.token;
1273 var description = this.parseDescription();
1274 this.expectKeyword('directive');
1275 this.expectToken(TokenKind.AT);
1276 var name = this.parseName();
1277 var args = this.parseArgumentDefs();
1278 var repeatable = this.expectOptionalKeyword('repeatable');
1279 this.expectKeyword('on');
1280 var locations = this.parseDirectiveLocations();
1281 return {
1282 kind: Kind.DIRECTIVE_DEFINITION,
1283 description: description,
1284 name: name,
1285 arguments: args,
1286 repeatable: repeatable,
1287 locations: locations,
1288 loc: this.loc(start)
1289 };
1290 }
1291 /**
1292 * DirectiveLocations :
1293 * - `|`? DirectiveLocation
1294 * - DirectiveLocations | DirectiveLocation
1295 */
1296 ;
1297
1298 _proto.parseDirectiveLocations = function parseDirectiveLocations() {
1299 // Optional leading pipe
1300 this.expectOptionalToken(TokenKind.PIPE);
1301 var locations = [];
1302
1303 do {
1304 locations.push(this.parseDirectiveLocation());
1305 } while (this.expectOptionalToken(TokenKind.PIPE));
1306
1307 return locations;
1308 }
1309 /*
1310 * DirectiveLocation :
1311 * - ExecutableDirectiveLocation
1312 * - TypeSystemDirectiveLocation
1313 *
1314 * ExecutableDirectiveLocation : one of
1315 * `QUERY`
1316 * `MUTATION`
1317 * `SUBSCRIPTION`
1318 * `FIELD`
1319 * `FRAGMENT_DEFINITION`
1320 * `FRAGMENT_SPREAD`
1321 * `INLINE_FRAGMENT`
1322 *
1323 * TypeSystemDirectiveLocation : one of
1324 * `SCHEMA`
1325 * `SCALAR`
1326 * `OBJECT`
1327 * `FIELD_DEFINITION`
1328 * `ARGUMENT_DEFINITION`
1329 * `INTERFACE`
1330 * `UNION`
1331 * `ENUM`
1332 * `ENUM_VALUE`
1333 * `INPUT_OBJECT`
1334 * `INPUT_FIELD_DEFINITION`
1335 */
1336 ;
1337
1338 _proto.parseDirectiveLocation = function parseDirectiveLocation() {
1339 var start = this._lexer.token;
1340 var name = this.parseName();
1341
1342 if (DirectiveLocation[name.value] !== undefined) {
1343 return name;
1344 }
1345
1346 throw this.unexpected(start);
1347 } // Core parsing utility functions
1348
1349 /**
1350 * Returns a location object, used to identify the place in
1351 * the source that created a given parsed object.
1352 */
1353 ;
1354
1355 _proto.loc = function loc(startToken) {
1356 if (!this._options.noLocation) {
1357 return new Loc(startToken, this._lexer.lastToken, this._lexer.source);
1358 }
1359 }
1360 /**
1361 * Determines if the next token is of a given kind
1362 */
1363 ;
1364
1365 _proto.peek = function peek(kind) {
1366 return this._lexer.token.kind === kind;
1367 }
1368 /**
1369 * If the next token is of the given kind, return that token after advancing
1370 * the lexer. Otherwise, do not change the parser state and throw an error.
1371 */
1372 ;
1373
1374 _proto.expectToken = function expectToken(kind) {
1375 var token = this._lexer.token;
1376
1377 if (token.kind === kind) {
1378 this._lexer.advance();
1379
1380 return token;
1381 }
1382
1383 throw syntaxError(this._lexer.source, token.start, "Expected ".concat(kind, ", found ").concat(getTokenDesc(token)));
1384 }
1385 /**
1386 * If the next token is of the given kind, return that token after advancing
1387 * the lexer. Otherwise, do not change the parser state and return undefined.
1388 */
1389 ;
1390
1391 _proto.expectOptionalToken = function expectOptionalToken(kind) {
1392 var token = this._lexer.token;
1393
1394 if (token.kind === kind) {
1395 this._lexer.advance();
1396
1397 return token;
1398 }
1399
1400 return undefined;
1401 }
1402 /**
1403 * If the next token is a given keyword, advance the lexer.
1404 * Otherwise, do not change the parser state and throw an error.
1405 */
1406 ;
1407
1408 _proto.expectKeyword = function expectKeyword(value) {
1409 var token = this._lexer.token;
1410
1411 if (token.kind === TokenKind.NAME && token.value === value) {
1412 this._lexer.advance();
1413 } else {
1414 throw syntaxError(this._lexer.source, token.start, "Expected \"".concat(value, "\", found ").concat(getTokenDesc(token)));
1415 }
1416 }
1417 /**
1418 * If the next token is a given keyword, return "true" after advancing
1419 * the lexer. Otherwise, do not change the parser state and return "false".
1420 */
1421 ;
1422
1423 _proto.expectOptionalKeyword = function expectOptionalKeyword(value) {
1424 var token = this._lexer.token;
1425
1426 if (token.kind === TokenKind.NAME && token.value === value) {
1427 this._lexer.advance();
1428
1429 return true;
1430 }
1431
1432 return false;
1433 }
1434 /**
1435 * Helper function for creating an error when an unexpected lexed token
1436 * is encountered.
1437 */
1438 ;
1439
1440 _proto.unexpected = function unexpected(atToken) {
1441 var token = atToken || this._lexer.token;
1442 return syntaxError(this._lexer.source, token.start, "Unexpected ".concat(getTokenDesc(token)));
1443 }
1444 /**
1445 * Returns a possibly empty list of parse nodes, determined by
1446 * the parseFn. This list begins with a lex token of openKind
1447 * and ends with a lex token of closeKind. Advances the parser
1448 * to the next lex token after the closing token.
1449 */
1450 ;
1451
1452 _proto.any = function any(openKind, parseFn, closeKind) {
1453 this.expectToken(openKind);
1454 var nodes = [];
1455
1456 while (!this.expectOptionalToken(closeKind)) {
1457 nodes.push(parseFn.call(this));
1458 }
1459
1460 return nodes;
1461 }
1462 /**
1463 * Returns a list of parse nodes, determined by the parseFn.
1464 * It can be empty only if open token is missing otherwise it will always
1465 * return non-empty list that begins with a lex token of openKind and ends
1466 * with a lex token of closeKind. Advances the parser to the next lex token
1467 * after the closing token.
1468 */
1469 ;
1470
1471 _proto.optionalMany = function optionalMany(openKind, parseFn, closeKind) {
1472 if (this.expectOptionalToken(openKind)) {
1473 var nodes = [];
1474
1475 do {
1476 nodes.push(parseFn.call(this));
1477 } while (!this.expectOptionalToken(closeKind));
1478
1479 return nodes;
1480 }
1481
1482 return [];
1483 }
1484 /**
1485 * Returns a non-empty list of parse nodes, determined by
1486 * the parseFn. This list begins with a lex token of openKind
1487 * and ends with a lex token of closeKind. Advances the parser
1488 * to the next lex token after the closing token.
1489 */
1490 ;
1491
1492 _proto.many = function many(openKind, parseFn, closeKind) {
1493 this.expectToken(openKind);
1494 var nodes = [];
1495
1496 do {
1497 nodes.push(parseFn.call(this));
1498 } while (!this.expectOptionalToken(closeKind));
1499
1500 return nodes;
1501 };
1502
1503 return Parser;
1504}();
1505
1506function Loc(startToken, endToken, source) {
1507 this.start = startToken.start;
1508 this.end = endToken.end;
1509 this.startToken = startToken;
1510 this.endToken = endToken;
1511 this.source = source;
1512} // Print a simplified form when appearing in JSON/util.inspect.
1513
1514
1515defineToJSON(Loc, function () {
1516 return {
1517 start: this.start,
1518 end: this.end
1519 };
1520});
1521/**
1522 * A helper function to describe a token as a string for debugging
1523 */
1524
1525function getTokenDesc(token) {
1526 var value = token.value;
1527 return value ? "".concat(token.kind, " \"").concat(value, "\"") : token.kind;
1528}