UNPKG

5 kBJavaScriptView Raw
1"use strict";
2Object.defineProperty(exports, "__esModule", { value: true });
3exports.DirectiveMetadata = void 0;
4const graphql_1 = require("graphql");
5const utilities_1 = require("../utilities");
6const utils_1 = require("./utils");
7class DirectiveMetadata {
8 constructor(subgraphs) {
9 this.directiveUsagesPerSubgraph = new Map();
10 for (const subgraph of subgraphs) {
11 const visitor = this.getTypeVisitor(subgraph.name);
12 (0, graphql_1.visit)(subgraph.typeDefs, {
13 ObjectTypeDefinition: visitor,
14 ObjectTypeExtension: visitor,
15 InterfaceTypeDefinition: visitor,
16 InterfaceTypeExtension: visitor,
17 UnionTypeDefinition: visitor,
18 UnionTypeExtension: visitor,
19 });
20 }
21 }
22 getTypeVisitor(subgraphName) {
23 function collectDirectiveUsages(node, usagesOnNode) {
24 var _a;
25 for (const directive of (_a = node.directives) !== null && _a !== void 0 ? _a : []) {
26 const usages = (0, utilities_1.mapGetOrSet)(usagesOnNode, directive.name.value, []);
27 usages.push(directive);
28 }
29 }
30 return (node) => {
31 const directiveUsagesPerType = (0, utilities_1.mapGetOrSet)(this.directiveUsagesPerSubgraph, subgraphName, new Map());
32 const { directives: usagesOnType, fields: usagesByFieldName } = (0, utilities_1.mapGetOrSet)(directiveUsagesPerType, node.name.value, {
33 directives: new Map(),
34 fields: new Map(),
35 });
36 collectDirectiveUsages(node, usagesOnType);
37 if ('fields' in node && node.fields) {
38 for (const field of node.fields) {
39 const usagesOnField = (0, utilities_1.mapGetOrSet)(usagesByFieldName, field.name.value, new Map());
40 collectDirectiveUsages(field, usagesOnField);
41 }
42 }
43 };
44 }
45 hasUsages(directiveName) {
46 for (const directiveUsagesPerType of this.directiveUsagesPerSubgraph.values()) {
47 for (const { directives, fields } of directiveUsagesPerType.values()) {
48 const usagesOnType = directives.get(directiveName);
49 if (usagesOnType && usagesOnType.length > 0)
50 return true;
51 for (const directiveUsages of fields.values()) {
52 const usagesOnField = directiveUsages.get(directiveName);
53 if (usagesOnField && usagesOnField.length > 0)
54 return true;
55 }
56 }
57 }
58 return false;
59 }
60 applyMetadataToSupergraphSchema(schema) {
61 for (const directiveUsagesPerType of this.directiveUsagesPerSubgraph.values()) {
62 for (const [typeName, { directives, fields },] of directiveUsagesPerType.entries()) {
63 const namedType = schema.getType(typeName);
64 if (!namedType)
65 continue;
66 const existingMetadata = (0, utils_1.getFederationMetadata)(namedType);
67 const typeFederationMetadata = {
68 ...existingMetadata,
69 directiveUsages: mergeDirectiveUsages(existingMetadata === null || existingMetadata === void 0 ? void 0 : existingMetadata.directiveUsages, directives),
70 };
71 namedType.extensions = {
72 ...namedType.extensions,
73 federation: typeFederationMetadata,
74 };
75 for (const [fieldName, usagesPerDirective] of fields.entries()) {
76 if (!('getFields' in namedType))
77 continue;
78 const field = namedType.getFields()[fieldName];
79 if (!field)
80 continue;
81 const existingMetadata = (0, utils_1.getFederationMetadata)(field);
82 const fieldFederationMetadata = {
83 ...existingMetadata,
84 directiveUsages: mergeDirectiveUsages(existingMetadata === null || existingMetadata === void 0 ? void 0 : existingMetadata.directiveUsages, usagesPerDirective),
85 };
86 field.extensions = {
87 ...field.extensions,
88 federation: fieldFederationMetadata,
89 };
90 }
91 }
92 }
93 }
94}
95exports.DirectiveMetadata = DirectiveMetadata;
96function mergeDirectiveUsages(first, second) {
97 const merged = new Map();
98 if (first) {
99 for (const [directiveName, usages] of first.entries()) {
100 merged.set(directiveName, [...usages]);
101 }
102 }
103 for (const [directiveName, newUsages] of second.entries()) {
104 const usages = (0, utilities_1.mapGetOrSet)(merged, directiveName, []);
105 usages.push(...newUsages);
106 }
107 return merged;
108}
109//# sourceMappingURL=DirectiveMetadata.js.map
\No newline at end of file