@wundergraph/composition 0.18.4 → 0.19.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/ast/utils.d.ts +2 -9
- package/dist/ast/utils.js +2 -73
- package/dist/ast/utils.js.map +1 -1
- package/dist/errors/errors.d.ts +13 -19
- package/dist/errors/errors.js +50 -67
- package/dist/errors/errors.js.map +1 -1
- package/dist/federation/federation-factory.d.ts +17 -46
- package/dist/federation/federation-factory.js +391 -1002
- package/dist/federation/federation-factory.js.map +1 -1
- package/dist/federation/utils.d.ts +1 -115
- package/dist/federation/utils.js +0 -29
- package/dist/federation/utils.js.map +1 -1
- package/dist/federation/walkers.d.ts +3 -0
- package/dist/federation/walkers.js +120 -0
- package/dist/federation/walkers.js.map +1 -0
- package/dist/index.d.ts +2 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/normalization/normalization-factory.d.ts +26 -18
- package/dist/normalization/normalization-factory.js +139 -141
- package/dist/normalization/normalization-factory.js.map +1 -1
- package/dist/normalization/utils.js +53 -54
- package/dist/normalization/utils.js.map +1 -1
- package/dist/normalization/walkers.js +156 -128
- package/dist/normalization/walkers.js.map +1 -1
- package/dist/router-configuration/router-configuration.d.ts +0 -1
- package/dist/schema-building/ast.d.ts +17 -5
- package/dist/schema-building/ast.js +32 -17
- package/dist/schema-building/ast.js.map +1 -1
- package/dist/schema-building/type-definition-data.d.ts +51 -25
- package/dist/schema-building/type-extension-data.d.ts +11 -7
- package/dist/schema-building/type-merging.d.ts +2 -4
- package/dist/schema-building/type-merging.js +8 -27
- package/dist/schema-building/type-merging.js.map +1 -1
- package/dist/schema-building/utils.d.ts +41 -18
- package/dist/schema-building/utils.js +855 -111
- package/dist/schema-building/utils.js.map +1 -1
- package/dist/subgraph/subgraph.d.ts +8 -10
- package/dist/subgraph/subgraph.js +1 -237
- package/dist/subgraph/subgraph.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/utils/constants.d.ts +8 -1
- package/dist/utils/constants.js +47 -19
- package/dist/utils/constants.js.map +1 -1
- package/dist/utils/string-constants.d.ts +10 -4
- package/dist/utils/string-constants.js +20 -6
- package/dist/utils/string-constants.js.map +1 -1
- package/dist/utils/utils.d.ts +4 -4
- package/dist/utils/utils.js +10 -4
- package/dist/utils/utils.js.map +1 -1
- package/package.json +4 -3
- package/dist/ast/ast.d.ts +0 -97
- package/dist/ast/ast.js +0 -168
- package/dist/ast/ast.js.map +0 -1
|
@@ -1,43 +1,38 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.federateSubgraphs = exports.FederationFactory = void 0;
|
|
4
|
-
const graphology_1 = require("graphology");
|
|
5
4
|
const graphql_1 = require("graphql");
|
|
6
|
-
const ast_1 = require("../
|
|
5
|
+
const ast_1 = require("../schema-building/ast");
|
|
7
6
|
const utils_1 = require("../ast/utils");
|
|
8
7
|
const errors_1 = require("../errors/errors");
|
|
9
|
-
const type_merging_1 = require("../schema-building/type-merging");
|
|
10
|
-
const utils_2 = require("./utils");
|
|
11
|
-
const subgraph_1 = require("../subgraph/subgraph");
|
|
12
8
|
const string_constants_1 = require("../utils/string-constants");
|
|
13
|
-
const
|
|
9
|
+
const utils_2 = require("../utils/utils");
|
|
14
10
|
const merge_1 = require("@graphql-tools/merge");
|
|
15
11
|
const constants_1 = require("../utils/constants");
|
|
16
12
|
const normalization_factory_1 = require("../normalization/normalization-factory");
|
|
17
|
-
const
|
|
13
|
+
const utils_3 = require("../normalization/utils");
|
|
14
|
+
const utils_4 = require("../schema-building/utils");
|
|
15
|
+
const walkers_1 = require("./walkers");
|
|
18
16
|
class FederationFactory {
|
|
19
17
|
authorizationDataByParentTypeName;
|
|
20
|
-
abstractToConcreteTypeNames = new Map();
|
|
21
18
|
areFieldsExternal = false;
|
|
22
19
|
areFieldsShareable = false;
|
|
23
|
-
|
|
20
|
+
concreteTypeNamesByAbstractTypeName;
|
|
24
21
|
fieldConfigurationByFieldPath = new Map();
|
|
22
|
+
namedInputValueTypeNames = new Set();
|
|
23
|
+
namedOutputTypeNames = new Set();
|
|
25
24
|
entityInterfaceFederationDataByTypeName;
|
|
26
25
|
executableDirectives = new Set();
|
|
27
26
|
parentTypeName = '';
|
|
28
|
-
persistedDirectives = new Set([string_constants_1.DEPRECATED, string_constants_1.INACCESSIBLE, string_constants_1.TAG]);
|
|
29
27
|
persistedDirectiveDefinitions = new Set([string_constants_1.AUTHENTICATED, string_constants_1.DEPRECATED, string_constants_1.INACCESSIBLE, string_constants_1.TAG, string_constants_1.REQUIRES_SCOPES]);
|
|
30
28
|
currentSubgraphName = '';
|
|
31
29
|
childName = '';
|
|
32
|
-
directiveDefinitions = new Map();
|
|
33
30
|
entityContainersByTypeName;
|
|
34
31
|
errors = [];
|
|
35
32
|
evaluatedObjectLikesBySubgraph = new Map();
|
|
36
|
-
|
|
37
|
-
graph = new graphology_1.MultiGraph();
|
|
33
|
+
graph;
|
|
38
34
|
graphEdges = new Set();
|
|
39
35
|
graphPaths = new Map();
|
|
40
|
-
inputFieldTypeNameSet = new Set();
|
|
41
36
|
invalidOrScopesHostPaths = new Set();
|
|
42
37
|
isCurrentParentEntity = false;
|
|
43
38
|
isCurrentParentInterface = false;
|
|
@@ -45,595 +40,54 @@ class FederationFactory {
|
|
|
45
40
|
isCurrentParentExtensionType = false;
|
|
46
41
|
isParentRootType = false;
|
|
47
42
|
isParentInputObject = false;
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
43
|
+
outputFieldTypeNames = new Set();
|
|
44
|
+
parentDefinitionDataByTypeName = new Map();
|
|
45
|
+
objectExtensionDataByTypeName = new Map();
|
|
46
|
+
persistedDirectiveDefinitionByDirectiveName = new Map([
|
|
47
|
+
[string_constants_1.AUTHENTICATED, constants_1.AUTHENTICATED_DEFINITION],
|
|
48
|
+
[string_constants_1.DEPRECATED, constants_1.DEPRECATED_DEFINITION],
|
|
49
|
+
[string_constants_1.INACCESSIBLE, constants_1.INACCESSIBLE_DEFINITION],
|
|
50
|
+
[string_constants_1.REQUIRES_SCOPES, constants_1.REQUIRES_SCOPES_DEFINITION],
|
|
51
|
+
[string_constants_1.TAG, constants_1.TAG_DEFINITION],
|
|
52
|
+
]);
|
|
51
53
|
rootTypeNames = new Set([string_constants_1.DEFAULT_MUTATION, string_constants_1.DEFAULT_QUERY, string_constants_1.DEFAULT_SUBSCRIPTION]);
|
|
52
54
|
internalSubgraphBySubgraphName;
|
|
53
55
|
shareableErrorTypeNames = new Map();
|
|
54
|
-
renamedTypeNameByOriginalTypeName = new Map();
|
|
55
56
|
warnings;
|
|
56
|
-
constructor(authorizationDataByParentTypeName, entityContainersByTypeName, entityInterfaceFederationDataByTypeName, internalSubgraphBySubgraphName, warnings) {
|
|
57
|
+
constructor(authorizationDataByParentTypeName, concreteTypeNamesByAbstractTypeName, entityContainersByTypeName, entityInterfaceFederationDataByTypeName, graph, internalSubgraphBySubgraphName, warnings) {
|
|
57
58
|
this.authorizationDataByParentTypeName = authorizationDataByParentTypeName;
|
|
59
|
+
this.concreteTypeNamesByAbstractTypeName = concreteTypeNamesByAbstractTypeName;
|
|
58
60
|
this.entityContainersByTypeName = entityContainersByTypeName;
|
|
59
61
|
this.entityInterfaceFederationDataByTypeName = entityInterfaceFederationDataByTypeName;
|
|
62
|
+
this.graph = graph;
|
|
60
63
|
this.internalSubgraphBySubgraphName = internalSubgraphBySubgraphName;
|
|
61
64
|
this.warnings = warnings || [];
|
|
62
65
|
}
|
|
63
|
-
|
|
64
|
-
return this.rootTypeNames.has(node.name.value);
|
|
65
|
-
}
|
|
66
|
-
populateMultiGraphAndRenameOperations(subgraphs) {
|
|
67
|
-
for (const subgraph of subgraphs.values()) {
|
|
68
|
-
this.currentSubgraphName = subgraph.name;
|
|
69
|
-
(0, subgraph_1.walkSubgraphToCollectObjectLikesAndDirectiveDefinitions)(this, subgraph);
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
getEnumMergeMethod(enumName) {
|
|
73
|
-
if (this.inputFieldTypeNameSet.has(enumName) || this.argumentTypeNameSet.has(enumName)) {
|
|
74
|
-
if (this.outputFieldTypeNameSet.has(enumName)) {
|
|
75
|
-
return utils_2.MergeMethod.CONSISTENT;
|
|
76
|
-
}
|
|
77
|
-
return utils_2.MergeMethod.INTERSECTION;
|
|
78
|
-
}
|
|
79
|
-
return utils_2.MergeMethod.UNION;
|
|
80
|
-
}
|
|
81
|
-
validateArgumentDefaultValues(argName, existingDefaultValue, newDefaultValue) {
|
|
82
|
-
if (existingDefaultValue.kind !== newDefaultValue.kind) {
|
|
83
|
-
// This should be caught by subgraph validation
|
|
84
|
-
this.errors.push((0, errors_1.incompatibleArgumentDefaultValueTypeError)(argName, this.parentTypeName, this.childName, existingDefaultValue.kind, newDefaultValue.kind));
|
|
85
|
-
}
|
|
86
|
-
if ('value' in newDefaultValue && existingDefaultValue.value !== newDefaultValue.value) {
|
|
87
|
-
this.errors.push((0, errors_1.incompatibleArgumentDefaultValueError)(argName, this.parentTypeName, this.childName, existingDefaultValue.value, newDefaultValue.value));
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
compareAndValidateArgumentDefaultValues(existingArg, newArg) {
|
|
91
|
-
const newDefaultValue = newArg.defaultValue;
|
|
92
|
-
existingArg.node.defaultValue = existingArg.node.defaultValue || newDefaultValue;
|
|
93
|
-
if (!existingArg.node.defaultValue || !newDefaultValue) {
|
|
94
|
-
existingArg.includeDefaultValue = false;
|
|
95
|
-
return;
|
|
96
|
-
}
|
|
97
|
-
const argumentName = existingArg.node.name.value;
|
|
98
|
-
const existingDefaultValue = existingArg.node.defaultValue;
|
|
99
|
-
switch (existingDefaultValue.kind) {
|
|
100
|
-
case graphql_1.Kind.LIST: // TODO
|
|
101
|
-
break;
|
|
102
|
-
case graphql_1.Kind.NULL:
|
|
103
|
-
break;
|
|
104
|
-
case graphql_1.Kind.OBJECT:
|
|
105
|
-
break;
|
|
106
|
-
// BOOLEAN, ENUM, FLOAT, INT, and STRING intentionally fall through
|
|
107
|
-
case graphql_1.Kind.BOOLEAN:
|
|
108
|
-
case graphql_1.Kind.ENUM:
|
|
109
|
-
case graphql_1.Kind.FLOAT:
|
|
110
|
-
case graphql_1.Kind.INT:
|
|
111
|
-
case graphql_1.Kind.STRING:
|
|
112
|
-
this.validateArgumentDefaultValues(argumentName, existingDefaultValue, newDefaultValue);
|
|
113
|
-
break;
|
|
114
|
-
default:
|
|
115
|
-
throw (0, errors_1.unexpectedArgumentKindFatalError)(argumentName, this.childName);
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
upsertRequiredSubgraph(set, isRequired) {
|
|
119
|
-
if (isRequired) {
|
|
120
|
-
set.add(this.currentSubgraphName);
|
|
121
|
-
}
|
|
122
|
-
return set;
|
|
123
|
-
}
|
|
124
|
-
upsertExtensionPersistedDirectives(extensionDirectives, baseDirectives) {
|
|
125
|
-
// Add unique tag directives
|
|
126
|
-
for (const [tagValue, tagDirectiveNode] of extensionDirectives.tags) {
|
|
127
|
-
baseDirectives.tags.set(tagValue, tagDirectiveNode);
|
|
128
|
-
}
|
|
129
|
-
// Push other directives
|
|
130
|
-
for (const [directiveName, directiveNodes] of extensionDirectives.directives) {
|
|
131
|
-
const existingDirectives = baseDirectives.directives.get(directiveName);
|
|
132
|
-
if (!existingDirectives) {
|
|
133
|
-
baseDirectives.directives.set(directiveName, directiveNodes);
|
|
134
|
-
continue;
|
|
135
|
-
}
|
|
136
|
-
existingDirectives.push(...directiveNodes);
|
|
137
|
-
}
|
|
138
|
-
// If the extension has no deprecated directive, there's nothing further to do
|
|
139
|
-
const extensionDeprecatedDirective = extensionDirectives.deprecated.directive;
|
|
140
|
-
const extensionDeprecatedReason = extensionDirectives.deprecated.reason;
|
|
141
|
-
if (!extensionDeprecatedDirective || !extensionDeprecatedReason) {
|
|
142
|
-
return;
|
|
143
|
-
}
|
|
144
|
-
// If there is no reason or the existing reason is longer, return
|
|
145
|
-
if (baseDirectives.deprecated.directive &&
|
|
146
|
-
baseDirectives.deprecated.reason &&
|
|
147
|
-
extensionDeprecatedReason.length < baseDirectives.deprecated.reason.length) {
|
|
148
|
-
return;
|
|
149
|
-
}
|
|
150
|
-
// Only update if the new reason is longer
|
|
151
|
-
baseDirectives.deprecated.directive = extensionDeprecatedDirective;
|
|
152
|
-
baseDirectives.deprecated.reason = extensionDeprecatedReason;
|
|
153
|
-
}
|
|
154
|
-
upsertExtensionFieldArguments(extensionFieldArguments, baseFieldArguments) {
|
|
155
|
-
for (const [argumentName, extensionArgumentContainer] of extensionFieldArguments) {
|
|
156
|
-
const existingArgumentContainer = baseFieldArguments.get(argumentName);
|
|
157
|
-
if (!existingArgumentContainer) {
|
|
158
|
-
// If the argument doesn't exist on the base field, simply add it
|
|
159
|
-
baseFieldArguments.set(argumentName, extensionArgumentContainer);
|
|
160
|
-
continue;
|
|
161
|
-
}
|
|
162
|
-
if (extensionArgumentContainer.requiredSubgraphs.size > 0) {
|
|
163
|
-
// If the argument is required on any extensions, add it to the base requiredSubgraphs set
|
|
164
|
-
(0, utils_3.addIterableValuesToSet)(extensionArgumentContainer.requiredSubgraphs, existingArgumentContainer.requiredSubgraphs);
|
|
165
|
-
}
|
|
166
|
-
// Add the subgraphs in which the extensions' arguments are found to the base subgraphs set
|
|
167
|
-
(0, utils_3.addIterableValuesToSet)(extensionArgumentContainer.subgraphs, existingArgumentContainer.subgraphs);
|
|
168
|
-
// Set the most restrictive type for the argument
|
|
169
|
-
const { typeErrors, typeNode } = (0, type_merging_1.getMostRestrictiveMergedTypeNode)(existingArgumentContainer.node.type, extensionArgumentContainer.node.type, this.childName, argumentName);
|
|
170
|
-
if (typeNode) {
|
|
171
|
-
existingArgumentContainer.node.type = typeNode;
|
|
172
|
-
}
|
|
173
|
-
else {
|
|
174
|
-
if (!typeErrors || typeErrors.length < 2) {
|
|
175
|
-
throw (0, errors_1.argumentTypeMergeFatalError)(argumentName, this.childName);
|
|
176
|
-
}
|
|
177
|
-
this.errors.push((0, errors_1.incompatibleArgumentTypesError)(argumentName, this.parentTypeName, this.childName, typeErrors[0], typeErrors[1]));
|
|
178
|
-
}
|
|
179
|
-
this.compareAndValidateArgumentDefaultValues(existingArgumentContainer, extensionArgumentContainer.node);
|
|
180
|
-
this.upsertExtensionPersistedDirectives(extensionArgumentContainer.directives, existingArgumentContainer.directives);
|
|
181
|
-
}
|
|
182
|
-
}
|
|
183
|
-
// TODO validation of default values
|
|
184
|
-
upsertArguments(node, argumentMap) {
|
|
185
|
-
if (!node.arguments) {
|
|
186
|
-
return argumentMap;
|
|
187
|
-
}
|
|
188
|
-
for (const argumentNode of node.arguments) {
|
|
189
|
-
const argName = argumentNode.name.value;
|
|
190
|
-
const argPath = `${node.name.value}(${argName}...)`;
|
|
191
|
-
this.argumentTypeNameSet.add((0, type_merging_1.getNamedTypeForChild)(argPath, argumentNode.type));
|
|
192
|
-
const isRequired = (0, type_merging_1.isTypeRequired)(argumentNode.type);
|
|
193
|
-
const existingArgumentContainer = argumentMap.get(argName);
|
|
194
|
-
if (!existingArgumentContainer) {
|
|
195
|
-
argumentMap.set(argName, {
|
|
196
|
-
directives: this.extractPersistedDirectives(argumentNode.directives || [], (0, utils_2.newPersistedDirectivesContainer)()),
|
|
197
|
-
includeDefaultValue: !!argumentNode.defaultValue,
|
|
198
|
-
node: (0, ast_1.inputValueDefinitionNodeToMutable)(argumentNode, this.childName),
|
|
199
|
-
requiredSubgraphs: this.upsertRequiredSubgraph(new Set(), isRequired),
|
|
200
|
-
subgraphs: new Set([this.currentSubgraphName]),
|
|
201
|
-
});
|
|
202
|
-
continue;
|
|
203
|
-
}
|
|
204
|
-
this.extractPersistedDirectives(argumentNode.directives || [], existingArgumentContainer.directives);
|
|
205
|
-
(0, utils_1.setLongestDescriptionForNode)(existingArgumentContainer.node, argumentNode.description);
|
|
206
|
-
this.upsertRequiredSubgraph(existingArgumentContainer.requiredSubgraphs, isRequired);
|
|
207
|
-
existingArgumentContainer.subgraphs.add(this.currentSubgraphName);
|
|
208
|
-
const { typeErrors, typeNode } = (0, type_merging_1.getMostRestrictiveMergedTypeNode)(existingArgumentContainer.node.type, argumentNode.type, this.childName, argName);
|
|
209
|
-
if (typeNode) {
|
|
210
|
-
existingArgumentContainer.node.type = typeNode;
|
|
211
|
-
}
|
|
212
|
-
else {
|
|
213
|
-
if (!typeErrors || typeErrors.length < 2) {
|
|
214
|
-
throw (0, errors_1.argumentTypeMergeFatalError)(argName, this.childName);
|
|
215
|
-
}
|
|
216
|
-
this.errors.push((0, errors_1.incompatibleArgumentTypesError)(argName, this.parentTypeName, this.childName, typeErrors[0], typeErrors[1]));
|
|
217
|
-
}
|
|
218
|
-
this.compareAndValidateArgumentDefaultValues(existingArgumentContainer, argumentNode);
|
|
219
|
-
}
|
|
220
|
-
return argumentMap;
|
|
221
|
-
}
|
|
222
|
-
isFieldEntityKey() {
|
|
223
|
-
const parent = this.keyFieldNamesByParentTypeName.get(this.parentTypeName);
|
|
224
|
-
if (parent) {
|
|
225
|
-
return parent.has(this.childName);
|
|
226
|
-
}
|
|
227
|
-
return false;
|
|
228
|
-
}
|
|
229
|
-
isFieldExternal(node) {
|
|
230
|
-
return this.areFieldsExternal || (0, utils_1.isNodeExternal)(node);
|
|
231
|
-
}
|
|
232
|
-
isFieldShareable(node) {
|
|
233
|
-
return (!this.isCurrentSubgraphVersionTwo || this.areFieldsShareable || this.isFieldEntityKey() || (0, utils_1.isNodeShareable)(node));
|
|
234
|
-
}
|
|
235
|
-
upsertDirectiveNode(node) {
|
|
236
|
-
const directiveName = node.name.value;
|
|
237
|
-
const directiveDefinition = this.directiveDefinitions.get(directiveName);
|
|
238
|
-
if (directiveDefinition) {
|
|
239
|
-
if (!this.executableDirectives.has(directiveName)) {
|
|
240
|
-
return;
|
|
241
|
-
}
|
|
242
|
-
if ((0, utils_1.mergeExecutableDirectiveLocations)(node.locations, directiveDefinition).size < 1) {
|
|
243
|
-
this.executableDirectives.delete(directiveName);
|
|
244
|
-
return;
|
|
245
|
-
}
|
|
246
|
-
this.upsertArguments(node, directiveDefinition.arguments);
|
|
247
|
-
(0, utils_1.setLongestDescriptionForNode)(directiveDefinition.node, node.description);
|
|
248
|
-
directiveDefinition.node.repeatable = directiveDefinition.node.repeatable && node.repeatable;
|
|
249
|
-
directiveDefinition.subgraphNames.add(this.currentSubgraphName);
|
|
250
|
-
return;
|
|
251
|
-
}
|
|
252
|
-
const executableLocations = (0, utils_1.extractExecutableDirectiveLocations)(node.locations, new Set());
|
|
253
|
-
this.directiveDefinitions.set(directiveName, {
|
|
254
|
-
arguments: this.upsertArguments(node, new Map()),
|
|
255
|
-
executableLocations,
|
|
256
|
-
node: (0, ast_1.directiveDefinitionNodeToMutable)(node),
|
|
257
|
-
subgraphNames: new Set([this.currentSubgraphName]),
|
|
258
|
-
});
|
|
259
|
-
if (executableLocations.size > 0) {
|
|
260
|
-
this.executableDirectives.add(directiveName);
|
|
261
|
-
}
|
|
262
|
-
}
|
|
263
|
-
isShareabilityOfAllFieldInstancesValid(fieldContainer) {
|
|
264
|
-
let shareableFields = 0;
|
|
265
|
-
let unshareableFields = 0;
|
|
266
|
-
for (const [subgraphName, isShareable] of fieldContainer.subgraphsByShareable) {
|
|
267
|
-
/*
|
|
268
|
-
shareability is ignored if:
|
|
269
|
-
1. the field is external
|
|
270
|
-
2. the field is overridden by another subgraph (in which case it has not been upserted)
|
|
271
|
-
*/
|
|
272
|
-
if (fieldContainer.subgraphsByExternal.get(subgraphName)) {
|
|
273
|
-
continue;
|
|
274
|
-
}
|
|
275
|
-
if (isShareable) {
|
|
276
|
-
if (unshareableFields) {
|
|
277
|
-
return false;
|
|
278
|
-
}
|
|
279
|
-
shareableFields += 1;
|
|
280
|
-
continue;
|
|
281
|
-
}
|
|
282
|
-
unshareableFields += 1;
|
|
283
|
-
if (shareableFields || unshareableFields > 1) {
|
|
284
|
-
return false;
|
|
285
|
-
}
|
|
286
|
-
}
|
|
287
|
-
return true;
|
|
288
|
-
}
|
|
289
|
-
upsertFieldNode(node) {
|
|
290
|
-
const parent = this.isCurrentParentExtensionType
|
|
291
|
-
? (0, utils_3.getOrThrowError)(this.extensions, this.parentTypeName, string_constants_1.EXTENSIONS)
|
|
292
|
-
: (0, utils_3.getOrThrowError)(this.parents, this.parentTypeName, string_constants_1.PARENTS);
|
|
293
|
-
if (parent.kind !== graphql_1.Kind.OBJECT_TYPE_DEFINITION &&
|
|
294
|
-
parent.kind !== graphql_1.Kind.INTERFACE_TYPE_DEFINITION &&
|
|
295
|
-
parent.kind !== graphql_1.Kind.OBJECT_TYPE_EXTENSION) {
|
|
296
|
-
throw (0, errors_1.unexpectedKindFatalError)(this.parentTypeName);
|
|
297
|
-
}
|
|
298
|
-
const fieldMap = parent.fields;
|
|
299
|
-
const isFieldExternal = this.isFieldExternal(node);
|
|
300
|
-
const isFieldShareable = this.isFieldShareable(node);
|
|
301
|
-
const fieldPath = `${this.parentTypeName}.${this.childName}`;
|
|
302
|
-
const fieldRootTypeName = (0, type_merging_1.getNamedTypeForChild)(fieldPath, node.type);
|
|
303
|
-
const existingFieldContainer = fieldMap.get(this.childName);
|
|
304
|
-
if (existingFieldContainer) {
|
|
305
|
-
this.extractPersistedDirectives(node.directives || [], existingFieldContainer.directives);
|
|
306
|
-
(0, utils_1.setLongestDescriptionForNode)(existingFieldContainer.node, node.description);
|
|
307
|
-
existingFieldContainer.subgraphNames.add(this.currentSubgraphName);
|
|
308
|
-
existingFieldContainer.subgraphsByShareable.set(this.currentSubgraphName, isFieldShareable);
|
|
309
|
-
existingFieldContainer.subgraphsByExternal.set(this.currentSubgraphName, isFieldExternal);
|
|
310
|
-
const { typeErrors, typeNode } = (0, type_merging_1.getLeastRestrictiveMergedTypeNode)(existingFieldContainer.node.type, node.type, this.parentTypeName, this.childName);
|
|
311
|
-
if (typeNode) {
|
|
312
|
-
existingFieldContainer.node.type = typeNode;
|
|
313
|
-
}
|
|
314
|
-
else {
|
|
315
|
-
if (!typeErrors || typeErrors.length < 2) {
|
|
316
|
-
throw (0, errors_1.fieldTypeMergeFatalError)(this.childName);
|
|
317
|
-
}
|
|
318
|
-
this.errors.push((0, errors_1.incompatibleChildTypesError)(this.parentTypeName, this.childName, typeErrors[0], typeErrors[1]));
|
|
319
|
-
}
|
|
320
|
-
this.upsertArguments(node, existingFieldContainer.arguments);
|
|
321
|
-
/* A field is valid if one of the following is true:
|
|
322
|
-
1. The field is an interface
|
|
323
|
-
2. The field is external
|
|
324
|
-
3. Non-external fields are ALL shareable
|
|
325
|
-
4. All other fields besides the current field are external
|
|
326
|
-
*/
|
|
327
|
-
if (this.isCurrentParentInterface ||
|
|
328
|
-
isFieldExternal ||
|
|
329
|
-
(existingFieldContainer.isShareable && isFieldShareable) ||
|
|
330
|
-
this.isShareabilityOfAllFieldInstancesValid(existingFieldContainer) ||
|
|
331
|
-
this.entityInterfaceFederationDataByTypeName.has(this.parentTypeName) // TODO handle shareability with interfaceObjects
|
|
332
|
-
) {
|
|
333
|
-
return;
|
|
334
|
-
}
|
|
335
|
-
const shareableErrorTypeNames = this.shareableErrorTypeNames.get(this.parentTypeName);
|
|
336
|
-
if (shareableErrorTypeNames) {
|
|
337
|
-
shareableErrorTypeNames.add(this.childName);
|
|
338
|
-
}
|
|
339
|
-
else {
|
|
340
|
-
this.shareableErrorTypeNames.set(this.parentTypeName, new Set([this.childName]));
|
|
341
|
-
}
|
|
342
|
-
return;
|
|
343
|
-
}
|
|
344
|
-
this.outputFieldTypeNameSet.add(fieldRootTypeName);
|
|
345
|
-
fieldMap.set(this.childName, {
|
|
346
|
-
arguments: this.upsertArguments(node, new Map()),
|
|
347
|
-
directives: this.extractPersistedDirectives(node.directives || [], (0, utils_2.newPersistedDirectivesContainer)()),
|
|
348
|
-
isShareable: isFieldShareable,
|
|
349
|
-
node: (0, ast_1.fieldDefinitionNodeToMutable)(node, this.parentTypeName),
|
|
350
|
-
namedTypeName: fieldRootTypeName,
|
|
351
|
-
subgraphNames: new Set([this.currentSubgraphName]),
|
|
352
|
-
subgraphsByShareable: new Map([[this.currentSubgraphName, isFieldShareable]]),
|
|
353
|
-
subgraphsByExternal: new Map([[this.currentSubgraphName, isFieldExternal]]),
|
|
354
|
-
});
|
|
355
|
-
}
|
|
356
|
-
upsertValueNode(node) {
|
|
357
|
-
const parent = this.parents.get(this.parentTypeName);
|
|
358
|
-
switch (node.kind) {
|
|
359
|
-
case graphql_1.Kind.ENUM_VALUE_DEFINITION:
|
|
360
|
-
if (!parent) {
|
|
361
|
-
// This should never happen
|
|
362
|
-
throw (0, errors_1.federationInvalidParentTypeError)(this.parentTypeName, this.childName);
|
|
363
|
-
}
|
|
364
|
-
if (parent.kind !== graphql_1.Kind.ENUM_TYPE_DEFINITION) {
|
|
365
|
-
throw (0, errors_1.incompatibleParentKindFatalError)(this.parentTypeName, graphql_1.Kind.ENUM_TYPE_DEFINITION, parent.kind);
|
|
366
|
-
}
|
|
367
|
-
const enumValues = parent.values;
|
|
368
|
-
const enumValueContainer = enumValues.get(this.childName);
|
|
369
|
-
if (enumValueContainer) {
|
|
370
|
-
this.extractPersistedDirectives(node.directives || [], enumValueContainer.directives);
|
|
371
|
-
(0, utils_1.setLongestDescriptionForNode)(enumValueContainer.node, node.description);
|
|
372
|
-
enumValueContainer.appearances += 1;
|
|
373
|
-
return;
|
|
374
|
-
}
|
|
375
|
-
enumValues.set(this.childName, {
|
|
376
|
-
appearances: 1,
|
|
377
|
-
directives: this.extractPersistedDirectives(node.directives || [], (0, utils_2.newPersistedDirectivesContainer)()),
|
|
378
|
-
node: (0, ast_1.enumValueDefinitionNodeToMutable)(node),
|
|
379
|
-
});
|
|
380
|
-
return;
|
|
381
|
-
case graphql_1.Kind.INPUT_VALUE_DEFINITION:
|
|
382
|
-
if (!parent || !this.isParentInputObject) {
|
|
383
|
-
// these are arguments to a directive
|
|
384
|
-
return;
|
|
385
|
-
}
|
|
386
|
-
if (parent.kind !== graphql_1.Kind.INPUT_OBJECT_TYPE_DEFINITION) {
|
|
387
|
-
throw (0, errors_1.incompatibleParentKindFatalError)(this.parentTypeName, graphql_1.Kind.INPUT_OBJECT_TYPE_DEFINITION, parent.kind);
|
|
388
|
-
}
|
|
389
|
-
const inputValues = parent.fields;
|
|
390
|
-
const inputValueContainer = inputValues.get(this.childName);
|
|
391
|
-
if (inputValueContainer) {
|
|
392
|
-
this.extractPersistedDirectives(node.directives || [], inputValueContainer.directives);
|
|
393
|
-
inputValueContainer.appearances += 1;
|
|
394
|
-
(0, utils_1.setLongestDescriptionForNode)(inputValueContainer.node, node.description);
|
|
395
|
-
const { typeErrors, typeNode } = (0, type_merging_1.getMostRestrictiveMergedTypeNode)(inputValueContainer.node.type, node.type, this.parentTypeName, this.childName);
|
|
396
|
-
if (typeNode) {
|
|
397
|
-
inputValueContainer.node.type = typeNode;
|
|
398
|
-
}
|
|
399
|
-
else {
|
|
400
|
-
if (!typeErrors || typeErrors.length < 2) {
|
|
401
|
-
throw (0, errors_1.fieldTypeMergeFatalError)(this.childName);
|
|
402
|
-
}
|
|
403
|
-
this.errors.push((0, errors_1.incompatibleChildTypesError)(this.parentTypeName, this.childName, typeErrors[0], typeErrors[1]));
|
|
404
|
-
}
|
|
405
|
-
return;
|
|
406
|
-
}
|
|
407
|
-
const valuePath = `${this.parentTypeName}.${this.childName}`;
|
|
408
|
-
const inputValueNamedType = (0, type_merging_1.getNamedTypeForChild)(valuePath, node.type);
|
|
409
|
-
this.inputFieldTypeNameSet.add(inputValueNamedType);
|
|
410
|
-
inputValues.set(this.childName, {
|
|
411
|
-
appearances: 1,
|
|
412
|
-
directives: this.extractPersistedDirectives(node.directives || [], (0, utils_2.newPersistedDirectivesContainer)()),
|
|
413
|
-
includeDefaultValue: !!node.defaultValue,
|
|
414
|
-
node: (0, ast_1.inputValueDefinitionNodeToMutable)(node, this.parentTypeName),
|
|
415
|
-
});
|
|
416
|
-
return;
|
|
417
|
-
default:
|
|
418
|
-
throw (0, errors_1.unexpectedKindFatalError)(this.childName);
|
|
419
|
-
}
|
|
420
|
-
}
|
|
421
|
-
upsertInterfaceObjectParentNode(node) {
|
|
422
|
-
const parentTypeName = node.name.value;
|
|
423
|
-
const parent = this.parents.get(parentTypeName);
|
|
424
|
-
if (parent) {
|
|
425
|
-
if (parent.kind !== graphql_1.Kind.INTERFACE_TYPE_DEFINITION) {
|
|
426
|
-
throw (0, errors_1.incompatibleParentKindFatalError)(parentTypeName, node.kind, parent.kind);
|
|
427
|
-
}
|
|
428
|
-
(0, utils_1.setLongestDescriptionForNode)(parent.node, node.description);
|
|
429
|
-
this.extractPersistedDirectives(node.directives || [], parent.directives);
|
|
430
|
-
(0, utils_1.extractInterfaces)(node, parent.interfaces);
|
|
431
|
-
parent.subgraphNames.add(this.currentSubgraphName);
|
|
432
|
-
return;
|
|
433
|
-
}
|
|
434
|
-
this.parents.set(parentTypeName, {
|
|
435
|
-
directives: this.extractPersistedDirectives(node.directives || [], (0, utils_2.newPersistedDirectivesContainer)()),
|
|
436
|
-
fields: new Map(),
|
|
437
|
-
interfaces: (0, utils_1.extractInterfaces)(node, new Set()),
|
|
438
|
-
kind: graphql_1.Kind.INTERFACE_TYPE_DEFINITION,
|
|
439
|
-
node: (0, ast_1.interfaceTypeDefinitionNodeToMutable)({
|
|
440
|
-
...node,
|
|
441
|
-
kind: graphql_1.Kind.INTERFACE_TYPE_DEFINITION,
|
|
442
|
-
}),
|
|
443
|
-
subgraphNames: new Set([this.currentSubgraphName]),
|
|
444
|
-
});
|
|
445
|
-
}
|
|
446
|
-
upsertParentNode(node) {
|
|
447
|
-
const parentTypeName = node.name.value;
|
|
448
|
-
const parent = this.parents.get(parentTypeName);
|
|
449
|
-
if (parent) {
|
|
450
|
-
(0, utils_1.setLongestDescriptionForNode)(parent.node, node.description);
|
|
451
|
-
this.extractPersistedDirectives(node.directives || [], parent.directives);
|
|
452
|
-
}
|
|
453
|
-
switch (node.kind) {
|
|
454
|
-
case graphql_1.Kind.ENUM_TYPE_DEFINITION:
|
|
455
|
-
if (parent) {
|
|
456
|
-
if (parent.kind !== node.kind) {
|
|
457
|
-
throw (0, errors_1.incompatibleParentKindFatalError)(parentTypeName, node.kind, parent.kind);
|
|
458
|
-
}
|
|
459
|
-
parent.appearances += 1;
|
|
460
|
-
return;
|
|
461
|
-
}
|
|
462
|
-
this.parents.set(parentTypeName, {
|
|
463
|
-
appearances: 1,
|
|
464
|
-
directives: this.extractPersistedDirectives(node.directives || [], (0, utils_2.newPersistedDirectivesContainer)()),
|
|
465
|
-
values: new Map(),
|
|
466
|
-
kind: node.kind,
|
|
467
|
-
node: (0, ast_1.enumTypeDefinitionNodeToMutable)(node),
|
|
468
|
-
});
|
|
469
|
-
return;
|
|
470
|
-
case graphql_1.Kind.INPUT_OBJECT_TYPE_DEFINITION:
|
|
471
|
-
if (parent) {
|
|
472
|
-
if (parent.kind !== node.kind) {
|
|
473
|
-
throw (0, errors_1.incompatibleParentKindFatalError)(parentTypeName, node.kind, parent.kind);
|
|
474
|
-
}
|
|
475
|
-
parent.appearances += 1;
|
|
476
|
-
return;
|
|
477
|
-
}
|
|
478
|
-
this.parents.set(parentTypeName, {
|
|
479
|
-
appearances: 1,
|
|
480
|
-
directives: this.extractPersistedDirectives(node.directives || [], (0, utils_2.newPersistedDirectivesContainer)()),
|
|
481
|
-
fields: new Map(),
|
|
482
|
-
kind: node.kind,
|
|
483
|
-
node: (0, ast_1.inputObjectTypeDefinitionNodeToMutable)(node),
|
|
484
|
-
});
|
|
485
|
-
return;
|
|
486
|
-
case graphql_1.Kind.INTERFACE_TYPE_DEFINITION:
|
|
487
|
-
if (parent) {
|
|
488
|
-
if (parent.kind !== node.kind) {
|
|
489
|
-
throw (0, errors_1.incompatibleParentKindFatalError)(parentTypeName, node.kind, parent.kind);
|
|
490
|
-
}
|
|
491
|
-
(0, utils_1.extractInterfaces)(node, parent.interfaces);
|
|
492
|
-
parent.subgraphNames.add(this.currentSubgraphName);
|
|
493
|
-
return;
|
|
494
|
-
}
|
|
495
|
-
this.parents.set(parentTypeName, {
|
|
496
|
-
directives: this.extractPersistedDirectives(node.directives || [], (0, utils_2.newPersistedDirectivesContainer)()),
|
|
497
|
-
fields: new Map(),
|
|
498
|
-
interfaces: (0, utils_1.extractInterfaces)(node, new Set()),
|
|
499
|
-
kind: node.kind,
|
|
500
|
-
node: (0, ast_1.interfaceTypeDefinitionNodeToMutable)(node),
|
|
501
|
-
subgraphNames: new Set([this.currentSubgraphName]),
|
|
502
|
-
});
|
|
503
|
-
return;
|
|
504
|
-
case graphql_1.Kind.SCALAR_TYPE_DEFINITION:
|
|
505
|
-
if (parent) {
|
|
506
|
-
if (parent.kind !== node.kind) {
|
|
507
|
-
throw (0, errors_1.incompatibleParentKindFatalError)(parentTypeName, node.kind, parent.kind);
|
|
508
|
-
}
|
|
509
|
-
return;
|
|
510
|
-
}
|
|
511
|
-
this.parents.set(parentTypeName, {
|
|
512
|
-
directives: this.extractPersistedDirectives(node.directives || [], (0, utils_2.newPersistedDirectivesContainer)()),
|
|
513
|
-
kind: node.kind,
|
|
514
|
-
node: (0, ast_1.scalarTypeDefinitionNodeToMutable)(node),
|
|
515
|
-
});
|
|
516
|
-
return;
|
|
517
|
-
case graphql_1.Kind.OBJECT_TYPE_DEFINITION:
|
|
518
|
-
if (parent) {
|
|
519
|
-
if (parent.kind !== node.kind) {
|
|
520
|
-
throw (0, errors_1.incompatibleParentKindFatalError)(parentTypeName, node.kind, parent.kind);
|
|
521
|
-
}
|
|
522
|
-
(0, utils_1.extractInterfaces)(node, parent.interfaces);
|
|
523
|
-
parent.subgraphNames.add(this.currentSubgraphName);
|
|
524
|
-
return;
|
|
525
|
-
}
|
|
526
|
-
this.parents.set(parentTypeName, {
|
|
527
|
-
directives: this.extractPersistedDirectives(node.directives || [], (0, utils_2.newPersistedDirectivesContainer)()),
|
|
528
|
-
fields: new Map(),
|
|
529
|
-
interfaces: (0, utils_1.extractInterfaces)(node, new Set()),
|
|
530
|
-
isRootType: this.isParentRootType,
|
|
531
|
-
kind: node.kind,
|
|
532
|
-
node: (0, ast_1.objectTypeDefinitionNodeToMutable)(node),
|
|
533
|
-
subgraphNames: new Set([this.currentSubgraphName]),
|
|
534
|
-
});
|
|
535
|
-
return;
|
|
536
|
-
case graphql_1.Kind.UNION_TYPE_DEFINITION:
|
|
537
|
-
if (parent) {
|
|
538
|
-
if (parent.kind !== node.kind) {
|
|
539
|
-
throw (0, errors_1.incompatibleParentKindFatalError)(parentTypeName, node.kind, parent.kind);
|
|
540
|
-
}
|
|
541
|
-
if (!node.types || node.types.length < 1) {
|
|
542
|
-
this.errors.push((0, errors_1.invalidUnionError)(parent.node.name.value));
|
|
543
|
-
return;
|
|
544
|
-
}
|
|
545
|
-
node.types?.forEach((member) => parent.members.add(member.name.value));
|
|
546
|
-
return;
|
|
547
|
-
}
|
|
548
|
-
this.parents.set(parentTypeName, {
|
|
549
|
-
directives: this.extractPersistedDirectives(node.directives || [], (0, utils_2.newPersistedDirectivesContainer)()),
|
|
550
|
-
kind: node.kind,
|
|
551
|
-
members: new Set(node.types?.map((member) => member.name.value)),
|
|
552
|
-
node: (0, ast_1.unionTypeDefinitionNodeToMutable)(node),
|
|
553
|
-
});
|
|
554
|
-
return;
|
|
555
|
-
}
|
|
556
|
-
}
|
|
557
|
-
upsertExtensionNode(node) {
|
|
558
|
-
const extension = this.extensions.get(this.parentTypeName);
|
|
559
|
-
if (extension) {
|
|
560
|
-
if (extension.kind !== graphql_1.Kind.OBJECT_TYPE_EXTENSION) {
|
|
561
|
-
throw (0, errors_1.incompatibleParentKindFatalError)(this.parentTypeName, graphql_1.Kind.OBJECT_TYPE_EXTENSION, extension.kind);
|
|
562
|
-
}
|
|
563
|
-
extension.subgraphNames.add(this.currentSubgraphName);
|
|
564
|
-
(0, utils_1.extractInterfaces)(node, extension.interfaces);
|
|
565
|
-
this.extractPersistedDirectives(node.directives || [], extension.directives);
|
|
566
|
-
return;
|
|
567
|
-
}
|
|
568
|
-
// build a new extension
|
|
569
|
-
const interfaces = (0, utils_1.extractInterfaces)(node, new Set());
|
|
570
|
-
this.extensions.set(this.parentTypeName, {
|
|
571
|
-
directives: this.extractPersistedDirectives(node.directives || [], (0, utils_2.newPersistedDirectivesContainer)()),
|
|
572
|
-
fields: new Map(),
|
|
573
|
-
interfaces,
|
|
574
|
-
isRootType: this.isParentRootType,
|
|
575
|
-
kind: graphql_1.Kind.OBJECT_TYPE_EXTENSION,
|
|
576
|
-
node: (0, ast_1.objectTypeExtensionNodeToMutable)(node),
|
|
577
|
-
subgraphNames: new Set([this.currentSubgraphName]),
|
|
578
|
-
});
|
|
579
|
-
}
|
|
580
|
-
isTypeValidImplementation(originalType, implementationType) {
|
|
581
|
-
if (originalType.kind === graphql_1.Kind.NON_NULL_TYPE) {
|
|
582
|
-
if (implementationType.kind !== graphql_1.Kind.NON_NULL_TYPE) {
|
|
583
|
-
return false;
|
|
584
|
-
}
|
|
585
|
-
return this.isTypeValidImplementation(originalType.type, implementationType.type);
|
|
586
|
-
}
|
|
587
|
-
if (implementationType.kind === graphql_1.Kind.NON_NULL_TYPE) {
|
|
588
|
-
return this.isTypeValidImplementation(originalType, implementationType.type);
|
|
589
|
-
}
|
|
590
|
-
switch (originalType.kind) {
|
|
591
|
-
case graphql_1.Kind.NAMED_TYPE:
|
|
592
|
-
if (implementationType.kind === graphql_1.Kind.NAMED_TYPE) {
|
|
593
|
-
const originalTypeName = originalType.name.value;
|
|
594
|
-
const implementationTypeName = implementationType.name.value;
|
|
595
|
-
if (originalTypeName === implementationTypeName) {
|
|
596
|
-
return true;
|
|
597
|
-
}
|
|
598
|
-
const concreteTypes = this.abstractToConcreteTypeNames.get(originalTypeName);
|
|
599
|
-
if (!concreteTypes) {
|
|
600
|
-
return false;
|
|
601
|
-
}
|
|
602
|
-
return concreteTypes.has(implementationTypeName);
|
|
603
|
-
}
|
|
604
|
-
return false;
|
|
605
|
-
default:
|
|
606
|
-
if (implementationType.kind === graphql_1.Kind.LIST_TYPE) {
|
|
607
|
-
return this.isTypeValidImplementation(originalType.type, implementationType.type);
|
|
608
|
-
}
|
|
609
|
-
return false;
|
|
610
|
-
}
|
|
611
|
-
}
|
|
612
|
-
getAndValidateImplementedInterfaces(container) {
|
|
66
|
+
getValidImplementedInterfaces(data) {
|
|
613
67
|
const interfaces = [];
|
|
614
|
-
if (
|
|
68
|
+
if (data.implementedInterfaceTypeNames.size < 1) {
|
|
615
69
|
return interfaces;
|
|
616
70
|
}
|
|
617
71
|
const implementationErrorsMap = new Map();
|
|
618
|
-
for (const interfaceName of
|
|
72
|
+
for (const interfaceName of data.implementedInterfaceTypeNames) {
|
|
619
73
|
interfaces.push((0, utils_1.stringToNamedTypeNode)(interfaceName));
|
|
620
|
-
const
|
|
621
|
-
if (!
|
|
74
|
+
const interfaceData = this.parentDefinitionDataByTypeName.get(interfaceName);
|
|
75
|
+
if (!interfaceData) {
|
|
622
76
|
this.errors.push((0, errors_1.undefinedTypeError)(interfaceName));
|
|
623
77
|
continue;
|
|
624
78
|
}
|
|
625
|
-
if (
|
|
626
|
-
throw (0, errors_1.incompatibleParentKindFatalError)(interfaceName, graphql_1.Kind.INTERFACE_TYPE_DEFINITION,
|
|
79
|
+
if (interfaceData.kind !== graphql_1.Kind.INTERFACE_TYPE_DEFINITION) {
|
|
80
|
+
throw (0, errors_1.incompatibleParentKindFatalError)(interfaceName, graphql_1.Kind.INTERFACE_TYPE_DEFINITION, interfaceData.kind);
|
|
627
81
|
}
|
|
628
82
|
const implementationErrors = {
|
|
629
83
|
invalidFieldImplementations: new Map(),
|
|
630
84
|
unimplementedFields: [],
|
|
631
85
|
};
|
|
632
86
|
let hasErrors = false;
|
|
633
|
-
for (const [fieldName, interfaceField] of
|
|
87
|
+
for (const [fieldName, interfaceField] of interfaceData.fieldDataByFieldName) {
|
|
634
88
|
let hasNestedErrors = false;
|
|
635
|
-
const
|
|
636
|
-
if (!
|
|
89
|
+
const fieldData = data.fieldDataByFieldName.get(fieldName);
|
|
90
|
+
if (!fieldData) {
|
|
637
91
|
hasErrors = true;
|
|
638
92
|
implementationErrors.unimplementedFields.push(fieldName);
|
|
639
93
|
continue;
|
|
@@ -645,25 +99,25 @@ class FederationFactory {
|
|
|
645
99
|
unimplementedArguments: new Set(),
|
|
646
100
|
};
|
|
647
101
|
// The implemented field type must be equally or more restrictive than the original interface field type
|
|
648
|
-
if (!
|
|
102
|
+
if (!(0, utils_4.isTypeValidImplementation)(interfaceField.node.type, fieldData.node.type, this.concreteTypeNamesByAbstractTypeName)) {
|
|
649
103
|
hasErrors = true;
|
|
650
104
|
hasNestedErrors = true;
|
|
651
|
-
invalidFieldImplementation.implementedResponseType = (0, merge_1.printTypeNode)(
|
|
105
|
+
invalidFieldImplementation.implementedResponseType = (0, merge_1.printTypeNode)(fieldData.node.type);
|
|
652
106
|
}
|
|
653
107
|
const handledArguments = new Set();
|
|
654
|
-
for (const [argumentName,
|
|
655
|
-
const interfaceArgument =
|
|
108
|
+
for (const [argumentName, inputValueData] of interfaceField.argumentDataByArgumentName) {
|
|
109
|
+
const interfaceArgument = inputValueData.node;
|
|
656
110
|
handledArguments.add(argumentName);
|
|
657
|
-
const
|
|
111
|
+
const argumentNode = fieldData.argumentDataByArgumentName.get(argumentName)?.node;
|
|
658
112
|
// The type implementing the interface must include all arguments with no variation for that argument
|
|
659
|
-
if (!
|
|
113
|
+
if (!argumentNode) {
|
|
660
114
|
hasErrors = true;
|
|
661
115
|
hasNestedErrors = true;
|
|
662
116
|
invalidFieldImplementation.unimplementedArguments.add(argumentName);
|
|
663
117
|
continue;
|
|
664
118
|
}
|
|
665
119
|
// Implemented arguments should be the exact same type
|
|
666
|
-
const actualType = (0, merge_1.printTypeNode)(
|
|
120
|
+
const actualType = (0, merge_1.printTypeNode)(argumentNode.type);
|
|
667
121
|
const expectedType = (0, merge_1.printTypeNode)(interfaceArgument.type);
|
|
668
122
|
if (expectedType !== actualType) {
|
|
669
123
|
hasErrors = true;
|
|
@@ -672,7 +126,7 @@ class FederationFactory {
|
|
|
672
126
|
}
|
|
673
127
|
}
|
|
674
128
|
// Additional arguments must be optional (nullable)
|
|
675
|
-
for (const [argumentName, inputValueContainer] of
|
|
129
|
+
for (const [argumentName, inputValueContainer] of fieldData.argumentDataByArgumentName) {
|
|
676
130
|
const argumentNode = inputValueContainer.node;
|
|
677
131
|
if (handledArguments.has(argumentName)) {
|
|
678
132
|
continue;
|
|
@@ -693,168 +147,10 @@ class FederationFactory {
|
|
|
693
147
|
}
|
|
694
148
|
}
|
|
695
149
|
if (implementationErrorsMap.size) {
|
|
696
|
-
this.errors.push((0, errors_1.unimplementedInterfaceFieldsError)(
|
|
150
|
+
this.errors.push((0, errors_1.unimplementedInterfaceFieldsError)(data.node.name.value, (0, utils_2.kindToTypeString)(data.kind), implementationErrorsMap));
|
|
697
151
|
}
|
|
698
152
|
return interfaces;
|
|
699
153
|
}
|
|
700
|
-
mergeArguments(container, args, errors, argumentNames) {
|
|
701
|
-
for (const argumentContainer of container.arguments.values()) {
|
|
702
|
-
const missingSubgraphs = (0, utils_3.getEntriesNotInHashSet)(container.subgraphNames, argumentContainer.subgraphs);
|
|
703
|
-
const argumentName = argumentContainer.node.name.value;
|
|
704
|
-
if (missingSubgraphs.length > 0) {
|
|
705
|
-
// Required arguments must be defined in all subgraphs that define the field
|
|
706
|
-
if (argumentContainer.requiredSubgraphs.size > 0) {
|
|
707
|
-
errors.push({
|
|
708
|
-
argumentName,
|
|
709
|
-
missingSubgraphs,
|
|
710
|
-
requiredSubgraphs: [...argumentContainer.requiredSubgraphs],
|
|
711
|
-
});
|
|
712
|
-
}
|
|
713
|
-
// If the argument is always optional, but it's not defined in all subgraphs that define the field,
|
|
714
|
-
// the argument should not be included in the federated graph
|
|
715
|
-
continue;
|
|
716
|
-
}
|
|
717
|
-
argumentContainer.node.defaultValue = argumentContainer.includeDefaultValue
|
|
718
|
-
? argumentContainer.node.defaultValue
|
|
719
|
-
: undefined;
|
|
720
|
-
args.push((0, utils_1.pushPersistedDirectivesAndGetNode)(argumentContainer));
|
|
721
|
-
if (argumentNames) {
|
|
722
|
-
argumentNames.push(argumentName);
|
|
723
|
-
}
|
|
724
|
-
}
|
|
725
|
-
}
|
|
726
|
-
addValidExecutableDirectiveDefinition(directiveName, directiveContainer, definitions) {
|
|
727
|
-
if (!this.executableDirectives.has(directiveName)) {
|
|
728
|
-
return;
|
|
729
|
-
}
|
|
730
|
-
if (this.internalSubgraphBySubgraphName.size !== directiveContainer.subgraphNames.size) {
|
|
731
|
-
return;
|
|
732
|
-
}
|
|
733
|
-
directiveContainer.node.locations = (0, utils_1.setToNameNodeArray)(directiveContainer.executableLocations);
|
|
734
|
-
if (!directiveContainer.arguments) {
|
|
735
|
-
definitions.push(directiveContainer.node);
|
|
736
|
-
return;
|
|
737
|
-
}
|
|
738
|
-
const args = [];
|
|
739
|
-
const errors = [];
|
|
740
|
-
this.mergeArguments(directiveContainer, args, errors);
|
|
741
|
-
if (errors.length > 0) {
|
|
742
|
-
this.errors.push((0, errors_1.invalidRequiredArgumentsError)(string_constants_1.DIRECTIVE_DEFINITION, directiveName, errors));
|
|
743
|
-
return;
|
|
744
|
-
}
|
|
745
|
-
directiveContainer.node.arguments = args;
|
|
746
|
-
definitions.push(directiveContainer.node);
|
|
747
|
-
}
|
|
748
|
-
pushAuthorizationDirectives(fieldContainer, parentTypeName) {
|
|
749
|
-
const authorizationData = this.authorizationDataByParentTypeName.get(parentTypeName);
|
|
750
|
-
if (!authorizationData) {
|
|
751
|
-
return;
|
|
752
|
-
}
|
|
753
|
-
const fieldAuthorizationData = authorizationData.fieldAuthorizationDataByFieldName.get(fieldContainer.node.name.value);
|
|
754
|
-
if (!fieldAuthorizationData) {
|
|
755
|
-
return;
|
|
756
|
-
}
|
|
757
|
-
if (fieldAuthorizationData.requiresAuthentication) {
|
|
758
|
-
fieldContainer.directives.directives.set(string_constants_1.AUTHENTICATED, [(0, utils_3.generateSimpleDirective)(string_constants_1.AUTHENTICATED)]);
|
|
759
|
-
}
|
|
760
|
-
if (fieldAuthorizationData.requiredScopes.length > 0) {
|
|
761
|
-
fieldContainer.directives.directives.set(string_constants_1.REQUIRES_SCOPES, [
|
|
762
|
-
(0, utils_3.generateRequiresScopesDirective)(fieldAuthorizationData.requiredScopes),
|
|
763
|
-
]);
|
|
764
|
-
}
|
|
765
|
-
}
|
|
766
|
-
getMergedFieldDefinitionNode(fieldContainer, parentTypeName) {
|
|
767
|
-
this.pushAuthorizationDirectives(fieldContainer, parentTypeName);
|
|
768
|
-
(0, utils_1.pushPersistedDirectivesAndGetNode)(fieldContainer);
|
|
769
|
-
if (fieldContainer.arguments.size < 1) {
|
|
770
|
-
return fieldContainer.node;
|
|
771
|
-
}
|
|
772
|
-
const fieldName = fieldContainer.node.name.value;
|
|
773
|
-
const fieldPath = `${parentTypeName}.${fieldName}`;
|
|
774
|
-
const args = [];
|
|
775
|
-
const errors = [];
|
|
776
|
-
const argumentNames = [];
|
|
777
|
-
this.mergeArguments(fieldContainer, args, errors, argumentNames);
|
|
778
|
-
if (errors.length > 0) {
|
|
779
|
-
this.errors.push((0, errors_1.invalidRequiredArgumentsError)(string_constants_1.FIELD, fieldPath, errors));
|
|
780
|
-
}
|
|
781
|
-
else if (argumentNames.length > 0) {
|
|
782
|
-
this.fieldConfigurationByFieldPath.set(`${parentTypeName}.${fieldName}`, {
|
|
783
|
-
argumentNames,
|
|
784
|
-
fieldName,
|
|
785
|
-
typeName: parentTypeName,
|
|
786
|
-
});
|
|
787
|
-
}
|
|
788
|
-
fieldContainer.node.arguments = args;
|
|
789
|
-
return fieldContainer.node;
|
|
790
|
-
}
|
|
791
|
-
// the deprecated directive with the longest reason is kept
|
|
792
|
-
upsertDeprecatedDirective(directive, deprecatedDirectiveContainer) {
|
|
793
|
-
if (!directive.arguments || directive.arguments.length < 1) {
|
|
794
|
-
deprecatedDirectiveContainer.directive = directive;
|
|
795
|
-
return;
|
|
796
|
-
}
|
|
797
|
-
if (directive.arguments.length !== 1) {
|
|
798
|
-
this.errors.push(errors_1.invalidDeprecatedDirectiveError);
|
|
799
|
-
return;
|
|
800
|
-
}
|
|
801
|
-
const reasonArgument = directive.arguments[0].value;
|
|
802
|
-
if (reasonArgument.kind !== graphql_1.Kind.STRING) {
|
|
803
|
-
this.errors.push(errors_1.invalidDeprecatedDirectiveError);
|
|
804
|
-
return;
|
|
805
|
-
}
|
|
806
|
-
if (deprecatedDirectiveContainer.reason &&
|
|
807
|
-
reasonArgument.value.length < deprecatedDirectiveContainer.reason.length) {
|
|
808
|
-
return;
|
|
809
|
-
}
|
|
810
|
-
deprecatedDirectiveContainer.reason = reasonArgument.value;
|
|
811
|
-
deprecatedDirectiveContainer.directive = directive;
|
|
812
|
-
}
|
|
813
|
-
// tags with the same name string are merged
|
|
814
|
-
mergeTagDirectives(directive, map) {
|
|
815
|
-
// the directive has been validated in the normalizer
|
|
816
|
-
if (!directive.arguments || directive.arguments.length !== 1) {
|
|
817
|
-
this.errors.push(errors_1.invalidTagDirectiveError); // should never happen
|
|
818
|
-
return;
|
|
819
|
-
}
|
|
820
|
-
const nameArgument = directive.arguments[0].value;
|
|
821
|
-
if (nameArgument.kind !== graphql_1.Kind.STRING) {
|
|
822
|
-
this.errors.push(errors_1.invalidTagDirectiveError); // should never happen
|
|
823
|
-
return;
|
|
824
|
-
}
|
|
825
|
-
map.set(nameArgument.value, directive);
|
|
826
|
-
}
|
|
827
|
-
extractPersistedDirectives(directives, container) {
|
|
828
|
-
if (directives.length < 1) {
|
|
829
|
-
return container;
|
|
830
|
-
}
|
|
831
|
-
for (const directive of directives) {
|
|
832
|
-
const directiveName = directive.name.value;
|
|
833
|
-
if (!this.persistedDirectives.has(directiveName)) {
|
|
834
|
-
continue;
|
|
835
|
-
}
|
|
836
|
-
if (directiveName == string_constants_1.DEPRECATED) {
|
|
837
|
-
this.upsertDeprecatedDirective(directive, container.deprecated);
|
|
838
|
-
continue;
|
|
839
|
-
}
|
|
840
|
-
if (directiveName === string_constants_1.TAG) {
|
|
841
|
-
this.mergeTagDirectives(directive, container.tags);
|
|
842
|
-
continue;
|
|
843
|
-
}
|
|
844
|
-
const existingDirectives = container.directives.get(directiveName);
|
|
845
|
-
if (!existingDirectives) {
|
|
846
|
-
container.directives.set(directiveName, [directive]);
|
|
847
|
-
continue;
|
|
848
|
-
}
|
|
849
|
-
// Naïvely ignore non-repeatable directives
|
|
850
|
-
const definition = (0, utils_3.getOrThrowError)(this.directiveDefinitions, directiveName, 'directiveDefinitions');
|
|
851
|
-
if (!definition.node.repeatable) {
|
|
852
|
-
continue;
|
|
853
|
-
}
|
|
854
|
-
existingDirectives.push(directive);
|
|
855
|
-
}
|
|
856
|
-
return container;
|
|
857
|
-
}
|
|
858
154
|
isFieldResolvableByEntityAncestor(entityAncestors, fieldSubgraphs, parentTypeName) {
|
|
859
155
|
if (!this.graph.hasNode(parentTypeName)) {
|
|
860
156
|
return false;
|
|
@@ -865,11 +161,11 @@ class FederationFactory {
|
|
|
865
161
|
return true;
|
|
866
162
|
}
|
|
867
163
|
if (entityAncestorName === parentTypeName) {
|
|
868
|
-
const hasOverlap = (0,
|
|
164
|
+
const hasOverlap = (0, utils_2.doSetsHaveAnyOverlap)(fieldSubgraphs, (0, utils_2.getOrThrowError)(this.entityContainersByTypeName, entityAncestorName, string_constants_1.ENTITIES).subgraphNames);
|
|
869
165
|
this.graphPaths.set(path, hasOverlap);
|
|
870
166
|
return hasOverlap;
|
|
871
167
|
}
|
|
872
|
-
if ((0,
|
|
168
|
+
if ((0, utils_2.hasSimplePath)(this.graph, entityAncestorName, parentTypeName)) {
|
|
873
169
|
this.graphPaths.set(path, true);
|
|
874
170
|
return true;
|
|
875
171
|
}
|
|
@@ -887,22 +183,8 @@ class FederationFactory {
|
|
|
887
183
|
}
|
|
888
184
|
return false;
|
|
889
185
|
}
|
|
890
|
-
isFieldExternalInAllMutualSubgraphs(subgraphs, fieldContainer) {
|
|
891
|
-
const mutualSubgraphs = (0, utils_3.getAllMutualEntries)(subgraphs, fieldContainer.subgraphNames);
|
|
892
|
-
if (mutualSubgraphs.size < 1) {
|
|
893
|
-
return false;
|
|
894
|
-
}
|
|
895
|
-
for (const mutualSubgraph of mutualSubgraphs) {
|
|
896
|
-
const isExternal = fieldContainer.subgraphsByExternal.get(mutualSubgraph);
|
|
897
|
-
if (isExternal) {
|
|
898
|
-
continue;
|
|
899
|
-
}
|
|
900
|
-
return false;
|
|
901
|
-
}
|
|
902
|
-
return true;
|
|
903
|
-
}
|
|
904
186
|
updateEvaluatedSubgraphOccurrences(rootTypeFieldSubgraphs, objectSubgraphs, entityAncestors, parentTypeName) {
|
|
905
|
-
const mutualSubgraphs = (0,
|
|
187
|
+
const mutualSubgraphs = (0, utils_2.getAllMutualEntries)(rootTypeFieldSubgraphs, objectSubgraphs);
|
|
906
188
|
if (mutualSubgraphs.size > 0) {
|
|
907
189
|
for (const mutualSubgraph of mutualSubgraphs) {
|
|
908
190
|
const evaluatedObjects = this.evaluatedObjectLikesBySubgraph.get(mutualSubgraph);
|
|
@@ -914,23 +196,23 @@ class FederationFactory {
|
|
|
914
196
|
}
|
|
915
197
|
}
|
|
916
198
|
}
|
|
917
|
-
for (const
|
|
918
|
-
const entityContainer = (0,
|
|
919
|
-
const mutualEntityAncestorRootTypeFieldSubgraphs = (0,
|
|
920
|
-
const
|
|
921
|
-
for (const
|
|
922
|
-
const objects = this.evaluatedObjectLikesBySubgraph.get(
|
|
199
|
+
for (const entityAncestorTypeName of entityAncestors) {
|
|
200
|
+
const entityContainer = (0, utils_2.getOrThrowError)(this.parentDefinitionDataByTypeName, entityAncestorTypeName, 'parentDefinitionDataByTypeName');
|
|
201
|
+
const mutualEntityAncestorRootTypeFieldSubgraphs = (0, utils_2.getAllMutualEntries)(rootTypeFieldSubgraphs, entityContainer.subgraphNames);
|
|
202
|
+
const mutualEntityAncestorSubgraphsNames = (0, utils_2.getAllMutualEntries)(mutualEntityAncestorRootTypeFieldSubgraphs, objectSubgraphs);
|
|
203
|
+
for (const mutualSubgraphName of mutualEntityAncestorSubgraphsNames) {
|
|
204
|
+
const objects = this.evaluatedObjectLikesBySubgraph.get(mutualSubgraphName);
|
|
923
205
|
if (objects) {
|
|
924
206
|
objects.add(parentTypeName);
|
|
925
207
|
}
|
|
926
208
|
else {
|
|
927
|
-
this.evaluatedObjectLikesBySubgraph.set(
|
|
209
|
+
this.evaluatedObjectLikesBySubgraph.set(mutualSubgraphName, new Set([parentTypeName]));
|
|
928
210
|
}
|
|
929
211
|
}
|
|
930
212
|
}
|
|
931
213
|
}
|
|
932
|
-
evaluateResolvabilityOfObject(
|
|
933
|
-
const parentTypeName =
|
|
214
|
+
evaluateResolvabilityOfObject(objectData, rootTypeFieldData, currentFieldPath, evaluatedObjectLikes, entityAncestors, isParentAbstract = false) {
|
|
215
|
+
const parentTypeName = objectData.name;
|
|
934
216
|
if (evaluatedObjectLikes.has(parentTypeName)) {
|
|
935
217
|
return;
|
|
936
218
|
}
|
|
@@ -938,68 +220,68 @@ class FederationFactory {
|
|
|
938
220
|
evaluatedObjectLikes.add(parentTypeName);
|
|
939
221
|
return;
|
|
940
222
|
}
|
|
941
|
-
for (const [fieldName,
|
|
942
|
-
const
|
|
943
|
-
if (string_constants_1.ROOT_TYPES.has(
|
|
223
|
+
for (const [fieldName, fieldData] of objectData.fieldDataByFieldName) {
|
|
224
|
+
const namedFieldTypeName = fieldData.namedTypeName;
|
|
225
|
+
if (string_constants_1.ROOT_TYPES.has(namedFieldTypeName)) {
|
|
944
226
|
continue;
|
|
945
227
|
}
|
|
946
228
|
// Avoid an infinite loop with self-referential objects
|
|
947
|
-
if (evaluatedObjectLikes.has(
|
|
229
|
+
if (evaluatedObjectLikes.has(namedFieldTypeName)) {
|
|
948
230
|
continue;
|
|
949
231
|
}
|
|
950
|
-
if (
|
|
232
|
+
if ((0, utils_4.isFieldExternalInAllMutualSubgraphs)(rootTypeFieldData.subgraphs, fieldData)) {
|
|
951
233
|
continue;
|
|
952
234
|
}
|
|
953
|
-
this.updateEvaluatedSubgraphOccurrences(rootTypeFieldData.subgraphs,
|
|
235
|
+
this.updateEvaluatedSubgraphOccurrences(rootTypeFieldData.subgraphs, objectData.subgraphNames, entityAncestors, parentTypeName);
|
|
954
236
|
evaluatedObjectLikes.add(parentTypeName);
|
|
955
|
-
const isFieldResolvable = (0,
|
|
956
|
-
this.isFieldResolvableByEntityAncestor(entityAncestors,
|
|
237
|
+
const isFieldResolvable = (0, utils_2.doSetsHaveAnyOverlap)(rootTypeFieldData.subgraphs, fieldData.subgraphNames) ||
|
|
238
|
+
this.isFieldResolvableByEntityAncestor(entityAncestors, fieldData.subgraphNames, parentTypeName);
|
|
957
239
|
const newCurrentFieldPath = currentFieldPath + (isParentAbstract ? ' ' : '.') + fieldName;
|
|
958
|
-
const entity = this.entityContainersByTypeName.get(
|
|
240
|
+
const entity = this.entityContainersByTypeName.get(namedFieldTypeName);
|
|
959
241
|
if (isFieldResolvable) {
|
|
960
242
|
// The base scalars are not in this.parentMap
|
|
961
|
-
if (constants_1.BASE_SCALARS.has(
|
|
243
|
+
if (constants_1.BASE_SCALARS.has(namedFieldTypeName)) {
|
|
962
244
|
continue;
|
|
963
245
|
}
|
|
964
|
-
const
|
|
965
|
-
switch (
|
|
246
|
+
const namedTypeData = (0, utils_2.getOrThrowError)(this.parentDefinitionDataByTypeName, namedFieldTypeName, 'parentDefinitionDataByTypeName');
|
|
247
|
+
switch (namedTypeData.kind) {
|
|
966
248
|
case graphql_1.Kind.ENUM_TYPE_DEFINITION:
|
|
967
249
|
// intentional fallthrough
|
|
968
250
|
case graphql_1.Kind.SCALAR_TYPE_DEFINITION:
|
|
969
251
|
continue;
|
|
970
252
|
case graphql_1.Kind.OBJECT_TYPE_DEFINITION:
|
|
971
|
-
this.evaluateResolvabilityOfObject(
|
|
253
|
+
this.evaluateResolvabilityOfObject(namedTypeData, rootTypeFieldData, newCurrentFieldPath, evaluatedObjectLikes, entity ? [...entityAncestors, namedFieldTypeName] : [...entityAncestors]);
|
|
972
254
|
continue;
|
|
973
255
|
case graphql_1.Kind.INTERFACE_TYPE_DEFINITION:
|
|
974
256
|
// intentional fallthrough
|
|
975
257
|
case graphql_1.Kind.UNION_TYPE_DEFINITION:
|
|
976
|
-
this.evaluateResolvabilityOfAbstractType(
|
|
258
|
+
this.evaluateResolvabilityOfAbstractType(namedFieldTypeName, namedTypeData.kind, rootTypeFieldData, newCurrentFieldPath, evaluatedObjectLikes, entity ? [...entityAncestors, namedFieldTypeName] : [...entityAncestors]);
|
|
977
259
|
continue;
|
|
978
260
|
default:
|
|
979
|
-
this.errors.push((0, errors_1.unexpectedObjectResponseType)(newCurrentFieldPath, (0,
|
|
261
|
+
this.errors.push((0, errors_1.unexpectedObjectResponseType)(newCurrentFieldPath, (0, utils_2.kindToTypeString)(namedTypeData.kind)));
|
|
980
262
|
continue;
|
|
981
263
|
}
|
|
982
264
|
}
|
|
983
|
-
if (constants_1.BASE_SCALARS.has(
|
|
984
|
-
this.errors.push((0, errors_1.unresolvableFieldError)(rootTypeFieldData, fieldName, [...
|
|
265
|
+
if (constants_1.BASE_SCALARS.has(namedFieldTypeName)) {
|
|
266
|
+
this.errors.push((0, errors_1.unresolvableFieldError)(rootTypeFieldData, fieldName, [...fieldData.subgraphNames], newCurrentFieldPath, parentTypeName));
|
|
985
267
|
continue;
|
|
986
268
|
}
|
|
987
|
-
const
|
|
988
|
-
switch (
|
|
269
|
+
const namedTypeData = (0, utils_2.getOrThrowError)(this.parentDefinitionDataByTypeName, namedFieldTypeName, 'parentDefinitionDataByTypeName');
|
|
270
|
+
switch (namedTypeData.kind) {
|
|
989
271
|
case graphql_1.Kind.ENUM_TYPE_DEFINITION:
|
|
990
272
|
// intentional fallthrough
|
|
991
273
|
case graphql_1.Kind.SCALAR_TYPE_DEFINITION:
|
|
992
|
-
this.errors.push((0, errors_1.unresolvableFieldError)(rootTypeFieldData, fieldName, [...
|
|
274
|
+
this.errors.push((0, errors_1.unresolvableFieldError)(rootTypeFieldData, fieldName, [...fieldData.subgraphNames], newCurrentFieldPath, parentTypeName));
|
|
993
275
|
continue;
|
|
994
276
|
case graphql_1.Kind.INTERFACE_TYPE_DEFINITION:
|
|
995
277
|
// intentional fallthrough
|
|
996
278
|
case graphql_1.Kind.UNION_TYPE_DEFINITION:
|
|
997
279
|
// intentional fallthrough
|
|
998
280
|
case graphql_1.Kind.OBJECT_TYPE_DEFINITION:
|
|
999
|
-
this.errors.push((0, errors_1.unresolvableFieldError)(rootTypeFieldData, fieldName, [...
|
|
281
|
+
this.errors.push((0, errors_1.unresolvableFieldError)(rootTypeFieldData, fieldName, [...fieldData.subgraphNames], newCurrentFieldPath + string_constants_1.SELECTION_REPRESENTATION, parentTypeName));
|
|
1000
282
|
continue;
|
|
1001
283
|
default:
|
|
1002
|
-
this.errors.push((0, errors_1.unexpectedObjectResponseType)(newCurrentFieldPath, (0,
|
|
284
|
+
this.errors.push((0, errors_1.unexpectedObjectResponseType)(newCurrentFieldPath, (0, utils_2.kindToTypeString)(namedTypeData.kind)));
|
|
1003
285
|
}
|
|
1004
286
|
}
|
|
1005
287
|
}
|
|
@@ -1008,30 +290,30 @@ class FederationFactory {
|
|
|
1008
290
|
return;
|
|
1009
291
|
}
|
|
1010
292
|
evaluatedObjectLikes.add(abstractTypeName);
|
|
1011
|
-
const concreteTypeNames = this.
|
|
293
|
+
const concreteTypeNames = this.concreteTypeNamesByAbstractTypeName.get(abstractTypeName);
|
|
1012
294
|
if (!concreteTypeNames) {
|
|
1013
|
-
(0, errors_1.noConcreteTypesForAbstractTypeError)((0,
|
|
295
|
+
(0, errors_1.noConcreteTypesForAbstractTypeError)((0, utils_2.kindToTypeString)(abstractKind), abstractTypeName);
|
|
1014
296
|
return;
|
|
1015
297
|
}
|
|
1016
298
|
for (const concreteTypeName of concreteTypeNames) {
|
|
1017
299
|
if (evaluatedObjectLikes.has(concreteTypeName)) {
|
|
1018
300
|
continue;
|
|
1019
301
|
}
|
|
1020
|
-
const
|
|
1021
|
-
if (
|
|
1022
|
-
throw (0, errors_1.unexpectedParentKindErrorMessage)(concreteTypeName, 'Object', (0,
|
|
302
|
+
const concreteTypeData = (0, utils_2.getOrThrowError)(this.parentDefinitionDataByTypeName, concreteTypeName, 'parentDefinitionDataByTypeName');
|
|
303
|
+
if (concreteTypeData.kind !== graphql_1.Kind.OBJECT_TYPE_DEFINITION) {
|
|
304
|
+
throw (0, errors_1.unexpectedParentKindErrorMessage)(concreteTypeName, 'Object', (0, utils_2.kindToTypeString)(concreteTypeData.kind));
|
|
1023
305
|
}
|
|
1024
306
|
// If the concrete type is unreachable through an inline fragment, it is not an error
|
|
1025
|
-
if (!(0,
|
|
307
|
+
if (!(0, utils_2.doSetsHaveAnyOverlap)(concreteTypeData.subgraphNames, rootTypeFieldData.subgraphs)) {
|
|
1026
308
|
continue;
|
|
1027
309
|
}
|
|
1028
310
|
const entity = this.entityContainersByTypeName.get(concreteTypeName);
|
|
1029
|
-
this.evaluateResolvabilityOfObject(
|
|
311
|
+
this.evaluateResolvabilityOfObject(concreteTypeData, rootTypeFieldData, currentFieldPath + ` ... on ` + concreteTypeName, evaluatedObjectLikes, entity ? [...entityAncestors, concreteTypeName] : [...entityAncestors], true);
|
|
1030
312
|
}
|
|
1031
313
|
}
|
|
1032
314
|
validateKeyFieldSetsForImplicitEntity(entityContainer) {
|
|
1033
|
-
const internalSubgraph = (0,
|
|
1034
|
-
const parentContainerByTypeName = internalSubgraph.
|
|
315
|
+
const internalSubgraph = (0, utils_2.getOrThrowError)(this.internalSubgraphBySubgraphName, this.currentSubgraphName, 'internalSubgraphBySubgraphName');
|
|
316
|
+
const parentContainerByTypeName = internalSubgraph.parentDefinitionDataByTypeName;
|
|
1035
317
|
const extensionContainerByTypeName = internalSubgraph.parentExtensionDataByTypeName;
|
|
1036
318
|
const implicitEntityContainer = parentContainerByTypeName.get(entityContainer.typeName) ||
|
|
1037
319
|
extensionContainerByTypeName.get(entityContainer.typeName);
|
|
@@ -1040,7 +322,7 @@ class FederationFactory {
|
|
|
1040
322
|
implicitEntityContainer.kind !== graphql_1.Kind.OBJECT_TYPE_EXTENSION)) {
|
|
1041
323
|
throw (0, errors_1.incompatibleParentKindFatalError)(entityContainer.typeName, graphql_1.Kind.OBJECT_TYPE_DEFINITION, implicitEntityContainer?.kind || graphql_1.Kind.NULL);
|
|
1042
324
|
}
|
|
1043
|
-
const configurationData = (0,
|
|
325
|
+
const configurationData = (0, utils_2.getOrThrowError)(internalSubgraph.configurationDataByParentTypeName, entityContainer.typeName, 'internalSubgraph.configurationDataMap');
|
|
1044
326
|
const keyFieldNames = new Set();
|
|
1045
327
|
const keys = [];
|
|
1046
328
|
// Any errors in the field sets would be caught when evaluating the explicit entities, so they are ignored here
|
|
@@ -1068,19 +350,15 @@ class FederationFactory {
|
|
|
1068
350
|
Field: {
|
|
1069
351
|
enter(node) {
|
|
1070
352
|
const parentContainer = parentContainers[currentDepth];
|
|
1071
|
-
const parentTypeName = parentContainer.typeName;
|
|
1072
353
|
// If an object-like was just visited, a selection set should have been entered
|
|
1073
354
|
if (shouldDefineSelectionSet) {
|
|
1074
355
|
shouldAddKeyFieldSet = false;
|
|
1075
356
|
return graphql_1.BREAK;
|
|
1076
357
|
}
|
|
1077
358
|
const fieldName = node.name.value;
|
|
1078
|
-
const
|
|
1079
|
-
const fieldContainer = parentContainer.fieldDataByFieldName.get(fieldName);
|
|
359
|
+
const fieldData = parentContainer.fieldDataByFieldName.get(fieldName);
|
|
1080
360
|
// undefined if the field does not exist on the parent
|
|
1081
|
-
if (!
|
|
1082
|
-
fieldContainer.argumentDataByArgumentName.size ||
|
|
1083
|
-
definedFields[currentDepth].has(fieldName)) {
|
|
361
|
+
if (!fieldData || fieldData.argumentDataByArgumentName.size || definedFields[currentDepth].has(fieldName)) {
|
|
1084
362
|
shouldAddKeyFieldSet = false;
|
|
1085
363
|
return graphql_1.BREAK;
|
|
1086
364
|
}
|
|
@@ -1090,7 +368,7 @@ class FederationFactory {
|
|
|
1090
368
|
if (currentDepth === 0) {
|
|
1091
369
|
keyFieldNames.add(fieldName);
|
|
1092
370
|
}
|
|
1093
|
-
const namedTypeName = (0,
|
|
371
|
+
const namedTypeName = (0, ast_1.getTypeNodeNamedTypeName)(fieldData.node.type);
|
|
1094
372
|
// The base scalars are not in the parents map
|
|
1095
373
|
if (constants_1.BASE_SCALARS.has(namedTypeName)) {
|
|
1096
374
|
return;
|
|
@@ -1150,10 +428,10 @@ class FederationFactory {
|
|
|
1150
428
|
continue;
|
|
1151
429
|
}
|
|
1152
430
|
// Add any top-level fields that compose the key in case they are external
|
|
1153
|
-
(0,
|
|
431
|
+
(0, utils_2.addIterableValuesToSet)(keyFieldNames, configurationData.fieldNames);
|
|
1154
432
|
keys.push({
|
|
1155
433
|
fieldName: '',
|
|
1156
|
-
selectionSet: (0,
|
|
434
|
+
selectionSet: (0, utils_3.getNormalizedFieldSet)(documentNode),
|
|
1157
435
|
disableEntityResolver: true,
|
|
1158
436
|
});
|
|
1159
437
|
}
|
|
@@ -1162,51 +440,76 @@ class FederationFactory {
|
|
|
1162
440
|
configurationData.keys = keys;
|
|
1163
441
|
}
|
|
1164
442
|
}
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
443
|
+
getEnumValueMergeMethod(enumTypeName) {
|
|
444
|
+
if (this.namedInputValueTypeNames.has(enumTypeName)) {
|
|
445
|
+
if (this.namedOutputTypeNames.has(enumTypeName)) {
|
|
446
|
+
return utils_4.MergeMethod.CONSISTENT;
|
|
447
|
+
}
|
|
448
|
+
return utils_4.MergeMethod.INTERSECTION;
|
|
449
|
+
}
|
|
450
|
+
return utils_4.MergeMethod.UNION;
|
|
451
|
+
}
|
|
452
|
+
federate() {
|
|
453
|
+
const persistedDirectiveDefinitionDataByDirectiveName = new Map();
|
|
454
|
+
let shouldSkipPersistedExecutableDirectives = false;
|
|
455
|
+
let subgraphNumber = 0;
|
|
456
|
+
let isVersionTwo = false;
|
|
457
|
+
for (const internalSubgraph of this.internalSubgraphBySubgraphName.values()) {
|
|
458
|
+
subgraphNumber += 1;
|
|
459
|
+
this.currentSubgraphName = internalSubgraph.name;
|
|
460
|
+
isVersionTwo ||= internalSubgraph.isVersionTwo;
|
|
461
|
+
(0, walkers_1.createMultiGraphAndRenameRootTypes)(this, internalSubgraph);
|
|
462
|
+
for (const parentDefinitionData of internalSubgraph.parentDefinitionDataByTypeName.values()) {
|
|
463
|
+
(0, utils_4.upsertParentDefinitionData)(this.parentDefinitionDataByTypeName, parentDefinitionData, this.persistedDirectiveDefinitionByDirectiveName, this.entityInterfaceFederationDataByTypeName, this.namedOutputTypeNames, this.namedInputValueTypeNames, internalSubgraph.name, this.errors);
|
|
464
|
+
}
|
|
465
|
+
for (const objectExtensionData of internalSubgraph.parentExtensionDataByTypeName.values()) {
|
|
466
|
+
(0, utils_4.upsertObjectExtensionData)(this.objectExtensionDataByTypeName, objectExtensionData, this.persistedDirectiveDefinitionByDirectiveName, this.namedOutputTypeNames, this.namedInputValueTypeNames, this.errors);
|
|
467
|
+
}
|
|
468
|
+
if (shouldSkipPersistedExecutableDirectives) {
|
|
1169
469
|
continue;
|
|
1170
470
|
}
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
if (!
|
|
1174
|
-
|
|
471
|
+
/* If a subgraph defines no executable directives, it is not possible for any definition to be in all subgraphs.
|
|
472
|
+
Consequently, it is no longer necessary to check for any persisted executable directives. */
|
|
473
|
+
if (!internalSubgraph.persistedDirectiveDefinitionDataByDirectiveName.size) {
|
|
474
|
+
shouldSkipPersistedExecutableDirectives = true;
|
|
475
|
+
continue;
|
|
1175
476
|
}
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
477
|
+
for (const persistedDirectiveDefinitionData of internalSubgraph.persistedDirectiveDefinitionDataByDirectiveName.values()) {
|
|
478
|
+
(0, utils_4.upsertPersistedDirectiveDefinitionData)(persistedDirectiveDefinitionDataByDirectiveName, persistedDirectiveDefinitionData, this.persistedDirectiveDefinitionByDirectiveName, this.namedInputValueTypeNames, subgraphNumber, this.errors);
|
|
479
|
+
}
|
|
480
|
+
/* Invalid directives keys are deleted; if there are no entries left, it is no longer necessary to evaluate more
|
|
481
|
+
executable directives. */
|
|
482
|
+
if (!persistedDirectiveDefinitionDataByDirectiveName.size) {
|
|
483
|
+
shouldSkipPersistedExecutableDirectives = true;
|
|
1182
484
|
}
|
|
1183
|
-
this.authorizationDataByParentTypeName.delete(originalTypeName);
|
|
1184
485
|
}
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
486
|
+
const definitions = isVersionTwo
|
|
487
|
+
? [
|
|
488
|
+
constants_1.AUTHENTICATED_DEFINITION,
|
|
489
|
+
constants_1.DEPRECATED_DEFINITION,
|
|
490
|
+
constants_1.INACCESSIBLE_DEFINITION,
|
|
491
|
+
constants_1.REQUIRES_SCOPES_DEFINITION,
|
|
492
|
+
constants_1.TAG_DEFINITION,
|
|
493
|
+
constants_1.SCOPE_SCALAR_DEFINITION,
|
|
494
|
+
]
|
|
495
|
+
: [constants_1.DEPRECATED_DEFINITION, constants_1.TAG_DEFINITION];
|
|
496
|
+
for (const data of persistedDirectiveDefinitionDataByDirectiveName.values()) {
|
|
497
|
+
(0, utils_4.addValidPersistedDirectiveDefinitionNodeByData)(definitions, data, this.persistedDirectiveDefinitionByDirectiveName, this.errors);
|
|
1194
498
|
}
|
|
1195
|
-
this.handleAuthorizationDataForRenamedTypes();
|
|
1196
499
|
for (const [typeName, entityInterfaceData] of this.entityInterfaceFederationDataByTypeName) {
|
|
1197
|
-
(0,
|
|
1198
|
-
const entityInterface = (0,
|
|
500
|
+
(0, utils_2.subtractSourceSetFromTargetSet)(entityInterfaceData.interfaceFieldNames, entityInterfaceData.interfaceObjectFieldNames);
|
|
501
|
+
const entityInterface = (0, utils_2.getOrThrowError)(this.parentDefinitionDataByTypeName, typeName, 'parentDefinitionDataByTypeName');
|
|
1199
502
|
if (entityInterface.kind !== graphql_1.Kind.INTERFACE_TYPE_DEFINITION) {
|
|
1200
503
|
// TODO error
|
|
1201
504
|
continue;
|
|
1202
505
|
}
|
|
1203
506
|
for (const subgraphName of entityInterfaceData.interfaceObjectSubgraphs) {
|
|
1204
|
-
const configurationDataMap = (0,
|
|
1205
|
-
const concreteTypeNames = this.
|
|
507
|
+
const configurationDataMap = (0, utils_2.getOrThrowError)(this.internalSubgraphBySubgraphName, subgraphName, 'internalSubgraphBySubgraphName').configurationDataByParentTypeName;
|
|
508
|
+
const concreteTypeNames = this.concreteTypeNamesByAbstractTypeName.get(typeName);
|
|
1206
509
|
if (!concreteTypeNames) {
|
|
1207
510
|
continue;
|
|
1208
511
|
}
|
|
1209
|
-
const interfaceObjectConfiguration = (0,
|
|
512
|
+
const interfaceObjectConfiguration = (0, utils_2.getOrThrowError)(configurationDataMap, typeName, 'configurationDataMap');
|
|
1210
513
|
const keys = interfaceObjectConfiguration.keys;
|
|
1211
514
|
if (!keys) {
|
|
1212
515
|
// TODO no keys error
|
|
@@ -1221,15 +524,15 @@ class FederationFactory {
|
|
|
1221
524
|
continue;
|
|
1222
525
|
}
|
|
1223
526
|
if (authorizationData) {
|
|
1224
|
-
const concreteAuthorizationData = (0,
|
|
527
|
+
const concreteAuthorizationData = (0, utils_2.getValueOrDefault)(this.authorizationDataByParentTypeName, concreteTypeName, () => (0, utils_2.newAuthorizationData)(concreteTypeName));
|
|
1225
528
|
for (const fieldAuthorizationData of authorizationData.fieldAuthorizationDataByFieldName.values()) {
|
|
1226
|
-
if (!(0,
|
|
529
|
+
if (!(0, utils_2.upsertFieldAuthorizationData)(concreteAuthorizationData.fieldAuthorizationDataByFieldName, fieldAuthorizationData)) {
|
|
1227
530
|
this.invalidOrScopesHostPaths.add(`${concreteTypeName}.${fieldAuthorizationData.fieldName}`);
|
|
1228
531
|
}
|
|
1229
532
|
}
|
|
1230
533
|
}
|
|
1231
|
-
const
|
|
1232
|
-
if (
|
|
534
|
+
const concreteTypeData = (0, utils_2.getOrThrowError)(this.parentDefinitionDataByTypeName, concreteTypeName, 'parentDefinitionDataByTypeName');
|
|
535
|
+
if (concreteTypeData.kind !== graphql_1.Kind.OBJECT_TYPE_DEFINITION) {
|
|
1233
536
|
continue;
|
|
1234
537
|
}
|
|
1235
538
|
// The subgraph locations of the interface object must be added to the concrete types that implement it
|
|
@@ -1245,198 +548,284 @@ class FederationFactory {
|
|
|
1245
548
|
typeName: concreteTypeName,
|
|
1246
549
|
};
|
|
1247
550
|
for (const fieldName of entityInterfaceData.interfaceObjectFieldNames) {
|
|
1248
|
-
const
|
|
1249
|
-
if (
|
|
551
|
+
const existingFieldData = concreteTypeData.fieldDataByFieldName.get(fieldName);
|
|
552
|
+
if (existingFieldData) {
|
|
1250
553
|
// TODO handle shareability
|
|
1251
554
|
continue;
|
|
1252
555
|
}
|
|
1253
|
-
const
|
|
1254
|
-
|
|
556
|
+
const interfaceFieldData = (0, utils_2.getOrThrowError)(entityInterface.fieldDataByFieldName, fieldName, `${typeName}.fieldDataByFieldName`);
|
|
557
|
+
concreteTypeData.fieldDataByFieldName.set(fieldName, { ...interfaceFieldData });
|
|
1255
558
|
}
|
|
1256
559
|
configurationDataMap.set(concreteTypeName, configurationData);
|
|
1257
560
|
}
|
|
1258
561
|
}
|
|
1259
562
|
}
|
|
1260
563
|
if (this.invalidOrScopesHostPaths.size > 0) {
|
|
1261
|
-
this.errors.push((0, errors_1.orScopesLimitError)(
|
|
1262
|
-
}
|
|
1263
|
-
const
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
if (
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
const parent = (0, utils_3.getOrThrowError)(this.parents, parentTypeName, string_constants_1.PARENTS);
|
|
1315
|
-
if (parent.kind !== graphql_1.Kind.OBJECT_TYPE_DEFINITION) {
|
|
1316
|
-
throw (0, errors_1.incompatibleParentKindFatalError)(parentTypeName, graphql_1.Kind.OBJECT_TYPE_DEFINITION, parent.kind);
|
|
1317
|
-
}
|
|
1318
|
-
this.errors.push((0, errors_1.shareableFieldDefinitionsError)(parent, children));
|
|
1319
|
-
}
|
|
1320
|
-
const objectLikeContainersWithInterfaces = [];
|
|
1321
|
-
for (const [parentTypeName, parentContainer] of this.parents) {
|
|
1322
|
-
switch (parentContainer.kind) {
|
|
564
|
+
this.errors.push((0, errors_1.orScopesLimitError)(utils_2.maxOrScopes, [...this.invalidOrScopesHostPaths]));
|
|
565
|
+
}
|
|
566
|
+
for (const [parentTypeName, objectExtensionData] of this.objectExtensionDataByTypeName) {
|
|
567
|
+
(0, utils_4.upsertValidObjectExtensionData)(this.parentDefinitionDataByTypeName, objectExtensionData, this.persistedDirectiveDefinitionByDirectiveName, this.namedOutputTypeNames, this.namedInputValueTypeNames, this.errors, this.authorizationDataByParentTypeName.get(parentTypeName));
|
|
568
|
+
}
|
|
569
|
+
// for (const [typeName, extension] of this.extensions) {
|
|
570
|
+
// this.parentTypeName = typeName;
|
|
571
|
+
// if (extension.isRootType && !this.parents.has(typeName)) {
|
|
572
|
+
// this.upsertParentNode(objectTypeExtensionNodeToMutableDefinitionNode(extension.node));
|
|
573
|
+
// }
|
|
574
|
+
// const baseObject = this.parents.get(typeName);
|
|
575
|
+
// if (!baseObject) {
|
|
576
|
+
// this.errors.push(noBaseTypeExtensionError(typeName));
|
|
577
|
+
// continue;
|
|
578
|
+
// }
|
|
579
|
+
//
|
|
580
|
+
// if (baseObject.kind !== Kind.OBJECT_TYPE_DEFINITION) {
|
|
581
|
+
// throw incompatibleParentKindFatalError(typeName, Kind.OBJECT_TYPE_DEFINITION, baseObject.kind);
|
|
582
|
+
// }
|
|
583
|
+
// this.upsertExtensionPersistedDirectives(extension.directives, baseObject.directives);
|
|
584
|
+
// for (const [extensionFieldName, extensionFieldContainer] of extension.fields) {
|
|
585
|
+
// const baseFieldContainer = baseObject.fields.get(extensionFieldName);
|
|
586
|
+
// if (!baseFieldContainer) {
|
|
587
|
+
// baseObject.fields.set(extensionFieldName, extensionFieldContainer);
|
|
588
|
+
// continue;
|
|
589
|
+
// }
|
|
590
|
+
// if (baseFieldContainer.isShareable && extensionFieldContainer.isShareable) {
|
|
591
|
+
// this.childName = extensionFieldName;
|
|
592
|
+
// this.upsertExtensionFieldArguments(extensionFieldContainer.arguments, baseFieldContainer.arguments);
|
|
593
|
+
// addIterableValuesToSet(extensionFieldContainer.subgraphNames, baseFieldContainer.subgraphNames);
|
|
594
|
+
// continue;
|
|
595
|
+
// }
|
|
596
|
+
// const parent = this.shareableErrorTypeNames.get(typeName);
|
|
597
|
+
// if (parent) {
|
|
598
|
+
// parent.add(extensionFieldName);
|
|
599
|
+
// continue;
|
|
600
|
+
// }
|
|
601
|
+
// this.shareableErrorTypeNames.set(typeName, new Set<string>([extensionFieldName]));
|
|
602
|
+
// }
|
|
603
|
+
// for (const interfaceName of extension.interfaces) {
|
|
604
|
+
// baseObject.interfaces.add(interfaceName);
|
|
605
|
+
// }
|
|
606
|
+
// }
|
|
607
|
+
// for (const [parentTypeName, children] of this.shareableErrorTypeNames) {
|
|
608
|
+
// const parent = getOrThrowError(this.parents, parentTypeName, PARENTS);
|
|
609
|
+
// if (parent.kind !== Kind.OBJECT_TYPE_DEFINITION) {
|
|
610
|
+
// throw incompatibleParentKindFatalError(parentTypeName, Kind.OBJECT_TYPE_DEFINITION, parent.kind);
|
|
611
|
+
// }
|
|
612
|
+
// this.errors.push(shareableFieldDefinitionsError(parent, children));
|
|
613
|
+
// }
|
|
614
|
+
const definitionsWithInterfaces = [];
|
|
615
|
+
for (const [parentTypeName, parentDefinitionData] of this.parentDefinitionDataByTypeName) {
|
|
616
|
+
switch (parentDefinitionData.kind) {
|
|
1323
617
|
case graphql_1.Kind.ENUM_TYPE_DEFINITION:
|
|
1324
|
-
const
|
|
1325
|
-
const mergeMethod = this.
|
|
1326
|
-
for (const
|
|
1327
|
-
(0,
|
|
618
|
+
const enumValueNodes = [];
|
|
619
|
+
const mergeMethod = this.getEnumValueMergeMethod(parentTypeName);
|
|
620
|
+
for (const enumValueData of parentDefinitionData.enumValueDataByValueName.values()) {
|
|
621
|
+
const enumValueNode = (0, utils_4.getNodeWithPersistedDirectivesByData)(enumValueData, this.persistedDirectiveDefinitionByDirectiveName, this.errors);
|
|
1328
622
|
switch (mergeMethod) {
|
|
1329
|
-
case
|
|
1330
|
-
if (
|
|
623
|
+
case utils_4.MergeMethod.CONSISTENT:
|
|
624
|
+
if (parentDefinitionData.appearances > enumValueData.appearances) {
|
|
1331
625
|
this.errors.push((0, errors_1.incompatibleSharedEnumError)(parentTypeName));
|
|
1332
626
|
}
|
|
1333
|
-
|
|
627
|
+
enumValueNodes.push(enumValueNode);
|
|
1334
628
|
break;
|
|
1335
|
-
case
|
|
1336
|
-
if (
|
|
1337
|
-
|
|
629
|
+
case utils_4.MergeMethod.INTERSECTION:
|
|
630
|
+
if (parentDefinitionData.appearances === enumValueData.appearances) {
|
|
631
|
+
enumValueNodes.push(enumValueNode);
|
|
1338
632
|
}
|
|
1339
633
|
break;
|
|
1340
634
|
default:
|
|
1341
|
-
|
|
635
|
+
enumValueNodes.push(enumValueNode);
|
|
1342
636
|
break;
|
|
1343
637
|
}
|
|
1344
638
|
}
|
|
1345
|
-
|
|
1346
|
-
definitions.push((0,
|
|
639
|
+
parentDefinitionData.node.values = enumValueNodes;
|
|
640
|
+
definitions.push((0, utils_4.getNodeWithPersistedDirectivesByData)(parentDefinitionData, this.persistedDirectiveDefinitionByDirectiveName, this.errors));
|
|
1347
641
|
break;
|
|
1348
642
|
case graphql_1.Kind.INPUT_OBJECT_TYPE_DEFINITION:
|
|
1349
|
-
const
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
if (
|
|
1353
|
-
|
|
643
|
+
const invalidRequiredInputs = [];
|
|
644
|
+
const inputValueNodes = [];
|
|
645
|
+
for (const [inputValueName, inputValueData] of parentDefinitionData.inputValueDataByValueName) {
|
|
646
|
+
if (parentDefinitionData.subgraphNames.size === inputValueData.subgraphNames.size) {
|
|
647
|
+
inputValueNodes.push((0, utils_4.getNodeWithPersistedDirectivesByInputValueData)(inputValueData, this.persistedDirectiveDefinitionByDirectiveName, this.errors));
|
|
1354
648
|
}
|
|
1355
|
-
else if ((0,
|
|
1356
|
-
|
|
1357
|
-
|
|
649
|
+
else if ((0, utils_4.isTypeRequired)(inputValueData.type)) {
|
|
650
|
+
invalidRequiredInputs.push({
|
|
651
|
+
inputValueName,
|
|
652
|
+
missingSubgraphs: (0, utils_2.getEntriesNotInHashSet)(parentDefinitionData.subgraphNames, inputValueData.subgraphNames),
|
|
653
|
+
requiredSubgraphs: [...inputValueData.requiredSubgraphNames],
|
|
654
|
+
});
|
|
1358
655
|
}
|
|
1359
656
|
}
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
case graphql_1.Kind.INTERFACE_TYPE_DEFINITION:
|
|
1364
|
-
const interfaceFields = [];
|
|
1365
|
-
for (const fieldContainer of parentContainer.fields.values()) {
|
|
1366
|
-
if ((0, utils_2.isFieldInaccessible)(fieldContainer)) {
|
|
1367
|
-
continue;
|
|
1368
|
-
}
|
|
1369
|
-
interfaceFields.push(this.getMergedFieldDefinitionNode(fieldContainer, parentTypeName));
|
|
1370
|
-
}
|
|
1371
|
-
parentContainer.node.fields = interfaceFields;
|
|
1372
|
-
(0, utils_1.pushPersistedDirectivesAndGetNode)(parentContainer);
|
|
1373
|
-
// Interface implementations can only be evaluated after they've been fully merged
|
|
1374
|
-
if (parentContainer.interfaces.size > 0) {
|
|
1375
|
-
objectLikeContainersWithInterfaces.push(parentContainer);
|
|
1376
|
-
}
|
|
1377
|
-
else {
|
|
1378
|
-
definitions.push(parentContainer.node);
|
|
1379
|
-
}
|
|
1380
|
-
if (interfaceFields.length < 1) {
|
|
1381
|
-
this.errors.push((0, errors_1.allFieldDefinitionsAreInaccessibleError)('interface', parentTypeName));
|
|
657
|
+
if (invalidRequiredInputs.length > 0) {
|
|
658
|
+
this.errors.push((0, errors_1.invalidRequiredInputValueError)(string_constants_1.INPUT_OBJECT, parentTypeName, invalidRequiredInputs, false));
|
|
659
|
+
break;
|
|
1382
660
|
}
|
|
661
|
+
parentDefinitionData.node.fields = inputValueNodes;
|
|
662
|
+
definitions.push((0, utils_4.getNodeWithPersistedDirectivesByData)(parentDefinitionData, this.persistedDirectiveDefinitionByDirectiveName, this.errors));
|
|
1383
663
|
break;
|
|
664
|
+
case graphql_1.Kind.INTERFACE_TYPE_DEFINITION:
|
|
665
|
+
// intentional fallthrough
|
|
1384
666
|
case graphql_1.Kind.OBJECT_TYPE_DEFINITION:
|
|
1385
|
-
const
|
|
1386
|
-
|
|
1387
|
-
|
|
667
|
+
const fieldNodes = [];
|
|
668
|
+
const invalidFieldNames = new Set();
|
|
669
|
+
const isObject = parentDefinitionData.kind === graphql_1.Kind.OBJECT_TYPE_DEFINITION;
|
|
670
|
+
for (const [fieldName, fieldData] of parentDefinitionData.fieldDataByFieldName) {
|
|
671
|
+
(0, utils_4.pushAuthorizationDirectives)(fieldData, this.authorizationDataByParentTypeName.get(parentTypeName));
|
|
672
|
+
const argumentNodes = (0, utils_4.getValidFieldArgumentNodes)(fieldData, this.persistedDirectiveDefinitionByDirectiveName, this.fieldConfigurationByFieldPath, this.errors);
|
|
673
|
+
if (isObject && !(0, utils_4.isShareabilityOfAllFieldInstancesValid)(fieldData)) {
|
|
674
|
+
invalidFieldNames.add(fieldName);
|
|
675
|
+
}
|
|
676
|
+
if (fieldData.isInaccessible) {
|
|
1388
677
|
continue;
|
|
1389
678
|
}
|
|
1390
|
-
|
|
679
|
+
fieldNodes.push((0, utils_4.getNodeWithPersistedDirectivesByFieldData)(fieldData, this.persistedDirectiveDefinitionByDirectiveName, argumentNodes, this.errors));
|
|
1391
680
|
}
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
681
|
+
if (isObject && invalidFieldNames.size > 0) {
|
|
682
|
+
this.errors.push((0, errors_1.invalidFieldShareabilityError)(parentDefinitionData, invalidFieldNames));
|
|
683
|
+
}
|
|
684
|
+
parentDefinitionData.node.fields = fieldNodes;
|
|
685
|
+
// Implemented interfaces can only be validated after all fields are merged
|
|
686
|
+
if (parentDefinitionData.implementedInterfaceTypeNames.size > 0) {
|
|
687
|
+
definitionsWithInterfaces.push(parentDefinitionData);
|
|
1397
688
|
}
|
|
1398
689
|
else {
|
|
1399
|
-
definitions.push(
|
|
690
|
+
definitions.push((0, utils_4.getNodeWithPersistedDirectivesByData)(parentDefinitionData, this.persistedDirectiveDefinitionByDirectiveName, this.errors));
|
|
1400
691
|
}
|
|
1401
|
-
if (
|
|
1402
|
-
if ((0,
|
|
692
|
+
if (fieldNodes.length < 1) {
|
|
693
|
+
if ((0, utils_3.isNodeQuery)(parentTypeName)) {
|
|
1403
694
|
this.errors.push(errors_1.noQueryRootTypeError);
|
|
1404
695
|
}
|
|
1405
696
|
else {
|
|
1406
|
-
this.errors.push((0, errors_1.allFieldDefinitionsAreInaccessibleError)(
|
|
697
|
+
this.errors.push((0, errors_1.allFieldDefinitionsAreInaccessibleError)((0, utils_2.kindToTypeString)(parentDefinitionData.kind), parentTypeName));
|
|
1407
698
|
}
|
|
1408
699
|
}
|
|
1409
700
|
break;
|
|
1410
701
|
case graphql_1.Kind.SCALAR_TYPE_DEFINITION:
|
|
1411
702
|
if (!constants_1.BASE_SCALARS.has(parentTypeName)) {
|
|
1412
|
-
definitions.push((0,
|
|
703
|
+
definitions.push((0, utils_4.getNodeWithPersistedDirectivesByData)(parentDefinitionData, this.persistedDirectiveDefinitionByDirectiveName, this.errors));
|
|
1413
704
|
}
|
|
1414
705
|
break;
|
|
1415
706
|
case graphql_1.Kind.UNION_TYPE_DEFINITION:
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
types.push((0, utils_1.stringToNamedTypeNode)(memberName));
|
|
1419
|
-
}
|
|
1420
|
-
parentContainer.node.types = types;
|
|
1421
|
-
definitions.push((0, utils_1.pushPersistedDirectivesAndGetNode)(parentContainer));
|
|
707
|
+
parentDefinitionData.node.types = (0, utils_2.mapToArrayOfValues)(parentDefinitionData.memberByMemberTypeName);
|
|
708
|
+
definitions.push((0, utils_4.getNodeWithPersistedDirectivesByData)(parentDefinitionData, this.persistedDirectiveDefinitionByDirectiveName, this.errors));
|
|
1422
709
|
break;
|
|
1423
710
|
}
|
|
1424
711
|
}
|
|
1425
|
-
for (const
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
const
|
|
1430
|
-
|
|
712
|
+
// for (const [parentTypeName, parentContainer] of this.parents) {
|
|
713
|
+
// switch (parentContainer.kind) {
|
|
714
|
+
// case Kind.ENUM_TYPE_DEFINITION:
|
|
715
|
+
// const values: MutableEnumValueDefinitionNode[] = [];
|
|
716
|
+
// const mergeMethod = this.getEnumMergeMethod(parentTypeName);
|
|
717
|
+
// for (const enumValueContainer of parentContainer.values.values()) {
|
|
718
|
+
// pushPersistedDirectivesAndGetNode(enumValueContainer);
|
|
719
|
+
// switch (mergeMethod) {
|
|
720
|
+
// case MergeMethod.CONSISTENT:
|
|
721
|
+
// if (enumValueContainer.appearances < parentContainer.appearances) {
|
|
722
|
+
// this.errors.push(incompatibleSharedEnumError(parentTypeName));
|
|
723
|
+
// }
|
|
724
|
+
// values.push(enumValueContainer.node);
|
|
725
|
+
// break;
|
|
726
|
+
// case MergeMethod.INTERSECTION:
|
|
727
|
+
// if (enumValueContainer.appearances === parentContainer.appearances) {
|
|
728
|
+
// values.push(enumValueContainer.node);
|
|
729
|
+
// }
|
|
730
|
+
// break;
|
|
731
|
+
// default:
|
|
732
|
+
// values.push(enumValueContainer.node);
|
|
733
|
+
// break;
|
|
734
|
+
// }
|
|
735
|
+
// }
|
|
736
|
+
// parentContainer.node.values = values;
|
|
737
|
+
// definitions.push(pushPersistedDirectivesAndGetNode(parentContainer));
|
|
738
|
+
// break;
|
|
739
|
+
// case Kind.INPUT_OBJECT_TYPE_DEFINITION:
|
|
740
|
+
// const inputValues: InputValueDefinitionNode[] = [];
|
|
741
|
+
// for (const inputValueContainer of parentContainer.fields.values()) {
|
|
742
|
+
// pushPersistedDirectivesAndGetNode(inputValueContainer);
|
|
743
|
+
// if (parentContainer.appearances === inputValueContainer.appearances) {
|
|
744
|
+
// inputValues.push(inputValueContainer.node);
|
|
745
|
+
// } else if (isTypeRequired(inputValueContainer.node.type)) {
|
|
746
|
+
// this.errors.push(federationRequiredInputFieldError(parentTypeName, inputValueContainer.node.name.value));
|
|
747
|
+
// break;
|
|
748
|
+
// }
|
|
749
|
+
// }
|
|
750
|
+
// parentContainer.node.fields = inputValues;
|
|
751
|
+
// definitions.push(pushPersistedDirectivesAndGetNode(parentContainer));
|
|
752
|
+
// break;
|
|
753
|
+
// case Kind.INTERFACE_TYPE_DEFINITION:
|
|
754
|
+
// const interfaceFields: FieldDefinitionNode[] = [];
|
|
755
|
+
// for (const fieldContainer of parentContainer.fields.values()) {
|
|
756
|
+
// if (isFieldInaccessible(fieldContainer)) {
|
|
757
|
+
// continue;
|
|
758
|
+
// }
|
|
759
|
+
// interfaceFields.push(this.getMergedFieldDefinitionNode(fieldContainer, parentTypeName));
|
|
760
|
+
// }
|
|
761
|
+
// parentContainer.node.fields = interfaceFields;
|
|
762
|
+
// pushPersistedDirectivesAndGetNode(parentContainer);
|
|
763
|
+
// // Interface implementations can only be evaluated after they've been fully merged
|
|
764
|
+
// if (parentContainer.interfaces.size > 0) {
|
|
765
|
+
// definitionsWithInterfaces.push(parentContainer);
|
|
766
|
+
// } else {
|
|
767
|
+
// definitions.push(parentContainer.node);
|
|
768
|
+
// }
|
|
769
|
+
// if (interfaceFields.length < 1) {
|
|
770
|
+
// this.errors.push(allFieldDefinitionsAreInaccessibleError('interface', parentTypeName));
|
|
771
|
+
// }
|
|
772
|
+
// break;
|
|
773
|
+
// case Kind.OBJECT_TYPE_DEFINITION:
|
|
774
|
+
// const fields: FieldDefinitionNode[] = [];
|
|
775
|
+
// for (const fieldContainer of parentContainer.fields.values()) {
|
|
776
|
+
// if (isFieldInaccessible(fieldContainer)) {
|
|
777
|
+
// continue;
|
|
778
|
+
// }
|
|
779
|
+
// fields.push(this.getMergedFieldDefinitionNode(fieldContainer, parentTypeName));
|
|
780
|
+
// }
|
|
781
|
+
// parentContainer.node.fields = fields;
|
|
782
|
+
// pushPersistedDirectivesAndGetNode(parentContainer);
|
|
783
|
+
// // Interface implementations can only be evaluated after they've been fully merged
|
|
784
|
+
// if (parentContainer.interfaces.size > 0) {
|
|
785
|
+
// definitionsWithInterfaces.push(parentContainer);
|
|
786
|
+
// }
|
|
787
|
+
// } else {
|
|
788
|
+
// definitions.push(parentContainer.node);
|
|
789
|
+
// }
|
|
790
|
+
// if (fields.length < 1) {
|
|
791
|
+
// if (isNodeQuery(parentTypeName)) {
|
|
792
|
+
// this.errors.push(noQueryRootTypeError);
|
|
793
|
+
// } else {
|
|
794
|
+
// this.errors.push(allFieldDefinitionsAreInaccessibleError('object', parentTypeName));
|
|
795
|
+
// }
|
|
796
|
+
// }
|
|
797
|
+
// break;
|
|
798
|
+
// case Kind.SCALAR_TYPE_DEFINITION:
|
|
799
|
+
// if (!BASE_SCALARS.has(parentTypeName)) {
|
|
800
|
+
// definitions.push(pushPersistedDirectivesAndGetNode(parentContainer));
|
|
801
|
+
// }
|
|
802
|
+
// break;
|
|
803
|
+
// case Kind.UNION_TYPE_DEFINITION:
|
|
804
|
+
// const types: NamedTypeNode[] = [];
|
|
805
|
+
// for (const memberName of parentContainer.members) {
|
|
806
|
+
// types.push(stringToNamedTypeNode(memberName));
|
|
807
|
+
// }
|
|
808
|
+
// parentContainer.node.types = types;
|
|
809
|
+
// definitions.push(pushPersistedDirectivesAndGetNode(parentContainer));
|
|
810
|
+
// break;
|
|
811
|
+
// }
|
|
812
|
+
// }
|
|
813
|
+
for (const data of definitionsWithInterfaces) {
|
|
814
|
+
data.node.interfaces = this.getValidImplementedInterfaces(data);
|
|
815
|
+
definitions.push((0, utils_4.getNodeWithPersistedDirectivesByData)(data, this.persistedDirectiveDefinitionByDirectiveName, this.errors));
|
|
816
|
+
}
|
|
817
|
+
const query = this.parentDefinitionDataByTypeName.get(string_constants_1.QUERY);
|
|
818
|
+
if (!query || query.kind !== graphql_1.Kind.OBJECT_TYPE_DEFINITION || query.fieldDataByFieldName.size < 1) {
|
|
1431
819
|
this.errors.push(errors_1.noQueryRootTypeError);
|
|
1432
820
|
}
|
|
1433
821
|
// return any composition errors before checking whether all fields are resolvable
|
|
1434
822
|
if (this.errors.length > 0) {
|
|
1435
823
|
return { errors: this.errors };
|
|
1436
824
|
}
|
|
825
|
+
// TODO add back resolvability check
|
|
1437
826
|
for (const rootTypeName of string_constants_1.ROOT_TYPES) {
|
|
1438
|
-
const
|
|
1439
|
-
if (!
|
|
827
|
+
const rootTypeData = this.parentDefinitionDataByTypeName.get(rootTypeName);
|
|
828
|
+
if (!rootTypeData || rootTypeData.kind !== graphql_1.Kind.OBJECT_TYPE_DEFINITION) {
|
|
1440
829
|
continue;
|
|
1441
830
|
}
|
|
1442
831
|
// After evaluating all of a root type's fields, break and return if there are errors
|
|
@@ -1445,41 +834,41 @@ class FederationFactory {
|
|
|
1445
834
|
}
|
|
1446
835
|
// If a root type field returns a Scalar or Enum, track it so that it is not evaluated it again
|
|
1447
836
|
const evaluatedRootScalarsAndEnums = new Set(constants_1.BASE_SCALARS);
|
|
1448
|
-
for (const [rootTypeFieldName,
|
|
1449
|
-
const
|
|
1450
|
-
if (evaluatedRootScalarsAndEnums.has(
|
|
837
|
+
for (const [rootTypeFieldName, fieldData] of rootTypeData.fieldDataByFieldName) {
|
|
838
|
+
const namedRootFieldTypeName = fieldData.namedTypeName;
|
|
839
|
+
if (evaluatedRootScalarsAndEnums.has(namedRootFieldTypeName)) {
|
|
1451
840
|
continue;
|
|
1452
841
|
}
|
|
1453
|
-
if (!this.shouldEvaluateObjectLike(
|
|
842
|
+
if (!this.shouldEvaluateObjectLike(fieldData.subgraphNames, namedRootFieldTypeName)) {
|
|
1454
843
|
continue;
|
|
1455
844
|
}
|
|
1456
|
-
const
|
|
845
|
+
const namedTypeData = (0, utils_2.getOrThrowError)(this.parentDefinitionDataByTypeName, namedRootFieldTypeName, 'parentDefinitionDataByTypeName');
|
|
1457
846
|
const fieldPath = `${rootTypeName}.${rootTypeFieldName}`;
|
|
1458
847
|
const rootTypeFieldData = {
|
|
1459
848
|
fieldName: rootTypeFieldName,
|
|
1460
|
-
fieldTypeNodeString: (0, merge_1.printTypeNode)(
|
|
849
|
+
fieldTypeNodeString: (0, merge_1.printTypeNode)(fieldData.node.type),
|
|
1461
850
|
path: fieldPath,
|
|
1462
851
|
typeName: rootTypeName,
|
|
1463
|
-
subgraphs:
|
|
852
|
+
subgraphs: fieldData.subgraphNames,
|
|
1464
853
|
};
|
|
1465
|
-
switch (
|
|
854
|
+
switch (namedTypeData.kind) {
|
|
1466
855
|
case graphql_1.Kind.ENUM_TYPE_DEFINITION:
|
|
1467
856
|
// intentional fallthrough
|
|
1468
857
|
case graphql_1.Kind.SCALAR_TYPE_DEFINITION:
|
|
1469
858
|
// Root type fields whose response type is an Enums and Scalars will always be resolvable
|
|
1470
859
|
// Consequently, subsequent checks can be skipped
|
|
1471
|
-
evaluatedRootScalarsAndEnums.add(
|
|
860
|
+
evaluatedRootScalarsAndEnums.add(namedRootFieldTypeName);
|
|
1472
861
|
continue;
|
|
1473
862
|
case graphql_1.Kind.OBJECT_TYPE_DEFINITION:
|
|
1474
|
-
this.evaluateResolvabilityOfObject(
|
|
863
|
+
this.evaluateResolvabilityOfObject(namedTypeData, rootTypeFieldData, fieldPath, new Set(), this.entityContainersByTypeName.has(namedRootFieldTypeName) ? [namedRootFieldTypeName] : []);
|
|
1475
864
|
continue;
|
|
1476
865
|
case graphql_1.Kind.INTERFACE_TYPE_DEFINITION:
|
|
1477
866
|
// intentional fallthrough
|
|
1478
867
|
case graphql_1.Kind.UNION_TYPE_DEFINITION:
|
|
1479
|
-
this.evaluateResolvabilityOfAbstractType(
|
|
868
|
+
this.evaluateResolvabilityOfAbstractType(namedRootFieldTypeName, namedTypeData.kind, rootTypeFieldData, fieldPath, new Set(), this.entityContainersByTypeName.has(namedRootFieldTypeName) ? [namedRootFieldTypeName] : []);
|
|
1480
869
|
continue;
|
|
1481
870
|
default:
|
|
1482
|
-
this.errors.push((0, errors_1.unexpectedObjectResponseType)(fieldPath, (0,
|
|
871
|
+
this.errors.push((0, errors_1.unexpectedObjectResponseType)(fieldPath, (0, utils_2.kindToTypeString)(namedTypeData.kind)));
|
|
1483
872
|
}
|
|
1484
873
|
}
|
|
1485
874
|
}
|
|
@@ -1494,12 +883,12 @@ class FederationFactory {
|
|
|
1494
883
|
const subgraphConfigBySubgraphName = new Map();
|
|
1495
884
|
for (const subgraph of this.internalSubgraphBySubgraphName.values()) {
|
|
1496
885
|
subgraphConfigBySubgraphName.set(subgraph.name, {
|
|
1497
|
-
configurationDataMap: subgraph.
|
|
886
|
+
configurationDataMap: subgraph.configurationDataByParentTypeName,
|
|
1498
887
|
schema: subgraph.schema,
|
|
1499
888
|
});
|
|
1500
889
|
}
|
|
1501
890
|
for (const authorizationData of this.authorizationDataByParentTypeName.values()) {
|
|
1502
|
-
(0,
|
|
891
|
+
(0, utils_2.upsertAuthorizationConfiguration)(this.fieldConfigurationByFieldPath, authorizationData);
|
|
1503
892
|
}
|
|
1504
893
|
return {
|
|
1505
894
|
federationResult: {
|
|
@@ -1517,7 +906,7 @@ function federateSubgraphs(subgraphs) {
|
|
|
1517
906
|
if (subgraphs.length < 1) {
|
|
1518
907
|
return { errors: [errors_1.minimumSubgraphRequirementError] };
|
|
1519
908
|
}
|
|
1520
|
-
const { authorizationDataByParentTypeName, entityContainerByTypeName, errors, internalSubgraphBySubgraphName, warnings, } = (0, normalization_factory_1.batchNormalize)(subgraphs);
|
|
909
|
+
const { authorizationDataByParentTypeName, concreteTypeNamesByAbstractTypeName, entityContainerByTypeName, errors, graph, internalSubgraphBySubgraphName, warnings, } = (0, normalization_factory_1.batchNormalize)(subgraphs);
|
|
1521
910
|
if (errors) {
|
|
1522
911
|
return { errors };
|
|
1523
912
|
}
|
|
@@ -1528,7 +917,7 @@ function federateSubgraphs(subgraphs) {
|
|
|
1528
917
|
for (const [typeName, entityInterfaceData] of internalSubgraph.entityInterfaces) {
|
|
1529
918
|
// Always add each entity interface to the invalid entity interfaces map
|
|
1530
919
|
// If not, earlier checks would not account for implementations not yet seen
|
|
1531
|
-
const invalidEntityInterfaces = (0,
|
|
920
|
+
const invalidEntityInterfaces = (0, utils_2.getValueOrDefault)(invalidEntityInterfacesByTypeName, typeName, () => []);
|
|
1532
921
|
invalidEntityInterfaces.push({
|
|
1533
922
|
subgraphName,
|
|
1534
923
|
concreteTypeNames: entityInterfaceData.concreteTypeNames || new Set(),
|
|
@@ -1536,10 +925,10 @@ function federateSubgraphs(subgraphs) {
|
|
|
1536
925
|
const existingData = entityInterfaceFederationDataByTypeName.get(typeName);
|
|
1537
926
|
if (!existingData) {
|
|
1538
927
|
validEntityInterfaceTypeNames.add(typeName);
|
|
1539
|
-
entityInterfaceFederationDataByTypeName.set(typeName, (0,
|
|
928
|
+
entityInterfaceFederationDataByTypeName.set(typeName, (0, utils_2.newEntityInterfaceFederationData)(entityInterfaceData, subgraphName));
|
|
1540
929
|
continue;
|
|
1541
930
|
}
|
|
1542
|
-
const areAnyImplementationsUndefined = (0,
|
|
931
|
+
const areAnyImplementationsUndefined = (0, utils_2.upsertEntityInterfaceFederationData)(existingData, entityInterfaceData, subgraphName);
|
|
1543
932
|
if (areAnyImplementationsUndefined) {
|
|
1544
933
|
validEntityInterfaceTypeNames.delete(typeName);
|
|
1545
934
|
}
|
|
@@ -1556,7 +945,7 @@ function federateSubgraphs(subgraphs) {
|
|
|
1556
945
|
],
|
|
1557
946
|
};
|
|
1558
947
|
}
|
|
1559
|
-
return new FederationFactory(authorizationDataByParentTypeName, entityContainerByTypeName, entityInterfaceFederationDataByTypeName, internalSubgraphBySubgraphName, warnings).federate();
|
|
948
|
+
return new FederationFactory(authorizationDataByParentTypeName, concreteTypeNamesByAbstractTypeName, entityContainerByTypeName, entityInterfaceFederationDataByTypeName, graph, internalSubgraphBySubgraphName, warnings).federate();
|
|
1560
949
|
}
|
|
1561
950
|
exports.federateSubgraphs = federateSubgraphs;
|
|
1562
951
|
//# sourceMappingURL=federation-factory.js.map
|