UNPKG

@apollo/federation

Version:
48 lines 3.37 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.providesNotOnEntity = void 0; const graphql_1 = require("graphql"); const utils_1 = require("../../utils"); const providesNotOnEntity = ({ schema, serviceList }) => { var _a, _b; const errors = []; const types = schema.getTypeMap(); for (const [typeName, namedType] of Object.entries(types)) { if (!(0, graphql_1.isObjectType)(namedType)) continue; for (const [fieldName, field] of Object.entries(namedType.getFields())) { const fieldFederationMetadata = (0, utils_1.getFederationMetadata)(field); const serviceName = fieldFederationMetadata === null || fieldFederationMetadata === void 0 ? void 0 : fieldFederationMetadata.serviceName; if (!serviceName && (fieldFederationMetadata === null || fieldFederationMetadata === void 0 ? void 0 : fieldFederationMetadata.provides) && !(fieldFederationMetadata === null || fieldFederationMetadata === void 0 ? void 0 : fieldFederationMetadata.belongsToValueType)) throw Error('Internal Consistency Error: field with provides information does not have service name.'); if (!serviceName) continue; const getBaseType = (type) => (0, graphql_1.isListType)(type) || (0, graphql_1.isNonNullType)(type) ? getBaseType(type.ofType) : type; const baseType = getBaseType(field.type); if (fieldFederationMetadata === null || fieldFederationMetadata === void 0 ? void 0 : fieldFederationMetadata.provides) { const typeNode = (0, utils_1.findTypeNodeInServiceList)(typeName, serviceName, serviceList); const fieldNode = typeNode && 'fields' in typeNode ? (_a = typeNode.fields) === null || _a === void 0 ? void 0 : _a.find(field => field.name.value === fieldName) : undefined; const providesDirectiveNode = (0, utils_1.findDirectivesOnNode)(fieldNode, 'provides'); if (!(0, graphql_1.isObjectType)(baseType)) { errors.push((0, utils_1.errorWithCode)('PROVIDES_NOT_ON_ENTITY', (0, utils_1.logServiceAndType)(serviceName, typeName, fieldName) + `uses the @provides directive but \`${typeName}.${fieldName}\` returns \`${field.type}\`, which is not an Object or List type. @provides can only be used on Object types with at least one @key, or Lists of such Objects.`, providesDirectiveNode)); continue; } const fieldType = types[baseType.name]; const selectedFieldIsEntity = (_b = (0, utils_1.getFederationMetadata)(fieldType)) === null || _b === void 0 ? void 0 : _b.keys; if (!selectedFieldIsEntity) { errors.push((0, utils_1.errorWithCode)('PROVIDES_NOT_ON_ENTITY', (0, utils_1.logServiceAndType)(serviceName, typeName, fieldName) + `uses the @provides directive but \`${typeName}.${fieldName}\` does not return a type that has a @key. Try adding a @key to the \`${baseType}\` type.`, providesDirectiveNode)); } } } } return errors; }; exports.providesNotOnEntity = providesNotOnEntity; //# sourceMappingURL=providesNotOnEntity.js.map