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