@@ -24,6 +24,7 @@ import type {
24
24
FieldDefinitionNode ,
25
25
FieldNode ,
26
26
FloatValueNode ,
27
+ FragmentArgumentDefinitionNode ,
27
28
FragmentDefinitionNode ,
28
29
FragmentSpreadNode ,
29
30
InlineFragmentNode ,
@@ -91,23 +92,6 @@ export interface ParseOptions {
91
92
*/
92
93
maxTokens ?: number | undefined ;
93
94
94
- /**
95
- * @deprecated will be removed in the v17.0.0
96
- *
97
- * If enabled, the parser will understand and parse variable definitions
98
- * contained in a fragment definition. They'll be represented in the
99
- * `variableDefinitions` field of the FragmentDefinitionNode.
100
- *
101
- * The syntax is identical to normal, query-defined variables. For example:
102
- *
103
- * ```graphql
104
- * fragment A($var: Boolean = false) on T {
105
- * ...
106
- * }
107
- * ```
108
- */
109
- allowLegacyFragmentVariables ?: boolean | undefined ;
110
-
111
95
/**
112
96
* EXPERIMENTAL:
113
97
*
@@ -550,7 +534,7 @@ export class Parser {
550
534
/**
551
535
* Corresponds to both FragmentSpread and InlineFragment in the spec.
552
536
*
553
- * FragmentSpread : ... FragmentName Directives?
537
+ * FragmentSpread : ... FragmentName Arguments? Directives?
554
538
*
555
539
* InlineFragment : ... TypeCondition? Directives? SelectionSet
556
540
*/
@@ -560,9 +544,18 @@ export class Parser {
560
544
561
545
const hasTypeCondition = this . expectOptionalKeyword ( 'on' ) ;
562
546
if ( ! hasTypeCondition && this . peek ( TokenKind . NAME ) ) {
547
+ const name = this . parseFragmentName ( ) ;
548
+ if ( this . peek ( TokenKind . PAREN_L ) ) {
549
+ return this . node < FragmentSpreadNode > ( start , {
550
+ kind : Kind . FRAGMENT_SPREAD ,
551
+ name,
552
+ arguments : this . parseArguments ( false ) ,
553
+ directives : this . parseDirectives ( false ) ,
554
+ } ) ;
555
+ }
563
556
return this . node < FragmentSpreadNode > ( start , {
564
557
kind : Kind . FRAGMENT_SPREAD ,
565
- name : this . parseFragmentName ( ) ,
558
+ name,
566
559
directives : this . parseDirectives ( false ) ,
567
560
} ) ;
568
561
}
@@ -576,29 +569,17 @@ export class Parser {
576
569
577
570
/**
578
571
* FragmentDefinition :
579
- * - fragment FragmentName on TypeCondition Directives? SelectionSet
572
+ * - fragment FragmentName FragmentArgumentsDefinition? on TypeCondition Directives? SelectionSet
580
573
*
581
574
* TypeCondition : NamedType
582
575
*/
583
576
parseFragmentDefinition ( ) : FragmentDefinitionNode {
584
577
const start = this . _lexer . token ;
585
578
this . expectKeyword ( 'fragment' ) ;
586
- // Legacy support for defining variables within fragments changes
587
- // the grammar of FragmentDefinition:
588
- // - fragment FragmentName VariableDefinitions? on TypeCondition Directives? SelectionSet
589
- if ( this . _options . allowLegacyFragmentVariables === true ) {
590
- return this . node < FragmentDefinitionNode > ( start , {
591
- kind : Kind . FRAGMENT_DEFINITION ,
592
- name : this . parseFragmentName ( ) ,
593
- variableDefinitions : this . parseVariableDefinitions ( ) ,
594
- typeCondition : ( this . expectKeyword ( 'on' ) , this . parseNamedType ( ) ) ,
595
- directives : this . parseDirectives ( false ) ,
596
- selectionSet : this . parseSelectionSet ( ) ,
597
- } ) ;
598
- }
599
579
return this . node < FragmentDefinitionNode > ( start , {
600
580
kind : Kind . FRAGMENT_DEFINITION ,
601
581
name : this . parseFragmentName ( ) ,
582
+ arguments : this . parseFragmentArgumentDefs ( ) ,
602
583
typeCondition : ( this . expectKeyword ( 'on' ) , this . parseNamedType ( ) ) ,
603
584
directives : this . parseDirectives ( false ) ,
604
585
selectionSet : this . parseSelectionSet ( ) ,
@@ -615,6 +596,48 @@ export class Parser {
615
596
return this . parseName ( ) ;
616
597
}
617
598
599
+ /**
600
+ * FragmentArgumentsDefinition : ( FragmentArgumentDefinition+ )
601
+ */
602
+ parseFragmentArgumentDefs ( ) : Array < FragmentArgumentDefinitionNode > {
603
+ return this . optionalMany (
604
+ TokenKind . PAREN_L ,
605
+ this . parseFragmentArgumentDef ,
606
+ TokenKind . PAREN_R ,
607
+ ) ;
608
+ }
609
+
610
+ /**
611
+ * FragmentArgumentDefinition :
612
+ * - Description? Variable : Type DefaultValue? Directives[Const]?
613
+ *
614
+ * Note: identical to InputValueDefinition, EXCEPT Name always begins
615
+ * with $, so we need to parse a Variable out instead of a plain Name.
616
+ *
617
+ * Note: identical to VariableDefinition, EXCEPT we allow Description.
618
+ * Fragments are re-used, and their arguments may need documentation.
619
+ */
620
+ parseFragmentArgumentDef ( ) : FragmentArgumentDefinitionNode {
621
+ const start = this . _lexer . token ;
622
+ const description = this . parseDescription ( ) ;
623
+ const variable = this . parseVariable ( ) ;
624
+ this . expectToken ( TokenKind . COLON ) ;
625
+ const type = this . parseTypeReference ( ) ;
626
+ let defaultValue ;
627
+ if ( this . expectOptionalToken ( TokenKind . EQUALS ) ) {
628
+ defaultValue = this . parseConstValueLiteral ( ) ;
629
+ }
630
+ const directives = this . parseConstDirectives ( ) ;
631
+ return this . node < FragmentArgumentDefinitionNode > ( start , {
632
+ kind : Kind . FRAGMENT_ARGUMENT_DEFINITION ,
633
+ description,
634
+ variable,
635
+ type,
636
+ defaultValue,
637
+ directives,
638
+ } ) ;
639
+ }
640
+
618
641
// Implements the parsing rules in the Values section.
619
642
620
643
/**
0 commit comments