Skip to content

Commit

Permalink
fix(core): Fix undefined type issue with nested fragment spreads (#3351)
Browse files Browse the repository at this point in the history
  • Loading branch information
jhmen authored Feb 14, 2025
1 parent 07a9254 commit d0c0454
Showing 1 changed file with 50 additions and 21 deletions.
71 changes: 50 additions & 21 deletions packages/core/src/api/common/graphql-value-transformer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -188,30 +188,56 @@ export class GraphqlValueTransformer {
inputType: GraphQLInputObjectType,
parent: TypeTreeNode,
): { [name: string]: TypeTreeNode } {
return Object.entries(inputType.getFields()).reduce((result, [key, field]) => {
const namedType = getNamedType(field.type);
if (namedType === parent.type) {
// prevent recursion-induced stack overflow
return result;
}
const child: TypeTreeNode = {
type: namedType,
isList: this.isList(field.type),
parent,
fragmentRefs: [],
children: {},
};
if (isInputObjectType(namedType)) {
child.children = this.getChildrenTreeNodes(namedType, child);
}
return { ...result, [key]: child };
}, {} as { [name: string]: TypeTreeNode });
return Object.entries(inputType.getFields()).reduce(
(result, [key, field]) => {
const namedType = getNamedType(field.type);
if (namedType === parent.type) {
// prevent recursion-induced stack overflow
return result;
}
const child: TypeTreeNode = {
type: namedType,
isList: this.isList(field.type),
parent,
fragmentRefs: [],
children: {},
};
if (isInputObjectType(namedType)) {
child.children = this.getChildrenTreeNodes(namedType, child);
}
return { ...result, [key]: child };
},
{} as { [name: string]: TypeTreeNode },
);
}

private isList(t: any): boolean {
return isListType(t) || (isNonNullType(t) && isListType(t.ofType));
}

private deepMergeChildren(
target: { [name: string]: TypeTreeNode },
source: { [name: string]: TypeTreeNode },
): { [name: string]: TypeTreeNode } {
const merged = { ...target };
for (const key in source) {
if (source.hasOwnProperty(key)) {
if (merged[key]) {
// If the key already exists, merge recursively
if (source[key].children && Object.keys(source[key].children).length > 0) {
merged[key].children = this.deepMergeChildren(
merged[key].children,
source[key].children,
);
}
} else {
merged[key] = source[key];
}
}
}
return merged;
}

private getTypeNodeByPath(typeTree: TypeTree, path: Array<string | number>): TypeTreeNode | undefined {
let targetNode: TypeTreeNode | undefined = typeTree.operation;
for (const segment of path) {
Expand All @@ -224,9 +250,12 @@ export class GraphqlValueTransformer {
const ref = fragmentRefs.pop();
if (ref) {
const fragment = typeTree.fragments[ref];
children = { ...children, ...fragment.children };
if (fragment.fragmentRefs) {
fragmentRefs.push(...fragment.fragmentRefs);
if (fragment) {
// Deeply merge the children
children = this.deepMergeChildren(children, fragment.children);
if (fragment.fragmentRefs) {
fragmentRefs.push(...fragment.fragmentRefs);
}
}
}
}
Expand Down

0 comments on commit d0c0454

Please sign in to comment.