Skip to content

Commit ac1361a

Browse files
committed
fix(stitch): handle @oneOfs in subschemas
1 parent e5eb881 commit ac1361a

File tree

3 files changed

+39
-0
lines changed

3 files changed

+39
-0
lines changed

.changeset/rare-chairs-itch.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@graphql-tools/stitch': patch
3+
---
4+
5+
Handle `@oneOf` directive properly while stitching subschemas

packages/stitch/src/mergeCandidates.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,9 @@ export function mergeCandidates<TContext = Record<string, any>>(
6464
typeMergingOptions?: TypeMergingOptions<TContext>,
6565
): GraphQLNamedType {
6666
const initialCandidateType = candidates[0]?.type;
67+
if (candidates.length === 1) {
68+
return initialCandidateType!;
69+
}
6770
if (
6871
candidates.some(
6972
(candidate) =>
@@ -165,6 +168,8 @@ function mergeObjectTypeCandidates<TContext = Record<string, any>>(
165168
astNode,
166169
extensionASTNodes,
167170
extensions,
171+
// @ts-expect-error We know isOneOf exists here
172+
isOneOf: candidates.every((candidate) => candidate.type.isOneOf),
168173
};
169174

170175
return new GraphQLObjectType(typeConfig);
@@ -220,6 +225,8 @@ function mergeInputObjectTypeCandidates<TContext = Record<string, any>>(
220225
astNode,
221226
extensionASTNodes,
222227
extensions,
228+
// @ts-expect-error We know isOneOf exists here
229+
isOneOf: candidates.every((candidate) => candidate.type.isOneOf),
223230
};
224231

225232
return new GraphQLInputObjectType(typeConfig);
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import { stitchSchemas } from '@graphql-tools/stitch';
2+
import { buildSchema, printSchema } from 'graphql';
3+
import { expect, it } from 'vitest';
4+
5+
it('should merge @oneOf directives', () => {
6+
const subschemaSdl = /* GraphQL */ `
7+
type Query {
8+
findPerson(in: FindPersonInput): Person
9+
findPersonById(id: String): Person @deprecated(reason: "use findPerson")
10+
}
11+
12+
type Person {
13+
Name: String
14+
ID: String
15+
}
16+
17+
input FindPersonInput @oneOf {
18+
byId: String
19+
byName: String
20+
}
21+
`.trim();
22+
const subschema = buildSchema(subschemaSdl);
23+
const gatewaySchema = stitchSchemas({
24+
subschemas: [{ schema: subschema }],
25+
});
26+
expect(printSchema(gatewaySchema)).toBe(subschemaSdl);
27+
});

0 commit comments

Comments
 (0)