@wundergraph/composition 0.45.0 → 0.46.1
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/errors/errors.d.ts +3 -2
- package/dist/errors/errors.js +9 -0
- package/dist/errors/errors.js.map +1 -1
- package/dist/errors/types.d.ts +5 -0
- package/dist/index.d.ts +4 -1
- package/dist/index.js +4 -1
- package/dist/index.js.map +1 -1
- package/dist/resolvability-graph/constants/string-constants.d.ts +8 -0
- package/dist/resolvability-graph/constants/string-constants.js +12 -0
- package/dist/resolvability-graph/constants/string-constants.js.map +1 -0
- package/dist/resolvability-graph/graph-nodes.d.ts +15 -14
- package/dist/resolvability-graph/graph-nodes.js +8 -8
- package/dist/resolvability-graph/graph-nodes.js.map +1 -1
- package/dist/resolvability-graph/graph.d.ts +27 -21
- package/dist/resolvability-graph/graph.js +284 -286
- package/dist/resolvability-graph/graph.js.map +1 -1
- package/dist/resolvability-graph/node-resolution-data/node-resolution-data.d.ts +16 -0
- package/dist/resolvability-graph/node-resolution-data/node-resolution-data.js +62 -0
- package/dist/resolvability-graph/node-resolution-data/node-resolution-data.js.map +1 -0
- package/dist/resolvability-graph/node-resolution-data/types/params.d.ts +9 -0
- package/dist/resolvability-graph/node-resolution-data/types/params.js +3 -0
- package/dist/resolvability-graph/node-resolution-data/types/params.js.map +1 -0
- package/dist/resolvability-graph/types/params.d.ts +22 -0
- package/dist/resolvability-graph/types/params.js +3 -0
- package/dist/resolvability-graph/types/params.js.map +1 -0
- package/dist/resolvability-graph/types/types.d.ts +23 -0
- package/dist/resolvability-graph/types/types.js +3 -0
- package/dist/resolvability-graph/types/types.js.map +1 -0
- package/dist/resolvability-graph/utils/types/params.d.ts +50 -0
- package/dist/resolvability-graph/utils/types/params.js +3 -0
- package/dist/resolvability-graph/utils/types/params.js.map +1 -0
- package/dist/resolvability-graph/utils/types/types.d.ts +16 -0
- package/dist/resolvability-graph/utils/types/types.js +3 -0
- package/dist/resolvability-graph/utils/types/types.js.map +1 -0
- package/dist/resolvability-graph/utils/utils.d.ts +19 -0
- package/dist/resolvability-graph/utils/utils.js +230 -0
- package/dist/resolvability-graph/utils/utils.js.map +1 -0
- package/dist/resolvability-graph/walker/entity-walker/entity-walker.d.ts +21 -0
- package/dist/resolvability-graph/walker/entity-walker/entity-walker.js +194 -0
- package/dist/resolvability-graph/walker/entity-walker/entity-walker.js.map +1 -0
- package/dist/resolvability-graph/walker/entity-walker/types/params.d.ts +40 -0
- package/dist/resolvability-graph/walker/entity-walker/types/params.js +3 -0
- package/dist/resolvability-graph/walker/entity-walker/types/params.js.map +1 -0
- package/dist/resolvability-graph/walker/root-field-walkers/root-field-walker.d.ts +23 -0
- package/dist/resolvability-graph/walker/root-field-walkers/root-field-walker.js +250 -0
- package/dist/resolvability-graph/walker/root-field-walkers/root-field-walker.js.map +1 -0
- package/dist/resolvability-graph/walker/root-field-walkers/types/params.d.ts +38 -0
- package/dist/resolvability-graph/walker/root-field-walkers/types/params.js +3 -0
- package/dist/resolvability-graph/walker/root-field-walkers/types/params.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/composition-version.js +1 -1
- package/dist/utils/string-constants.d.ts +1 -0
- package/dist/utils/string-constants.js +6 -5
- package/dist/utils/string-constants.js.map +1 -1
- package/dist/utils/utils.d.ts +1 -1
- package/dist/utils/utils.js +2 -2
- package/dist/utils/utils.js.map +1 -1
- package/dist/v1/federation/federation-factory.d.ts +2 -0
- package/dist/v1/federation/federation-factory.js +62 -21
- package/dist/v1/federation/federation-factory.js.map +1 -1
- package/dist/v1/federation/params.d.ts +8 -0
- package/dist/v1/federation/params.js +3 -0
- package/dist/v1/federation/params.js.map +1 -0
- package/dist/v1/normalization/directive-definition-data.d.ts +5 -4
- package/dist/v1/normalization/directive-definition-data.js +113 -104
- package/dist/v1/normalization/directive-definition-data.js.map +1 -1
- package/dist/v1/normalization/normalization-factory.d.ts +2 -0
- package/dist/v1/normalization/normalization-factory.js +52 -12
- package/dist/v1/normalization/normalization-factory.js.map +1 -1
- package/dist/v1/normalization/params.d.ts +6 -0
- package/dist/v1/normalization/params.js +3 -0
- package/dist/v1/normalization/params.js.map +1 -0
- package/dist/v1/normalization/utils.js +1 -0
- package/dist/v1/normalization/utils.js.map +1 -1
- package/dist/v1/utils/constants.d.ts +1 -0
- package/dist/v1/utils/constants.js +9 -1
- package/dist/v1/utils/constants.js.map +1 -1
- package/dist/v1/warnings/params.d.ts +10 -0
- package/dist/v1/warnings/params.js +3 -0
- package/dist/v1/warnings/params.js.map +1 -0
- package/dist/v1/warnings/warnings.d.ts +3 -0
- package/dist/v1/warnings/warnings.js +23 -0
- package/dist/v1/warnings/warnings.js.map +1 -1
- package/package.json +2 -2
- package/dist/resolvability-graph/utils.d.ts +0 -65
- package/dist/resolvability-graph/utils.js +0 -143
- package/dist/resolvability-graph/utils.js.map +0 -1
|
@@ -2,25 +2,26 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.Graph = void 0;
|
|
4
4
|
const graph_nodes_1 = require("./graph-nodes");
|
|
5
|
-
const utils_1 = require("./utils");
|
|
6
|
-
const string_constants_1 = require("../utils/string-constants");
|
|
5
|
+
const utils_1 = require("./utils/utils");
|
|
7
6
|
const utils_2 = require("../utils/utils");
|
|
7
|
+
const string_constants_1 = require("./constants/string-constants");
|
|
8
|
+
const entity_walker_1 = require("./walker/entity-walker/entity-walker");
|
|
9
|
+
const root_field_walker_1 = require("./walker/root-field-walkers/root-field-walker");
|
|
8
10
|
class Graph {
|
|
9
11
|
edgeId = -1;
|
|
10
|
-
|
|
11
|
-
entityNodeNamesBySharedFieldPath = new Map();
|
|
12
|
+
entityDataNodeByTypeName = new Map();
|
|
12
13
|
nodeByNodeName = new Map();
|
|
13
14
|
nodesByTypeName = new Map();
|
|
14
|
-
|
|
15
|
+
resolvedRootFieldNodeNames = new Set();
|
|
16
|
+
rootNodeByTypeName = new Map();
|
|
15
17
|
subgraphName = string_constants_1.NOT_APPLICABLE;
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
failureResultByEntityNodeName = new Map();
|
|
18
|
+
resDataByNodeName = new Map();
|
|
19
|
+
resDataByRelativePathByEntity = new Map();
|
|
20
|
+
visitedEntitiesByOriginEntity = new Map();
|
|
20
21
|
walkerIndex = -1;
|
|
21
22
|
constructor() { }
|
|
22
23
|
getRootNode(typeName) {
|
|
23
|
-
return (0, utils_2.getValueOrDefault)(this.
|
|
24
|
+
return (0, utils_2.getValueOrDefault)(this.rootNodeByTypeName, typeName, () => new graph_nodes_1.RootNode(typeName));
|
|
24
25
|
}
|
|
25
26
|
addOrUpdateNode(typeName, options) {
|
|
26
27
|
const nodeName = `${this.subgraphName}.${typeName}`;
|
|
@@ -40,7 +41,7 @@ class Graph {
|
|
|
40
41
|
addEdge(headNode, tailNode, fieldName, isAbstractEdge = false) {
|
|
41
42
|
if (headNode.isRootNode) {
|
|
42
43
|
const edge = new graph_nodes_1.Edge(this.getNextEdgeId(), tailNode, fieldName);
|
|
43
|
-
(0, utils_2.getValueOrDefault)(headNode.
|
|
44
|
+
(0, utils_2.getValueOrDefault)(headNode.headToSharedTailEdges, fieldName, () => []).push(edge);
|
|
44
45
|
return edge;
|
|
45
46
|
}
|
|
46
47
|
const headGraphNode = headNode;
|
|
@@ -49,17 +50,20 @@ class Graph {
|
|
|
49
50
|
return headToTailEdge;
|
|
50
51
|
}
|
|
51
52
|
addEntityDataNode(typeName) {
|
|
52
|
-
const node = this.
|
|
53
|
+
const node = this.entityDataNodeByTypeName.get(typeName);
|
|
53
54
|
if (node) {
|
|
54
55
|
return node;
|
|
55
56
|
}
|
|
56
57
|
const newNode = new graph_nodes_1.EntityDataNode(typeName);
|
|
57
|
-
this.
|
|
58
|
+
this.entityDataNodeByTypeName.set(typeName, newNode);
|
|
58
59
|
return newNode;
|
|
59
60
|
}
|
|
60
61
|
getNextEdgeId() {
|
|
61
62
|
return (this.edgeId += 1);
|
|
62
63
|
}
|
|
64
|
+
getNextWalkerIndex() {
|
|
65
|
+
return (this.walkerIndex += 1);
|
|
66
|
+
}
|
|
63
67
|
setNodeInaccessible(typeName) {
|
|
64
68
|
const nodes = this.nodesByTypeName.get(typeName);
|
|
65
69
|
if (!nodes) {
|
|
@@ -69,12 +73,12 @@ class Graph {
|
|
|
69
73
|
node.isInaccessible = true;
|
|
70
74
|
}
|
|
71
75
|
}
|
|
72
|
-
initializeNode(typeName,
|
|
73
|
-
const entityDataNode = this.
|
|
76
|
+
initializeNode(typeName, fieldDataByName) {
|
|
77
|
+
const entityDataNode = this.entityDataNodeByTypeName.get(typeName);
|
|
74
78
|
if (string_constants_1.ROOT_TYPE_NAMES.has(typeName)) {
|
|
75
79
|
const rootNode = this.getRootNode(typeName);
|
|
76
|
-
rootNode.removeInaccessibleEdges(
|
|
77
|
-
rootNode.
|
|
80
|
+
rootNode.removeInaccessibleEdges(fieldDataByName);
|
|
81
|
+
rootNode.fieldDataByName = fieldDataByName;
|
|
78
82
|
return;
|
|
79
83
|
}
|
|
80
84
|
const nodes = this.nodesByTypeName.get(typeName);
|
|
@@ -82,7 +86,7 @@ class Graph {
|
|
|
82
86
|
return;
|
|
83
87
|
}
|
|
84
88
|
for (const node of nodes) {
|
|
85
|
-
node.
|
|
89
|
+
node.fieldDataByName = fieldDataByName;
|
|
86
90
|
node.handleInaccessibleEdges();
|
|
87
91
|
node.isLeaf = false;
|
|
88
92
|
if (!entityDataNode) {
|
|
@@ -91,7 +95,7 @@ class Graph {
|
|
|
91
95
|
node.hasEntitySiblings = true;
|
|
92
96
|
for (const fieldSet of node.satisfiedFieldSets) {
|
|
93
97
|
const subgraphNames = entityDataNode.targetSubgraphNamesByFieldSet.get(fieldSet);
|
|
94
|
-
for (const subgraphName of subgraphNames
|
|
98
|
+
for (const subgraphName of subgraphNames ?? []) {
|
|
95
99
|
// A subgraph should not jump to itself
|
|
96
100
|
if (subgraphName === node.subgraphName) {
|
|
97
101
|
continue;
|
|
@@ -107,300 +111,294 @@ class Graph {
|
|
|
107
111
|
setSubgraphName(subgraphName) {
|
|
108
112
|
this.subgraphName = subgraphName;
|
|
109
113
|
}
|
|
110
|
-
|
|
111
|
-
const
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
for (const entityNodeName of entityNodeNames) {
|
|
135
|
-
const entityNode = this.nodeByNodeName.get(entityNodeName);
|
|
136
|
-
if (!entityNode) {
|
|
137
|
-
throw new Error(`Fatal: Could not find entity node for "${entityNodeName}".`);
|
|
138
|
-
}
|
|
139
|
-
const resolvableFieldNamesByRelativeFieldPath = this.resolvableFieldNamesByRelativeFieldPathByEntityNodeName.get(entityNodeName);
|
|
140
|
-
if (resolvableFieldNamesByRelativeFieldPath) {
|
|
141
|
-
// If at least one of the referenced entities is always fully resolvable, the path is resolvable.
|
|
142
|
-
const entityFailureResult = this.failureResultByEntityNodeName.get(entityNodeName);
|
|
143
|
-
if (!entityFailureResult) {
|
|
144
|
-
failureResult = undefined;
|
|
145
|
-
break;
|
|
146
|
-
}
|
|
147
|
-
// If the path is shared, it must be assessed collectively
|
|
148
|
-
if (!isFieldShared) {
|
|
149
|
-
return entityFailureResult;
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
const interSubgraphNodes = this.nodesByTypeName.get(entityNode.typeName) || [];
|
|
153
|
-
const nestedEntityNodeNamesBySharedFieldPath = (0, utils_2.getValueOrDefault)(nestedEntityNodeNamesBySharedFieldPathByParentNodeName, entityNodeName, () => (isFieldShared ? sharedNestedEntityNodeNamesBySharedFieldPath : new Map()));
|
|
154
|
-
const walker = new Walker({
|
|
155
|
-
interSubgraphNodes,
|
|
156
|
-
entityNodeNamesBySharedFieldPath: nestedEntityNodeNamesBySharedFieldPath,
|
|
157
|
-
originNode: entityNode,
|
|
158
|
-
resolvableFieldNamesByRelativeFieldPathByEntityNodeName: this.resolvableFieldNamesByRelativeFieldPathByEntityNodeName,
|
|
159
|
-
walkerIndex: (this.walkerIndex += 1),
|
|
160
|
-
sharedResolvableFieldNamesByRelativeFieldPath,
|
|
161
|
-
unresolvableSharedFieldPaths,
|
|
162
|
-
});
|
|
163
|
-
walker.visitEntityNode(entityNode);
|
|
164
|
-
if (walker.unresolvableFieldPaths.size > 0) {
|
|
165
|
-
if (isFieldShared && unresolvableSharedFieldPaths.size < 1) {
|
|
166
|
-
failureResult = undefined;
|
|
167
|
-
break;
|
|
168
|
-
}
|
|
169
|
-
failureResult = {
|
|
170
|
-
entityAncestorData: {
|
|
171
|
-
fieldSetsByTargetSubgraphName: (0, utils_2.getOrThrowError)(this.entityDataNodes, entityNode.typeName, 'entityDataNodes').fieldSetsByTargetSubgraphName,
|
|
172
|
-
subgraphName: entityNode.subgraphName,
|
|
173
|
-
typeName: entityNode.typeName,
|
|
174
|
-
},
|
|
175
|
-
nodeName: entityNodeName,
|
|
176
|
-
parentFieldPathForEntityReference: [sharedFieldPath],
|
|
177
|
-
success: false,
|
|
178
|
-
typeName: entityNode.typeName,
|
|
179
|
-
unresolvableFieldPaths: isFieldShared ? unresolvableSharedFieldPaths : walker.unresolvableFieldPaths,
|
|
180
|
-
};
|
|
181
|
-
this.failureResultByEntityNodeName.set(entityNodeName, failureResult);
|
|
182
|
-
continue;
|
|
183
|
-
}
|
|
184
|
-
// In a shared path, only a single instance need succeed
|
|
185
|
-
failureResult = undefined;
|
|
186
|
-
break;
|
|
114
|
+
visitEntity({ encounteredEntityNodeNames, entityNodeName, relativeOriginPaths, resDataByRelativeOriginPath, subgraphNameByUnresolvablePath, visitedEntities, }) {
|
|
115
|
+
const entityNode = this.nodeByNodeName.get(entityNodeName);
|
|
116
|
+
if (!entityNode) {
|
|
117
|
+
throw new Error(`Fatal: Could not find entity node for "${entityNodeName}".`);
|
|
118
|
+
}
|
|
119
|
+
visitedEntities.add(entityNodeName);
|
|
120
|
+
const interSubgraphNodes = this.nodesByTypeName.get(entityNode.typeName);
|
|
121
|
+
if (!interSubgraphNodes?.length) {
|
|
122
|
+
throw new Error(`Fatal: Could not find any nodes for "${entityNodeName}".`);
|
|
123
|
+
}
|
|
124
|
+
const walker = new entity_walker_1.EntityWalker({
|
|
125
|
+
encounteredEntityNodeNames,
|
|
126
|
+
index: this.getNextWalkerIndex(),
|
|
127
|
+
relativeOriginPaths,
|
|
128
|
+
resDataByNodeName: this.resDataByNodeName,
|
|
129
|
+
resDataByRelativeOriginPath,
|
|
130
|
+
subgraphNameByUnresolvablePath,
|
|
131
|
+
visitedEntities,
|
|
132
|
+
});
|
|
133
|
+
const accessibleEntityNodeNames = entityNode.getAllAccessibleEntityNodeNames();
|
|
134
|
+
for (const siblingEntityNode of interSubgraphNodes) {
|
|
135
|
+
if (siblingEntityNode.nodeName !== entityNode.nodeName &&
|
|
136
|
+
!accessibleEntityNodeNames.has(siblingEntityNode.nodeName)) {
|
|
137
|
+
continue;
|
|
187
138
|
}
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
139
|
+
const { areDescendantsResolved } = walker.visitEntityDescendantConcreteNode({
|
|
140
|
+
node: siblingEntityNode,
|
|
141
|
+
selectionPath: '',
|
|
142
|
+
});
|
|
143
|
+
// All fields and descendent fields are resolved; nothing more to do for this entity.
|
|
144
|
+
if (areDescendantsResolved) {
|
|
145
|
+
return;
|
|
193
146
|
}
|
|
194
147
|
}
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
148
|
+
// Because of shared entity descendant paths, we can only assess the errors after checking all nested entities.
|
|
149
|
+
for (const [nestedEntityNodeName, selectionPath] of walker.selectionPathByEntityNodeName) {
|
|
150
|
+
/* Short circuiting on failures here can cause false positives.
|
|
151
|
+
* For example, an Object that is an entity at least one graph and defines at least one unique (nested) field.
|
|
152
|
+
* If that Object has no accessible keys but is accessible through an ancestor, short-circuiting here would
|
|
153
|
+
* produce an error before that shared path has been visited.
|
|
154
|
+
*/
|
|
155
|
+
this.visitEntity({
|
|
156
|
+
encounteredEntityNodeNames,
|
|
157
|
+
entityNodeName: nestedEntityNodeName,
|
|
158
|
+
relativeOriginPaths: (0, utils_1.getMultipliedRelativeOriginPaths)({
|
|
159
|
+
relativeOriginPaths,
|
|
160
|
+
selectionPath: selectionPath,
|
|
161
|
+
}),
|
|
162
|
+
resDataByRelativeOriginPath,
|
|
163
|
+
subgraphNameByUnresolvablePath,
|
|
164
|
+
visitedEntities,
|
|
165
|
+
});
|
|
210
166
|
}
|
|
211
|
-
return { success: true };
|
|
212
167
|
}
|
|
213
168
|
validate() {
|
|
214
|
-
const
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
169
|
+
for (const rootNode of this.rootNodeByTypeName.values()) {
|
|
170
|
+
for (const [rootFieldName, sharedRootFieldEdges] of rootNode.headToSharedTailEdges) {
|
|
171
|
+
const isSharedRootField = sharedRootFieldEdges.length > 1;
|
|
172
|
+
if (!isSharedRootField) {
|
|
173
|
+
const namedTypeNodeName = sharedRootFieldEdges[0].node.nodeName;
|
|
174
|
+
if (this.resolvedRootFieldNodeNames.has(namedTypeNodeName)) {
|
|
175
|
+
continue;
|
|
220
176
|
}
|
|
221
|
-
this.
|
|
222
|
-
this.visitEdge(rootFieldEdge, `${rootNode.typeName.toLowerCase()}`);
|
|
177
|
+
this.resolvedRootFieldNodeNames.add(namedTypeNodeName);
|
|
223
178
|
}
|
|
224
|
-
const
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
179
|
+
const rootFieldWalker = new root_field_walker_1.RootFieldWalker({
|
|
180
|
+
index: this.getNextWalkerIndex(),
|
|
181
|
+
nodeResolutionDataByNodeName: this.resDataByNodeName,
|
|
182
|
+
});
|
|
183
|
+
if (rootFieldWalker.visitRootFieldEdges({
|
|
184
|
+
edges: sharedRootFieldEdges,
|
|
185
|
+
rootTypeName: rootNode.typeName.toLowerCase(),
|
|
186
|
+
}).areDescendantsResolved) {
|
|
187
|
+
continue;
|
|
233
188
|
}
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
189
|
+
const involvesEntities = isSharedRootField
|
|
190
|
+
? rootFieldWalker.entityNodeNamesByPath.size > 0
|
|
191
|
+
: rootFieldWalker.pathsByEntityNodeName.size > 0;
|
|
192
|
+
if (rootFieldWalker.unresolvablePaths.size < 1 && !involvesEntities) {
|
|
193
|
+
continue;
|
|
239
194
|
}
|
|
240
|
-
|
|
241
|
-
|
|
195
|
+
const fieldData = (0, utils_2.getOrThrowError)(rootNode.fieldDataByName, rootFieldName, 'fieldDataByName');
|
|
196
|
+
const rootFieldData = (0, utils_1.newRootFieldData)(rootNode.typeName, rootFieldName, fieldData.subgraphNames);
|
|
197
|
+
// If there are no nested entities, then the unresolvable fields must be impossible to resolve.
|
|
198
|
+
if (!involvesEntities) {
|
|
199
|
+
return {
|
|
200
|
+
errors: (0, utils_1.generateRootResolvabilityErrors)({
|
|
201
|
+
unresolvablePaths: rootFieldWalker.unresolvablePaths,
|
|
202
|
+
resDataByPath: rootFieldWalker.resDataByPath,
|
|
203
|
+
rootFieldData,
|
|
204
|
+
}),
|
|
205
|
+
success: false,
|
|
206
|
+
};
|
|
207
|
+
}
|
|
208
|
+
const result = this.validateEntities({ isSharedRootField, rootFieldData, walker: rootFieldWalker });
|
|
209
|
+
if (!result.success) {
|
|
210
|
+
return result;
|
|
242
211
|
}
|
|
243
|
-
this.entityNodeNamesBySharedFieldPath = new Map();
|
|
244
212
|
}
|
|
245
213
|
}
|
|
246
|
-
return
|
|
214
|
+
return {
|
|
215
|
+
success: true,
|
|
216
|
+
};
|
|
247
217
|
}
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
}
|
|
253
|
-
if (!(0, utils_2.add)(edge.visitedIndices, this.walkerIndex) || edge.node.isLeaf) {
|
|
254
|
-
return true;
|
|
255
|
-
}
|
|
256
|
-
if (edge.node.isAbstract) {
|
|
257
|
-
this.validateAbstractNode(edge.node, `${fieldPath}.${edge.edgeName}`);
|
|
258
|
-
}
|
|
259
|
-
else {
|
|
260
|
-
this.validateConcreteNode(edge.node, `${fieldPath}.${edge.edgeName}`);
|
|
261
|
-
}
|
|
262
|
-
return true;
|
|
263
|
-
}
|
|
264
|
-
validateConcreteNode(node, fieldPath) {
|
|
265
|
-
if (node.headToTailEdges.size < 1) {
|
|
266
|
-
return;
|
|
267
|
-
}
|
|
268
|
-
if (node.hasEntitySiblings) {
|
|
269
|
-
(0, utils_2.getValueOrDefault)(this.entityNodeNamesBySharedFieldPath, fieldPath, () => new Set()).add(node.nodeName);
|
|
270
|
-
return;
|
|
271
|
-
}
|
|
272
|
-
const resolvedFieldNames = (0, utils_2.getValueOrDefault)(this.nodeResolutionDataByFieldPath, fieldPath, () => new utils_1.NodeResolutionData(node.typeName, node.fieldDataByFieldName));
|
|
273
|
-
for (const [fieldName, edge] of node.headToTailEdges) {
|
|
274
|
-
// Returns true if the edge was visited
|
|
275
|
-
if (this.visitEdge(edge, fieldPath)) {
|
|
276
|
-
resolvedFieldNames.add(fieldName);
|
|
218
|
+
consolidateUnresolvableRootWithEntityPaths({ pathFromRoot, resDataByRelativeOriginPath, subgraphNameByUnresolvablePath, walker, }) {
|
|
219
|
+
for (const unresolvableRootPath of walker.unresolvablePaths) {
|
|
220
|
+
if (!unresolvableRootPath.startsWith(pathFromRoot)) {
|
|
221
|
+
continue;
|
|
277
222
|
}
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
223
|
+
const relativePath = unresolvableRootPath.slice(pathFromRoot.length);
|
|
224
|
+
const rootResData = (0, utils_2.getOrThrowError)(walker.resDataByPath, unresolvableRootPath, `rootFieldWalker.unresolvablePaths`);
|
|
225
|
+
const entityResData = resDataByRelativeOriginPath.get(relativePath);
|
|
226
|
+
if (!entityResData) {
|
|
227
|
+
continue;
|
|
228
|
+
}
|
|
229
|
+
rootResData.addData(entityResData);
|
|
230
|
+
entityResData.addData(rootResData);
|
|
231
|
+
if (!rootResData.isResolved()) {
|
|
232
|
+
// Delete the root path so that the error only propagates once through the entity.
|
|
233
|
+
walker.unresolvablePaths.delete(unresolvableRootPath);
|
|
234
|
+
continue;
|
|
235
|
+
}
|
|
236
|
+
walker.unresolvablePaths.delete(unresolvableRootPath);
|
|
237
|
+
subgraphNameByUnresolvablePath.delete(relativePath);
|
|
292
238
|
}
|
|
293
239
|
}
|
|
294
|
-
|
|
295
|
-
const
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
240
|
+
consolidateUnresolvableEntityWithRootPaths({ pathFromRoot, resDataByRelativeOriginPath, subgraphNameByUnresolvablePath, walker, }) {
|
|
241
|
+
for (const unresolvableEntityPath of subgraphNameByUnresolvablePath.keys()) {
|
|
242
|
+
const entityResData = (0, utils_2.getOrThrowError)(resDataByRelativeOriginPath, unresolvableEntityPath, `resDataByRelativeOriginPath`);
|
|
243
|
+
const fullPath = `${pathFromRoot}${unresolvableEntityPath}`;
|
|
244
|
+
const rootResData = (0, utils_2.getOrThrowError)(walker.resDataByPath, fullPath, `rootFieldWalker.resDataByPath`);
|
|
245
|
+
entityResData.addData(rootResData);
|
|
246
|
+
rootResData.addData(entityResData);
|
|
247
|
+
if (!entityResData.isResolved()) {
|
|
248
|
+
continue;
|
|
249
|
+
}
|
|
250
|
+
subgraphNameByUnresolvablePath.delete(unresolvableEntityPath);
|
|
300
251
|
}
|
|
301
|
-
(0, utils_1.generateResolvabilityErrors)({
|
|
302
|
-
unresolvableFieldPaths: result.unresolvableFieldPaths,
|
|
303
|
-
nodeResolutionDataByFieldPath,
|
|
304
|
-
rootFieldData: rootFieldData,
|
|
305
|
-
errors,
|
|
306
|
-
pathFromRoot,
|
|
307
|
-
entityAncestorData: result.entityAncestorData,
|
|
308
|
-
});
|
|
309
252
|
}
|
|
310
|
-
}
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
253
|
+
validateSharedRootFieldEntities({ rootFieldData, walker }) {
|
|
254
|
+
for (const [pathFromRoot, entityNodeNames] of walker.entityNodeNamesByPath) {
|
|
255
|
+
const subgraphNameByUnresolvablePath = new Map();
|
|
256
|
+
// Shared fields are unique contexts, so the resolution data cannot be reused.
|
|
257
|
+
const resDataByRelativeOriginPath = new Map();
|
|
258
|
+
/* The entity nodes are connected through the root (and not necessarily through a key), so all origins must be
|
|
259
|
+
* explored before an error can be propagated with certainty.
|
|
260
|
+
* */
|
|
261
|
+
for (const entityNodeName of entityNodeNames) {
|
|
262
|
+
this.visitEntity({
|
|
263
|
+
encounteredEntityNodeNames: new Set(),
|
|
264
|
+
entityNodeName,
|
|
265
|
+
resDataByRelativeOriginPath: resDataByRelativeOriginPath,
|
|
266
|
+
subgraphNameByUnresolvablePath,
|
|
267
|
+
visitedEntities: new Set(),
|
|
268
|
+
});
|
|
269
|
+
}
|
|
270
|
+
/* There might be root errors that rely on entity data propagation.
|
|
271
|
+
* Always propagate entity resolution data to the root data before moving on.
|
|
272
|
+
* */
|
|
273
|
+
this.consolidateUnresolvableRootWithEntityPaths({
|
|
274
|
+
pathFromRoot,
|
|
275
|
+
resDataByRelativeOriginPath,
|
|
276
|
+
subgraphNameByUnresolvablePath,
|
|
277
|
+
walker,
|
|
278
|
+
});
|
|
279
|
+
if (subgraphNameByUnresolvablePath.size < 1) {
|
|
280
|
+
continue;
|
|
281
|
+
}
|
|
282
|
+
this.consolidateUnresolvableEntityWithRootPaths({
|
|
283
|
+
pathFromRoot,
|
|
284
|
+
resDataByRelativeOriginPath,
|
|
285
|
+
subgraphNameByUnresolvablePath,
|
|
286
|
+
walker,
|
|
287
|
+
});
|
|
288
|
+
const errors = new Array();
|
|
289
|
+
if (subgraphNameByUnresolvablePath.size > 0) {
|
|
290
|
+
errors.push(...this.getSharedEntityResolvabilityErrors({
|
|
291
|
+
entityNodeNames,
|
|
292
|
+
resDataByPath: resDataByRelativeOriginPath,
|
|
293
|
+
pathFromRoot,
|
|
294
|
+
rootFieldData,
|
|
295
|
+
subgraphNameByUnresolvablePath,
|
|
296
|
+
}));
|
|
297
|
+
}
|
|
298
|
+
if (walker.unresolvablePaths.size > 0) {
|
|
299
|
+
errors.push(...(0, utils_1.generateRootResolvabilityErrors)({
|
|
300
|
+
unresolvablePaths: walker.unresolvablePaths,
|
|
301
|
+
resDataByPath: walker.resDataByPath,
|
|
302
|
+
rootFieldData,
|
|
303
|
+
}));
|
|
304
|
+
}
|
|
305
|
+
if (errors.length < 1) {
|
|
306
|
+
continue;
|
|
307
|
+
}
|
|
308
|
+
return {
|
|
309
|
+
errors,
|
|
310
|
+
success: false,
|
|
311
|
+
};
|
|
312
|
+
}
|
|
313
|
+
if (walker.unresolvablePaths.size > 0) {
|
|
314
|
+
return {
|
|
315
|
+
errors: (0, utils_1.generateRootResolvabilityErrors)({
|
|
316
|
+
resDataByPath: walker.resDataByPath,
|
|
317
|
+
rootFieldData,
|
|
318
|
+
unresolvablePaths: walker.unresolvablePaths,
|
|
319
|
+
}),
|
|
320
|
+
success: false,
|
|
321
|
+
};
|
|
322
|
+
}
|
|
323
|
+
return {
|
|
324
|
+
success: true,
|
|
325
|
+
};
|
|
332
326
|
}
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
return;
|
|
327
|
+
validateRootFieldEntities({ rootFieldData, walker }) {
|
|
328
|
+
for (const [entityNodeName, entityPaths] of walker.pathsByEntityNodeName) {
|
|
329
|
+
const subgraphNameByUnresolvablePath = new Map();
|
|
330
|
+
if (this.resDataByNodeName.has(entityNodeName)) {
|
|
331
|
+
continue;
|
|
339
332
|
}
|
|
340
|
-
|
|
333
|
+
const resDataByRelativeOriginPath = (0, utils_2.getValueOrDefault)(this.resDataByRelativePathByEntity, entityNodeName, () => new Map());
|
|
334
|
+
this.visitEntity({
|
|
335
|
+
encounteredEntityNodeNames: new Set(),
|
|
336
|
+
entityNodeName,
|
|
337
|
+
resDataByRelativeOriginPath: resDataByRelativeOriginPath,
|
|
338
|
+
subgraphNameByUnresolvablePath,
|
|
339
|
+
visitedEntities: (0, utils_2.getValueOrDefault)(this.visitedEntitiesByOriginEntity, entityNodeName, () => new Set()),
|
|
340
|
+
});
|
|
341
|
+
if (subgraphNameByUnresolvablePath.size < 1) {
|
|
341
342
|
continue;
|
|
342
343
|
}
|
|
343
|
-
|
|
344
|
-
|
|
344
|
+
return {
|
|
345
|
+
errors: this.getEntityResolvabilityErrors({
|
|
346
|
+
entityNodeName,
|
|
347
|
+
// Propagate errors for the first encounter only.
|
|
348
|
+
pathFromRoot: (0, utils_2.getFirstEntry)(entityPaths) ?? '',
|
|
349
|
+
rootFieldData,
|
|
350
|
+
subgraphNameByUnresolvablePath,
|
|
351
|
+
}),
|
|
352
|
+
success: false,
|
|
353
|
+
};
|
|
354
|
+
}
|
|
355
|
+
return {
|
|
356
|
+
success: true,
|
|
357
|
+
};
|
|
345
358
|
}
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
return false;
|
|
350
|
-
}
|
|
351
|
-
if (!(0, utils_2.add)(edge.visitedIndices, this.walkerIndex) || edge.node.isLeaf) {
|
|
352
|
-
return true;
|
|
353
|
-
}
|
|
354
|
-
if (edge.node.hasEntitySiblings) {
|
|
355
|
-
(0, utils_2.getValueOrDefault)(this.entityNodeNamesBySharedFieldPath, `${fieldPath}.${edge.edgeName}`, () => new Set()).add(edge.node.nodeName);
|
|
356
|
-
return true;
|
|
357
|
-
}
|
|
358
|
-
if (edge.node.isAbstract) {
|
|
359
|
-
this.validateEntityRelatedAbstractNode(edge.node, `${fieldPath}.${edge.edgeName}`);
|
|
359
|
+
validateEntities(params) {
|
|
360
|
+
if (params.isSharedRootField) {
|
|
361
|
+
return this.validateSharedRootFieldEntities(params);
|
|
360
362
|
}
|
|
361
|
-
|
|
362
|
-
this.validateEntityRelatedConcreteNode(edge.node, `${fieldPath}.${edge.edgeName}`);
|
|
363
|
-
}
|
|
364
|
-
return true;
|
|
363
|
+
return this.validateRootFieldEntities(params);
|
|
365
364
|
}
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
}
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
}
|
|
381
|
-
if (originResolvedFieldNames.isResolved) {
|
|
382
|
-
this.unresolvableFieldPaths.delete(fieldPath);
|
|
383
|
-
}
|
|
384
|
-
else {
|
|
385
|
-
this.unresolvableFieldPaths.add(fieldPath);
|
|
386
|
-
}
|
|
387
|
-
if (!sharedResolvedFieldNames) {
|
|
388
|
-
return;
|
|
389
|
-
}
|
|
390
|
-
if (sharedResolvedFieldNames.isResolved) {
|
|
391
|
-
this.unresolvableSharedFieldPaths.delete(fieldPath);
|
|
392
|
-
}
|
|
393
|
-
else {
|
|
394
|
-
this.unresolvableSharedFieldPaths.add(fieldPath);
|
|
395
|
-
}
|
|
365
|
+
getEntityResolvabilityErrors({ entityNodeName, pathFromRoot, rootFieldData, subgraphNameByUnresolvablePath, }) {
|
|
366
|
+
const nodeResolutionDataByFieldPath = (0, utils_2.getOrThrowError)(this.resDataByRelativePathByEntity, entityNodeName, 'resDataByRelativePathByEntity');
|
|
367
|
+
const entityTypeName = entityNodeName.split(string_constants_1.LITERAL_PERIOD)[1];
|
|
368
|
+
const { fieldSetsByTargetSubgraphName } = (0, utils_2.getOrThrowError)(this.entityDataNodeByTypeName, entityTypeName, 'entityDataNodeByTypeName');
|
|
369
|
+
return (0, utils_1.generateEntityResolvabilityErrors)({
|
|
370
|
+
entityAncestorData: {
|
|
371
|
+
fieldSetsByTargetSubgraphName,
|
|
372
|
+
subgraphName: '',
|
|
373
|
+
typeName: entityTypeName,
|
|
374
|
+
},
|
|
375
|
+
pathFromRoot,
|
|
376
|
+
resDataByPath: nodeResolutionDataByFieldPath,
|
|
377
|
+
rootFieldData: rootFieldData,
|
|
378
|
+
subgraphNameByUnresolvablePath,
|
|
379
|
+
});
|
|
396
380
|
}
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
381
|
+
getSharedEntityResolvabilityErrors({ entityNodeNames, pathFromRoot, rootFieldData, resDataByPath, subgraphNameByUnresolvablePath, }) {
|
|
382
|
+
let entityTypeName = undefined;
|
|
383
|
+
const subgraphNames = new Array();
|
|
384
|
+
for (const entityNodeName of entityNodeNames) {
|
|
385
|
+
const segments = entityNodeName.split(string_constants_1.LITERAL_PERIOD);
|
|
386
|
+
entityTypeName ??= segments[1];
|
|
387
|
+
subgraphNames.push(segments[0]);
|
|
388
|
+
}
|
|
389
|
+
const { fieldSetsByTargetSubgraphName } = (0, utils_2.getOrThrowError)(this.entityDataNodeByTypeName, entityTypeName, 'entityDataNodeByTypeName');
|
|
390
|
+
return (0, utils_1.generateSharedEntityResolvabilityErrors)({
|
|
391
|
+
entityAncestors: {
|
|
392
|
+
fieldSetsByTargetSubgraphName,
|
|
393
|
+
subgraphNames,
|
|
394
|
+
typeName: entityTypeName,
|
|
395
|
+
},
|
|
396
|
+
pathFromRoot,
|
|
397
|
+
resDataByPath,
|
|
398
|
+
rootFieldData: rootFieldData,
|
|
399
|
+
subgraphNameByUnresolvablePath,
|
|
400
|
+
});
|
|
404
401
|
}
|
|
405
402
|
}
|
|
403
|
+
exports.Graph = Graph;
|
|
406
404
|
//# sourceMappingURL=graph.js.map
|