UNPKG

@theguild/federation-composition

Version:

Open Source Composition library for Apollo Federation

90 lines (89 loc) 4.33 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.FieldsOfTheSameTypeRule = void 0; const graphql_1 = require("graphql"); function FieldsOfTheSameTypeRule(context) { return { ObjectTypeField(objectTypeState, fieldState) { const typeToGraphs = new Map(); fieldState.byGraph.forEach((field, graphName) => { const isNullable = !field.type.endsWith('!'); const isNullableInSupergraph = !fieldState.type.endsWith('!'); const isMatchingNonNullablePart = fieldState.type.replace(/!$/, '') === field.type.replace(/!$/, ''); let normalizedOutputType; if (isMatchingNonNullablePart) { normalizedOutputType = isNullableInSupergraph ? isNullable ? field.type : field.type.replace(/!$/, '') : field.type; } else { normalizedOutputType = field.type; } const existing = typeToGraphs.get(normalizedOutputType); if (existing) { existing.push(graphName); } else { typeToGraphs.set(normalizedOutputType, [graphName]); } }); if (typeToGraphs.size > 1) { const groups = Array.from(typeToGraphs.entries()).map(([outputType, graphs]) => { const plural = graphs.length > 1 ? 's' : ''; return `type "${outputType}" in subgraph${plural} "${graphs .map(context.graphIdToName) .join('", "')}"`; }); const [first, second, ...rest] = groups; context.reportError(new graphql_1.GraphQLError(`Type of field "${objectTypeState.name}.${fieldState.name}" is incompatible across subgraphs: it has ${first} but ${second}${rest.length ? ` and ${rest.join(' and ')}` : ''}`, { extensions: { code: 'FIELD_TYPE_MISMATCH', }, })); } }, InputObjectTypeField(inputObjectTypeState, fieldState) { const typeToGraphs = new Map(); fieldState.byGraph.forEach((field, graphName) => { const isNonNullable = field.type.endsWith('!'); const isNonNullableInSupergraph = fieldState.type.endsWith('!'); const isMatchingNonNullablePart = fieldState.type.replace(/!$/, '') === field.type.replace(/!$/, ''); let normalizedOutputType; if (isMatchingNonNullablePart) { normalizedOutputType = isNonNullableInSupergraph ? isNonNullable ? field.type : field.type + '!' : field.type; } else { normalizedOutputType = field.type; } const existing = typeToGraphs.get(normalizedOutputType); if (existing) { existing.push(graphName); } else { typeToGraphs.set(normalizedOutputType, [graphName]); } }); if (typeToGraphs.size > 1) { const groups = Array.from(typeToGraphs.entries()).map(([outputType, graphs]) => { const plural = graphs.length > 1 ? 's' : ''; return `type "${outputType}" in subgraph${plural} "${graphs .map(context.graphIdToName) .join('", "')}"`; }); const [first, second, ...rest] = groups; context.reportError(new graphql_1.GraphQLError(`Type of field "${inputObjectTypeState.name}.${fieldState.name}" is incompatible across subgraphs: it has ${first} but ${second}${rest.length ? ` and ${rest.join(' and ')}` : ''}`, { extensions: { code: 'FIELD_TYPE_MISMATCH', }, })); } }, }; } exports.FieldsOfTheSameTypeRule = FieldsOfTheSameTypeRule;