UNPKG

@theguild/federation-composition

Version:

Open Source Composition library for Apollo Federation

42 lines (41 loc) 2.1 kB
import { GraphQLError } from 'graphql'; import { andList } from '../../../utils/format.js'; export function InvalidFieldSharingRule(context) { return { ObjectTypeField(objectTypeState, fieldState) { if (fieldState.usedAsKey && Array.from(fieldState.byGraph.values()).every(field => field.usedAsKey)) { return; } const nonSharableIn = []; const resolvableIn = []; for (const [graphId, field] of fieldState.byGraph) { const objectTypeIsShareable = objectTypeState.byGraph.get(graphId).shareable; const fieldIsShareable = field.shareable; const fieldIsExternal = field.external; const fieldHasOverride = field.override; const fieldIsUsedAsKey = field.usedAsKey; if (fieldIsExternal || fieldHasOverride) { continue; } if (objectTypeIsShareable || fieldIsShareable || fieldIsUsedAsKey) { resolvableIn.push(graphId); continue; } nonSharableIn.push(graphId); resolvableIn.push(graphId); } if (nonSharableIn.length >= 1 && resolvableIn.length > 1) { const isNonSharableInAll = resolvableIn.every(graphId => nonSharableIn.includes(graphId)); const message = `Non-shareable field "${objectTypeState.name}.${fieldState.name}" is resolved from multiple subgraphs: it is resolved from subgraphs ${andList(resolvableIn.map(context.graphIdToName), false, '"')} and defined as non-shareable in ${isNonSharableInAll ? 'all of them' : `subgraph${nonSharableIn.length > 1 ? 's' : ''} ${andList(nonSharableIn.map(context.graphIdToName), true, '"')}`}`; context.reportError(new GraphQLError(message, { extensions: { code: 'INVALID_FIELD_SHARING', }, })); } }, }; }