@apollo/federation
Version:
Apollo Federation Utilities
64 lines • 3.29 kB
JavaScript
Object.defineProperty(exports, "__esModule", { value: true });
exports.keyFieldsMissingExternal = void 0;
const graphql_1 = require("graphql");
const schema_helper_1 = require("@apollo/subgraph/dist/schema-helper");
const directives_1 = require("@apollo/subgraph/dist/directives");
const utils_1 = require("../../utils");
const utilities_1 = require("../../../utilities");
const keyFieldsMissingExternal = ({ name: serviceName, typeDefs, }) => {
const errors = [];
let keyDirectiveInfoOnTypeExtensions = [];
(0, graphql_1.visit)(typeDefs, {
ObjectTypeExtension(node) {
const keyDirectivesOnTypeExtension = (0, utils_1.findDirectivesOnNode)(node, 'key');
const keyDirectivesInfo = keyDirectivesOnTypeExtension
.map(keyDirective => keyDirective.arguments &&
(0, utils_1.isStringValueNode)(keyDirective.arguments[0].value)
? {
typeName: node.name.value,
keyArgument: keyDirective.arguments[0].value.value,
}
: null)
.filter(utilities_1.isNotNullOrUndefined);
keyDirectiveInfoOnTypeExtensions.push(...keyDirectivesInfo);
},
});
let schema = new graphql_1.GraphQLSchema({
query: undefined,
directives: [...graphql_1.specifiedDirectives, ...directives_1.knownSubgraphDirectives],
});
try {
schema = (0, schema_helper_1.buildSchemaFromSDL)(typeDefs, schema);
}
catch (e) {
errors.push(e);
return errors;
}
const typeInfo = new graphql_1.TypeInfo(schema);
for (const { typeName, keyArgument } of keyDirectiveInfoOnTypeExtensions) {
const keyDirectiveSelectionSet = (0, graphql_1.parse)(`fragment __generated on ${typeName} { ${keyArgument} }`);
(0, graphql_1.visit)(keyDirectiveSelectionSet, (0, graphql_1.visitWithTypeInfo)(typeInfo, {
Field(node) {
var _a;
const fieldDef = typeInfo.getFieldDef();
const parentType = typeInfo.getParentType();
if (parentType) {
if (!fieldDef) {
errors.push((0, utils_1.errorWithCode)('KEY_FIELDS_MISSING_EXTERNAL', (0, utils_1.logServiceAndType)(serviceName, parentType.name) +
`A @key directive specifies a field which is not found in this service. Add a field to this type with @external.`, node));
return;
}
const externalDirectivesOnField = (0, utils_1.findDirectivesOnNode)(fieldDef.astNode, 'external');
if (externalDirectivesOnField.length === 0) {
errors.push((0, utils_1.errorWithCode)('KEY_FIELDS_MISSING_EXTERNAL', (0, utils_1.logServiceAndType)(serviceName, parentType.name) +
`A @key directive specifies the \`${fieldDef.name}\` field which has no matching @external field.`, (_a = fieldDef.astNode) !== null && _a !== void 0 ? _a : undefined));
}
}
},
}));
}
return errors;
};
exports.keyFieldsMissingExternal = keyFieldsMissingExternal;
//# sourceMappingURL=keyFieldsMissingExternal.js.map
;