@@ -188,30 +188,56 @@ export class GraphqlValueTransformer {
188
188
inputType : GraphQLInputObjectType ,
189
189
parent : TypeTreeNode ,
190
190
) : { [ name : string ] : TypeTreeNode } {
191
- return Object . entries ( inputType . getFields ( ) ) . reduce ( ( result , [ key , field ] ) => {
192
- const namedType = getNamedType ( field . type ) ;
193
- if ( namedType === parent . type ) {
194
- // prevent recursion-induced stack overflow
195
- return result ;
196
- }
197
- const child : TypeTreeNode = {
198
- type : namedType ,
199
- isList : this . isList ( field . type ) ,
200
- parent,
201
- fragmentRefs : [ ] ,
202
- children : { } ,
203
- } ;
204
- if ( isInputObjectType ( namedType ) ) {
205
- child . children = this . getChildrenTreeNodes ( namedType , child ) ;
206
- }
207
- return { ...result , [ key ] : child } ;
208
- } , { } as { [ name : string ] : TypeTreeNode } ) ;
191
+ return Object . entries ( inputType . getFields ( ) ) . reduce (
192
+ ( result , [ key , field ] ) => {
193
+ const namedType = getNamedType ( field . type ) ;
194
+ if ( namedType === parent . type ) {
195
+ // prevent recursion-induced stack overflow
196
+ return result ;
197
+ }
198
+ const child : TypeTreeNode = {
199
+ type : namedType ,
200
+ isList : this . isList ( field . type ) ,
201
+ parent,
202
+ fragmentRefs : [ ] ,
203
+ children : { } ,
204
+ } ;
205
+ if ( isInputObjectType ( namedType ) ) {
206
+ child . children = this . getChildrenTreeNodes ( namedType , child ) ;
207
+ }
208
+ return { ...result , [ key ] : child } ;
209
+ } ,
210
+ { } as { [ name : string ] : TypeTreeNode } ,
211
+ ) ;
209
212
}
210
213
211
214
private isList ( t : any ) : boolean {
212
215
return isListType ( t ) || ( isNonNullType ( t ) && isListType ( t . ofType ) ) ;
213
216
}
214
217
218
+ private deepMergeChildren (
219
+ target : { [ name : string ] : TypeTreeNode } ,
220
+ source : { [ name : string ] : TypeTreeNode } ,
221
+ ) : { [ name : string ] : TypeTreeNode } {
222
+ const merged = { ...target } ;
223
+ for ( const key in source ) {
224
+ if ( source . hasOwnProperty ( key ) ) {
225
+ if ( merged [ key ] ) {
226
+ // If the key already exists, merge recursively
227
+ if ( source [ key ] . children && Object . keys ( source [ key ] . children ) . length > 0 ) {
228
+ merged [ key ] . children = this . deepMergeChildren (
229
+ merged [ key ] . children ,
230
+ source [ key ] . children ,
231
+ ) ;
232
+ }
233
+ } else {
234
+ merged [ key ] = source [ key ] ;
235
+ }
236
+ }
237
+ }
238
+ return merged ;
239
+ }
240
+
215
241
private getTypeNodeByPath ( typeTree : TypeTree , path : Array < string | number > ) : TypeTreeNode | undefined {
216
242
let targetNode : TypeTreeNode | undefined = typeTree . operation ;
217
243
for ( const segment of path ) {
@@ -224,9 +250,12 @@ export class GraphqlValueTransformer {
224
250
const ref = fragmentRefs . pop ( ) ;
225
251
if ( ref ) {
226
252
const fragment = typeTree . fragments [ ref ] ;
227
- children = { ...children , ...fragment . children } ;
228
- if ( fragment . fragmentRefs ) {
229
- fragmentRefs . push ( ...fragment . fragmentRefs ) ;
253
+ if ( fragment ) {
254
+ // Deeply merge the children
255
+ children = this . deepMergeChildren ( children , fragment . children ) ;
256
+ if ( fragment . fragmentRefs ) {
257
+ fragmentRefs . push ( ...fragment . fragmentRefs ) ;
258
+ }
230
259
}
231
260
}
232
261
}
0 commit comments