@@ -25,8 +25,12 @@ import type {
2525 FragmentSpreadNode ,
2626 InlineFragmentNode ,
2727 FragmentDefinitionNode ,
28+ ArgumentNode ,
29+ ValueNode ,
30+ DirectiveNode ,
2831} from '../language/ast' ;
2932import { Kind } from '../language/kinds' ;
33+ import { print } from '../language/printer' ;
3034
3135import type { GraphQLSchema } from '../type/schema' ;
3236import type {
@@ -66,6 +70,7 @@ import {
6670 getArgumentValues ,
6771 getDirectiveValues ,
6872} from './values' ;
73+ import { visit } from '../language' ;
6974
7075/**
7176 * Terminology
@@ -511,10 +516,14 @@ export function collectFields(
511516 ) {
512517 continue ;
513518 }
519+ const selectionSet = selectionSetWithFragmentArgumentsApplied (
520+ fragment ,
521+ selection . arguments ,
522+ ) ;
514523 collectFields (
515524 exeContext ,
516525 runtimeType ,
517- fragment . selectionSet ,
526+ selectionSet ,
518527 fields ,
519528 visitedFragmentNames ,
520529 ) ;
@@ -525,6 +534,38 @@ export function collectFields(
525534 return fields ;
526535}
527536
537+ function selectionSetWithFragmentArgumentsApplied ( fragment : FragmentDefinitionNode , fragmentArguments ?: ReadonlyArray < ArgumentNode > ) : SelectionSetNode {
538+ if ( fragment . variableDefinitions == null ) {
539+ return fragment . selectionSet ;
540+ }
541+
542+ const providedArguments : Map < string , ArgumentNode > = new Map ( ) ;
543+ for ( const arg of fragmentArguments ?? [ ] ) {
544+ providedArguments . set ( arg . name . value , arg ) ;
545+ }
546+ const fragmentArgumentValues : Map < string , ValueNode > = new Map ( ) ;
547+ for ( const argDef of fragment . variableDefinitions ?? [ ] ) {
548+ const argName = argDef . variable . name . value ;
549+ const providedArg = providedArguments . get ( argName ) ;
550+ const argDefaultValue = argDef . defaultValue ;
551+ if ( providedArg != null ) {
552+ fragmentArgumentValues . set ( argName , providedArg . value ) ;
553+ } else if ( argDefaultValue != null ) {
554+ fragmentArgumentValues . set ( argName , argDefaultValue ) ;
555+ }
556+ }
557+
558+ return visit ( fragment . selectionSet , {
559+ Variable ( variable ) {
560+ const replacementValue = fragmentArgumentValues . get ( variable . name . value ) ;
561+ if ( replacementValue != null ) {
562+ return replacementValue ;
563+ }
564+ return variable ;
565+ }
566+ } ) ;
567+ }
568+
528569/**
529570 * Determines if a field should be included based on the @include and @skip
530571 * directives, where @skip has higher precedence than @include.
0 commit comments