UNPKG

@apollo/federation

Version:
109 lines 5 kB
"use strict"; 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) { 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); const typeFederationMetadata = { ...existingMetadata, directiveUsages: mergeDirectiveUsages(existingMetadata === null || existingMetadata === void 0 ? void 0 : existingMetadata.directiveUsages, directives), }; 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 existingMetadata = (0, utils_1.getFederationMetadata)(field); const fieldFederationMetadata = { ...existingMetadata, directiveUsages: mergeDirectiveUsages(existingMetadata === null || existingMetadata === void 0 ? void 0 : existingMetadata.directiveUsages, usagesPerDirective), }; field.extensions = { ...field.extensions, federation: fieldFederationMetadata, }; } } } } } exports.DirectiveMetadata = DirectiveMetadata; function mergeDirectiveUsages(first, second) { const merged = new Map(); if (first) { for (const [directiveName, usages] of first.entries()) { merged.set(directiveName, [...usages]); } } for (const [directiveName, newUsages] of second.entries()) { const usages = (0, utilities_1.mapGetOrSet)(merged, directiveName, []); usages.push(...newUsages); } return merged; } //# sourceMappingURL=DirectiveMetadata.js.map