Skip to content

Commit 67ba13a

Browse files
committed
Allow to use @provide with interfaces
1 parent 9579f9d commit 67ba13a

File tree

4 files changed

+38
-26
lines changed

4 files changed

+38
-26
lines changed

packages/apollo-federation/src/composition/compose.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,9 @@ export function buildMapsFromServiceList(serviceList: ServiceDefinition[]) {
131131
for (let definition of typeDefsWithoutExternalFields.definitions) {
132132
if (
133133
definition.kind === Kind.OBJECT_TYPE_DEFINITION ||
134-
definition.kind === Kind.OBJECT_TYPE_EXTENSION
134+
definition.kind === Kind.OBJECT_TYPE_EXTENSION ||
135+
definition.kind === Kind.INTERFACE_TYPE_DEFINITION ||
136+
definition.kind === Kind.INTERFACE_TYPE_EXTENSION
135137
) {
136138
const typeName = definition.name.value;
137139

packages/apollo-federation/src/composition/utils.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import {
1616
GraphQLError,
1717
GraphQLSchema,
1818
isObjectType,
19+
isInterfaceType,
1920
GraphQLObjectType,
2021
getNamedType,
2122
GraphQLField,
@@ -219,7 +220,7 @@ export function findFieldsThatReturnType({
219220
schema: GraphQLSchema;
220221
typeToFind: GraphQLNamedType;
221222
}): GraphQLField<any, any>[] {
222-
if (!isObjectType(typeToFind)) return [];
223+
if (!isObjectType(typeToFind) && !isInterfaceType(typeToFind)) return [];
223224

224225
const fieldsThatReturnType: GraphQLField<any, any>[] = [];
225226
const types = schema.getTypeMap();

packages/apollo-federation/src/composition/validate/postComposition/externalUnused.ts

Lines changed: 31 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -62,29 +62,37 @@ export const externalUnused = (schema: GraphQLSchema) => {
6262
reviews: [Review]
6363
}
6464
*/
65-
const hasMatchingProvidesOnAnotherType = findFieldsThatReturnType({
66-
schema,
67-
typeToFind: parentType,
68-
}).some(field =>
69-
findDirectivesOnTypeOrField(field.astNode, 'provides').some(
70-
directive => {
71-
if (!directive.arguments) return false;
72-
const selections =
73-
isStringValueNode(directive.arguments[0].value) &&
74-
parseSelections(directive.arguments[0].value.value);
75-
// find the selections which are fields with names matching
76-
// our external field name
77-
return (
78-
selections &&
79-
selections.some(
80-
selection =>
81-
selection.kind === Kind.FIELD &&
82-
selection.name.value === externalFieldName,
83-
)
84-
);
85-
},
86-
),
87-
);
65+
const hasMatchingProvidesOnAnotherType = [
66+
parentType,
67+
...parentType.getInterfaces(),
68+
]
69+
.map(searchType =>
70+
findFieldsThatReturnType({
71+
schema,
72+
typeToFind: searchType,
73+
}),
74+
)
75+
.flat()
76+
.some(field =>
77+
findDirectivesOnTypeOrField(field.astNode, 'provides').some(
78+
directive => {
79+
if (!directive.arguments) return false;
80+
const selections =
81+
isStringValueNode(directive.arguments[0].value) &&
82+
parseSelections(directive.arguments[0].value.value);
83+
// find the selections which are fields with names matching
84+
// our external field name
85+
return (
86+
selections &&
87+
selections.some(
88+
selection =>
89+
selection.kind === Kind.FIELD &&
90+
selection.name.value === externalFieldName,
91+
)
92+
);
93+
},
94+
),
95+
);
8896

8997
if (hasMatchingProvidesOnAnotherType) continue;
9098

packages/apollo-federation/src/composition/validate/postComposition/providesNotOnEntity.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import {
22
GraphQLSchema,
33
isObjectType,
4+
isInterfaceType,
45
GraphQLError,
56
isListType,
67
isNonNullType,
@@ -47,7 +48,7 @@ export const providesNotOnEntity = (schema: GraphQLSchema) => {
4748

4849
// field has a @provides directive on it
4950
if (field.federation && field.federation.provides) {
50-
if (!isObjectType(baseType)) {
51+
if (!isObjectType(baseType) && !isInterfaceType(baseType)) {
5152
errors.push(
5253
errorWithCode(
5354
'PROVIDES_NOT_ON_ENTITY',

0 commit comments

Comments
 (0)