@@ -2,10 +2,12 @@ import { invariant } from '../jsutils/invariant.js';
22import { isObjectLike } from '../jsutils/isObjectLike.js' ;
33import type { ObjMap } from '../jsutils/ObjMap.js' ;
44import type { Path } from '../jsutils/Path.js' ;
5- import { addPath } from '../jsutils/Path.js' ;
5+ import { addPath , pathToArray } from '../jsutils/Path.js' ;
66
77import type { GraphQLError } from '../error/GraphQLError.js' ;
88
9+ import { Kind } from '../language/kinds.js' ;
10+
911import type {
1012 GraphQLObjectType ,
1113 GraphQLOutputType ,
@@ -16,17 +18,18 @@ import {
1618 isNonNullType ,
1719 isObjectType ,
1820} from '../type/definition.js' ;
21+ import { GraphQLStreamDirective } from '../type/directives.js' ;
1922
2023import type { TransformationContext } from './buildTransformationContext.js' ;
21- import type { FieldDetailsList , GroupedFieldSet } from './collectFields.js' ;
24+ import type { FieldDetails , GroupedFieldSet } from './collectFields.js' ;
2225import { collectSubfields as _collectSubfields } from './collectFields.js' ;
2326import { memoize3of4 } from './memoize3of4.js' ;
2427
2528const collectSubfields = memoize3of4 (
2629 (
2730 context : TransformationContext ,
2831 returnType : GraphQLObjectType ,
29- fieldDetailsList : FieldDetailsList ,
32+ fieldDetailsList : ReadonlyArray < FieldDetails > ,
3033 path : Path | undefined ,
3134 ) => _collectSubfields ( context , returnType , fieldDetailsList , path ) ,
3235) ;
@@ -67,13 +70,14 @@ export function completeValue(
6770}
6871
6972// eslint-disable-next-line @typescript-eslint/max-params
70- function completeSubValue (
73+ export function completeSubValue (
7174 context : TransformationContext ,
7275 errors : Array < GraphQLError > ,
7376 returnType : GraphQLOutputType ,
74- fieldDetailsList : FieldDetailsList ,
77+ fieldDetailsList : ReadonlyArray < FieldDetails > ,
7578 result : unknown ,
7679 path : Path ,
80+ listDepth = 0 ,
7781) : unknown {
7882 if ( isNonNullType ( returnType ) ) {
7983 return completeSubValue (
@@ -110,6 +114,7 @@ function completeSubValue(
110114 fieldDetailsList ,
111115 result ,
112116 path ,
117+ listDepth ,
113118 ) ;
114119 }
115120
@@ -120,7 +125,7 @@ function completeSubValue(
120125function completeObjectType (
121126 context : TransformationContext ,
122127 errors : Array < GraphQLError > ,
123- fieldDetailsList : FieldDetailsList ,
128+ fieldDetailsList : ReadonlyArray < FieldDetails > ,
124129 result : ObjMap < unknown > ,
125130 path : Path ,
126131) : ObjMap < unknown > {
@@ -172,22 +177,87 @@ function completeObjectType(
172177function completeListValue (
173178 context : TransformationContext ,
174179 errors : Array < GraphQLError > ,
175- returnType : GraphQLOutputType ,
176- fieldDetailsList : FieldDetailsList ,
180+ itemType : GraphQLOutputType ,
181+ fieldDetailsList : ReadonlyArray < FieldDetails > ,
177182 result : Array < unknown > ,
178183 path : Path ,
184+ listDepth : number ,
179185) : Array < unknown > {
180186 const completedItems = [ ] ;
187+
181188 for ( let index = 0 ; index < result . length ; index ++ ) {
182189 const completed = completeSubValue (
183190 context ,
184191 errors ,
185- returnType ,
192+ itemType ,
186193 fieldDetailsList ,
187194 result [ index ] ,
188195 addPath ( path , index , undefined ) ,
196+ listDepth + 1 ,
189197 ) ;
190198 completedItems . push ( completed ) ;
191199 }
200+
201+ maybeAddStream (
202+ context ,
203+ itemType ,
204+ fieldDetailsList ,
205+ listDepth ,
206+ path ,
207+ result . length ,
208+ ) ;
209+
192210 return completedItems ;
193211}
212+
213+ // eslint-disable-next-line @typescript-eslint/max-params
214+ function maybeAddStream (
215+ context : TransformationContext ,
216+ itemType : GraphQLOutputType ,
217+ fieldDetailsList : ReadonlyArray < FieldDetails > ,
218+ listDepth : number ,
219+ path : Path ,
220+ nextIndex : number ,
221+ ) : void {
222+ if ( listDepth > 0 ) {
223+ return ;
224+ }
225+
226+ let stream ;
227+ for ( const fieldDetails of fieldDetailsList ) {
228+ const directives = fieldDetails . node . directives ;
229+ if ( ! directives ) {
230+ continue ;
231+ }
232+ stream = directives . find (
233+ ( directive ) => directive . name . value === GraphQLStreamDirective . name ,
234+ ) ;
235+ if ( stream != null ) {
236+ break ;
237+ }
238+ }
239+
240+ if ( stream == null ) {
241+ return ;
242+ }
243+
244+ const labelArg = stream . arguments ?. find ( ( arg ) => arg . name . value === 'label' ) ;
245+ invariant ( labelArg != null ) ;
246+ const labelValue = labelArg . value ;
247+ invariant ( labelValue . kind === Kind . STRING ) ;
248+ const label = labelValue . value ;
249+ invariant ( label != null ) ;
250+ const pendingLabels = context . pendingLabelsByPath . get (
251+ pathToArray ( path ) . join ( '.' ) ,
252+ ) ;
253+ if ( pendingLabels ?. has ( label ) ) {
254+ const streamUsage = context . streamUsageMap . get ( label ) ;
255+ invariant ( streamUsage != null ) ;
256+ streamUsage . nextIndex = nextIndex ;
257+ streamUsage . streams . add ( {
258+ path,
259+ itemType,
260+ fieldDetailsList,
261+ } ) ;
262+ }
263+ }
0 commit comments