@@ -21,6 +21,11 @@ import { typeFromAST } from '../utilities/typeFromAST';
21
21
22
22
import { getDirectiveValues } from './values' ;
23
23
24
+ interface FragmentEntry {
25
+ fragment : FragmentDefinitionNode ;
26
+ runtimeType : GraphQLObjectType ;
27
+ } ;
28
+
24
29
/**
25
30
* Given a selectionSet, collects all of the fields and returns them.
26
31
*
@@ -37,16 +42,34 @@ export function collectFields(
37
42
runtimeType : GraphQLObjectType ,
38
43
selectionSet : SelectionSetNode ,
39
44
) : Map < string , ReadonlyArray < FieldNode > > {
45
+ const foundFragments : Array < FragmentEntry > = [ ] ;
40
46
const fields = new Map ( ) ;
47
+ const visited = new Set < string > ( ) ;
41
48
collectFieldsImpl (
42
49
schema ,
43
50
fragments ,
44
51
variableValues ,
45
52
runtimeType ,
46
53
selectionSet ,
47
54
fields ,
48
- new Set ( ) ,
55
+ visited ,
56
+ foundFragments ,
49
57
) ;
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
+
50
73
return fields ;
51
74
}
52
75
@@ -68,6 +91,7 @@ export function collectSubfields(
68
91
fieldNodes : ReadonlyArray < FieldNode > ,
69
92
) : Map < string , ReadonlyArray < FieldNode > > {
70
93
const subFieldNodes = new Map ( ) ;
94
+ const foundFragments : Array < FragmentEntry > = [ ] ;
71
95
const visitedFragmentNames = new Set < string > ( ) ;
72
96
for ( const node of fieldNodes ) {
73
97
if ( node . selectionSet ) {
@@ -79,9 +103,25 @@ export function collectSubfields(
79
103
node . selectionSet ,
80
104
subFieldNodes ,
81
105
visitedFragmentNames ,
106
+ foundFragments ,
82
107
) ;
83
108
}
84
109
}
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
+
85
125
return subFieldNodes ;
86
126
}
87
127
@@ -93,6 +133,7 @@ function collectFieldsImpl(
93
133
selectionSet : SelectionSetNode ,
94
134
fields : Map < string , Array < FieldNode > > ,
95
135
visitedFragmentNames : Set < string > ,
136
+ foundFragments : Array < FragmentEntry > ,
96
137
) : void {
97
138
for ( const selection of selectionSet . selections ) {
98
139
switch ( selection . kind ) {
@@ -124,6 +165,7 @@ function collectFieldsImpl(
124
165
selection . selectionSet ,
125
166
fields ,
126
167
visitedFragmentNames ,
168
+ foundFragments ,
127
169
) ;
128
170
break ;
129
171
}
@@ -143,15 +185,8 @@ function collectFieldsImpl(
143
185
) {
144
186
continue ;
145
187
}
146
- collectFieldsImpl (
147
- schema ,
148
- fragments ,
149
- variableValues ,
150
- runtimeType ,
151
- fragment . selectionSet ,
152
- fields ,
153
- visitedFragmentNames ,
154
- ) ;
188
+
189
+ foundFragments . push ( { runtimeType, fragment } ) ;
155
190
break ;
156
191
}
157
192
}
0 commit comments