@@ -225,9 +225,10 @@ export class Parser {
225225 if ( this . peek ( TokenKind . NAME ) ) {
226226 switch ( this . _lexer . token . value ) {
227227 case 'query' :
228+ return this . parseOperationDefinition ( true ) ;
228229 case 'mutation' :
229230 case 'subscription' :
230- return this . parseOperationDefinition ( ) ;
231+ return this . parseOperationDefinition ( false ) ;
231232 case 'fragment' :
232233 return this . parseFragmentDefinition ( ) ;
233234 case 'schema' :
@@ -243,7 +244,7 @@ export class Parser {
243244 return this . parseTypeSystemExtension ( ) ;
244245 }
245246 } else if ( this . peek ( TokenKind . BRACE_L ) ) {
246- return this . parseOperationDefinition ( ) ;
247+ return this . parseOperationDefinition ( true ) ;
247248 } else if ( this . peekDescription ( ) ) {
248249 return this . parseTypeSystemDefinition ( ) ;
249250 }
@@ -258,7 +259,7 @@ export class Parser {
258259 * - SelectionSet
259260 * - OperationType Name? VariableDefinitions? Directives? SelectionSet
260261 */
261- parseOperationDefinition ( ) : OperationDefinitionNode {
262+ parseOperationDefinition ( allowRequiredField : boolean ) : OperationDefinitionNode {
262263 const start = this . _lexer . token ;
263264 if ( this . peek ( TokenKind . BRACE_L ) ) {
264265 return {
@@ -267,7 +268,7 @@ export class Parser {
267268 name : undefined ,
268269 variableDefinitions : [ ] ,
269270 directives : [ ] ,
270- selectionSet : this . parseSelectionSet ( ) ,
271+ selectionSet : this . parseSelectionSet ( allowRequiredField ) ,
271272 loc : this . loc ( start ) ,
272273 } ;
273274 }
@@ -282,7 +283,7 @@ export class Parser {
282283 name,
283284 variableDefinitions : this . parseVariableDefinitions ( ) ,
284285 directives : this . parseDirectives ( false ) ,
285- selectionSet : this . parseSelectionSet ( ) ,
286+ selectionSet : this . parseSelectionSet ( allowRequiredField ) ,
286287 loc : this . loc ( start ) ,
287288 } ;
288289 }
@@ -348,13 +349,18 @@ export class Parser {
348349 /**
349350 * SelectionSet : { Selection+ }
350351 */
351- parseSelectionSet ( ) : SelectionSetNode {
352+ parseSelectionSet ( allowRequiredField : boolean = false ) : SelectionSetNode {
352353 const start = this . _lexer . token ;
354+ const _allowRequiredField = allowRequiredField
355+ let parseSelectionFn : ( ) => SelectionNode = function ( ) : SelectionNode {
356+ return this . parseSelection ( _allowRequiredField )
357+ }
358+
353359 return {
354360 kind : Kind . SELECTION_SET ,
355361 selections : this . many (
356362 TokenKind . BRACE_L ,
357- this . parseSelection ,
363+ parseSelectionFn ,
358364 TokenKind . BRACE_R ,
359365 ) ,
360366 loc : this . loc ( start ) ,
@@ -367,23 +373,30 @@ export class Parser {
367373 * - FragmentSpread
368374 * - InlineFragment
369375 */
370- parseSelection ( ) : SelectionNode {
376+ parseSelection ( allowRequiredField : boolean ) : SelectionNode {
371377 return this . peek ( TokenKind . SPREAD )
372378 ? this . parseFragment ( )
373- : this . parseField ( ) ;
379+ : this . parseField ( allowRequiredField ) ;
374380 }
375381
376382 /**
377383 * Field : Alias? Name Arguments? Directives? SelectionSet?
378384 *
379385 * Alias : Name :
380386 */
381- parseField ( ) : FieldNode {
387+ parseField ( allowRequiredField : boolean ) : FieldNode {
382388 const start = this . _lexer . token ;
383389
384390 const nameOrAlias = this . parseName ( ) ;
385391 let alias ;
386392 let name ;
393+ let required ;
394+ if ( allowRequiredField && this . expectOptionalToken ( TokenKind . BANG ) ) {
395+ required = true
396+ } else {
397+ required = false
398+ }
399+
387400 if ( this . expectOptionalToken ( TokenKind . COLON ) ) {
388401 alias = nameOrAlias ;
389402 name = this . parseName ( ) ;
@@ -398,8 +411,9 @@ export class Parser {
398411 arguments : this . parseArguments ( false ) ,
399412 directives : this . parseDirectives ( false ) ,
400413 selectionSet : this . peek ( TokenKind . BRACE_L )
401- ? this . parseSelectionSet ( )
414+ ? this . parseSelectionSet ( allowRequiredField )
402415 : undefined ,
416+ required : required ,
403417 loc : this . loc ( start ) ,
404418 } ;
405419 }
@@ -464,7 +478,7 @@ export class Parser {
464478 kind : Kind . INLINE_FRAGMENT ,
465479 typeCondition : hasTypeCondition ? this . parseNamedType ( ) : undefined ,
466480 directives : this . parseDirectives ( false ) ,
467- selectionSet : this . parseSelectionSet ( ) ,
481+ selectionSet : this . parseSelectionSet ( true ) ,
468482 loc : this . loc ( start ) ,
469483 } ;
470484 }
@@ -488,7 +502,7 @@ export class Parser {
488502 variableDefinitions : this . parseVariableDefinitions ( ) ,
489503 typeCondition : ( this . expectKeyword ( 'on' ) , this . parseNamedType ( ) ) ,
490504 directives : this . parseDirectives ( false ) ,
491- selectionSet : this . parseSelectionSet ( ) ,
505+ selectionSet : this . parseSelectionSet ( true ) ,
492506 loc : this . loc ( start ) ,
493507 } ;
494508 }
@@ -497,7 +511,7 @@ export class Parser {
497511 name : this . parseFragmentName ( ) ,
498512 typeCondition : ( this . expectKeyword ( 'on' ) , this . parseNamedType ( ) ) ,
499513 directives : this . parseDirectives ( false ) ,
500- selectionSet : this . parseSelectionSet ( ) ,
514+ selectionSet : this . parseSelectionSet ( true ) ,
501515 loc : this . loc ( start ) ,
502516 } ;
503517 }
0 commit comments