UNPKG

@theguild/federation-composition

Version:

Open Source Composition library for Apollo Federation

43 lines (42 loc) 2.14 kB
import { GraphQLError } from 'graphql'; export function InterfaceKeyMissingImplementationTypeRule(context) { return { InterfaceType(interfaceState) { let someSubgraphsAreMissingImplementation = false; for (const interfaceStateInGraph of interfaceState.byGraph.values()) { if (interfaceStateInGraph.keys.length === 0) { continue; } if (interfaceStateInGraph.implementedBy.size === 0) { someSubgraphsAreMissingImplementation = true; break; } } if (!someSubgraphsAreMissingImplementation) { return; } for (const [graph, interfaceStateInGraph] of interfaceState.byGraph) { if (interfaceStateInGraph.keys.length === 0) { continue; } const firstKeyFields = interfaceStateInGraph.keys[0].fields; const graphName = context.graphIdToName(graph); const typesToDefine = Array.from(interfaceState.implementedBy) .filter(objectTypeName => !interfaceStateInGraph.implementedBy.has(objectTypeName)) .sort(); context.reportError(new GraphQLError(`[${graphName}] Interface type "${interfaceState.name}" has a resolvable key (@key(fields: "${firstKeyFields}")) in subgraph "${graphName}" but that subgraph is missing some of the supergraph implementation types of "${interfaceState.name}". Subgraph "${graphName}" should define ${typesToDefine.length > 1 ? 'types' : 'type'} ${joinWithAnd(typesToDefine)} (and have ${typesToDefine.length > 1 ? 'them' : 'it'} implement "${interfaceState.name}").`, { extensions: { code: 'INTERFACE_KEY_MISSING_IMPLEMENTATION_TYPE', }, })); } }, }; } function joinWithAnd(list) { if (list.length <= 2) { return `"${list.join('" and "')}"`; } const last = list.pop(); return `"${list.join('", "')}" and "${last}"`; }