Skip to content

Commit 44ac2db

Browse files
committed
extendSchema: Fix infinite loop with recursive union
1 parent 0ad0e46 commit 44ac2db

File tree

2 files changed

+29
-11
lines changed

2 files changed

+29
-11
lines changed

src/utilities/__tests__/extendSchema-test.js

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -280,6 +280,19 @@ describe('extendSchema', () => {
280280
expect(unionField.type).to.equal(someUnionType);
281281
});
282282

283+
it('allows extension of union by adding itself', () => {
284+
const extendedSchema = extendTestSchema(`
285+
extend union SomeUnion = SomeUnion
286+
`);
287+
288+
const errors = validateSchema(extendedSchema);
289+
expect(errors.length).to.be.above(0);
290+
291+
expect(printTestSchemaChanges(extendedSchema)).to.equal(dedent`
292+
union SomeUnion = Foo | Biz | SomeUnion
293+
`);
294+
});
295+
283296
it('extends inputs by adding new fields', () => {
284297
const extendedSchema = extendTestSchema(`
285298
extend input SomeInput {

src/utilities/extendSchema.js

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -494,7 +494,20 @@ export function extendSchema(
494494
? type.extensionASTNodes.concat(typeExtensionsMap[name])
495495
: typeExtensionsMap[name]
496496
: type.extensionASTNodes;
497-
const unionTypes = type.getTypes().map(extendNamedType);
497+
return new GraphQLUnionType({
498+
name,
499+
description: type.description,
500+
types: () => extendPossibleTypes(type),
501+
astNode: type.astNode,
502+
resolveType: type.resolveType,
503+
extensionASTNodes,
504+
});
505+
}
506+
507+
function extendPossibleTypes(
508+
type: GraphQLUnionType,
509+
): Array<GraphQLObjectType> {
510+
const possibleTypes = type.getTypes().map(extendNamedType);
498511

499512
// If there are any extensions to the union, apply those here.
500513
const extensions = typeExtensionsMap[type.name];
@@ -504,19 +517,11 @@ export function extendSchema(
504517
// Note: While this could make early assertions to get the correctly
505518
// typed values, that would throw immediately while type system
506519
// validation with validateSchema() will produce more actionable results.
507-
unionTypes.push((astBuilder.buildType(namedType): any));
520+
possibleTypes.push((astBuilder.buildType(namedType): any));
508521
}
509522
}
510523
}
511-
512-
return new GraphQLUnionType({
513-
name,
514-
description: type.description,
515-
types: unionTypes,
516-
astNode: type.astNode,
517-
resolveType: type.resolveType,
518-
extensionASTNodes,
519-
});
524+
return possibleTypes;
520525
}
521526

522527
function extendImplementedInterfaces(

0 commit comments

Comments
 (0)