@apollo/federation
Version:
Apollo Federation Utilities
115 lines • 5.44 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.DirectiveMetadata = void 0;
const graphql_1 = require("graphql");
const utilities_1 = require("../utilities");
const utils_1 = require("./utils");
class DirectiveMetadata {
constructor(subgraphs) {
this.directiveUsagesPerSubgraph = new Map();
for (const subgraph of subgraphs) {
const visitor = this.getTypeVisitor(subgraph.name);
(0, graphql_1.visit)(subgraph.typeDefs, {
ObjectTypeDefinition: visitor,
ObjectTypeExtension: visitor,
InterfaceTypeDefinition: visitor,
InterfaceTypeExtension: visitor,
UnionTypeDefinition: visitor,
UnionTypeExtension: visitor,
});
}
}
getTypeVisitor(subgraphName) {
function collectDirectiveUsages(node, usagesOnNode) {
var _a;
for (const directive of (_a = node.directives) !== null && _a !== void 0 ? _a : []) {
const usages = (0, utilities_1.mapGetOrSet)(usagesOnNode, directive.name.value, []);
usages.push(directive);
}
}
return (node) => {
const directiveUsagesPerType = (0, utilities_1.mapGetOrSet)(this.directiveUsagesPerSubgraph, subgraphName, new Map());
const { directives: usagesOnType, fields: usagesByFieldName } = (0, utilities_1.mapGetOrSet)(directiveUsagesPerType, node.name.value, {
directives: new Map(),
fields: new Map(),
});
collectDirectiveUsages(node, usagesOnType);
if ('fields' in node && node.fields) {
for (const field of node.fields) {
const usagesOnField = (0, utilities_1.mapGetOrSet)(usagesByFieldName, field.name.value, new Map());
collectDirectiveUsages(field, usagesOnField);
}
}
};
}
hasUsages(directiveName) {
for (const directiveUsagesPerType of this.directiveUsagesPerSubgraph.values()) {
for (const { directives, fields } of directiveUsagesPerType.values()) {
const usagesOnType = directives.get(directiveName);
if (usagesOnType && usagesOnType.length > 0)
return true;
for (const directiveUsages of fields.values()) {
const usagesOnField = directiveUsages.get(directiveName);
if (usagesOnField && usagesOnField.length > 0)
return true;
}
}
}
return false;
}
applyMetadataToSupergraphSchema(schema) {
var _a, _b;
for (const directiveUsagesPerType of this.directiveUsagesPerSubgraph.values()) {
for (const [typeName, { directives, fields },] of directiveUsagesPerType.entries()) {
const namedType = schema.getType(typeName);
if (!namedType)
continue;
const existingMetadata = (0, utils_1.getFederationMetadata)(namedType);
let directiveUsages = existingMetadata === null || existingMetadata === void 0 ? void 0 : existingMetadata.directiveUsages;
if (directiveUsages && directiveUsages.size > 0) {
for (const [directiveName, usages] of directiveUsages.entries()) {
usages.push(...((_a = directives.get(directiveName)) !== null && _a !== void 0 ? _a : []));
}
}
else {
directiveUsages = directives;
}
const typeFederationMetadata = {
...existingMetadata,
directiveUsages,
};
namedType.extensions = {
...namedType.extensions,
federation: typeFederationMetadata,
};
for (const [fieldName, usagesPerDirective] of fields.entries()) {
if (!('getFields' in namedType))
continue;
const field = namedType.getFields()[fieldName];
if (!field)
continue;
const originalMetadata = (0, utils_1.getFederationMetadata)(field);
let directiveUsages = originalMetadata === null || originalMetadata === void 0 ? void 0 : originalMetadata.directiveUsages;
if (directiveUsages && directiveUsages.size > 0) {
for (const [directiveName, usages] of directiveUsages.entries()) {
usages.push(...((_b = usagesPerDirective.get(directiveName)) !== null && _b !== void 0 ? _b : []));
}
}
else {
directiveUsages = usagesPerDirective;
}
const fieldFederationMetadata = {
...originalMetadata,
directiveUsages,
};
field.extensions = {
...field.extensions,
federation: fieldFederationMetadata,
};
}
}
}
}
}
exports.DirectiveMetadata = DirectiveMetadata;
//# sourceMappingURL=DirectiveMetadata.js.map