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.
Files changed (343) hide show
  1. package/README.md +5 -10
  2. package/error/GraphQLError.d.ts +87 -0
  3. package/error/GraphQLError.js +7 -45
  4. package/error/GraphQLError.js.flow +1 -0
  5. package/error/GraphQLError.mjs +7 -45
  6. package/error/formatError.d.ts +39 -0
  7. package/error/formatError.js +5 -2
  8. package/error/formatError.js.flow +27 -3
  9. package/error/formatError.mjs +5 -2
  10. package/error/index.d.ts +4 -0
  11. package/error/locatedError.d.ts +13 -0
  12. package/error/locatedError.js.flow +2 -1
  13. package/error/locatedError.mjs +1 -1
  14. package/error/syntaxError.d.ts +12 -0
  15. package/error/syntaxError.js.flow +1 -0
  16. package/execution/execute.d.ts +190 -0
  17. package/execution/execute.js +55 -89
  18. package/execution/execute.js.flow +95 -133
  19. package/execution/execute.mjs +75 -80
  20. package/execution/index.d.ts +11 -0
  21. package/execution/index.js +8 -6
  22. package/execution/index.js.flow +3 -6
  23. package/execution/index.mjs +2 -1
  24. package/execution/values.d.ts +68 -0
  25. package/execution/values.js +119 -128
  26. package/execution/values.js.flow +150 -127
  27. package/execution/values.mjs +117 -125
  28. package/graphql.d.ts +88 -0
  29. package/graphql.js +5 -5
  30. package/graphql.js.flow +9 -5
  31. package/graphql.mjs +41 -1
  32. package/index.d.ts +446 -0
  33. package/index.js +6 -0
  34. package/index.js.flow +3 -1
  35. package/index.mjs +2 -1
  36. package/jsutils/ObjMap.js.flow +6 -0
  37. package/jsutils/Path.d.ts +14 -0
  38. package/jsutils/Path.js +33 -0
  39. package/jsutils/Path.js.flow +26 -0
  40. package/jsutils/Path.mjs +24 -0
  41. package/jsutils/PromiseOrValue.d.ts +1 -0
  42. package/jsutils/dedent.js +6 -24
  43. package/jsutils/dedent.mjs +6 -24
  44. package/jsutils/defineToStringTag.js.flow +1 -1
  45. package/jsutils/devAssert.js +14 -0
  46. package/jsutils/devAssert.js.flow +8 -0
  47. package/jsutils/devAssert.mjs +7 -0
  48. package/jsutils/inspect.js +1 -1
  49. package/jsutils/inspect.js.flow +1 -1
  50. package/jsutils/inspect.mjs +1 -1
  51. package/jsutils/invariant.js +1 -2
  52. package/jsutils/invariant.js.flow +2 -3
  53. package/jsutils/invariant.mjs +1 -2
  54. package/jsutils/mapValue.js +6 -24
  55. package/jsutils/mapValue.js.flow +2 -1
  56. package/jsutils/mapValue.mjs +6 -24
  57. package/jsutils/printPathArray.js +15 -0
  58. package/jsutils/printPathArray.js.flow +14 -0
  59. package/jsutils/printPathArray.mjs +8 -0
  60. package/jsutils/suggestionList.js +14 -34
  61. package/jsutils/suggestionList.js.flow +4 -6
  62. package/jsutils/suggestionList.mjs +14 -34
  63. package/jsutils/toObjMap.js +28 -0
  64. package/jsutils/toObjMap.js.flow +26 -0
  65. package/jsutils/toObjMap.mjs +18 -0
  66. package/language/ast.d.ts +573 -0
  67. package/language/blockString.d.ts +21 -0
  68. package/language/directiveLocation.d.ts +35 -0
  69. package/language/index.d.ts +96 -0
  70. package/language/kinds.d.ts +77 -0
  71. package/language/lexer.d.ts +60 -0
  72. package/language/lexer.js +2 -12
  73. package/language/lexer.js.flow +6 -12
  74. package/language/lexer.mjs +1 -9
  75. package/language/location.d.ts +15 -0
  76. package/language/parser.d.ts +89 -0
  77. package/language/parser.js +1329 -1302
  78. package/language/parser.js.flow +1289 -1298
  79. package/language/parser.mjs +1326 -1297
  80. package/language/predicates.d.ts +36 -0
  81. package/language/predicates.js.flow +1 -1
  82. package/language/printLocation.d.ts +16 -0
  83. package/language/printLocation.js.flow +1 -1
  84. package/language/printer.d.ts +7 -0
  85. package/language/printer.js.flow +1 -1
  86. package/language/source.d.ts +19 -0
  87. package/language/source.js +3 -3
  88. package/language/source.js.flow +3 -3
  89. package/language/source.mjs +3 -3
  90. package/language/tokenKind.d.ts +35 -0
  91. package/language/visitor.d.ts +264 -0
  92. package/language/visitor.js +2 -2
  93. package/language/visitor.js.flow +3 -1
  94. package/language/visitor.mjs +2 -2
  95. package/package.json +1 -1
  96. package/polyfills/find.js +2 -2
  97. package/polyfills/find.js.flow +1 -2
  98. package/polyfills/find.mjs +2 -2
  99. package/polyfills/flatMap.js +3 -3
  100. package/polyfills/flatMap.js.flow +2 -3
  101. package/polyfills/flatMap.mjs +3 -3
  102. package/subscription/asyncIteratorReject.d.ts +6 -0
  103. package/subscription/index.d.ts +5 -0
  104. package/subscription/mapAsyncIterator.d.ts +9 -0
  105. package/subscription/mapAsyncIterator.js.flow +1 -0
  106. package/subscription/subscribe.d.ts +86 -0
  107. package/subscription/subscribe.js +29 -10
  108. package/subscription/subscribe.js.flow +45 -24
  109. package/subscription/subscribe.mjs +27 -9
  110. package/tsutils/Maybe.d.ts +4 -0
  111. package/type/definition.d.ts +805 -0
  112. package/type/definition.js +154 -70
  113. package/type/definition.js.flow +217 -160
  114. package/type/definition.mjs +149 -66
  115. package/type/directives.d.ts +72 -0
  116. package/type/directives.js +20 -12
  117. package/type/directives.js.flow +34 -19
  118. package/type/directives.mjs +17 -10
  119. package/type/index.d.ts +155 -0
  120. package/type/index.js.flow +2 -2
  121. package/type/introspection.d.ts +40 -0
  122. package/type/introspection.js +24 -10
  123. package/type/introspection.js.flow +29 -8
  124. package/type/introspection.mjs +23 -10
  125. package/type/scalars.d.ts +11 -0
  126. package/type/scalars.js +2 -2
  127. package/type/scalars.js.flow +4 -1
  128. package/type/scalars.mjs +2 -2
  129. package/type/schema.d.ts +108 -0
  130. package/type/schema.js +74 -151
  131. package/type/schema.js.flow +75 -73
  132. package/type/schema.mjs +75 -149
  133. package/type/validate.d.ts +19 -0
  134. package/type/validate.js +227 -486
  135. package/type/validate.js.flow +13 -8
  136. package/type/validate.mjs +218 -477
  137. package/utilities/TypeInfo.d.ts +49 -0
  138. package/utilities/TypeInfo.js.flow +9 -6
  139. package/utilities/assertValidName.d.ts +15 -0
  140. package/utilities/assertValidName.js +3 -3
  141. package/utilities/assertValidName.js.flow +3 -2
  142. package/utilities/assertValidName.mjs +2 -2
  143. package/utilities/astFromValue.d.ts +25 -0
  144. package/utilities/astFromValue.js +22 -38
  145. package/utilities/astFromValue.js.flow +7 -4
  146. package/utilities/astFromValue.mjs +19 -36
  147. package/utilities/buildASTSchema.d.ts +114 -0
  148. package/utilities/buildASTSchema.js +37 -68
  149. package/utilities/buildASTSchema.js.flow +32 -30
  150. package/utilities/buildASTSchema.mjs +32 -64
  151. package/utilities/buildClientSchema.d.ts +21 -0
  152. package/utilities/buildClientSchema.js +23 -15
  153. package/utilities/buildClientSchema.js.flow +17 -16
  154. package/utilities/buildClientSchema.mjs +20 -12
  155. package/utilities/coerceInputValue.d.ts +17 -0
  156. package/utilities/coerceInputValue.js +161 -0
  157. package/utilities/coerceInputValue.js.flow +214 -0
  158. package/utilities/coerceInputValue.mjs +142 -0
  159. package/utilities/coerceValue.d.ts +23 -0
  160. package/utilities/coerceValue.js +21 -199
  161. package/utilities/coerceValue.js.flow +31 -223
  162. package/utilities/coerceValue.mjs +20 -195
  163. package/utilities/concatAST.d.ts +8 -0
  164. package/utilities/concatAST.js.flow +1 -0
  165. package/utilities/extendSchema.d.ts +45 -0
  166. package/utilities/extendSchema.js +64 -131
  167. package/utilities/extendSchema.js.flow +27 -24
  168. package/utilities/extendSchema.mjs +61 -129
  169. package/utilities/findBreakingChanges.d.ts +64 -0
  170. package/utilities/findBreakingChanges.js +194 -619
  171. package/utilities/findBreakingChanges.js.flow +8 -5
  172. package/utilities/findBreakingChanges.mjs +194 -619
  173. package/utilities/findDeprecatedUsages.d.ts +13 -0
  174. package/utilities/findDeprecatedUsages.js.flow +4 -1
  175. package/utilities/getOperationAST.d.ts +12 -0
  176. package/utilities/getOperationAST.js +13 -31
  177. package/utilities/getOperationAST.mjs +13 -31
  178. package/utilities/getOperationRootType.d.ts +14 -0
  179. package/utilities/getOperationRootType.js.flow +2 -0
  180. package/utilities/index.d.ts +127 -0
  181. package/utilities/index.js +8 -0
  182. package/utilities/index.js.flow +4 -1
  183. package/utilities/index.mjs +3 -1
  184. package/utilities/introspectionFromSchema.d.ts +16 -0
  185. package/utilities/introspectionFromSchema.js +5 -3
  186. package/utilities/introspectionFromSchema.js.flow +4 -2
  187. package/utilities/introspectionFromSchema.mjs +4 -2
  188. package/utilities/introspectionQuery.d.ts +177 -0
  189. package/utilities/isValidJSValue.d.ts +8 -0
  190. package/utilities/isValidJSValue.js +1 -1
  191. package/utilities/isValidJSValue.js.flow +3 -2
  192. package/utilities/isValidJSValue.mjs +2 -2
  193. package/utilities/isValidLiteralValue.d.ts +15 -0
  194. package/utilities/isValidLiteralValue.js +4 -4
  195. package/utilities/isValidLiteralValue.js.flow +8 -4
  196. package/utilities/isValidLiteralValue.mjs +2 -2
  197. package/utilities/lexicographicSortSchema.d.ts +6 -0
  198. package/utilities/lexicographicSortSchema.js +11 -8
  199. package/utilities/lexicographicSortSchema.js.flow +5 -3
  200. package/utilities/lexicographicSortSchema.mjs +9 -7
  201. package/utilities/schemaPrinter.d.ts +30 -0
  202. package/utilities/schemaPrinter.js +15 -32
  203. package/utilities/schemaPrinter.js.flow +14 -10
  204. package/utilities/schemaPrinter.mjs +14 -32
  205. package/utilities/separateOperations.d.ts +11 -0
  206. package/utilities/separateOperations.js +6 -6
  207. package/utilities/separateOperations.js.flow +2 -1
  208. package/utilities/separateOperations.mjs +6 -6
  209. package/utilities/stripIgnoredCharacters.d.ts +55 -0
  210. package/utilities/stripIgnoredCharacters.js.flow +1 -0
  211. package/utilities/typeComparators.d.ts +32 -0
  212. package/utilities/typeComparators.js.flow +1 -1
  213. package/utilities/typeComparators.mjs +1 -1
  214. package/utilities/typeFromAST.d.ts +29 -0
  215. package/utilities/typeFromAST.js +5 -3
  216. package/utilities/typeFromAST.js.flow +5 -3
  217. package/utilities/typeFromAST.mjs +14 -3
  218. package/utilities/valueFromAST.d.ts +29 -0
  219. package/utilities/valueFromAST.js +40 -74
  220. package/utilities/valueFromAST.js.flow +7 -4
  221. package/utilities/valueFromAST.mjs +39 -74
  222. package/utilities/valueFromASTUntyped.d.ts +23 -0
  223. package/utilities/valueFromASTUntyped.js +4 -3
  224. package/utilities/valueFromASTUntyped.js.flow +3 -2
  225. package/utilities/valueFromASTUntyped.mjs +3 -3
  226. package/validation/ValidationContext.d.ts +96 -0
  227. package/validation/ValidationContext.js +38 -86
  228. package/validation/ValidationContext.js.flow +22 -7
  229. package/validation/ValidationContext.mjs +37 -85
  230. package/validation/index.d.ts +126 -0
  231. package/validation/rules/ExecutableDefinitions.d.ts +14 -0
  232. package/validation/rules/ExecutableDefinitions.js +4 -23
  233. package/validation/rules/ExecutableDefinitions.js.flow +4 -2
  234. package/validation/rules/ExecutableDefinitions.mjs +4 -23
  235. package/validation/rules/FieldsOnCorrectType.d.ts +17 -0
  236. package/validation/rules/FieldsOnCorrectType.js +21 -57
  237. package/validation/rules/FieldsOnCorrectType.js.flow +7 -3
  238. package/validation/rules/FieldsOnCorrectType.mjs +21 -57
  239. package/validation/rules/FragmentsOnCompositeTypes.d.ts +20 -0
  240. package/validation/rules/FragmentsOnCompositeTypes.js.flow +5 -1
  241. package/validation/rules/KnownArgumentNames.d.ts +28 -0
  242. package/validation/rules/KnownArgumentNames.js +26 -79
  243. package/validation/rules/KnownArgumentNames.js.flow +10 -6
  244. package/validation/rules/KnownArgumentNames.mjs +22 -75
  245. package/validation/rules/KnownDirectives.d.ts +19 -0
  246. package/validation/rules/KnownDirectives.js +12 -48
  247. package/validation/rules/KnownDirectives.js.flow +8 -5
  248. package/validation/rules/KnownDirectives.mjs +12 -48
  249. package/validation/rules/KnownFragmentNames.d.ts +12 -0
  250. package/validation/rules/KnownFragmentNames.js.flow +2 -1
  251. package/validation/rules/KnownTypeNames.d.ts +15 -0
  252. package/validation/rules/KnownTypeNames.js +6 -24
  253. package/validation/rules/KnownTypeNames.js.flow +10 -6
  254. package/validation/rules/KnownTypeNames.mjs +6 -24
  255. package/validation/rules/LoneAnonymousOperation.d.ts +14 -0
  256. package/validation/rules/LoneAnonymousOperation.js.flow +3 -1
  257. package/validation/rules/LoneSchemaDefinition.d.ts +13 -0
  258. package/validation/rules/LoneSchemaDefinition.js.flow +2 -1
  259. package/validation/rules/NoFragmentCycles.d.ts +9 -0
  260. package/validation/rules/NoFragmentCycles.js +17 -35
  261. package/validation/rules/NoFragmentCycles.js.flow +4 -2
  262. package/validation/rules/NoFragmentCycles.mjs +17 -35
  263. package/validation/rules/NoUndefinedVariables.d.ts +16 -0
  264. package/validation/rules/NoUndefinedVariables.js +6 -24
  265. package/validation/rules/NoUndefinedVariables.js.flow +2 -1
  266. package/validation/rules/NoUndefinedVariables.mjs +6 -24
  267. package/validation/rules/NoUnusedFragments.d.ts +12 -0
  268. package/validation/rules/NoUnusedFragments.js +7 -25
  269. package/validation/rules/NoUnusedFragments.js.flow +2 -1
  270. package/validation/rules/NoUnusedFragments.mjs +7 -25
  271. package/validation/rules/NoUnusedVariables.d.ts +16 -0
  272. package/validation/rules/NoUnusedVariables.js +6 -24
  273. package/validation/rules/NoUnusedVariables.js.flow +2 -1
  274. package/validation/rules/NoUnusedVariables.mjs +6 -24
  275. package/validation/rules/OverlappingFieldsCanBeMerged.d.ts +24 -0
  276. package/validation/rules/OverlappingFieldsCanBeMerged.js +27 -46
  277. package/validation/rules/OverlappingFieldsCanBeMerged.js.flow +17 -8
  278. package/validation/rules/OverlappingFieldsCanBeMerged.mjs +25 -44
  279. package/validation/rules/PossibleFragmentSpreads.d.ts +22 -0
  280. package/validation/rules/PossibleFragmentSpreads.js +2 -2
  281. package/validation/rules/PossibleFragmentSpreads.js.flow +8 -3
  282. package/validation/rules/PossibleFragmentSpreads.mjs +2 -2
  283. package/validation/rules/PossibleTypeExtensions.d.ts +21 -0
  284. package/validation/rules/PossibleTypeExtensions.js +4 -22
  285. package/validation/rules/PossibleTypeExtensions.js.flow +6 -2
  286. package/validation/rules/PossibleTypeExtensions.mjs +4 -22
  287. package/validation/rules/ProvidedRequiredArguments.d.ts +29 -0
  288. package/validation/rules/ProvidedRequiredArguments.js +27 -79
  289. package/validation/rules/ProvidedRequiredArguments.js.flow +12 -8
  290. package/validation/rules/ProvidedRequiredArguments.mjs +25 -77
  291. package/validation/rules/ScalarLeafs.d.ts +20 -0
  292. package/validation/rules/ScalarLeafs.js.flow +6 -2
  293. package/validation/rules/SingleFieldSubscriptions.d.ts +14 -0
  294. package/validation/rules/SingleFieldSubscriptions.js.flow +4 -2
  295. package/validation/rules/UniqueArgumentNames.d.ts +12 -0
  296. package/validation/rules/UniqueArgumentNames.js.flow +2 -1
  297. package/validation/rules/UniqueDirectiveNames.d.ts +13 -0
  298. package/validation/rules/UniqueDirectiveNames.js.flow +2 -1
  299. package/validation/rules/UniqueDirectivesPerLocation.d.ts +14 -0
  300. package/validation/rules/UniqueDirectivesPerLocation.js +15 -69
  301. package/validation/rules/UniqueDirectivesPerLocation.js.flow +7 -4
  302. package/validation/rules/UniqueDirectivesPerLocation.mjs +15 -69
  303. package/validation/rules/UniqueEnumValueNames.d.ts +19 -0
  304. package/validation/rules/UniqueEnumValueNames.js +10 -28
  305. package/validation/rules/UniqueEnumValueNames.js.flow +2 -1
  306. package/validation/rules/UniqueEnumValueNames.mjs +10 -28
  307. package/validation/rules/UniqueFieldDefinitionNames.d.ts +21 -0
  308. package/validation/rules/UniqueFieldDefinitionNames.js +9 -27
  309. package/validation/rules/UniqueFieldDefinitionNames.js.flow +2 -1
  310. package/validation/rules/UniqueFieldDefinitionNames.mjs +9 -27
  311. package/validation/rules/UniqueFragmentNames.d.ts +11 -0
  312. package/validation/rules/UniqueFragmentNames.js.flow +2 -1
  313. package/validation/rules/UniqueInputFieldNames.d.ts +14 -0
  314. package/validation/rules/UniqueInputFieldNames.js.flow +2 -1
  315. package/validation/rules/UniqueOperationNames.d.ts +11 -0
  316. package/validation/rules/UniqueOperationNames.js.flow +2 -1
  317. package/validation/rules/UniqueOperationTypes.d.ts +13 -0
  318. package/validation/rules/UniqueOperationTypes.js +11 -30
  319. package/validation/rules/UniqueOperationTypes.js.flow +2 -1
  320. package/validation/rules/UniqueOperationTypes.mjs +10 -29
  321. package/validation/rules/UniqueTypeNames.d.ts +13 -0
  322. package/validation/rules/UniqueTypeNames.js.flow +3 -1
  323. package/validation/rules/UniqueVariableNames.d.ts +11 -0
  324. package/validation/rules/UniqueVariableNames.js.flow +4 -2
  325. package/validation/rules/ValuesOfCorrectType.d.ts +34 -0
  326. package/validation/rules/ValuesOfCorrectType.js +16 -34
  327. package/validation/rules/ValuesOfCorrectType.js.flow +11 -6
  328. package/validation/rules/ValuesOfCorrectType.mjs +12 -30
  329. package/validation/rules/VariablesAreInputTypes.d.ts +15 -0
  330. package/validation/rules/VariablesAreInputTypes.js.flow +6 -2
  331. package/validation/rules/VariablesInAllowedPosition.d.ts +15 -0
  332. package/validation/rules/VariablesInAllowedPosition.js +22 -40
  333. package/validation/rules/VariablesInAllowedPosition.js.flow +8 -3
  334. package/validation/rules/VariablesInAllowedPosition.mjs +18 -36
  335. package/validation/specifiedRules.d.ts +98 -0
  336. package/validation/validate.d.ts +56 -0
  337. package/validation/validate.js +35 -7
  338. package/validation/validate.js.flow +51 -9
  339. package/validation/validate.mjs +30 -7
  340. package/version.d.ts +14 -0
  341. package/version.js +3 -3
  342. package/version.js.flow +3 -3
  343. package/version.mjs +3 -3
@@ -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
- import { Source } from './source';
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 sourceObj = typeof source === 'string' ? new Source(source) : source;
125
- if (!(sourceObj instanceof Source)) {
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 sourceObj = typeof source === 'string' ? new Source(source) : source;
147
- const lexer = createLexer(sourceObj, options || {});
148
- expectToken(lexer, TokenKind.SOF);
149
- const value = parseValueLiteral(lexer, false);
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 sourceObj = typeof source === 'string' ? new Source(source) : source;
169
- const lexer = createLexer(sourceObj, options || {});
170
- expectToken(lexer, TokenKind.SOF);
171
- const type = parseTypeReference(lexer);
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
- * Converts a name lex token into a name parse node.
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
- // Implements the parsing rules in the Document section.
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
- * Document : Definition+
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
- * Definition :
204
- * - ExecutableDefinition
205
- * - TypeSystemDefinition
206
- * - TypeSystemExtension
207
- */
208
- function parseDefinition(lexer: Lexer<*>): DefinitionNode {
209
- if (peek(lexer, TokenKind.NAME)) {
210
- switch (lexer.token.value) {
211
- case 'query':
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
- throw unexpected(lexer);
235
- }
196
+ // Implements the parsing rules in the Document section.
236
197
 
237
- /**
238
- * ExecutableDefinition :
239
- * - OperationDefinition
240
- * - FragmentDefinition
241
- */
242
- function parseExecutableDefinition(lexer: Lexer<*>): ExecutableDefinitionNode {
243
- if (peek(lexer, TokenKind.NAME)) {
244
- switch (lexer.token.value) {
245
- case 'query':
246
- case 'mutation':
247
- case 'subscription':
248
- return parseOperationDefinition(lexer);
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
- case 'fragment':
251
- return parseFragmentDefinition(lexer);
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
- throw unexpected(lexer);
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
- * OperationDefinition :
264
- * - SelectionSet
265
- * - OperationType Name? VariableDefinitions? Directives? SelectionSet
266
- */
267
- function parseOperationDefinition(lexer: Lexer<*>): OperationDefinitionNode {
268
- const start = lexer.token;
269
- if (peek(lexer, TokenKind.BRACE_L)) {
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: 'query',
273
- name: undefined,
274
- variableDefinitions: [],
275
- directives: [],
276
- selectionSet: parseSelectionSet(lexer),
277
- loc: loc(lexer, start),
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
- * OperationType : one of query mutation subscription
298
- */
299
- function parseOperationType(lexer: Lexer<*>): OperationTypeNode {
300
- const operationToken = expectToken(lexer, TokenKind.NAME);
301
- switch (operationToken.value) {
302
- case 'query':
303
- return 'query';
304
- case 'mutation':
305
- return 'mutation';
306
- case 'subscription':
307
- return 'subscription';
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
- * VariableDefinitions : ( VariableDefinition+ )
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
- * VariableDefinition : Variable : Type DefaultValue? Directives[Const]?
326
- */
327
- function parseVariableDefinition(lexer: Lexer<*>): VariableDefinitionNode {
328
- const start = lexer.token;
329
- return {
330
- kind: Kind.VARIABLE_DEFINITION,
331
- variable: parseVariable(lexer),
332
- type: (expectToken(lexer, TokenKind.COLON), parseTypeReference(lexer)),
333
- defaultValue: expectOptionalToken(lexer, TokenKind.EQUALS)
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
- * Variable : $ Name
343
- */
344
- function parseVariable(lexer: Lexer<*>): VariableNode {
345
- const start = lexer.token;
346
- expectToken(lexer, TokenKind.DOLLAR);
347
- return {
348
- kind: Kind.VARIABLE,
349
- name: parseName(lexer),
350
- loc: loc(lexer, start),
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
- * SelectionSet : { Selection+ }
356
- */
357
- function parseSelectionSet(lexer: Lexer<*>): SelectionSetNode {
358
- const start = lexer.token;
359
- return {
360
- kind: Kind.SELECTION_SET,
361
- selections: many(
362
- lexer,
363
- TokenKind.BRACE_L,
364
- parseSelection,
365
- TokenKind.BRACE_R,
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
- * Selection :
373
- * - Field
374
- * - FragmentSpread
375
- * - InlineFragment
376
- */
377
- function parseSelection(lexer: Lexer<*>): SelectionNode {
378
- return peek(lexer, TokenKind.SPREAD)
379
- ? parseFragment(lexer)
380
- : parseField(lexer);
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
- * Field : Alias? Name Arguments? Directives? SelectionSet?
385
- *
386
- * Alias : Name :
387
- */
388
- function parseField(lexer: Lexer<*>): FieldNode {
389
- const start = lexer.token;
390
-
391
- const nameOrAlias = parseName(lexer);
392
- let alias;
393
- let name;
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
- * Arguments[Const] : ( Argument[?Const]+ )
416
- */
417
- function parseArguments(
418
- lexer: Lexer<*>,
419
- isConst: boolean,
420
- ): Array<ArgumentNode> {
421
- const item = isConst ? parseConstArgument : parseArgument;
422
- return peek(lexer, TokenKind.PAREN_L)
423
- ? many(lexer, TokenKind.PAREN_L, item, TokenKind.PAREN_R)
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
- * Argument[Const] : Name : Value[?Const]
429
- */
430
- function parseArgument(lexer: Lexer<*>): ArgumentNode {
431
- const start = lexer.token;
432
- const name = parseName(lexer);
433
-
434
- expectToken(lexer, TokenKind.COLON);
435
- return {
436
- kind: Kind.ARGUMENT,
437
- name,
438
- value: parseValueLiteral(lexer, false),
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
- function parseConstArgument(lexer: Lexer<*>): ArgumentNode {
444
- const start = lexer.token;
445
- return {
446
- kind: Kind.ARGUMENT,
447
- name: parseName(lexer),
448
- value: (expectToken(lexer, TokenKind.COLON), parseConstValue(lexer)),
449
- loc: loc(lexer, start),
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
- // Implements the parsing rules in the Fragments section.
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.FRAGMENT_SPREAD,
472
- name: parseFragmentName(lexer),
473
- directives: parseDirectives(lexer, false),
474
- loc: loc(lexer, start),
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
- * FragmentDefinition :
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.FRAGMENT_DEFINITION,
501
- name: parseFragmentName(lexer),
502
- variableDefinitions: parseVariableDefinitions(lexer),
503
- typeCondition: (expectKeyword(lexer, 'on'), parseNamedType(lexer)),
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
- // Implements the parsing rules in the Values section.
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
- * Value[Const] :
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.INT,
560
- value: ((token.value: any): string),
561
- loc: loc(lexer, token),
457
+ kind: Kind.FRAGMENT_SPREAD,
458
+ name: this.parseFragmentName(),
459
+ directives: this.parseDirectives(false),
460
+ loc: this.loc(start),
562
461
  };
563
- case TokenKind.FLOAT:
564
- lexer.advance();
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.FLOAT,
567
- value: ((token.value: any): string),
568
- loc: loc(lexer, token),
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
- case TokenKind.STRING:
571
- case TokenKind.BLOCK_STRING:
572
- return parseStringLiteral(lexer);
573
- case TokenKind.NAME:
574
- if (token.value === 'true' || token.value === 'false') {
575
- lexer.advance();
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.BOOLEAN,
578
- value: token.value === 'true',
579
- loc: loc(lexer, token),
545
+ kind: Kind.INT,
546
+ value: ((token.value: any): string),
547
+ loc: this.loc(token),
580
548
  };
581
- } else if (token.value === 'null') {
582
- lexer.advance();
549
+ case TokenKind.FLOAT:
550
+ this._lexer.advance();
583
551
  return {
584
- kind: Kind.NULL,
585
- loc: loc(lexer, token),
552
+ kind: Kind.FLOAT,
553
+ value: ((token.value: any): string),
554
+ loc: this.loc(token),
586
555
  };
587
- }
588
- lexer.advance();
589
- return {
590
- kind: Kind.ENUM,
591
- value: ((token.value: any): string),
592
- loc: loc(lexer, token),
593
- };
594
- case TokenKind.DOLLAR:
595
- if (!isConst) {
596
- return parseVariable(lexer);
597
- }
598
- break;
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
- * ListValue[Const] :
624
- * - [ ]
625
- * - [ Value[?Const]+ ]
626
- */
627
- function parseList(lexer: Lexer<*>, isConst: boolean): ListValueNode {
628
- const start = lexer.token;
629
- const item = isConst ? parseConstValue : parseValueValue;
630
- return {
631
- kind: Kind.LIST,
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
- * ObjectValue[Const] :
639
- * - { }
640
- * - { ObjectField[?Const]+ }
641
- */
642
- function parseObject(lexer: Lexer<*>, isConst: boolean): ObjectValueNode {
643
- const start = lexer.token;
644
- const item = () => parseObjectField(lexer, isConst);
645
- return {
646
- kind: Kind.OBJECT,
647
- fields: any(lexer, TokenKind.BRACE_L, item, TokenKind.BRACE_R),
648
- loc: loc(lexer, start),
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
- * ObjectField[Const] : Name : Value[?Const]
654
- */
655
- function parseObjectField(lexer: Lexer<*>, isConst: boolean): ObjectFieldNode {
656
- const start = lexer.token;
657
- const name = parseName(lexer);
658
- expectToken(lexer, TokenKind.COLON);
659
-
660
- return {
661
- kind: Kind.OBJECT_FIELD,
662
- name,
663
- value: parseValueLiteral(lexer, isConst),
664
- loc: loc(lexer, start),
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
- // Implements the parsing rules in the Directives section.
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
- * Directives[Const] : Directive[?Const]+
672
- */
673
- function parseDirectives(
674
- lexer: Lexer<*>,
675
- isConst: boolean,
676
- ): Array<DirectiveNode> {
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
- // Implements the parsing rules in the Types section.
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
- * Type :
702
- * - NamedType
703
- * - ListType
704
- * - NonNullType
705
- */
706
- export function parseTypeReference(lexer: Lexer<*>): TypeNode {
707
- const start = lexer.token;
708
- let type;
709
- if (expectOptionalToken(lexer, TokenKind.BRACKET_L)) {
710
- type = parseTypeReference(lexer);
711
- expectToken(lexer, TokenKind.BRACKET_R);
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
- // Implements the parsing rules in the Type Definition section.
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
- * TypeSystemDefinition :
746
- * - SchemaDefinition
747
- * - TypeDefinition
748
- * - DirectiveDefinition
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
- throw unexpected(lexer, keywordToken);
784
- }
785
-
786
- function peekDescription(lexer: Lexer<*>): boolean {
787
- return peek(lexer, TokenKind.STRING) || peek(lexer, TokenKind.BLOCK_STRING);
788
- }
789
-
790
- /**
791
- * Description : StringValue
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
- * OperationTypeDefinition : OperationType : NamedType
822
- */
823
- function parseOperationTypeDefinition(
824
- lexer: Lexer<*>,
825
- ): OperationTypeDefinitionNode {
826
- const start = lexer.token;
827
- const operation = parseOperationType(lexer);
828
- expectToken(lexer, TokenKind.COLON);
829
- const type = parseNamedType(lexer);
830
- return {
831
- kind: Kind.OPERATION_TYPE_DEFINITION,
832
- operation,
833
- type,
834
- loc: loc(lexer, start),
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
- * ScalarTypeDefinition : Description? scalar Name Directives[Const]?
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
- * ObjectTypeDefinition :
858
- * Description?
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
- * ImplementsInterfaces :
882
- * - implements `&`? NamedType
883
- * - ImplementsInterfaces & NamedType
884
- */
885
- function parseImplementsInterfaces(lexer: Lexer<*>): Array<NamedTypeNode> {
886
- const types = [];
887
- if (expectOptionalKeyword(lexer, 'implements')) {
888
- // Optional leading ampersand
889
- expectOptionalToken(lexer, TokenKind.AMP);
890
- do {
891
- types.push(parseNamedType(lexer));
892
- } while (
893
- expectOptionalToken(lexer, TokenKind.AMP) ||
894
- // Legacy support for the SDL?
895
- (lexer.options.allowLegacySDLImplementsInterfaces &&
896
- peek(lexer, TokenKind.NAME))
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
- * FieldsDefinition : { FieldDefinition+ }
904
- */
905
- function parseFieldsDefinition(lexer: Lexer<*>): Array<FieldDefinitionNode> {
906
- // Legacy support for the SDL?
907
- if (
908
- lexer.options.allowLegacySDLEmptyFields &&
909
- peek(lexer, TokenKind.BRACE_L) &&
910
- lexer.lookahead().kind === TokenKind.BRACE_R
911
- ) {
912
- lexer.advance();
913
- lexer.advance();
914
- return [];
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
- * FieldDefinition :
923
- * - Description? Name ArgumentsDefinition? : Type Directives[Const]?
924
- */
925
- function parseFieldDefinition(lexer: Lexer<*>): FieldDefinitionNode {
926
- const start = lexer.token;
927
- const description = parseDescription(lexer);
928
- const name = parseName(lexer);
929
- const args = parseArgumentDefs(lexer);
930
- expectToken(lexer, TokenKind.COLON);
931
- const type = parseTypeReference(lexer);
932
- const directives = parseDirectives(lexer, true);
933
- return {
934
- kind: Kind.FIELD_DEFINITION,
935
- description,
936
- name,
937
- arguments: args,
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
- * ArgumentsDefinition : ( InputValueDefinition+ )
946
- */
947
- function parseArgumentDefs(lexer: Lexer<*>): Array<InputValueDefinitionNode> {
948
- if (!peek(lexer, TokenKind.PAREN_L)) {
949
- return [];
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
- * InputValueDefinition :
956
- * - Description? Name : Type DefaultValue? Directives[Const]?
957
- */
958
- function parseInputValueDef(lexer: Lexer<*>): InputValueDefinitionNode {
959
- const start = lexer.token;
960
- const description = parseDescription(lexer);
961
- const name = parseName(lexer);
962
- expectToken(lexer, TokenKind.COLON);
963
- const type = parseTypeReference(lexer);
964
- let defaultValue;
965
- if (expectOptionalToken(lexer, TokenKind.EQUALS)) {
966
- defaultValue = parseConstValue(lexer);
967
- }
968
- const directives = parseDirectives(lexer, true);
969
- return {
970
- kind: Kind.INPUT_VALUE_DEFINITION,
971
- description,
972
- name,
973
- type,
974
- defaultValue,
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
- * InterfaceTypeDefinition :
982
- * - Description? interface Name Directives[Const]? FieldsDefinition?
983
- */
984
- function parseInterfaceTypeDefinition(
985
- lexer: Lexer<*>,
986
- ): InterfaceTypeDefinitionNode {
987
- const start = lexer.token;
988
- const description = parseDescription(lexer);
989
- expectKeyword(lexer, 'interface');
990
- const name = parseName(lexer);
991
- const directives = parseDirectives(lexer, true);
992
- const fields = parseFieldsDefinition(lexer);
993
- return {
994
- kind: Kind.INTERFACE_TYPE_DEFINITION,
995
- description,
996
- name,
997
- directives,
998
- fields,
999
- loc: loc(lexer, start),
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
- * UnionTypeDefinition :
1005
- * - Description? union Name Directives[Const]? UnionMemberTypes?
1006
- */
1007
- function parseUnionTypeDefinition(lexer: Lexer<*>): UnionTypeDefinitionNode {
1008
- const start = lexer.token;
1009
- const description = parseDescription(lexer);
1010
- expectKeyword(lexer, 'union');
1011
- const name = parseName(lexer);
1012
- const directives = parseDirectives(lexer, true);
1013
- const types = parseUnionMemberTypes(lexer);
1014
- return {
1015
- kind: Kind.UNION_TYPE_DEFINITION,
1016
- description,
1017
- name,
1018
- directives,
1019
- types,
1020
- loc: loc(lexer, start),
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
- * UnionMemberTypes :
1026
- * - = `|`? NamedType
1027
- * - UnionMemberTypes | NamedType
1028
- */
1029
- function parseUnionMemberTypes(lexer: Lexer<*>): Array<NamedTypeNode> {
1030
- const types = [];
1031
- if (expectOptionalToken(lexer, TokenKind.EQUALS)) {
1032
- // Optional leading pipe
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
- * EnumTypeDefinition :
1043
- * - Description? enum Name Directives[Const]? EnumValuesDefinition?
1044
- */
1045
- function parseEnumTypeDefinition(lexer: Lexer<*>): EnumTypeDefinitionNode {
1046
- const start = lexer.token;
1047
- const description = parseDescription(lexer);
1048
- expectKeyword(lexer, 'enum');
1049
- const name = parseName(lexer);
1050
- const directives = parseDirectives(lexer, true);
1051
- const values = parseEnumValuesDefinition(lexer);
1052
- return {
1053
- kind: Kind.ENUM_TYPE_DEFINITION,
1054
- description,
1055
- name,
1056
- directives,
1057
- values,
1058
- loc: loc(lexer, start),
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
- * EnumValuesDefinition : { EnumValueDefinition+ }
1064
- */
1065
- function parseEnumValuesDefinition(
1066
- lexer: Lexer<*>,
1067
- ): Array<EnumValueDefinitionNode> {
1068
- return peek(lexer, TokenKind.BRACE_L)
1069
- ? many(
1070
- lexer,
1071
- TokenKind.BRACE_L,
1072
- parseEnumValueDefinition,
1073
- TokenKind.BRACE_R,
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
- * EnumValueDefinition : Description? EnumValue Directives[Const]?
1080
- *
1081
- * EnumValue : Name
1082
- */
1083
- function parseEnumValueDefinition(lexer: Lexer<*>): EnumValueDefinitionNode {
1084
- const start = lexer.token;
1085
- const description = parseDescription(lexer);
1086
- const name = parseName(lexer);
1087
- const directives = parseDirectives(lexer, true);
1088
- return {
1089
- kind: Kind.ENUM_VALUE_DEFINITION,
1090
- description,
1091
- name,
1092
- directives,
1093
- loc: loc(lexer, start),
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
- * InputObjectTypeDefinition :
1099
- * - Description? input Name Directives[Const]? InputFieldsDefinition?
1100
- */
1101
- function parseInputObjectTypeDefinition(
1102
- lexer: Lexer<*>,
1103
- ): InputObjectTypeDefinitionNode {
1104
- const start = lexer.token;
1105
- const description = parseDescription(lexer);
1106
- expectKeyword(lexer, 'input');
1107
- const name = parseName(lexer);
1108
- const directives = parseDirectives(lexer, true);
1109
- const fields = parseInputFieldsDefinition(lexer);
1110
- return {
1111
- kind: Kind.INPUT_OBJECT_TYPE_DEFINITION,
1112
- description,
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
- * InputFieldsDefinition : { InputValueDefinition+ }
1122
- */
1123
- function parseInputFieldsDefinition(
1124
- lexer: Lexer<*>,
1125
- ): Array<InputValueDefinitionNode> {
1126
- return peek(lexer, TokenKind.BRACE_L)
1127
- ? many(lexer, TokenKind.BRACE_L, parseInputValueDef, TokenKind.BRACE_R)
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
- * TypeSystemExtension :
1133
- * - SchemaExtension
1134
- * - TypeExtension
1135
- *
1136
- * TypeExtension :
1137
- * - ScalarTypeExtension
1138
- * - ObjectTypeExtension
1139
- * - InterfaceTypeExtension
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
- throw unexpected(lexer, keywordToken);
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
- * SchemaExtension :
1171
- * - extend schema Directives[Const]? { OperationTypeDefinition+ }
1172
- * - extend schema Directives[Const]
1173
- */
1174
- function parseSchemaExtension(lexer: Lexer<*>): SchemaExtensionNode {
1175
- const start = lexer.token;
1176
- expectKeyword(lexer, 'extend');
1177
- expectKeyword(lexer, 'schema');
1178
- const directives = parseDirectives(lexer, true);
1179
- const operationTypes = peek(lexer, TokenKind.BRACE_L)
1180
- ? many(
1181
- lexer,
1182
- TokenKind.BRACE_L,
1183
- parseOperationTypeDefinition,
1184
- TokenKind.BRACE_R,
1185
- )
1186
- : [];
1187
- if (directives.length === 0 && operationTypes.length === 0) {
1188
- throw unexpected(lexer);
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
- * ScalarTypeExtension :
1200
- * - extend scalar Name Directives[Const]
1201
- */
1202
- function parseScalarTypeExtension(lexer: Lexer<*>): ScalarTypeExtensionNode {
1203
- const start = lexer.token;
1204
- expectKeyword(lexer, 'extend');
1205
- expectKeyword(lexer, 'scalar');
1206
- const name = parseName(lexer);
1207
- const directives = parseDirectives(lexer, true);
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
- * ObjectTypeExtension :
1221
- * - extend type Name ImplementsInterfaces? Directives[Const]? FieldsDefinition
1222
- * - extend type Name ImplementsInterfaces? Directives[Const]
1223
- * - extend type Name ImplementsInterfaces
1224
- */
1225
- function parseObjectTypeExtension(lexer: Lexer<*>): ObjectTypeExtensionNode {
1226
- const start = lexer.token;
1227
- expectKeyword(lexer, 'extend');
1228
- expectKeyword(lexer, 'type');
1229
- const name = parseName(lexer);
1230
- const interfaces = parseImplementsInterfaces(lexer);
1231
- const directives = parseDirectives(lexer, true);
1232
- const fields = parseFieldsDefinition(lexer);
1233
- if (
1234
- interfaces.length === 0 &&
1235
- directives.length === 0 &&
1236
- fields.length === 0
1237
- ) {
1238
- throw unexpected(lexer);
1239
- }
1240
- return {
1241
- kind: Kind.OBJECT_TYPE_EXTENSION,
1242
- name,
1243
- interfaces,
1244
- directives,
1245
- fields,
1246
- loc: loc(lexer, start),
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
- * InterfaceTypeExtension :
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
- * UnionTypeExtension :
1278
- * - extend union Name Directives[Const]? UnionMemberTypes
1279
- * - extend union Name Directives[Const]
1280
- */
1281
- function parseUnionTypeExtension(lexer: Lexer<*>): UnionTypeExtensionNode {
1282
- const start = lexer.token;
1283
- expectKeyword(lexer, 'extend');
1284
- expectKeyword(lexer, 'union');
1285
- const name = parseName(lexer);
1286
- const directives = parseDirectives(lexer, true);
1287
- const types = parseUnionMemberTypes(lexer);
1288
- if (directives.length === 0 && types.length === 0) {
1289
- throw unexpected(lexer);
1290
- }
1291
- return {
1292
- kind: Kind.UNION_TYPE_EXTENSION,
1293
- name,
1294
- directives,
1295
- types,
1296
- loc: loc(lexer, start),
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
- * EnumTypeExtension :
1302
- * - extend enum Name Directives[Const]? EnumValuesDefinition
1303
- * - extend enum Name Directives[Const]
1304
- */
1305
- function parseEnumTypeExtension(lexer: Lexer<*>): EnumTypeExtensionNode {
1306
- const start = lexer.token;
1307
- expectKeyword(lexer, 'extend');
1308
- expectKeyword(lexer, 'enum');
1309
- const name = parseName(lexer);
1310
- const directives = parseDirectives(lexer, true);
1311
- const values = parseEnumValuesDefinition(lexer);
1312
- if (directives.length === 0 && values.length === 0) {
1313
- throw unexpected(lexer);
1314
- }
1315
- return {
1316
- kind: Kind.ENUM_TYPE_EXTENSION,
1317
- name,
1318
- directives,
1319
- values,
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
- * InputObjectTypeExtension :
1326
- * - extend input Name Directives[Const]? InputFieldsDefinition
1327
- * - extend input Name Directives[Const]
1328
- */
1329
- function parseInputObjectTypeExtension(
1330
- lexer: Lexer<*>,
1331
- ): InputObjectTypeExtensionNode {
1332
- const start = lexer.token;
1333
- expectKeyword(lexer, 'extend');
1334
- expectKeyword(lexer, 'input');
1335
- const name = parseName(lexer);
1336
- const directives = parseDirectives(lexer, true);
1337
- const fields = parseInputFieldsDefinition(lexer);
1338
- if (directives.length === 0 && fields.length === 0) {
1339
- throw unexpected(lexer);
1340
- }
1341
- return {
1342
- kind: Kind.INPUT_OBJECT_TYPE_EXTENSION,
1343
- name,
1344
- directives,
1345
- fields,
1346
- loc: loc(lexer, start),
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
- * DirectiveDefinition :
1352
- * - Description? directive @ Name ArgumentsDefinition? `repeatable`? on DirectiveLocations
1353
- */
1354
- function parseDirectiveDefinition(lexer: Lexer<*>): DirectiveDefinitionNode {
1355
- const start = lexer.token;
1356
- const description = parseDescription(lexer);
1357
- expectKeyword(lexer, 'directive');
1358
- expectToken(lexer, TokenKind.AT);
1359
- const name = parseName(lexer);
1360
- const args = parseArgumentDefs(lexer);
1361
- const repeatable = expectOptionalKeyword(lexer, 'repeatable');
1362
- expectKeyword(lexer, 'on');
1363
- const locations = parseDirectiveLocations(lexer);
1364
- return {
1365
- kind: Kind.DIRECTIVE_DEFINITION,
1366
- description,
1367
- name,
1368
- arguments: args,
1369
- repeatable,
1370
- locations,
1371
- loc: loc(lexer, start),
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
- * DirectiveLocations :
1377
- * - `|`? DirectiveLocation
1378
- * - DirectiveLocations | DirectiveLocation
1379
- */
1380
- function parseDirectiveLocations(lexer: Lexer<*>): Array<NameNode> {
1381
- // Optional leading pipe
1382
- expectOptionalToken(lexer, TokenKind.PIPE);
1383
- const locations = [];
1384
- do {
1385
- locations.push(parseDirectiveLocation(lexer));
1386
- } while (expectOptionalToken(lexer, TokenKind.PIPE));
1387
- return locations;
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
- * DirectiveLocation :
1392
- * - ExecutableDirectiveLocation
1393
- * - TypeSystemDirectiveLocation
1394
- *
1395
- * ExecutableDirectiveLocation : one of
1396
- * `QUERY`
1397
- * `MUTATION`
1398
- * `SUBSCRIPTION`
1399
- * `FIELD`
1400
- * `FRAGMENT_DEFINITION`
1401
- * `FRAGMENT_SPREAD`
1402
- * `INLINE_FRAGMENT`
1403
- *
1404
- * TypeSystemDirectiveLocation : one of
1405
- * `SCHEMA`
1406
- * `SCALAR`
1407
- * `OBJECT`
1408
- * `FIELD_DEFINITION`
1409
- * `ARGUMENT_DEFINITION`
1410
- * `INTERFACE`
1411
- * `UNION`
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
- // Core parsing utility functions
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
- * Returns a location object, used to identify the place in
1430
- * the source that created a given parsed object.
1431
- */
1432
- function loc(lexer: Lexer<*>, startToken: Token): Location | void {
1433
- if (!lexer.options.noLocation) {
1434
- return new Loc(startToken, lexer.lastToken, lexer.source);
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
- function Loc(startToken: Token, endToken: Token, source: Source) {
1439
- this.start = startToken.start;
1440
- this.end = endToken.end;
1441
- this.startToken = startToken;
1442
- this.endToken = endToken;
1443
- this.source = source;
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
- // Print a simplified form when appearing in JSON/util.inspect.
1447
- defineToJSON(Loc, function() {
1448
- return { start: this.start, end: this.end };
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
- * If the next token is of the given kind, return that token after advancing
1460
- * the lexer. Otherwise, do not change the parser state and throw an error.
1461
- */
1462
- function expectToken(lexer: Lexer<*>, kind: TokenKindEnum): Token {
1463
- const token = lexer.token;
1464
- if (token.kind === kind) {
1465
- lexer.advance();
1466
- return token;
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
- * If the next token is of the given kind, return that token after advancing
1478
- * the lexer. Otherwise, do not change the parser state and return undefined.
1479
- */
1480
- function expectOptionalToken(lexer: Lexer<*>, kind: TokenKindEnum): ?Token {
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
- * If the next token is a given keyword, advance the lexer.
1491
- * Otherwise, do not change the parser state and throw an error.
1492
- */
1493
- function expectKeyword(lexer: Lexer<*>, value: string) {
1494
- const token = lexer.token;
1495
- if (token.kind === TokenKind.NAME && token.value === value) {
1496
- lexer.advance();
1497
- } else {
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
- lexer.source,
1419
+ this._lexer.source,
1500
1420
  token.start,
1501
- `Expected "${value}", found ${getTokenDesc(token)}`,
1421
+ `Expected ${kind}, found ${getTokenDesc(token)}`,
1502
1422
  );
1503
1423
  }
1504
- }
1505
1424
 
1506
- /**
1507
- * If the next token is a given keyword, return "true" after advancing
1508
- * the lexer. Otherwise, do not change the parser state and return "false".
1509
- */
1510
- function expectOptionalKeyword(lexer: Lexer<*>, value: string): boolean {
1511
- const token = lexer.token;
1512
- if (token.kind === TokenKind.NAME && token.value === value) {
1513
- lexer.advance();
1514
- return true;
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
- * Helper function for creating an error when an unexpected lexed token
1521
- * is encountered.
1522
- */
1523
- function unexpected(lexer: Lexer<*>, atToken?: ?Token): GraphQLError {
1524
- const token = atToken || lexer.token;
1525
- return syntaxError(
1526
- lexer.source,
1527
- token.start,
1528
- `Unexpected ${getTokenDesc(token)}`,
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
- * Returns a possibly empty list of parse nodes, determined by
1534
- * the parseFn. This list begins with a lex token of openKind
1535
- * and ends with a lex token of closeKind. Advances the parser
1536
- * to the next lex token after the closing token.
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
- * Returns a non-empty list of parse nodes, determined by
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 many<T>(
1559
- lexer: Lexer<*>,
1560
- openKind: TokenKindEnum,
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
  }