UNPKG

@apollo/federation

Version:
92 lines 6.16 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.UniqueTypeNamesWithFields = exports.existedTypeNameMessage = exports.duplicateTypeNameMessage = void 0; const graphql_1 = require("graphql"); const utils_1 = require("../../utils"); function duplicateTypeNameMessage(typeName) { return `There can be only one type named "${typeName}".`; } exports.duplicateTypeNameMessage = duplicateTypeNameMessage; function existedTypeNameMessage(typeName) { return `Type "${typeName}" already exists in the schema. It cannot also be defined in this type definition.`; } exports.existedTypeNameMessage = existedTypeNameMessage; function UniqueTypeNamesWithFields(context) { const knownTypes = Object.create(null); const schema = context.getSchema(); return { ScalarTypeDefinition: checkTypeName, ObjectTypeDefinition: checkTypeName, InterfaceTypeDefinition: checkTypeName, UnionTypeDefinition: checkTypeName, EnumTypeDefinition: checkTypeName, InputObjectTypeDefinition: checkTypeName, }; function checkTypeName(node) { const typeName = node.name.value; const typeFromSchema = schema && schema.getType(typeName); const typeNodeFromSchema = typeFromSchema && typeFromSchema.astNode; const typeNodeFromDefs = knownTypes[typeName]; const duplicateTypeNode = typeNodeFromSchema || typeNodeFromDefs; if (duplicateTypeNode) { const possibleErrors = []; const { kind, fields, fieldArgs } = (0, utils_1.diffTypeNodes)(node, duplicateTypeNode); const fieldsDiff = Object.entries(fields); if (kind.length > 0) { context.reportError((0, utils_1.errorWithCode)('VALUE_TYPE_KIND_MISMATCH', `${(0, utils_1.logServiceAndType)(duplicateTypeNode.serviceName, typeName)}Found kind mismatch on expected value type belonging to services \`${duplicateTypeNode.serviceName}\` and \`${node.serviceName}\`. \`${typeName}\` is defined as both a \`${kind[0]}\` and a \`${kind[1]}\`. In order to define \`${typeName}\` in multiple places, the kinds must be identical.`, [node, duplicateTypeNode])); return; } const typesHaveSameFieldShape = fieldsDiff.length === 0 || fieldsDiff.every(([fieldName, types]) => { var _a, _b; if (types.length === 2) { const fieldNode = 'fields' in node && ((_a = node.fields) === null || _a === void 0 ? void 0 : _a.find((field) => field.name.value === fieldName)); const duplicateFieldNode = 'fields' in duplicateTypeNode && ((_b = duplicateTypeNode.fields) === null || _b === void 0 ? void 0 : _b.find(field => field.name.value === fieldName)); possibleErrors.push((0, utils_1.errorWithCode)('VALUE_TYPE_FIELD_TYPE_MISMATCH', `${(0, utils_1.logServiceAndType)(duplicateTypeNode.serviceName, typeName, fieldName)}A field was defined differently in different services. \`${duplicateTypeNode.serviceName}\` and \`${node.serviceName}\` define \`${typeName}.${fieldName}\` as a ${types[1]} and ${types[0]} respectively. In order to define \`${typeName}\` in multiple places, the fields and their types must be identical.`, fieldNode && duplicateFieldNode ? [fieldNode.type, duplicateFieldNode.type] : undefined)); return true; } return false; }); const fieldArgDiffs = Object.values(fieldArgs); const typesHaveSameInputValuesShape = fieldArgDiffs.length === 0 || fieldArgDiffs.every((fieldArgDiff) => { const argTypeDiff = Object.entries(fieldArgDiff); return (argTypeDiff.length === 0 || argTypeDiff.every(([argName, types]) => { if (types.length === 2) { possibleErrors.push((0, utils_1.errorWithCode)('VALUE_TYPE_INPUT_VALUE_MISMATCH', `${(0, utils_1.logServiceAndType)(duplicateTypeNode.serviceName, typeName)}A field's input type (\`${argName}\`) was defined differently in different services. \`${duplicateTypeNode.serviceName}\` and \`${node.serviceName}\` define \`${argName}\` as a ${types[1]} and ${types[0]} respectively. In order to define \`${typeName}\` in multiple places, the input values and their types must be identical.`, [node, duplicateTypeNode])); return true; } return false; })); }); if (typesHaveSameFieldShape && typesHaveSameInputValuesShape) { possibleErrors.forEach(error => context.reportError(error)); if ((0, utils_1.isTypeNodeAnEntity)(node) || (0, utils_1.isTypeNodeAnEntity)(duplicateTypeNode)) { const entityNode = (0, utils_1.isTypeNodeAnEntity)(duplicateTypeNode) ? duplicateTypeNode : node; context.reportError((0, utils_1.errorWithCode)('VALUE_TYPE_NO_ENTITY', `${(0, utils_1.logServiceAndType)(entityNode.serviceName, typeName)}Value types cannot be entities (using the \`@key\` directive). Please ensure that the \`${typeName}\` type is extended properly or remove the \`@key\` directive if this is not an entity.`, [node, duplicateTypeNode])); } return false; } } if (typeFromSchema) { context.reportError(new graphql_1.GraphQLError(existedTypeNameMessage(typeName), node.name)); return; } if (knownTypes[typeName]) { context.reportError(new graphql_1.GraphQLError(duplicateTypeNameMessage(typeName), [ knownTypes[typeName], node.name, ])); } else { knownTypes[typeName] = node; } return false; } } exports.UniqueTypeNamesWithFields = UniqueTypeNamesWithFields; //# sourceMappingURL=uniqueTypeNamesWithFields.js.map