@@ -21,6 +21,11 @@ import { typeFromAST } from '../utilities/typeFromAST';
2121
2222import { getDirectiveValues } from './values' ;
2323
24+ interface FragmentEntry {
25+ fragment : FragmentDefinitionNode ;
26+ runtimeType : GraphQLObjectType ;
27+ }
28+
2429/**
2530 * Given a selectionSet, collects all of the fields and returns them.
2631 *
@@ -37,16 +42,34 @@ export function collectFields(
3742 runtimeType : GraphQLObjectType ,
3843 selectionSet : SelectionSetNode ,
3944) : Map < string , ReadonlyArray < FieldNode > > {
45+ const foundFragments : Array < FragmentEntry > = [ ] ;
4046 const fields = new Map ( ) ;
47+ const visited = new Set < string > ( ) ;
4148 collectFieldsImpl (
4249 schema ,
4350 fragments ,
4451 variableValues ,
4552 runtimeType ,
4653 selectionSet ,
4754 fields ,
48- new Set ( ) ,
55+ visited ,
56+ foundFragments ,
4957 ) ;
58+
59+ let entry ;
60+ while ( ( entry = foundFragments . pop ( ) ) !== undefined ) {
61+ collectFieldsImpl (
62+ schema ,
63+ fragments ,
64+ variableValues ,
65+ entry . runtimeType ,
66+ entry . fragment . selectionSet ,
67+ fields ,
68+ visited ,
69+ foundFragments ,
70+ ) ;
71+ }
72+
5073 return fields ;
5174}
5275
@@ -68,6 +91,7 @@ export function collectSubfields(
6891 fieldNodes : ReadonlyArray < FieldNode > ,
6992) : Map < string , ReadonlyArray < FieldNode > > {
7093 const subFieldNodes = new Map ( ) ;
94+ const foundFragments : Array < FragmentEntry > = [ ] ;
7195 const visitedFragmentNames = new Set < string > ( ) ;
7296 for ( const node of fieldNodes ) {
7397 if ( node . selectionSet ) {
@@ -79,9 +103,25 @@ export function collectSubfields(
79103 node . selectionSet ,
80104 subFieldNodes ,
81105 visitedFragmentNames ,
106+ foundFragments ,
82107 ) ;
83108 }
84109 }
110+
111+ let entry ;
112+ while ( ( entry = foundFragments . pop ( ) ) !== undefined ) {
113+ collectFieldsImpl (
114+ schema ,
115+ fragments ,
116+ variableValues ,
117+ entry . runtimeType ,
118+ entry . fragment . selectionSet ,
119+ subFieldNodes ,
120+ visitedFragmentNames ,
121+ foundFragments ,
122+ ) ;
123+ }
124+
85125 return subFieldNodes ;
86126}
87127
@@ -93,6 +133,7 @@ function collectFieldsImpl(
93133 selectionSet : SelectionSetNode ,
94134 fields : Map < string , Array < FieldNode > > ,
95135 visitedFragmentNames : Set < string > ,
136+ foundFragments : Array < FragmentEntry > ,
96137) : void {
97138 for ( const selection of selectionSet . selections ) {
98139 switch ( selection . kind ) {
@@ -124,6 +165,7 @@ function collectFieldsImpl(
124165 selection . selectionSet ,
125166 fields ,
126167 visitedFragmentNames ,
168+ foundFragments ,
127169 ) ;
128170 break ;
129171 }
@@ -143,15 +185,8 @@ function collectFieldsImpl(
143185 ) {
144186 continue ;
145187 }
146- collectFieldsImpl (
147- schema ,
148- fragments ,
149- variableValues ,
150- runtimeType ,
151- fragment . selectionSet ,
152- fields ,
153- visitedFragmentNames ,
154- ) ;
188+
189+ foundFragments . push ( { runtimeType, fragment } ) ;
155190 break ;
156191 }
157192 }
0 commit comments