@wundergraph/composition 0.27.1 → 0.28.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 +0 -2
- package/dist/ast/utils.js +0 -34
- package/dist/ast/utils.js.map +1 -1
- package/dist/errors/errors.d.ts +3 -0
- package/dist/errors/errors.js +13 -0
- package/dist/errors/errors.js.map +1 -1
- package/dist/federation/federation-factory.d.ts +9 -12
- package/dist/federation/federation-factory.js +134 -347
- package/dist/federation/federation-factory.js.map +1 -1
- package/dist/federation/utils.d.ts +27 -6
- package/dist/federation/utils.js +123 -0
- package/dist/federation/utils.js.map +1 -1
- package/dist/federation/walkers.d.ts +1 -1
- package/dist/federation/walkers.js +7 -28
- package/dist/federation/walkers.js.map +1 -1
- package/dist/index.d.ts +3 -0
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/dist/normalization/normalization-factory.d.ts +12 -10
- package/dist/normalization/normalization-factory.js +52 -29
- package/dist/normalization/normalization-factory.js.map +1 -1
- package/dist/normalization/utils.d.ts +1 -1
- package/dist/normalization/utils.js +54 -25
- package/dist/normalization/utils.js.map +1 -1
- package/dist/normalization/walkers.js +78 -73
- package/dist/normalization/walkers.js.map +1 -1
- package/dist/resolvability-graph/graph-nodes.d.ts +48 -0
- package/dist/resolvability-graph/graph-nodes.js +104 -0
- package/dist/resolvability-graph/graph-nodes.js.map +1 -0
- package/dist/resolvability-graph/graph.d.ts +33 -0
- package/dist/resolvability-graph/graph.js +406 -0
- package/dist/resolvability-graph/graph.js.map +1 -0
- package/dist/resolvability-graph/utils.d.ts +65 -0
- package/dist/resolvability-graph/utils.js +143 -0
- package/dist/resolvability-graph/utils.js.map +1 -0
- package/dist/schema-building/utils.js +1 -1
- package/dist/schema-building/utils.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/utils/string-constants.d.ts +5 -2
- package/dist/utils/string-constants.js +6 -4
- package/dist/utils/string-constants.js.map +1 -1
- package/dist/utils/utils.d.ts +16 -2
- package/dist/utils/utils.js +35 -33
- package/dist/utils/utils.js.map +1 -1
- package/package.json +3 -5
|
@@ -28,12 +28,11 @@ class FederationFactory {
|
|
|
28
28
|
entityDataByTypeName;
|
|
29
29
|
entityInterfaceFederationDataByTypeName;
|
|
30
30
|
errors = [];
|
|
31
|
-
evaluatedObjectLikesBySubgraph = new Map();
|
|
32
31
|
fieldConfigurationByFieldPath = new Map();
|
|
33
|
-
graph;
|
|
34
32
|
graphEdges = new Set();
|
|
35
33
|
graphPaths = new Map();
|
|
36
34
|
inaccessiblePaths = new Set();
|
|
35
|
+
internalGraph;
|
|
37
36
|
internalSubgraphBySubgraphName;
|
|
38
37
|
invalidOrScopesHostPaths = new Set();
|
|
39
38
|
isVersionTwo = false;
|
|
@@ -63,8 +62,8 @@ class FederationFactory {
|
|
|
63
62
|
this.concreteTypeNamesByAbstractTypeName = options.concreteTypeNamesByAbstractTypeName;
|
|
64
63
|
this.entityDataByTypeName = options.entityDataByTypeName;
|
|
65
64
|
this.entityInterfaceFederationDataByTypeName = options.entityInterfaceFederationDataByTypeName;
|
|
66
|
-
this.graph = options.graph;
|
|
67
65
|
this.internalSubgraphBySubgraphName = options.internalSubgraphBySubgraphName;
|
|
66
|
+
this.internalGraph = options.internalGraph;
|
|
68
67
|
this.warnings = options.warnings || [];
|
|
69
68
|
}
|
|
70
69
|
getValidImplementedInterfaces(data) {
|
|
@@ -163,295 +162,85 @@ class FederationFactory {
|
|
|
163
162
|
}
|
|
164
163
|
return interfaces;
|
|
165
164
|
}
|
|
166
|
-
|
|
167
|
-
if (!
|
|
168
|
-
return false;
|
|
169
|
-
}
|
|
170
|
-
for (const entityAncestorName of entityAncestors) {
|
|
171
|
-
const path = `${entityAncestorName}.${parentTypeName}`;
|
|
172
|
-
if (entityAncestorName !== parentTypeName && this.graphPaths.get(path)) {
|
|
173
|
-
return true;
|
|
174
|
-
}
|
|
175
|
-
if (entityAncestorName === parentTypeName) {
|
|
176
|
-
const hasOverlap = (0, utils_3.doSetsIntersect)(fieldSubgraphs, (0, utils_3.getOrThrowError)(this.entityDataByTypeName, entityAncestorName, string_constants_1.ENTITIES).subgraphNames);
|
|
177
|
-
this.graphPaths.set(path, hasOverlap);
|
|
178
|
-
return hasOverlap;
|
|
179
|
-
}
|
|
180
|
-
if ((0, utils_3.hasSimplePath)(this.graph, entityAncestorName, parentTypeName)) {
|
|
181
|
-
this.graphPaths.set(path, true);
|
|
182
|
-
return true;
|
|
183
|
-
}
|
|
184
|
-
this.graphPaths.set(path, false);
|
|
185
|
-
}
|
|
186
|
-
return false;
|
|
187
|
-
}
|
|
188
|
-
shouldEvaluateObjectLike(rootTypeFieldSubgraphs, parentTypeName) {
|
|
189
|
-
for (const subgraph of rootTypeFieldSubgraphs) {
|
|
190
|
-
const evaluatedObjectLikes = this.evaluatedObjectLikesBySubgraph.get(subgraph);
|
|
191
|
-
if (evaluatedObjectLikes && evaluatedObjectLikes.has(parentTypeName)) {
|
|
192
|
-
continue;
|
|
193
|
-
}
|
|
194
|
-
return true;
|
|
195
|
-
}
|
|
196
|
-
return false;
|
|
197
|
-
}
|
|
198
|
-
updateEvaluatedSubgraphOccurrences(rootTypeFieldSubgraphs, objectSubgraphs, entityAncestors, parentTypeName) {
|
|
199
|
-
const mutualSubgraphs = (0, utils_3.getAllMutualEntries)(rootTypeFieldSubgraphs, objectSubgraphs);
|
|
200
|
-
if (mutualSubgraphs.size > 0) {
|
|
201
|
-
for (const mutualSubgraph of mutualSubgraphs) {
|
|
202
|
-
const evaluatedObjects = this.evaluatedObjectLikesBySubgraph.get(mutualSubgraph);
|
|
203
|
-
if (evaluatedObjects) {
|
|
204
|
-
evaluatedObjects.add(parentTypeName);
|
|
205
|
-
}
|
|
206
|
-
else {
|
|
207
|
-
this.evaluatedObjectLikesBySubgraph.set(mutualSubgraph, new Set([parentTypeName]));
|
|
208
|
-
}
|
|
209
|
-
}
|
|
210
|
-
}
|
|
211
|
-
for (const entityAncestorTypeName of entityAncestors) {
|
|
212
|
-
const entityObjectData = (0, utils_3.getOrThrowError)(this.parentDefinitionDataByTypeName, entityAncestorTypeName, 'parentDefinitionDataByTypeName');
|
|
213
|
-
const mutualEntityAncestorRootTypeFieldSubgraphs = (0, utils_3.getAllMutualEntries)(rootTypeFieldSubgraphs, entityObjectData.subgraphNames);
|
|
214
|
-
const mutualEntityAncestorSubgraphsNames = (0, utils_3.getAllMutualEntries)(mutualEntityAncestorRootTypeFieldSubgraphs, objectSubgraphs);
|
|
215
|
-
for (const mutualSubgraphName of mutualEntityAncestorSubgraphsNames) {
|
|
216
|
-
const objects = this.evaluatedObjectLikesBySubgraph.get(mutualSubgraphName);
|
|
217
|
-
if (objects) {
|
|
218
|
-
objects.add(parentTypeName);
|
|
219
|
-
}
|
|
220
|
-
else {
|
|
221
|
-
this.evaluatedObjectLikesBySubgraph.set(mutualSubgraphName, new Set([parentTypeName]));
|
|
222
|
-
}
|
|
223
|
-
}
|
|
224
|
-
}
|
|
225
|
-
}
|
|
226
|
-
evaluateResolvabilityOfObject(objectData, rootTypeFieldData, currentFieldPath, evaluatedObjectLikes, entityAncestors, isParentAbstract = false) {
|
|
227
|
-
const parentTypeName = objectData.name;
|
|
228
|
-
if (evaluatedObjectLikes.has(parentTypeName)) {
|
|
165
|
+
addValidPrimaryKeyTargetsToEntityData(entityData) {
|
|
166
|
+
if (!entityData) {
|
|
229
167
|
return;
|
|
230
168
|
}
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
169
|
+
const internalSubgraph = (0, utils_3.getOrThrowError)(this.internalSubgraphBySubgraphName, this.currentSubgraphName, 'internalSubgraphBySubgraphName');
|
|
170
|
+
const parentDefinitionDataByTypeName = internalSubgraph.parentDefinitionDataByTypeName;
|
|
171
|
+
const parentExtensionDataByTypeName = internalSubgraph.parentExtensionDataByTypeName;
|
|
172
|
+
const objectData = parentDefinitionDataByTypeName.get(entityData.typeName) || parentExtensionDataByTypeName.get(entityData.typeName);
|
|
173
|
+
if (!objectData ||
|
|
174
|
+
(objectData.kind !== graphql_1.Kind.OBJECT_TYPE_DEFINITION && objectData.kind !== graphql_1.Kind.OBJECT_TYPE_EXTENSION)) {
|
|
175
|
+
throw (0, errors_1.incompatibleParentKindFatalError)(entityData.typeName, graphql_1.Kind.OBJECT_TYPE_DEFINITION, objectData?.kind || graphql_1.Kind.NULL);
|
|
234
176
|
}
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
177
|
+
const configurationData = (0, utils_3.getOrThrowError)(internalSubgraph.configurationDataByParentTypeName, entityData.typeName, 'internalSubgraph.configurationDataByParentTypeName');
|
|
178
|
+
const implicitKeys = [];
|
|
179
|
+
const graphNode = this.internalGraph.nodeByNodeName.get(`${this.currentSubgraphName}.${entityData.typeName}`);
|
|
180
|
+
// Any errors in the field sets would be caught when evaluating the explicit entities, so they are ignored here
|
|
181
|
+
(0, utils_2.validateImplicitFieldSets)({
|
|
182
|
+
configurationData,
|
|
183
|
+
fieldSets: entityData.keyFieldSets,
|
|
184
|
+
implicitKeys,
|
|
185
|
+
objectData,
|
|
186
|
+
parentDefinitionDataByTypeName,
|
|
187
|
+
parentExtensionDataByTypeName,
|
|
188
|
+
graphNode,
|
|
189
|
+
});
|
|
190
|
+
for (const [typeName, entityInterfaceFederationData] of this.entityInterfaceFederationDataByTypeName) {
|
|
191
|
+
if (!entityInterfaceFederationData.concreteTypeNames?.has(entityData.typeName)) {
|
|
249
192
|
continue;
|
|
250
193
|
}
|
|
251
|
-
this.
|
|
252
|
-
|
|
253
|
-
const isFieldResolvable = (0, utils_3.doSetsIntersect)(rootTypeFieldData.subgraphs, fieldData.subgraphNames) ||
|
|
254
|
-
this.isFieldResolvableByEntityAncestor(entityAncestors, fieldData.subgraphNames, parentTypeName);
|
|
255
|
-
const newCurrentFieldPath = currentFieldPath + (isParentAbstract ? ' ' : '.') + fieldName;
|
|
256
|
-
const entity = this.entityDataByTypeName.get(namedFieldTypeName);
|
|
257
|
-
if (isFieldResolvable) {
|
|
258
|
-
// The base scalars are not in this.parentMap
|
|
259
|
-
if (constants_1.BASE_SCALARS.has(namedFieldTypeName)) {
|
|
260
|
-
continue;
|
|
261
|
-
}
|
|
262
|
-
const namedTypeData = (0, utils_3.getOrThrowError)(this.parentDefinitionDataByTypeName, namedFieldTypeName, string_constants_1.PARENT_DEFINITION_DATA);
|
|
263
|
-
switch (namedTypeData.kind) {
|
|
264
|
-
case graphql_1.Kind.ENUM_TYPE_DEFINITION:
|
|
265
|
-
// intentional fallthrough
|
|
266
|
-
case graphql_1.Kind.SCALAR_TYPE_DEFINITION:
|
|
267
|
-
continue;
|
|
268
|
-
case graphql_1.Kind.OBJECT_TYPE_DEFINITION:
|
|
269
|
-
this.evaluateResolvabilityOfObject(namedTypeData, rootTypeFieldData, newCurrentFieldPath, evaluatedObjectLikes, entity ? [...entityAncestors, namedFieldTypeName] : [...entityAncestors]);
|
|
270
|
-
continue;
|
|
271
|
-
case graphql_1.Kind.INTERFACE_TYPE_DEFINITION:
|
|
272
|
-
// intentional fallthrough
|
|
273
|
-
case graphql_1.Kind.UNION_TYPE_DEFINITION:
|
|
274
|
-
this.evaluateResolvabilityOfAbstractType(namedFieldTypeName, namedTypeData.kind, rootTypeFieldData, newCurrentFieldPath, evaluatedObjectLikes, entity ? [...entityAncestors, namedFieldTypeName] : [...entityAncestors]);
|
|
275
|
-
continue;
|
|
276
|
-
default:
|
|
277
|
-
this.errors.push((0, errors_1.unexpectedObjectResponseType)(newCurrentFieldPath, (0, utils_3.kindToTypeString)(namedTypeData.kind)));
|
|
278
|
-
continue;
|
|
279
|
-
}
|
|
280
|
-
}
|
|
281
|
-
if (constants_1.BASE_SCALARS.has(namedFieldTypeName)) {
|
|
282
|
-
this.errors.push((0, errors_1.unresolvableFieldError)(rootTypeFieldData, fieldName, [...fieldData.subgraphNames], newCurrentFieldPath, parentTypeName));
|
|
194
|
+
const interfaceObjectEntityData = this.entityDataByTypeName.get(typeName);
|
|
195
|
+
if (!interfaceObjectEntityData) {
|
|
283
196
|
continue;
|
|
284
197
|
}
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
case graphql_1.Kind.UNION_TYPE_DEFINITION:
|
|
295
|
-
// intentional fallthrough
|
|
296
|
-
case graphql_1.Kind.OBJECT_TYPE_DEFINITION:
|
|
297
|
-
this.errors.push((0, errors_1.unresolvableFieldError)(rootTypeFieldData, fieldName, [...fieldData.subgraphNames], newCurrentFieldPath + string_constants_1.SELECTION_REPRESENTATION, parentTypeName));
|
|
298
|
-
continue;
|
|
299
|
-
default:
|
|
300
|
-
this.errors.push((0, errors_1.unexpectedObjectResponseType)(newCurrentFieldPath, (0, utils_3.kindToTypeString)(namedTypeData.kind)));
|
|
301
|
-
}
|
|
198
|
+
(0, utils_2.validateImplicitFieldSets)({
|
|
199
|
+
configurationData,
|
|
200
|
+
fieldSets: interfaceObjectEntityData.keyFieldSets,
|
|
201
|
+
implicitKeys,
|
|
202
|
+
objectData,
|
|
203
|
+
parentDefinitionDataByTypeName,
|
|
204
|
+
parentExtensionDataByTypeName,
|
|
205
|
+
graphNode,
|
|
206
|
+
});
|
|
302
207
|
}
|
|
303
|
-
|
|
304
|
-
evaluateResolvabilityOfAbstractType(abstractTypeName, abstractKind, rootTypeFieldData, currentFieldPath, evaluatedObjectLikes, entityAncestors) {
|
|
305
|
-
if (evaluatedObjectLikes.has(abstractTypeName)) {
|
|
208
|
+
if (implicitKeys.length < 1) {
|
|
306
209
|
return;
|
|
307
210
|
}
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
(0, errors_1.noConcreteTypesForAbstractTypeError)((0, utils_3.kindToTypeString)(abstractKind), abstractTypeName);
|
|
211
|
+
if (!configurationData.keys || configurationData.keys.length < 1) {
|
|
212
|
+
configurationData.isRootNode = true;
|
|
213
|
+
configurationData.keys = implicitKeys;
|
|
312
214
|
return;
|
|
313
215
|
}
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
}
|
|
318
|
-
const concreteTypeData = (0, utils_3.getOrThrowError)(this.parentDefinitionDataByTypeName, concreteTypeName, 'parentDefinitionDataByTypeName');
|
|
319
|
-
if (concreteTypeData.kind !== graphql_1.Kind.OBJECT_TYPE_DEFINITION) {
|
|
320
|
-
throw (0, errors_1.unexpectedParentKindErrorMessage)(concreteTypeName, 'Object', (0, utils_3.kindToTypeString)(concreteTypeData.kind));
|
|
321
|
-
}
|
|
322
|
-
// If the concrete type is unreachable through an inline fragment, it is not an error
|
|
323
|
-
if (!(0, utils_3.doSetsIntersect)(concreteTypeData.subgraphNames, rootTypeFieldData.subgraphs)) {
|
|
216
|
+
const existingKeys = new Set(configurationData.keys.map((key) => key.selectionSet));
|
|
217
|
+
for (const implicitKey of implicitKeys) {
|
|
218
|
+
if (existingKeys.has(implicitKey.selectionSet)) {
|
|
324
219
|
continue;
|
|
325
220
|
}
|
|
326
|
-
|
|
327
|
-
|
|
221
|
+
configurationData.keys.push(implicitKey);
|
|
222
|
+
existingKeys.add(implicitKey.selectionSet);
|
|
328
223
|
}
|
|
329
224
|
}
|
|
330
|
-
|
|
331
|
-
if (!entityData) {
|
|
332
|
-
return;
|
|
333
|
-
}
|
|
334
|
-
const internalSubgraph = (0, utils_3.getOrThrowError)(this.internalSubgraphBySubgraphName, this.currentSubgraphName, 'internalSubgraphBySubgraphName');
|
|
225
|
+
addValidPrimaryKeyTargetsFromInterfaceObject(internalSubgraph, interfaceObjectTypeName, entityData, graphNode) {
|
|
335
226
|
const parentDefinitionDataByTypeName = internalSubgraph.parentDefinitionDataByTypeName;
|
|
336
227
|
const parentExtensionDataByTypeName = internalSubgraph.parentExtensionDataByTypeName;
|
|
337
|
-
const
|
|
338
|
-
if (!
|
|
339
|
-
(
|
|
340
|
-
throw (0, errors_1.incompatibleParentKindFatalError)(entityData.typeName, graphql_1.Kind.OBJECT_TYPE_DEFINITION, objectData?.kind || graphql_1.Kind.NULL);
|
|
228
|
+
const interfaceObjectData = parentDefinitionDataByTypeName.get(interfaceObjectTypeName);
|
|
229
|
+
if (!interfaceObjectData || interfaceObjectData.kind !== graphql_1.Kind.INTERFACE_TYPE_DEFINITION) {
|
|
230
|
+
throw (0, errors_1.incompatibleParentKindFatalError)(interfaceObjectTypeName, graphql_1.Kind.INTERFACE_TYPE_DEFINITION, interfaceObjectData?.kind || graphql_1.Kind.NULL);
|
|
341
231
|
}
|
|
342
|
-
const configurationData = (0, utils_3.getOrThrowError)(internalSubgraph.configurationDataByParentTypeName, entityData.typeName, 'internalSubgraph.
|
|
343
|
-
const keyFieldNames = new Set();
|
|
232
|
+
const configurationData = (0, utils_3.getOrThrowError)(internalSubgraph.configurationDataByParentTypeName, entityData.typeName, 'internalSubgraph.configurationDataByParentTypeName');
|
|
344
233
|
const implicitKeys = [];
|
|
345
234
|
// Any errors in the field sets would be caught when evaluating the explicit entities, so they are ignored here
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
let currentDepth = -1;
|
|
356
|
-
let shouldDefineSelectionSet = true;
|
|
357
|
-
let shouldAddKeyFieldSet = true;
|
|
358
|
-
(0, graphql_1.visit)(documentNode, {
|
|
359
|
-
Argument: {
|
|
360
|
-
enter() {
|
|
361
|
-
// Fields that define arguments are never allowed in a key FieldSet
|
|
362
|
-
// However, at this stage, it actually means the argument is undefined on the field
|
|
363
|
-
shouldAddKeyFieldSet = false;
|
|
364
|
-
return graphql_1.BREAK;
|
|
365
|
-
},
|
|
366
|
-
},
|
|
367
|
-
Field: {
|
|
368
|
-
enter(node) {
|
|
369
|
-
const parentData = parentDatas[currentDepth];
|
|
370
|
-
// If an object-like was just visited, a selection set should have been entered
|
|
371
|
-
if (shouldDefineSelectionSet) {
|
|
372
|
-
shouldAddKeyFieldSet = false;
|
|
373
|
-
return graphql_1.BREAK;
|
|
374
|
-
}
|
|
375
|
-
const fieldName = node.name.value;
|
|
376
|
-
const fieldData = parentData.fieldDataByFieldName.get(fieldName);
|
|
377
|
-
// undefined if the field does not exist on the parent
|
|
378
|
-
if (!fieldData || fieldData.argumentDataByArgumentName.size || definedFields[currentDepth].has(fieldName)) {
|
|
379
|
-
shouldAddKeyFieldSet = false;
|
|
380
|
-
return graphql_1.BREAK;
|
|
381
|
-
}
|
|
382
|
-
definedFields[currentDepth].add(fieldName);
|
|
383
|
-
// Depth 0 is the original parent type
|
|
384
|
-
// If a field is external, but it's part of a key FieldSet, it will be included in the root configuration
|
|
385
|
-
if (currentDepth === 0) {
|
|
386
|
-
keyFieldNames.add(fieldName);
|
|
387
|
-
}
|
|
388
|
-
const namedTypeName = (0, ast_1.getTypeNodeNamedTypeName)(fieldData.node.type);
|
|
389
|
-
// The base scalars are not in the parents map
|
|
390
|
-
if (constants_1.BASE_SCALARS.has(namedTypeName)) {
|
|
391
|
-
return;
|
|
392
|
-
}
|
|
393
|
-
// The child could itself be a parent and could exist as an object extension
|
|
394
|
-
const fieldNamedTypeData = parentDefinitionDataByTypeName.get(namedTypeName) || parentExtensionDataByTypeName.get(namedTypeName);
|
|
395
|
-
if (!fieldNamedTypeData) {
|
|
396
|
-
shouldAddKeyFieldSet = false;
|
|
397
|
-
return graphql_1.BREAK;
|
|
398
|
-
}
|
|
399
|
-
if (fieldNamedTypeData.kind === graphql_1.Kind.OBJECT_TYPE_DEFINITION ||
|
|
400
|
-
fieldNamedTypeData.kind === graphql_1.Kind.OBJECT_TYPE_EXTENSION) {
|
|
401
|
-
shouldDefineSelectionSet = true;
|
|
402
|
-
parentDatas.push(fieldNamedTypeData);
|
|
403
|
-
return;
|
|
404
|
-
}
|
|
405
|
-
// interfaces and unions are invalid in a key directive
|
|
406
|
-
if ((0, utils_1.isKindAbstract)(fieldNamedTypeData.kind)) {
|
|
407
|
-
shouldAddKeyFieldSet = false;
|
|
408
|
-
return graphql_1.BREAK;
|
|
409
|
-
}
|
|
410
|
-
},
|
|
411
|
-
},
|
|
412
|
-
InlineFragment: {
|
|
413
|
-
enter() {
|
|
414
|
-
shouldAddKeyFieldSet = false;
|
|
415
|
-
return graphql_1.BREAK;
|
|
416
|
-
},
|
|
417
|
-
},
|
|
418
|
-
SelectionSet: {
|
|
419
|
-
enter() {
|
|
420
|
-
if (!shouldDefineSelectionSet) {
|
|
421
|
-
shouldAddKeyFieldSet = false;
|
|
422
|
-
return graphql_1.BREAK;
|
|
423
|
-
}
|
|
424
|
-
currentDepth += 1;
|
|
425
|
-
shouldDefineSelectionSet = false;
|
|
426
|
-
if (currentDepth < 0 || currentDepth >= parentDatas.length) {
|
|
427
|
-
shouldAddKeyFieldSet = false;
|
|
428
|
-
return graphql_1.BREAK;
|
|
429
|
-
}
|
|
430
|
-
definedFields.push(new Set());
|
|
431
|
-
},
|
|
432
|
-
leave() {
|
|
433
|
-
if (shouldDefineSelectionSet) {
|
|
434
|
-
shouldAddKeyFieldSet = false;
|
|
435
|
-
return graphql_1.BREAK;
|
|
436
|
-
}
|
|
437
|
-
// Empty selection sets would be a parse error, so it is unnecessary to handle them
|
|
438
|
-
currentDepth -= 1;
|
|
439
|
-
parentDatas.pop();
|
|
440
|
-
definedFields.pop();
|
|
441
|
-
},
|
|
442
|
-
},
|
|
443
|
-
});
|
|
444
|
-
if (!shouldAddKeyFieldSet) {
|
|
445
|
-
continue;
|
|
446
|
-
}
|
|
447
|
-
// Add any top-level fields that compose the key in case they are external
|
|
448
|
-
(0, utils_3.addIterableValuesToSet)(keyFieldNames, configurationData.fieldNames);
|
|
449
|
-
implicitKeys.push({
|
|
450
|
-
fieldName: '',
|
|
451
|
-
selectionSet: (0, utils_4.getNormalizedFieldSet)(documentNode),
|
|
452
|
-
disableEntityResolver: true,
|
|
453
|
-
});
|
|
454
|
-
}
|
|
235
|
+
(0, utils_2.validateImplicitFieldSets)({
|
|
236
|
+
configurationData,
|
|
237
|
+
fieldSets: entityData.keyFieldSets,
|
|
238
|
+
implicitKeys,
|
|
239
|
+
objectData: interfaceObjectData,
|
|
240
|
+
parentDefinitionDataByTypeName,
|
|
241
|
+
parentExtensionDataByTypeName,
|
|
242
|
+
graphNode,
|
|
243
|
+
});
|
|
455
244
|
if (implicitKeys.length < 1) {
|
|
456
245
|
return;
|
|
457
246
|
}
|
|
@@ -512,60 +301,6 @@ class FederationFactory {
|
|
|
512
301
|
}
|
|
513
302
|
}
|
|
514
303
|
}
|
|
515
|
-
evaluateRootNodeFieldsResolvability() {
|
|
516
|
-
for (const rootTypeName of string_constants_1.ROOT_TYPES) {
|
|
517
|
-
const rootTypeData = this.parentDefinitionDataByTypeName.get(rootTypeName);
|
|
518
|
-
if (!rootTypeData || rootTypeData.kind !== graphql_1.Kind.OBJECT_TYPE_DEFINITION) {
|
|
519
|
-
continue;
|
|
520
|
-
}
|
|
521
|
-
// After evaluating all of a root type's fields, break and return if there are errors
|
|
522
|
-
if (this.errors.length > 0) {
|
|
523
|
-
break;
|
|
524
|
-
}
|
|
525
|
-
// If a root type field returns a Scalar or Enum, track it so that it is not evaluated it again
|
|
526
|
-
const evaluatedRootScalarsAndEnums = new Set(constants_1.BASE_SCALARS);
|
|
527
|
-
for (const [rootTypeFieldName, fieldData] of rootTypeData.fieldDataByFieldName) {
|
|
528
|
-
const namedRootFieldTypeName = fieldData.namedTypeName;
|
|
529
|
-
if (evaluatedRootScalarsAndEnums.has(namedRootFieldTypeName)) {
|
|
530
|
-
continue;
|
|
531
|
-
}
|
|
532
|
-
if (!this.shouldEvaluateObjectLike(fieldData.subgraphNames, namedRootFieldTypeName)) {
|
|
533
|
-
continue;
|
|
534
|
-
}
|
|
535
|
-
const namedTypeData = (0, utils_3.getOrThrowError)(this.parentDefinitionDataByTypeName, namedRootFieldTypeName, 'parentDefinitionDataByTypeName');
|
|
536
|
-
const fieldPath = `${rootTypeName}.${rootTypeFieldName}`;
|
|
537
|
-
if (this.inaccessiblePaths.has(fieldPath)) {
|
|
538
|
-
continue;
|
|
539
|
-
}
|
|
540
|
-
const rootTypeFieldData = {
|
|
541
|
-
fieldName: rootTypeFieldName,
|
|
542
|
-
fieldTypeNodeString: (0, merge_1.printTypeNode)(fieldData.node.type),
|
|
543
|
-
path: fieldPath,
|
|
544
|
-
typeName: rootTypeName,
|
|
545
|
-
subgraphs: fieldData.subgraphNames,
|
|
546
|
-
};
|
|
547
|
-
switch (namedTypeData.kind) {
|
|
548
|
-
case graphql_1.Kind.ENUM_TYPE_DEFINITION:
|
|
549
|
-
// intentional fallthrough
|
|
550
|
-
case graphql_1.Kind.SCALAR_TYPE_DEFINITION:
|
|
551
|
-
// Root type fields whose response type is an Enums and Scalars will always be resolvable
|
|
552
|
-
// Consequently, subsequent checks can be skipped
|
|
553
|
-
evaluatedRootScalarsAndEnums.add(namedRootFieldTypeName);
|
|
554
|
-
continue;
|
|
555
|
-
case graphql_1.Kind.OBJECT_TYPE_DEFINITION:
|
|
556
|
-
this.evaluateResolvabilityOfObject(namedTypeData, rootTypeFieldData, fieldPath, new Set(), this.entityDataByTypeName.has(namedRootFieldTypeName) ? [namedRootFieldTypeName] : []);
|
|
557
|
-
continue;
|
|
558
|
-
case graphql_1.Kind.INTERFACE_TYPE_DEFINITION:
|
|
559
|
-
// intentional fallthrough
|
|
560
|
-
case graphql_1.Kind.UNION_TYPE_DEFINITION:
|
|
561
|
-
this.evaluateResolvabilityOfAbstractType(namedRootFieldTypeName, namedTypeData.kind, rootTypeFieldData, fieldPath, new Set(), this.entityDataByTypeName.has(namedRootFieldTypeName) ? [namedRootFieldTypeName] : []);
|
|
562
|
-
continue;
|
|
563
|
-
default:
|
|
564
|
-
this.errors.push((0, errors_1.unexpectedObjectResponseType)(fieldPath, (0, utils_3.kindToTypeString)(namedTypeData.kind)));
|
|
565
|
-
}
|
|
566
|
-
}
|
|
567
|
-
}
|
|
568
|
-
}
|
|
569
304
|
upsertEnumValueData(enumValueDataByValueName, incomingData, isParentInaccessible) {
|
|
570
305
|
const existingData = enumValueDataByValueName.get(incomingData.name);
|
|
571
306
|
const baseData = existingData || incomingData;
|
|
@@ -752,10 +487,10 @@ class FederationFactory {
|
|
|
752
487
|
if (isParentInaccessible) {
|
|
753
488
|
this.inaccessiblePaths.add(incomingData.name);
|
|
754
489
|
}
|
|
490
|
+
if (entityInterfaceData && entityInterfaceData.interfaceObjectSubgraphs.has(subgraphName)) {
|
|
491
|
+
incomingData.kind = graphql_1.Kind.INTERFACE_TYPE_DEFINITION;
|
|
492
|
+
}
|
|
755
493
|
if (!existingData) {
|
|
756
|
-
if (entityInterfaceData && entityInterfaceData.interfaceObjectSubgraphs.has(subgraphName)) {
|
|
757
|
-
incomingData.kind = graphql_1.Kind.INTERFACE_TYPE_DEFINITION;
|
|
758
|
-
}
|
|
759
494
|
incomingData.node = {
|
|
760
495
|
kind: incomingData.kind,
|
|
761
496
|
name: (0, utils_1.stringToNameNode)(incomingData.name),
|
|
@@ -1072,7 +807,7 @@ class FederationFactory {
|
|
|
1072
807
|
subgraphNumber += 1;
|
|
1073
808
|
this.currentSubgraphName = internalSubgraph.name;
|
|
1074
809
|
this.isVersionTwo ||= internalSubgraph.isVersionTwo;
|
|
1075
|
-
(0, walkers_1.
|
|
810
|
+
(0, walkers_1.renameRootTypes)(this, internalSubgraph);
|
|
1076
811
|
for (const parentDefinitionData of internalSubgraph.parentDefinitionDataByTypeName.values()) {
|
|
1077
812
|
this.upsertParentDefinitionData(parentDefinitionData, internalSubgraph.name);
|
|
1078
813
|
}
|
|
@@ -1098,21 +833,38 @@ class FederationFactory {
|
|
|
1098
833
|
}
|
|
1099
834
|
}
|
|
1100
835
|
}
|
|
836
|
+
handleInterfaceObjectForInternalGraph({ entityData, internalSubgraph, interfaceObjectData, interfaceObjectNode, resolvableKeyFieldSets, subgraphName, }) {
|
|
837
|
+
const entityGraphNode = this.internalGraph.addOrUpdateNode(entityData.typeName);
|
|
838
|
+
const entityDataNode = this.internalGraph.addEntityDataNode(entityData.typeName);
|
|
839
|
+
for (const satisfiedFieldSet of interfaceObjectNode.satisfiedFieldSets) {
|
|
840
|
+
entityGraphNode.satisfiedFieldSets.add(satisfiedFieldSet);
|
|
841
|
+
if (resolvableKeyFieldSets.has(satisfiedFieldSet)) {
|
|
842
|
+
entityDataNode.addTargetSubgraphByFieldSet(satisfiedFieldSet, subgraphName);
|
|
843
|
+
}
|
|
844
|
+
}
|
|
845
|
+
const fieldDatas = interfaceObjectData.fieldDatasBySubgraphName.get(subgraphName);
|
|
846
|
+
for (const { name, namedTypeName } of fieldDatas || []) {
|
|
847
|
+
this.internalGraph.addEdge(entityGraphNode, this.internalGraph.addOrUpdateNode(namedTypeName), name);
|
|
848
|
+
}
|
|
849
|
+
this.internalGraph.addEdge(interfaceObjectNode, entityGraphNode, entityData.typeName, true);
|
|
850
|
+
this.addValidPrimaryKeyTargetsFromInterfaceObject(internalSubgraph, interfaceObjectNode.typeName, entityData, entityGraphNode);
|
|
851
|
+
}
|
|
1101
852
|
handleEntityInterfaces() {
|
|
1102
|
-
for (const [
|
|
853
|
+
for (const [entityInterfaceTypeName, entityInterfaceData] of this.entityInterfaceFederationDataByTypeName) {
|
|
1103
854
|
(0, utils_3.subtractSourceSetFromTargetSet)(entityInterfaceData.interfaceFieldNames, entityInterfaceData.interfaceObjectFieldNames);
|
|
1104
|
-
const entityInterface = (0, utils_3.getOrThrowError)(this.parentDefinitionDataByTypeName,
|
|
855
|
+
const entityInterface = (0, utils_3.getOrThrowError)(this.parentDefinitionDataByTypeName, entityInterfaceTypeName, string_constants_1.PARENT_DEFINITION_DATA);
|
|
1105
856
|
if (entityInterface.kind !== graphql_1.Kind.INTERFACE_TYPE_DEFINITION) {
|
|
1106
857
|
// TODO error
|
|
1107
858
|
continue;
|
|
1108
859
|
}
|
|
1109
860
|
for (const subgraphName of entityInterfaceData.interfaceObjectSubgraphs) {
|
|
1110
|
-
const
|
|
1111
|
-
const
|
|
861
|
+
const internalSubgraph = (0, utils_3.getOrThrowError)(this.internalSubgraphBySubgraphName, subgraphName, 'internalSubgraphBySubgraphName');
|
|
862
|
+
const configurationDataMap = internalSubgraph.configurationDataByParentTypeName;
|
|
863
|
+
const concreteTypeNames = this.concreteTypeNamesByAbstractTypeName.get(entityInterfaceTypeName);
|
|
1112
864
|
if (!concreteTypeNames) {
|
|
1113
865
|
continue;
|
|
1114
866
|
}
|
|
1115
|
-
const interfaceObjectConfiguration = (0, utils_3.getOrThrowError)(configurationDataMap,
|
|
867
|
+
const interfaceObjectConfiguration = (0, utils_3.getOrThrowError)(configurationDataMap, entityInterfaceTypeName, 'configurationDataMap');
|
|
1116
868
|
const keys = interfaceObjectConfiguration.keys;
|
|
1117
869
|
if (!keys) {
|
|
1118
870
|
// TODO no keys error
|
|
@@ -1121,6 +873,8 @@ class FederationFactory {
|
|
|
1121
873
|
interfaceObjectConfiguration.entityInterfaceConcreteTypeNames = entityInterfaceData.concreteTypeNames;
|
|
1122
874
|
const fieldNames = interfaceObjectConfiguration.fieldNames;
|
|
1123
875
|
const authorizationData = this.authorizationDataByParentTypeName.get(entityInterfaceData.typeName);
|
|
876
|
+
this.internalGraph.setSubgraphName(subgraphName);
|
|
877
|
+
const interfaceObjectNode = this.internalGraph.addOrUpdateNode(entityInterfaceTypeName, { isAbstract: true });
|
|
1124
878
|
for (const concreteTypeName of concreteTypeNames) {
|
|
1125
879
|
if (configurationDataMap.has(concreteTypeName)) {
|
|
1126
880
|
// error TODO
|
|
@@ -1139,31 +893,48 @@ class FederationFactory {
|
|
|
1139
893
|
continue;
|
|
1140
894
|
}
|
|
1141
895
|
// The subgraph locations of the interface object must be added to the concrete types that implement it
|
|
1142
|
-
const
|
|
1143
|
-
|
|
1144
|
-
// TODO error if not an entity
|
|
1145
|
-
entity.subgraphNames.add(subgraphName);
|
|
1146
|
-
}
|
|
896
|
+
const entityData = (0, utils_3.getOrThrowError)(this.entityDataByTypeName, concreteTypeName, 'entityDataByTypeName');
|
|
897
|
+
entityData.subgraphNames.add(subgraphName);
|
|
1147
898
|
const configurationData = {
|
|
1148
899
|
fieldNames,
|
|
1149
900
|
isRootNode: true,
|
|
1150
901
|
keys,
|
|
1151
902
|
typeName: concreteTypeName,
|
|
1152
903
|
};
|
|
904
|
+
const resolvableKeyFieldSets = new Set();
|
|
905
|
+
for (const key of keys.filter((k) => !k.disableEntityResolver)) {
|
|
906
|
+
resolvableKeyFieldSets.add(key.selectionSet);
|
|
907
|
+
}
|
|
1153
908
|
for (const fieldName of entityInterfaceData.interfaceObjectFieldNames) {
|
|
1154
909
|
const existingFieldData = concreteTypeData.fieldDataByFieldName.get(fieldName);
|
|
1155
910
|
if (existingFieldData) {
|
|
1156
911
|
// TODO handle shareability
|
|
1157
912
|
continue;
|
|
1158
913
|
}
|
|
1159
|
-
const interfaceFieldData = (0, utils_3.getOrThrowError)(entityInterface.fieldDataByFieldName, fieldName, `${
|
|
914
|
+
const interfaceFieldData = (0, utils_3.getOrThrowError)(entityInterface.fieldDataByFieldName, fieldName, `${entityInterfaceTypeName}.fieldDataByFieldName`);
|
|
1160
915
|
concreteTypeData.fieldDataByFieldName.set(fieldName, { ...interfaceFieldData });
|
|
1161
916
|
}
|
|
1162
917
|
configurationDataMap.set(concreteTypeName, configurationData);
|
|
918
|
+
this.handleInterfaceObjectForInternalGraph({
|
|
919
|
+
internalSubgraph,
|
|
920
|
+
subgraphName,
|
|
921
|
+
interfaceObjectData: entityInterfaceData,
|
|
922
|
+
interfaceObjectNode,
|
|
923
|
+
resolvableKeyFieldSets,
|
|
924
|
+
entityData,
|
|
925
|
+
});
|
|
1163
926
|
}
|
|
1164
927
|
}
|
|
1165
928
|
}
|
|
1166
929
|
}
|
|
930
|
+
fieldDataToGraphFieldData(fieldData) {
|
|
931
|
+
return {
|
|
932
|
+
name: fieldData.name,
|
|
933
|
+
namedTypeName: fieldData.namedTypeName,
|
|
934
|
+
isLeaf: (0, utils_3.isNodeLeaf)(this.parentDefinitionDataByTypeName.get(fieldData.namedTypeName)?.kind),
|
|
935
|
+
subgraphNames: fieldData.subgraphNames,
|
|
936
|
+
};
|
|
937
|
+
}
|
|
1167
938
|
pushParentDefinitionDataToDocumentDefinitions(interfaceImplementations) {
|
|
1168
939
|
for (const [parentTypeName, parentDefinitionData] of this.parentDefinitionDataByTypeName) {
|
|
1169
940
|
switch (parentDefinitionData.kind) {
|
|
@@ -1208,6 +979,7 @@ class FederationFactory {
|
|
|
1208
979
|
this.routerDefinitions.push((0, utils_5.getNodeForRouterSchemaByData)(parentDefinitionData, this.persistedDirectiveDefinitionByDirectiveName, this.errors));
|
|
1209
980
|
if ((0, utils_5.isNodeDataInaccessible)(parentDefinitionData)) {
|
|
1210
981
|
this.validateReferencesOfInaccessibleType(parentDefinitionData);
|
|
982
|
+
this.internalGraph.setNodeInaccessible(parentDefinitionData.name);
|
|
1211
983
|
break;
|
|
1212
984
|
}
|
|
1213
985
|
if (clientEnumValueNodes.length < 1) {
|
|
@@ -1268,6 +1040,7 @@ class FederationFactory {
|
|
|
1268
1040
|
case graphql_1.Kind.OBJECT_TYPE_DEFINITION:
|
|
1269
1041
|
const fieldNodes = [];
|
|
1270
1042
|
const clientSchemaFieldNodes = [];
|
|
1043
|
+
const graphFieldDataByFieldName = new Map();
|
|
1271
1044
|
const invalidFieldNames = new Set();
|
|
1272
1045
|
const isObject = parentDefinitionData.kind === graphql_1.Kind.OBJECT_TYPE_DEFINITION;
|
|
1273
1046
|
for (const [fieldName, fieldData] of parentDefinitionData.fieldDataByFieldName) {
|
|
@@ -1281,11 +1054,13 @@ class FederationFactory {
|
|
|
1281
1054
|
continue;
|
|
1282
1055
|
}
|
|
1283
1056
|
clientSchemaFieldNodes.push((0, utils_5.getClientSchemaFieldNodeByFieldData)(fieldData));
|
|
1057
|
+
graphFieldDataByFieldName.set(fieldName, this.fieldDataToGraphFieldData(fieldData));
|
|
1284
1058
|
}
|
|
1285
1059
|
if (isObject && invalidFieldNames.size > 0) {
|
|
1286
1060
|
this.errors.push((0, errors_1.invalidFieldShareabilityError)(parentDefinitionData, invalidFieldNames));
|
|
1287
1061
|
}
|
|
1288
1062
|
parentDefinitionData.node.fields = fieldNodes;
|
|
1063
|
+
this.internalGraph.initializeNode(parentTypeName, graphFieldDataByFieldName);
|
|
1289
1064
|
// Implemented interfaces can only be validated after all fields are merged
|
|
1290
1065
|
if (parentDefinitionData.implementedInterfaceTypeNames.size > 0) {
|
|
1291
1066
|
interfaceImplementations.push({ data: parentDefinitionData, clientSchemaFieldNodes });
|
|
@@ -1299,6 +1074,7 @@ class FederationFactory {
|
|
|
1299
1074
|
break;
|
|
1300
1075
|
}
|
|
1301
1076
|
this.validateReferencesOfInaccessibleType(parentDefinitionData);
|
|
1077
|
+
this.internalGraph.setNodeInaccessible(parentDefinitionData.name);
|
|
1302
1078
|
break;
|
|
1303
1079
|
}
|
|
1304
1080
|
if (clientSchemaFieldNodes.length < 1) {
|
|
@@ -1321,6 +1097,7 @@ class FederationFactory {
|
|
|
1321
1097
|
this.routerDefinitions.push((0, utils_5.getNodeForRouterSchemaByData)(parentDefinitionData, this.persistedDirectiveDefinitionByDirectiveName, this.errors));
|
|
1322
1098
|
if ((0, utils_5.isNodeDataInaccessible)(parentDefinitionData)) {
|
|
1323
1099
|
this.validateReferencesOfInaccessibleType(parentDefinitionData);
|
|
1100
|
+
this.internalGraph.setNodeInaccessible(parentDefinitionData.name);
|
|
1324
1101
|
break;
|
|
1325
1102
|
}
|
|
1326
1103
|
this.clientDefinitions.push({
|
|
@@ -1333,6 +1110,7 @@ class FederationFactory {
|
|
|
1333
1110
|
this.routerDefinitions.push((0, utils_5.getNodeForRouterSchemaByData)(parentDefinitionData, this.persistedDirectiveDefinitionByDirectiveName, this.errors));
|
|
1334
1111
|
if ((0, utils_5.isNodeDataInaccessible)(parentDefinitionData)) {
|
|
1335
1112
|
this.validateReferencesOfInaccessibleType(parentDefinitionData);
|
|
1113
|
+
this.internalGraph.setNodeInaccessible(parentDefinitionData.name);
|
|
1336
1114
|
break;
|
|
1337
1115
|
}
|
|
1338
1116
|
const clientMembers = this.getClientSchemaUnionMembers(parentDefinitionData);
|
|
@@ -1365,6 +1143,7 @@ class FederationFactory {
|
|
|
1365
1143
|
this.routerDefinitions.push((0, utils_5.getNodeForRouterSchemaByData)(data, this.persistedDirectiveDefinitionByDirectiveName, this.errors));
|
|
1366
1144
|
if ((0, utils_5.isNodeDataInaccessible)(data)) {
|
|
1367
1145
|
this.validateReferencesOfInaccessibleType(data);
|
|
1146
|
+
this.internalGraph.setNodeInaccessible(data.name);
|
|
1368
1147
|
continue;
|
|
1369
1148
|
}
|
|
1370
1149
|
const clientInterfaces = [];
|
|
@@ -1373,6 +1152,9 @@ class FederationFactory {
|
|
|
1373
1152
|
clientInterfaces.push((0, utils_1.stringToNamedTypeNode)(interfaceTypeName));
|
|
1374
1153
|
}
|
|
1375
1154
|
}
|
|
1155
|
+
/* It is not possible for clientSchemaFieldNodes to be empty.
|
|
1156
|
+
* If all interface fields were declared @inaccessible, the error would be caught above.
|
|
1157
|
+
* */
|
|
1376
1158
|
this.clientDefinitions.push({
|
|
1377
1159
|
...data.node,
|
|
1378
1160
|
directives: (0, utils_5.getClientPersistedDirectiveNodes)(data),
|
|
@@ -1706,14 +1488,20 @@ class FederationFactory {
|
|
|
1706
1488
|
this.pushParentDefinitionDataToDocumentDefinitions(definitionsWithInterfaces);
|
|
1707
1489
|
this.validateInterfaceImplementationsAndPushToDocumentDefinitions(definitionsWithInterfaces);
|
|
1708
1490
|
this.validateQueryRootType();
|
|
1709
|
-
//
|
|
1491
|
+
// Return any composition errors before checking whether all fields are resolvable
|
|
1710
1492
|
if (this.errors.length > 0) {
|
|
1711
1493
|
return { errors: this.errors };
|
|
1712
1494
|
}
|
|
1713
1495
|
/* Resolvability evaluations are not necessary for contracts because the source graph resolvability checks must
|
|
1714
|
-
|
|
1496
|
+
* have already completed without error. */
|
|
1715
1497
|
const warnings = this.warnings.length > 0 ? { warnings: this.warnings } : {};
|
|
1716
|
-
|
|
1498
|
+
// Resolvability checks are unnecessary for a single subgraph
|
|
1499
|
+
if (this.internalSubgraphBySubgraphName.size > 1) {
|
|
1500
|
+
const resolvabilityErrors = this.internalGraph.validate();
|
|
1501
|
+
if (resolvabilityErrors.length > 0) {
|
|
1502
|
+
return { errors: resolvabilityErrors, ...warnings };
|
|
1503
|
+
}
|
|
1504
|
+
}
|
|
1717
1505
|
if (this.errors.length > 0) {
|
|
1718
1506
|
return { errors: this.errors, ...warnings };
|
|
1719
1507
|
}
|
|
@@ -1902,7 +1690,7 @@ function initializeFederationFactory(subgraphs) {
|
|
|
1902
1690
|
if (subgraphs.length < 1) {
|
|
1903
1691
|
return { errors: [errors_1.minimumSubgraphRequirementError] };
|
|
1904
1692
|
}
|
|
1905
|
-
const { authorizationDataByParentTypeName, concreteTypeNamesByAbstractTypeName, entityDataByTypeName, errors,
|
|
1693
|
+
const { authorizationDataByParentTypeName, concreteTypeNamesByAbstractTypeName, entityDataByTypeName, errors, internalSubgraphBySubgraphName, internalGraph, warnings, } = (0, normalization_factory_1.batchNormalize)(subgraphs);
|
|
1906
1694
|
if (errors) {
|
|
1907
1695
|
return { errors };
|
|
1908
1696
|
}
|
|
@@ -1913,8 +1701,7 @@ function initializeFederationFactory(subgraphs) {
|
|
|
1913
1701
|
for (const [typeName, entityInterfaceData] of internalSubgraph.entityInterfaces) {
|
|
1914
1702
|
// Always add each entity interface to the invalid entity interfaces map
|
|
1915
1703
|
// If not, earlier checks would not account for implementations not yet seen
|
|
1916
|
-
|
|
1917
|
-
invalidEntityInterfaces.push({
|
|
1704
|
+
(0, utils_3.getValueOrDefault)(invalidEntityInterfacesByTypeName, typeName, () => []).push({
|
|
1918
1705
|
subgraphName,
|
|
1919
1706
|
concreteTypeNames: entityInterfaceData.concreteTypeNames || new Set(),
|
|
1920
1707
|
});
|
|
@@ -1947,8 +1734,8 @@ function initializeFederationFactory(subgraphs) {
|
|
|
1947
1734
|
concreteTypeNamesByAbstractTypeName,
|
|
1948
1735
|
entityDataByTypeName,
|
|
1949
1736
|
entityInterfaceFederationDataByTypeName,
|
|
1950
|
-
graph,
|
|
1951
1737
|
internalSubgraphBySubgraphName,
|
|
1738
|
+
internalGraph,
|
|
1952
1739
|
warnings,
|
|
1953
1740
|
}),
|
|
1954
1741
|
};
|