Skip to content

Commit 4d9e0f6

Browse files
authored
Allow @interfaceObject to stand in for all runtime types (#3087)
Rather than relying on the fact that one filteredPaths is reached, allow @interfaceObject types to intersect with all runtime types
1 parent 0cad761 commit 4d9e0f6

File tree

3 files changed

+82
-0
lines changed

3 files changed

+82
-0
lines changed

.changeset/curvy-papayas-sit.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@apollo/composition": patch
3+
---
4+
5+
When doing interface type intersection detection, allow @interfaceObject to stand in for any type

composition-js/src/__tests__/compose.test.ts

+69
Original file line numberDiff line numberDiff line change
@@ -5220,4 +5220,73 @@ describe('@source* directives', () => {
52205220
);
52215221
});
52225222
});
5223+
5224+
it('fed-354 repro @interfaceObject failure', () => {
5225+
const subgraph1 = {
5226+
name: 'Subgraph1',
5227+
url: 'https://Subgraph1',
5228+
typeDefs: gql`
5229+
type Query {
5230+
error_query: TicketField!
5231+
}
5232+
5233+
type User @interfaceObject @key(fields: "id") {
5234+
id: ID!
5235+
}
5236+
5237+
interface TicketField {
5238+
id: ID!
5239+
createdBy: User
5240+
}
5241+
5242+
type TextTicketField implements TicketField @key(fields: "id") @shareable {
5243+
id: ID!
5244+
createdBy: User
5245+
}
5246+
`
5247+
};
5248+
5249+
const subgraph2 = {
5250+
name: 'Subgraph2',
5251+
url: 'https://Subgraph2',
5252+
typeDefs: gql`
5253+
interface Ticket @key(fields : "id", resolvable : true) {
5254+
id: ID!
5255+
}
5256+
5257+
interface User @key(fields : "id", resolvable : true) {
5258+
id: ID!
5259+
requestedTickets: [Ticket!]!
5260+
}
5261+
5262+
interface TicketField {
5263+
createdBy: User
5264+
id: ID!
5265+
}
5266+
5267+
type TextTicketField implements TicketField @shareable {
5268+
createdBy: User
5269+
id: ID!
5270+
}
5271+
5272+
type Customer implements User @key(fields : "id", resolvable : true) @shareable {
5273+
id: ID!
5274+
requestedTickets: [Ticket!]!
5275+
}
5276+
5277+
type Agent implements User @key(fields : "id", resolvable : true) @shareable {
5278+
id: ID!
5279+
requestedTickets: [Ticket!]!
5280+
}
5281+
5282+
type Question implements Ticket @key(fields : "id", resolvable : true) {
5283+
fields: [TicketField!]!
5284+
id: ID!
5285+
}
5286+
`
5287+
};
5288+
5289+
const result = composeAsFed2Subgraphs([subgraph1, subgraph2]);
5290+
assertCompositionSuccess(result);
5291+
});
52235292
});

composition-js/src/validate.ts

+8
Original file line numberDiff line numberDiff line change
@@ -580,6 +580,14 @@ export class ValidationState {
580580
for (const { path } of newSubgraphPathInfos) {
581581
const subgraph = path.path.tail.source;
582582
const typeNames = possibleRuntimeTypeNamesSorted(path.path);
583+
584+
// if we see a type here that is not included in the list of all
585+
// runtime types, it is safe to assume that it is an interface
586+
// behaving like a runtime type (i.e. an @interfaceObject) and
587+
// we should allow it to stand in for any runtime type
588+
if (typeNames.length === 1 && !allRuntimeTypes.includes(typeNames[0])) {
589+
continue;
590+
}
583591
runtimeTypesPerSubgraphs.set(subgraph, typeNames);
584592
// Note: we're formatting the elements in `runtimeTYpesToSubgraphs` because we're going to use it if we display an error. This doesn't
585593
// impact our set equality though since the formatting is consistent betweeen elements and type names syntax is sufficiently restricted

0 commit comments

Comments
 (0)