UNPKG

@apollo/federation

Version:
106 lines 5.23 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.UniqueFieldDefinitionNames = exports.existedFieldDefinitionNameMessage = exports.duplicateFieldDefinitionNameMessage = void 0; const graphql_1 = require("graphql"); const utils_1 = require("../../utils"); function duplicateFieldDefinitionNameMessage(typeName, fieldName) { return `Field "${typeName}.${fieldName}" can only be defined once.`; } exports.duplicateFieldDefinitionNameMessage = duplicateFieldDefinitionNameMessage; function existedFieldDefinitionNameMessage(typeName, fieldName, serviceName) { return `${(0, utils_1.logServiceAndType)(serviceName, typeName, fieldName)}Field "${typeName}.${fieldName}" already exists in the schema. It cannot also be defined in this type extension. If this is meant to be an external field, add the \`@external\` directive.`; } exports.existedFieldDefinitionNameMessage = existedFieldDefinitionNameMessage; function UniqueFieldDefinitionNames(context) { const schema = context.getSchema(); const existingTypeMap = schema ? schema.getTypeMap() : Object.create(null); const knownFieldNames = Object.create(null); const possibleValueTypes = Object.create(null); return { InputObjectTypeExtension: checkFieldUniqueness, InterfaceTypeExtension: checkFieldUniqueness, ObjectTypeExtension: checkFieldUniqueness, InputObjectTypeDefinition: checkFieldUniquenessExcludingValueTypes, InterfaceTypeDefinition: checkFieldUniquenessExcludingValueTypes, ObjectTypeDefinition: checkFieldUniquenessExcludingValueTypes, }; function checkFieldUniqueness(node) { var _a; const typeName = node.name.value; if (!knownFieldNames[typeName]) { knownFieldNames[typeName] = Object.create(null); } if (!node.fields) { return false; } const fieldNames = knownFieldNames[typeName]; for (const fieldDef of node.fields) { const fieldName = fieldDef.name.value; if (hasField(existingTypeMap[typeName], fieldName)) { const type = existingTypeMap[typeName]; context.reportError(new graphql_1.GraphQLError(existedFieldDefinitionNameMessage(typeName, fieldName, (_a = node.serviceName) !== null && _a !== void 0 ? _a : ''), (0, graphql_1.isObjectType)(type) || (0, graphql_1.isInterfaceType)(type) || (0, graphql_1.isInputObjectType)(type) ? type.getFields()[fieldName].astNode : undefined)); } else if (fieldNames[fieldName]) { context.reportError(new graphql_1.GraphQLError(duplicateFieldDefinitionNameMessage(typeName, fieldName), [fieldNames[fieldName], fieldDef.name])); } else { fieldNames[fieldName] = fieldDef.name; } } return false; } function checkFieldUniquenessExcludingValueTypes(node) { const typeName = node.name.value; const valueTypeFromSchema = existingTypeMap[typeName] && existingTypeMap[typeName].astNode; const duplicateTypeNode = valueTypeFromSchema || possibleValueTypes[node.name.value]; if (duplicateTypeNode) { const { fields, fieldArgs } = (0, utils_1.diffTypeNodes)(node, duplicateTypeNode); if (Object.values(fields).every(diffEntry => diffEntry.length === 2)) { return false; } const fieldArgDiffs = Object.values(fieldArgs); for (const argDiff of fieldArgDiffs) { const argTypes = Object.values(argDiff); if (argTypes.length > 0 && argTypes.every((diffEntry) => diffEntry.length === 2)) { return false; } } } else { possibleValueTypes[node.name.value] = node; } if (!knownFieldNames[typeName]) { knownFieldNames[typeName] = Object.create(null); } if (!node.fields) { return false; } const fieldNames = knownFieldNames[typeName]; for (const fieldDef of node.fields) { const fieldName = fieldDef.name.value; if (hasField(existingTypeMap[typeName], fieldName)) { context.reportError(new graphql_1.GraphQLError(existedFieldDefinitionNameMessage(typeName, fieldName, existingTypeMap[typeName].astNode.serviceName), fieldDef.name)); } else if (fieldNames[fieldName]) { context.reportError(new graphql_1.GraphQLError(duplicateFieldDefinitionNameMessage(typeName, fieldName), [fieldNames[fieldName], fieldDef.name])); } else { fieldNames[fieldName] = fieldDef.name; } } return false; } } exports.UniqueFieldDefinitionNames = UniqueFieldDefinitionNames; function hasField(type, fieldName) { if ((0, graphql_1.isObjectType)(type) || (0, graphql_1.isInterfaceType)(type) || (0, graphql_1.isInputObjectType)(type)) { return Boolean(type.getFields()[fieldName]); } return false; } //# sourceMappingURL=uniqueFieldDefinitionNames.js.map