@wundergraph/composition 0.17.1 → 0.18.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/ast/ast.d.ts +2 -9
- package/dist/ast/ast.js +4 -32
- package/dist/ast/ast.js.map +1 -1
- package/dist/ast/utils.d.ts +1 -2
- package/dist/ast/utils.js.map +1 -1
- package/dist/errors/errors.d.ts +8 -12
- package/dist/errors/errors.js +27 -29
- package/dist/errors/errors.js.map +1 -1
- package/dist/federation/federation-factory.d.ts +7 -6
- package/dist/federation/federation-factory.js +38 -20
- package/dist/federation/federation-factory.js.map +1 -1
- package/dist/federation/utils.d.ts +4 -4
- package/dist/federation/utils.js +2 -2
- package/dist/federation/utils.js.map +1 -1
- package/dist/index.d.ts +8 -1
- package/dist/index.js +8 -1
- package/dist/index.js.map +1 -1
- package/dist/normalization/normalization-factory.d.ts +24 -27
- package/dist/normalization/normalization-factory.js +256 -961
- package/dist/normalization/normalization-factory.js.map +1 -1
- package/dist/normalization/utils.d.ts +6 -126
- package/dist/normalization/utils.js +71 -166
- package/dist/normalization/utils.js.map +1 -1
- package/dist/normalization/walkers.d.ts +5 -0
- package/dist/normalization/walkers.js +593 -0
- package/dist/normalization/walkers.js.map +1 -0
- package/dist/schema-building/ast.d.ts +104 -0
- package/dist/schema-building/ast.js +156 -0
- package/dist/schema-building/ast.js.map +1 -0
- package/dist/schema-building/type-definition-data.d.ts +108 -0
- package/dist/schema-building/type-definition-data.js +3 -0
- package/dist/schema-building/type-definition-data.js.map +1 -0
- package/dist/schema-building/type-extension-data.d.ts +45 -0
- package/dist/schema-building/type-extension-data.js +3 -0
- package/dist/schema-building/type-extension-data.js.map +1 -0
- package/dist/{type-merging → schema-building}/type-merging.js +5 -4
- package/dist/schema-building/type-merging.js.map +1 -0
- package/dist/schema-building/utils.d.ts +42 -0
- package/dist/schema-building/utils.js +600 -0
- package/dist/schema-building/utils.js.map +1 -0
- package/dist/subgraph/subgraph.d.ts +4 -5
- package/dist/subgraph/subgraph.js +2 -65
- package/dist/subgraph/subgraph.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/utils/constants.d.ts +4 -2
- package/dist/utils/constants.js +383 -359
- package/dist/utils/constants.js.map +1 -1
- package/dist/utils/string-constants.d.ts +4 -0
- package/dist/utils/string-constants.js +6 -2
- package/dist/utils/string-constants.js.map +1 -1
- package/dist/utils/utils.d.ts +8 -6
- package/dist/utils/utils.js +72 -30
- package/dist/utils/utils.js.map +1 -1
- package/package.json +2 -2
- package/dist/type-merging/type-merging.js.map +0 -1
- /package/dist/{type-merging → schema-building}/type-merging.d.ts +0 -0
|
@@ -5,7 +5,7 @@ const graphql_1 = require("graphql");
|
|
|
5
5
|
const utils_1 = require("../ast/utils");
|
|
6
6
|
const utils_2 = require("./utils");
|
|
7
7
|
const constants_1 = require("../utils/constants");
|
|
8
|
-
const type_merging_1 = require("../
|
|
8
|
+
const type_merging_1 = require("../schema-building/type-merging");
|
|
9
9
|
const utils_3 = require("../utils/utils");
|
|
10
10
|
const errors_1 = require("../errors/errors");
|
|
11
11
|
const string_constants_1 = require("../utils/string-constants");
|
|
@@ -14,6 +14,8 @@ const merge_1 = require("@graphql-tools/merge");
|
|
|
14
14
|
const ast_1 = require("../ast/ast");
|
|
15
15
|
const subgraph_1 = require("../subgraph/subgraph");
|
|
16
16
|
const warnings_1 = require("../warnings/warnings");
|
|
17
|
+
const walkers_1 = require("./walkers");
|
|
18
|
+
const utils_4 = require("../schema-building/utils");
|
|
17
19
|
function normalizeSubgraphFromString(subgraphSDL) {
|
|
18
20
|
const { error, documentNode } = (0, utils_1.safeParse)(subgraphSDL);
|
|
19
21
|
if (error || !documentNode) {
|
|
@@ -30,7 +32,7 @@ function normalizeSubgraph(document, subgraphName) {
|
|
|
30
32
|
exports.normalizeSubgraph = normalizeSubgraph;
|
|
31
33
|
class NormalizationFactory {
|
|
32
34
|
abstractToConcreteTypeNames = new Map();
|
|
33
|
-
|
|
35
|
+
directiveDefinitionByDirectiveName = new Map();
|
|
34
36
|
argumentName = '';
|
|
35
37
|
authorizationDataByParentTypeName = new Map();
|
|
36
38
|
childName = '';
|
|
@@ -39,36 +41,38 @@ class NormalizationFactory {
|
|
|
39
41
|
errors = [];
|
|
40
42
|
entityContainerByTypeName = new Map();
|
|
41
43
|
entityInterfaces = new Map();
|
|
42
|
-
|
|
44
|
+
parentExtensionDataByTypeName = new Map();
|
|
45
|
+
interfaceTypeNamesWithAuthorizationDirectives = new Set();
|
|
43
46
|
isCurrentParentExtension = false;
|
|
44
|
-
isCurrentParentRootType = false;
|
|
45
47
|
isSubgraphVersionTwo = false;
|
|
46
48
|
fieldSetContainerByTypeName = new Map();
|
|
49
|
+
heirFieldAuthorizationDataByTypeName = new Map();
|
|
47
50
|
handledRepeatedDirectivesByHostPath = new Map();
|
|
48
51
|
lastParentNodeKind = graphql_1.Kind.NULL;
|
|
49
52
|
lastChildNodeKind = graphql_1.Kind.NULL;
|
|
50
53
|
leafTypeNamesWithAuthorizationDirectives = new Set();
|
|
51
54
|
keyFieldNamesByParentTypeName = new Map();
|
|
52
55
|
operationTypeNames = new Map();
|
|
53
|
-
|
|
56
|
+
parentDefinitionDataByTypeName = new Map();
|
|
54
57
|
parentTypeName = '';
|
|
55
58
|
parentsWithChildArguments = new Set();
|
|
56
59
|
eventsConfigurations = new Map();
|
|
57
60
|
overridesByTargetSubgraphName = new Map();
|
|
61
|
+
invalidOrScopesHostPaths = new Set();
|
|
58
62
|
schemaDefinition;
|
|
59
|
-
|
|
63
|
+
referencedDirectiveNames = new Set();
|
|
60
64
|
referencedTypeNames = new Set();
|
|
61
65
|
warnings = [];
|
|
62
66
|
subgraphName;
|
|
63
67
|
constructor(subgraphName) {
|
|
64
|
-
for (const baseDirectiveDefinition of constants_1.
|
|
65
|
-
this.
|
|
68
|
+
for (const [baseDirectiveName, baseDirectiveDefinition] of constants_1.BASE_DIRECTIVE_DEFINITION_BY_DIRECTIVE_NAME) {
|
|
69
|
+
this.directiveDefinitionByDirectiveName.set(baseDirectiveName, baseDirectiveDefinition);
|
|
66
70
|
}
|
|
67
71
|
this.subgraphName = subgraphName;
|
|
68
72
|
this.schemaDefinition = {
|
|
69
|
-
|
|
73
|
+
directivesByDirectiveName: new Map(),
|
|
70
74
|
kind: graphql_1.Kind.SCHEMA_DEFINITION,
|
|
71
|
-
|
|
75
|
+
typeName: string_constants_1.SCHEMA,
|
|
72
76
|
operationTypes: new Map(),
|
|
73
77
|
};
|
|
74
78
|
}
|
|
@@ -76,7 +80,7 @@ class NormalizationFactory {
|
|
|
76
80
|
if (constants_1.BASE_SCALARS.has(namedType)) {
|
|
77
81
|
return { hasUnhandledError: false, typeString: '' };
|
|
78
82
|
}
|
|
79
|
-
const parentContainer = this.
|
|
83
|
+
const parentContainer = this.parentDefinitionDataByTypeName.get(namedType);
|
|
80
84
|
if (!parentContainer) {
|
|
81
85
|
this.errors.push((0, errors_1.undefinedTypeError)(namedType));
|
|
82
86
|
return { hasUnhandledError: false, typeString: '' };
|
|
@@ -90,28 +94,28 @@ class NormalizationFactory {
|
|
|
90
94
|
return { hasUnhandledError: true, typeString: (0, utils_3.kindToTypeString)(parentContainer.kind) };
|
|
91
95
|
}
|
|
92
96
|
}
|
|
93
|
-
extractArguments(node,
|
|
97
|
+
extractArguments(node, argumentDataByArgumentName, fieldPath) {
|
|
94
98
|
if (!node.arguments) {
|
|
95
|
-
return
|
|
99
|
+
return argumentDataByArgumentName;
|
|
96
100
|
}
|
|
97
101
|
this.parentsWithChildArguments.add(this.parentTypeName);
|
|
98
102
|
const duplicatedArguments = new Set();
|
|
99
103
|
for (const argumentNode of node.arguments) {
|
|
100
104
|
const argumentName = argumentNode.name.value;
|
|
101
|
-
if (
|
|
105
|
+
if (argumentDataByArgumentName.has(argumentName)) {
|
|
102
106
|
duplicatedArguments.add(argumentName);
|
|
103
107
|
continue;
|
|
104
108
|
}
|
|
105
|
-
|
|
109
|
+
argumentDataByArgumentName.set(argumentName, (0, ast_1.inputValueDefinitionNodeToMutable)(argumentNode, this.parentTypeName));
|
|
106
110
|
}
|
|
107
111
|
if (duplicatedArguments.size > 0) {
|
|
108
112
|
this.errors.push((0, errors_1.duplicateArgumentsError)(fieldPath, [...duplicatedArguments]));
|
|
109
113
|
}
|
|
110
|
-
return
|
|
114
|
+
return argumentDataByArgumentName;
|
|
111
115
|
}
|
|
112
|
-
validateArguments(
|
|
116
|
+
validateArguments(fieldData, fieldPath) {
|
|
113
117
|
const invalidArguments = [];
|
|
114
|
-
for (const [argumentName, argumentNode] of
|
|
118
|
+
for (const [argumentName, argumentNode] of fieldData.argumentDataByArgumentName) {
|
|
115
119
|
const namedType = (0, type_merging_1.getNamedTypeForChild)(fieldPath + `(${argumentName}...)`, argumentNode.type);
|
|
116
120
|
const { hasUnhandledError, typeString } = this.validateInputNamedType(namedType);
|
|
117
121
|
if (hasUnhandledError) {
|
|
@@ -122,51 +126,118 @@ class NormalizationFactory {
|
|
|
122
126
|
this.errors.push((0, errors_1.invalidArgumentsError)(fieldPath, invalidArguments));
|
|
123
127
|
}
|
|
124
128
|
}
|
|
125
|
-
|
|
129
|
+
// Note that directive validation errors are handled elsewhere
|
|
130
|
+
getAuthorizationData(node) {
|
|
131
|
+
let authorizationData = this.authorizationDataByParentTypeName.get(this.parentTypeName);
|
|
132
|
+
(0, utils_3.resetAuthorizationData)(authorizationData);
|
|
126
133
|
if (!node.directives) {
|
|
127
|
-
return
|
|
134
|
+
return authorizationData;
|
|
128
135
|
}
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
136
|
+
let requiresAuthentication = false;
|
|
137
|
+
const requiresScopes = [];
|
|
138
|
+
for (const directiveNode of node.directives) {
|
|
139
|
+
const directiveName = directiveNode.name.value;
|
|
140
|
+
if (directiveName === string_constants_1.AUTHENTICATED) {
|
|
141
|
+
// @authenticated is not repeatable
|
|
142
|
+
if (requiresAuthentication) {
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
145
|
+
requiresAuthentication = true;
|
|
132
146
|
continue;
|
|
133
147
|
}
|
|
134
|
-
|
|
135
|
-
if (existingDirectives) {
|
|
136
|
-
existingDirectives.push(directive);
|
|
148
|
+
if (directiveName !== string_constants_1.REQUIRES_SCOPES) {
|
|
137
149
|
continue;
|
|
138
150
|
}
|
|
139
|
-
|
|
151
|
+
// @requiresScopes is not repeatable
|
|
152
|
+
if (requiresScopes.length > 0) {
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
155
|
+
requiresScopes.push(directiveNode);
|
|
140
156
|
}
|
|
141
|
-
|
|
157
|
+
if (!requiresAuthentication && requiresScopes.length < 1) {
|
|
158
|
+
return authorizationData;
|
|
159
|
+
}
|
|
160
|
+
if ((0, utils_3.isNodeKindInterface)(node.kind)) {
|
|
161
|
+
this.interfaceTypeNamesWithAuthorizationDirectives.add(this.parentTypeName);
|
|
162
|
+
}
|
|
163
|
+
if (!authorizationData) {
|
|
164
|
+
authorizationData = (0, utils_3.setAndGetValue)(this.authorizationDataByParentTypeName, this.parentTypeName, (0, utils_3.newAuthorizationData)(this.parentTypeName));
|
|
165
|
+
}
|
|
166
|
+
authorizationData.hasParentLevelAuthorization = true;
|
|
167
|
+
authorizationData.requiresAuthentication = requiresAuthentication;
|
|
168
|
+
if (requiresScopes.length !== 1) {
|
|
169
|
+
return authorizationData;
|
|
170
|
+
}
|
|
171
|
+
const directiveNode = requiresScopes[0];
|
|
172
|
+
if (!directiveNode.arguments || directiveNode.arguments.length !== 1) {
|
|
173
|
+
return;
|
|
174
|
+
}
|
|
175
|
+
const scopesArgument = directiveNode.arguments[0];
|
|
176
|
+
if (scopesArgument.name.value !== string_constants_1.SCOPES || scopesArgument.value.kind !== graphql_1.Kind.LIST) {
|
|
177
|
+
return;
|
|
178
|
+
}
|
|
179
|
+
const orScopes = scopesArgument.value.values;
|
|
180
|
+
if (orScopes.length < 1) {
|
|
181
|
+
return authorizationData;
|
|
182
|
+
}
|
|
183
|
+
if (orScopes.length > utils_3.maxOrScopes) {
|
|
184
|
+
this.invalidOrScopesHostPaths.add(this.parentTypeName);
|
|
185
|
+
return;
|
|
186
|
+
}
|
|
187
|
+
for (const scopes of orScopes) {
|
|
188
|
+
if (scopes.kind !== graphql_1.Kind.LIST) {
|
|
189
|
+
return;
|
|
190
|
+
}
|
|
191
|
+
const andScopes = new Set();
|
|
192
|
+
for (const scope of scopes.values) {
|
|
193
|
+
if (scope.kind !== graphql_1.Kind.STRING) {
|
|
194
|
+
return;
|
|
195
|
+
}
|
|
196
|
+
andScopes.add(scope.value);
|
|
197
|
+
}
|
|
198
|
+
if (andScopes.size) {
|
|
199
|
+
authorizationData.requiredScopes.push(andScopes);
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
return authorizationData;
|
|
142
203
|
}
|
|
143
|
-
extractDirectivesAndAuthorization(node,
|
|
204
|
+
extractDirectivesAndAuthorization(node, directivesByDirectiveName) {
|
|
144
205
|
if (!node.directives) {
|
|
145
|
-
return
|
|
206
|
+
return directivesByDirectiveName;
|
|
146
207
|
}
|
|
208
|
+
const hostPath = this.childName ? `${this.parentTypeName}.${this.childName}` : this.parentTypeName;
|
|
147
209
|
const authorizationDirectives = [];
|
|
148
|
-
for (const
|
|
149
|
-
const
|
|
210
|
+
for (const directiveNode of node.directives) {
|
|
211
|
+
const errorMessages = (0, utils_4.getDirectiveValidationErrors)(directiveNode, node.kind, directivesByDirectiveName, this.directiveDefinitionByDirectiveName, this.handledRepeatedDirectivesByHostPath, hostPath);
|
|
212
|
+
const directiveName = directiveNode.name.value;
|
|
213
|
+
if (errorMessages.length > 0) {
|
|
214
|
+
this.errors.push((0, errors_1.invalidDirectiveError)(directiveName, hostPath, errorMessages));
|
|
215
|
+
continue;
|
|
216
|
+
}
|
|
150
217
|
if (directiveName === string_constants_1.EXTENDS) {
|
|
151
218
|
continue;
|
|
152
219
|
}
|
|
220
|
+
if (directiveName === string_constants_1.OVERRIDE) {
|
|
221
|
+
this.handleOverrideDeclaration(directiveNode, hostPath, errorMessages);
|
|
222
|
+
if (errorMessages.length > 0) {
|
|
223
|
+
this.errors.push((0, errors_1.invalidDirectiveError)(directiveName, hostPath, errorMessages));
|
|
224
|
+
}
|
|
225
|
+
continue;
|
|
226
|
+
}
|
|
153
227
|
if (directiveName === string_constants_1.AUTHENTICATED || directiveName === string_constants_1.REQUIRES_SCOPES) {
|
|
154
|
-
authorizationDirectives.push(
|
|
228
|
+
authorizationDirectives.push(directiveNode);
|
|
229
|
+
continue;
|
|
155
230
|
}
|
|
156
|
-
const existingDirectives =
|
|
231
|
+
const existingDirectives = directivesByDirectiveName.get(directiveName);
|
|
157
232
|
if (existingDirectives) {
|
|
158
|
-
existingDirectives.push(
|
|
159
|
-
continue;
|
|
233
|
+
existingDirectives.push(directiveNode);
|
|
160
234
|
}
|
|
161
|
-
|
|
235
|
+
directivesByDirectiveName.set(directiveName, [directiveNode]);
|
|
162
236
|
}
|
|
163
237
|
if (authorizationDirectives.length < 1) {
|
|
164
|
-
return
|
|
238
|
+
return directivesByDirectiveName;
|
|
165
239
|
}
|
|
166
|
-
if (node.kind
|
|
167
|
-
node.kind === graphql_1.Kind.ENUM_TYPE_EXTENSION ||
|
|
168
|
-
node.kind === graphql_1.Kind.SCALAR_TYPE_DEFINITION ||
|
|
169
|
-
node.kind === graphql_1.Kind.SCALAR_TYPE_EXTENSION) {
|
|
240
|
+
if (node.kind !== graphql_1.Kind.FIELD_DEFINITION) {
|
|
170
241
|
this.leafTypeNamesWithAuthorizationDirectives.add(this.parentTypeName);
|
|
171
242
|
}
|
|
172
243
|
const parentAuthorizationData = (0, utils_3.getValueOrDefault)(this.authorizationDataByParentTypeName, this.parentTypeName, () => (0, utils_3.newAuthorizationData)(this.parentTypeName));
|
|
@@ -177,29 +248,14 @@ class NormalizationFactory {
|
|
|
177
248
|
authorizationData.requiresAuthentication = true;
|
|
178
249
|
continue;
|
|
179
250
|
}
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
const scopesArgument = directiveNode.arguments[0];
|
|
184
|
-
if (scopesArgument.name.value !== string_constants_1.SCOPES) {
|
|
185
|
-
break;
|
|
186
|
-
}
|
|
187
|
-
if (scopesArgument.value.kind !== graphql_1.Kind.LIST) {
|
|
188
|
-
break;
|
|
189
|
-
}
|
|
190
|
-
const orScopes = scopesArgument.value.values;
|
|
191
|
-
if (orScopes.length < 1) {
|
|
251
|
+
const orScopes = directiveNode.arguments[0].value.values;
|
|
252
|
+
if (orScopes.length > utils_3.maxOrScopes) {
|
|
253
|
+
this.invalidOrScopesHostPaths.add(hostPath);
|
|
192
254
|
continue;
|
|
193
255
|
}
|
|
194
256
|
for (const scopes of orScopes) {
|
|
195
|
-
if (scopes.kind !== graphql_1.Kind.LIST) {
|
|
196
|
-
return map;
|
|
197
|
-
}
|
|
198
257
|
const andScopes = new Set();
|
|
199
258
|
for (const scope of scopes.values) {
|
|
200
|
-
if (scope.kind !== graphql_1.Kind.STRING) {
|
|
201
|
-
return map;
|
|
202
|
-
}
|
|
203
259
|
andScopes.add(scope.value);
|
|
204
260
|
}
|
|
205
261
|
if (andScopes.size) {
|
|
@@ -207,21 +263,7 @@ class NormalizationFactory {
|
|
|
207
263
|
}
|
|
208
264
|
}
|
|
209
265
|
}
|
|
210
|
-
return
|
|
211
|
-
}
|
|
212
|
-
extractUniqueUnionMembers(members, map) {
|
|
213
|
-
for (const member of members) {
|
|
214
|
-
const name = member.name.value;
|
|
215
|
-
if (map.has(name)) {
|
|
216
|
-
this.errors.push(new Error(`Member "${name} can only be defined on union "${this.parentTypeName}" once.`));
|
|
217
|
-
continue;
|
|
218
|
-
}
|
|
219
|
-
if (!constants_1.BASE_SCALARS.has(name)) {
|
|
220
|
-
this.referencedTypeNames.add(name);
|
|
221
|
-
}
|
|
222
|
-
map.set(name, member);
|
|
223
|
-
}
|
|
224
|
-
return map;
|
|
266
|
+
return directivesByDirectiveName;
|
|
225
267
|
}
|
|
226
268
|
mergeUniqueInterfaces(extensionInterfaces, interfaces, typeName) {
|
|
227
269
|
for (const interfaceName of extensionInterfaces) {
|
|
@@ -232,109 +274,6 @@ class NormalizationFactory {
|
|
|
232
274
|
this.errors.push((0, errors_1.duplicateInterfaceExtensionError)(interfaceName, typeName));
|
|
233
275
|
}
|
|
234
276
|
}
|
|
235
|
-
mergeUniqueUnionMembers(baseUnion, extensionUnion) {
|
|
236
|
-
if (!extensionUnion) {
|
|
237
|
-
return;
|
|
238
|
-
}
|
|
239
|
-
const extensionMembers = extensionUnion.types;
|
|
240
|
-
const members = baseUnion.types;
|
|
241
|
-
const typeName = baseUnion.name.value;
|
|
242
|
-
for (const [memberName, namedTypeNode] of extensionMembers) {
|
|
243
|
-
if (!members.has(memberName)) {
|
|
244
|
-
members.set(memberName, namedTypeNode);
|
|
245
|
-
continue;
|
|
246
|
-
}
|
|
247
|
-
this.errors.push((0, errors_1.duplicateUnionMemberError)(memberName, typeName));
|
|
248
|
-
}
|
|
249
|
-
}
|
|
250
|
-
mergeDirectives(baseTypeDirectives, extension) {
|
|
251
|
-
if (!extension) {
|
|
252
|
-
return;
|
|
253
|
-
}
|
|
254
|
-
for (const [directiveName, directives] of extension.directives) {
|
|
255
|
-
const existingDirectives = baseTypeDirectives.get(directiveName);
|
|
256
|
-
if (existingDirectives) {
|
|
257
|
-
existingDirectives.push(...directives);
|
|
258
|
-
continue;
|
|
259
|
-
}
|
|
260
|
-
baseTypeDirectives.set(directiveName, [...directives]);
|
|
261
|
-
}
|
|
262
|
-
}
|
|
263
|
-
getValidatedAndNormalizedParentDirectives(parent) {
|
|
264
|
-
const parentTypeName = parent.name.value;
|
|
265
|
-
const normalizedDirectives = [];
|
|
266
|
-
for (const [directiveName, directives] of parent.directives) {
|
|
267
|
-
const definition = this.allDirectiveDefinitions.get(directiveName);
|
|
268
|
-
if (!definition) {
|
|
269
|
-
this.errors.push((0, errors_1.undefinedDirectiveError)(directiveName, parentTypeName));
|
|
270
|
-
continue;
|
|
271
|
-
}
|
|
272
|
-
const allArguments = new Set();
|
|
273
|
-
const requiredArguments = new Set();
|
|
274
|
-
(0, utils_2.getDirectiveDefinitionArgumentSets)(definition.arguments || [], allArguments, requiredArguments);
|
|
275
|
-
const entityKeys = new Set();
|
|
276
|
-
const errorMessages = [];
|
|
277
|
-
for (const directive of directives) {
|
|
278
|
-
if (!(0, utils_2.areNodeKindAndDirectiveLocationCompatible)(parent.kind, definition)) {
|
|
279
|
-
errorMessages.push((0, errors_1.invalidDirectiveLocationErrorMessage)(parentTypeName, parent.kind, directiveName));
|
|
280
|
-
}
|
|
281
|
-
if (!definition.repeatable && directives.length > 1) {
|
|
282
|
-
errorMessages.push((0, errors_1.invalidRepeatedDirectiveErrorMessage)(directiveName, parentTypeName));
|
|
283
|
-
}
|
|
284
|
-
if (!definition.arguments || definition.arguments.length < 1) {
|
|
285
|
-
if (directive.arguments && directive.arguments.length > 0) {
|
|
286
|
-
errorMessages.push((0, errors_1.unexpectedDirectiveArgumentsErrorMessage)(directive, parentTypeName));
|
|
287
|
-
}
|
|
288
|
-
else {
|
|
289
|
-
normalizedDirectives.push(directive);
|
|
290
|
-
}
|
|
291
|
-
continue;
|
|
292
|
-
}
|
|
293
|
-
if (!directive.arguments || directive.arguments.length < 1) {
|
|
294
|
-
if (requiredArguments.size > 0) {
|
|
295
|
-
errorMessages.push((0, errors_1.undefinedRequiredArgumentsErrorMessage)(directiveName, parentTypeName, [...requiredArguments]));
|
|
296
|
-
}
|
|
297
|
-
else {
|
|
298
|
-
normalizedDirectives.push(directive);
|
|
299
|
-
}
|
|
300
|
-
continue;
|
|
301
|
-
}
|
|
302
|
-
const definedArguments = (0, utils_2.getDefinedArgumentsForDirective)(directive.arguments, allArguments, directiveName, parentTypeName, errorMessages);
|
|
303
|
-
const missingRequiredArguments = (0, utils_3.getEntriesNotInHashSet)(requiredArguments, definedArguments);
|
|
304
|
-
if (missingRequiredArguments.length > 0) {
|
|
305
|
-
errorMessages.push((0, errors_1.undefinedRequiredArgumentsErrorMessage)(directiveName, parentTypeName, [...requiredArguments], missingRequiredArguments));
|
|
306
|
-
}
|
|
307
|
-
// Only add unique entity keys
|
|
308
|
-
if (directiveName === string_constants_1.KEY) {
|
|
309
|
-
const directiveKind = directive.arguments[0].value.kind;
|
|
310
|
-
if (directiveKind !== graphql_1.Kind.STRING) {
|
|
311
|
-
errorMessages.push((0, errors_1.invalidKeyDirectiveArgumentErrorMessage)(directiveKind));
|
|
312
|
-
continue;
|
|
313
|
-
}
|
|
314
|
-
const entityKey = directive.arguments[0].value.value;
|
|
315
|
-
if (entityKeys.has(entityKey)) {
|
|
316
|
-
continue;
|
|
317
|
-
}
|
|
318
|
-
entityKeys.add(entityKey);
|
|
319
|
-
}
|
|
320
|
-
normalizedDirectives.push(directive);
|
|
321
|
-
}
|
|
322
|
-
if (errorMessages.length > 0) {
|
|
323
|
-
this.errors.push((0, errors_1.invalidDirectiveError)(directiveName, parentTypeName, errorMessages));
|
|
324
|
-
}
|
|
325
|
-
}
|
|
326
|
-
return normalizedDirectives;
|
|
327
|
-
}
|
|
328
|
-
convertKindForExtension(node) {
|
|
329
|
-
switch (node.kind) {
|
|
330
|
-
case graphql_1.Kind.INTERFACE_TYPE_DEFINITION:
|
|
331
|
-
return graphql_1.Kind.INTERFACE_TYPE_EXTENSION;
|
|
332
|
-
case graphql_1.Kind.OBJECT_TYPE_DEFINITION:
|
|
333
|
-
return graphql_1.Kind.OBJECT_TYPE_EXTENSION;
|
|
334
|
-
default:
|
|
335
|
-
return node.kind;
|
|
336
|
-
}
|
|
337
|
-
}
|
|
338
277
|
handleInterfaceObject(node) {
|
|
339
278
|
if (!(0, utils_1.isNodeInterfaceObject)(node)) {
|
|
340
279
|
return;
|
|
@@ -351,28 +290,22 @@ class NormalizationFactory {
|
|
|
351
290
|
typeName: name,
|
|
352
291
|
});
|
|
353
292
|
}
|
|
354
|
-
|
|
293
|
+
handleExtensionWithFields(node) {
|
|
355
294
|
this.isCurrentParentExtension = true;
|
|
356
|
-
const extension = this.
|
|
357
|
-
const convertedKind =
|
|
295
|
+
const extension = this.parentExtensionDataByTypeName.get(this.parentTypeName);
|
|
296
|
+
const convertedKind = (0, utils_4.convertKindForExtension)(node);
|
|
358
297
|
if (extension) {
|
|
359
298
|
if (extension.kind !== convertedKind) {
|
|
360
299
|
this.errors.push((0, errors_1.incompatibleExtensionKindsError)(node, extension.kind));
|
|
361
300
|
return false;
|
|
362
301
|
}
|
|
363
|
-
|
|
364
|
-
(0, utils_1.extractInterfaces)(node, extension.
|
|
302
|
+
(0, utils_4.extractDirectives)(node, extension.directivesByDirectiveName, this.errors, this.directiveDefinitionByDirectiveName, this.handledRepeatedDirectivesByHostPath, this.parentTypeName);
|
|
303
|
+
(0, utils_1.extractInterfaces)(node, extension.implementedInterfaceTypeNames, this.errors);
|
|
365
304
|
return;
|
|
366
305
|
}
|
|
367
306
|
const isEntity = (0, utils_1.isObjectLikeNodeEntity)(node);
|
|
368
|
-
this.
|
|
369
|
-
|
|
370
|
-
fields: new Map(),
|
|
371
|
-
interfaces: (0, utils_1.extractInterfaces)(node, new Set(), this.errors),
|
|
372
|
-
isEntity,
|
|
373
|
-
kind: convertedKind,
|
|
374
|
-
name: node.name,
|
|
375
|
-
});
|
|
307
|
+
(0, utils_4.upsertExtensionWithFieldsDataByNode)(this.parentExtensionDataByTypeName, node, this.errors, this.directiveDefinitionByDirectiveName, this.handledRepeatedDirectivesByHostPath, isEntity);
|
|
308
|
+
// TODO re-assess this line
|
|
376
309
|
if (node.kind === graphql_1.Kind.INTERFACE_TYPE_DEFINITION || node.kind === graphql_1.Kind.INTERFACE_TYPE_EXTENSION || !isEntity) {
|
|
377
310
|
return;
|
|
378
311
|
}
|
|
@@ -384,48 +317,6 @@ class NormalizationFactory {
|
|
|
384
317
|
...(this.subgraphName ? { subgraphNames: [this.subgraphName] } : {}),
|
|
385
318
|
});
|
|
386
319
|
}
|
|
387
|
-
validateChildDirectives(child, hostPath) {
|
|
388
|
-
const childKind = child.node.kind;
|
|
389
|
-
for (const [directiveName, directives] of child.directives) {
|
|
390
|
-
const definition = this.allDirectiveDefinitions.get(directiveName);
|
|
391
|
-
if (!definition) {
|
|
392
|
-
this.errors.push((0, errors_1.undefinedDirectiveError)(directiveName, hostPath));
|
|
393
|
-
continue;
|
|
394
|
-
}
|
|
395
|
-
const allArguments = new Set();
|
|
396
|
-
const requiredArguments = new Set();
|
|
397
|
-
(0, utils_2.getDirectiveDefinitionArgumentSets)(definition.arguments || [], allArguments, requiredArguments);
|
|
398
|
-
const errorMessages = [];
|
|
399
|
-
for (const directive of directives) {
|
|
400
|
-
if (!(0, utils_2.areNodeKindAndDirectiveLocationCompatible)(childKind, definition)) {
|
|
401
|
-
errorMessages.push((0, errors_1.invalidDirectiveLocationErrorMessage)(hostPath, childKind, directiveName));
|
|
402
|
-
}
|
|
403
|
-
if (!definition.repeatable && directives.length > 1) {
|
|
404
|
-
errorMessages.push((0, errors_1.invalidRepeatedDirectiveErrorMessage)(directiveName, hostPath));
|
|
405
|
-
}
|
|
406
|
-
if (!definition.arguments || definition.arguments.length < 1) {
|
|
407
|
-
if (directive.arguments && directive.arguments.length > 0) {
|
|
408
|
-
errorMessages.push((0, errors_1.unexpectedDirectiveArgumentsErrorMessage)(directive, hostPath));
|
|
409
|
-
}
|
|
410
|
-
continue;
|
|
411
|
-
}
|
|
412
|
-
if (!directive.arguments || directive.arguments.length < 1) {
|
|
413
|
-
if (requiredArguments.size > 0) {
|
|
414
|
-
errorMessages.push((0, errors_1.undefinedRequiredArgumentsErrorMessage)(directiveName, hostPath, [...requiredArguments]));
|
|
415
|
-
}
|
|
416
|
-
continue;
|
|
417
|
-
}
|
|
418
|
-
const definedArguments = (0, utils_2.getDefinedArgumentsForDirective)(directive.arguments, allArguments, directiveName, hostPath, errorMessages);
|
|
419
|
-
const missingRequiredArguments = (0, utils_3.getEntriesNotInHashSet)(requiredArguments, definedArguments);
|
|
420
|
-
if (missingRequiredArguments.length > 0) {
|
|
421
|
-
errorMessages.push((0, errors_1.undefinedRequiredArgumentsErrorMessage)(directiveName, hostPath, [...requiredArguments], missingRequiredArguments));
|
|
422
|
-
}
|
|
423
|
-
}
|
|
424
|
-
if (errorMessages.length > 0) {
|
|
425
|
-
this.errors.push((0, errors_1.invalidDirectiveError)(directiveName, hostPath, errorMessages));
|
|
426
|
-
}
|
|
427
|
-
}
|
|
428
|
-
}
|
|
429
320
|
isTypeValidImplementation(originalType, implementationType) {
|
|
430
321
|
if (originalType.kind === graphql_1.Kind.NON_NULL_TYPE) {
|
|
431
322
|
if (implementationType.kind !== graphql_1.Kind.NON_NULL_TYPE) {
|
|
@@ -458,18 +349,6 @@ class NormalizationFactory {
|
|
|
458
349
|
return false;
|
|
459
350
|
}
|
|
460
351
|
}
|
|
461
|
-
canContainEventDirectives() {
|
|
462
|
-
if (!this.isCurrentParentRootType) {
|
|
463
|
-
return false;
|
|
464
|
-
}
|
|
465
|
-
const operationTypeNode = this.operationTypeNames.get(this.parentTypeName);
|
|
466
|
-
if (!operationTypeNode) {
|
|
467
|
-
return string_constants_1.ROOT_TYPES.has(this.parentTypeName);
|
|
468
|
-
}
|
|
469
|
-
return (operationTypeNode === graphql_1.OperationTypeNode.QUERY ||
|
|
470
|
-
operationTypeNode === graphql_1.OperationTypeNode.MUTATION ||
|
|
471
|
-
operationTypeNode === graphql_1.OperationTypeNode.SUBSCRIPTION);
|
|
472
|
-
}
|
|
473
352
|
extractKeyFieldSets(node, fieldSetContainer) {
|
|
474
353
|
const rawFieldSets = fieldSetContainer.keys;
|
|
475
354
|
const parentTypeName = node.name.value;
|
|
@@ -511,12 +390,12 @@ class NormalizationFactory {
|
|
|
511
390
|
}
|
|
512
391
|
}
|
|
513
392
|
validateInterfaceImplementations(container) {
|
|
514
|
-
if (container.
|
|
393
|
+
if (container.implementedInterfaceTypeNames.size < 1) {
|
|
515
394
|
return;
|
|
516
395
|
}
|
|
517
396
|
const implementationErrorsMap = new Map();
|
|
518
|
-
for (const interfaceName of container.
|
|
519
|
-
const interfaceContainer = (0, utils_3.getOrThrowError)(this.
|
|
397
|
+
for (const interfaceName of container.implementedInterfaceTypeNames) {
|
|
398
|
+
const interfaceContainer = (0, utils_3.getOrThrowError)(this.parentDefinitionDataByTypeName, interfaceName, string_constants_1.PARENTS);
|
|
520
399
|
if (interfaceContainer.kind !== graphql_1.Kind.INTERFACE_TYPE_DEFINITION) {
|
|
521
400
|
throw (0, errors_1.incompatibleParentKindFatalError)(interfaceName, graphql_1.Kind.INTERFACE_TYPE_DEFINITION, interfaceContainer.kind);
|
|
522
401
|
}
|
|
@@ -525,9 +404,9 @@ class NormalizationFactory {
|
|
|
525
404
|
unimplementedFields: [],
|
|
526
405
|
};
|
|
527
406
|
let hasErrors = false;
|
|
528
|
-
for (const [fieldName, interfaceField] of interfaceContainer.
|
|
407
|
+
for (const [fieldName, interfaceField] of interfaceContainer.fieldDataByFieldName) {
|
|
529
408
|
let hasNestedErrors = false;
|
|
530
|
-
const containerField = container.
|
|
409
|
+
const containerField = container.fieldDataByFieldName.get(fieldName);
|
|
531
410
|
if (!containerField) {
|
|
532
411
|
hasErrors = true;
|
|
533
412
|
implementationErrors.unimplementedFields.push(fieldName);
|
|
@@ -546,9 +425,9 @@ class NormalizationFactory {
|
|
|
546
425
|
invalidFieldImplementation.implementedResponseType = (0, merge_1.printTypeNode)(containerField.node.type);
|
|
547
426
|
}
|
|
548
427
|
const handledArguments = new Set();
|
|
549
|
-
for (const [argumentName, interfaceArgument] of interfaceField.
|
|
428
|
+
for (const [argumentName, interfaceArgument] of interfaceField.argumentDataByArgumentName) {
|
|
550
429
|
handledArguments.add(argumentName);
|
|
551
|
-
const containerArgument = containerField.
|
|
430
|
+
const containerArgument = containerField.argumentDataByArgumentName.get(argumentName);
|
|
552
431
|
// The type implementing the interface must include all arguments with no variation for that argument
|
|
553
432
|
if (!containerArgument) {
|
|
554
433
|
hasErrors = true;
|
|
@@ -566,11 +445,11 @@ class NormalizationFactory {
|
|
|
566
445
|
}
|
|
567
446
|
}
|
|
568
447
|
// Additional arguments must be optional (nullable)
|
|
569
|
-
for (const [argumentName,
|
|
448
|
+
for (const [argumentName, argumentData] of containerField.argumentDataByArgumentName) {
|
|
570
449
|
if (handledArguments.has(argumentName)) {
|
|
571
450
|
continue;
|
|
572
451
|
}
|
|
573
|
-
if (
|
|
452
|
+
if (argumentData.type.kind !== graphql_1.Kind.NON_NULL_TYPE) {
|
|
574
453
|
continue;
|
|
575
454
|
}
|
|
576
455
|
hasErrors = true;
|
|
@@ -586,81 +465,25 @@ class NormalizationFactory {
|
|
|
586
465
|
}
|
|
587
466
|
}
|
|
588
467
|
if (implementationErrorsMap.size) {
|
|
589
|
-
this.errors.push((0, errors_1.unimplementedInterfaceFieldsError)(container.
|
|
468
|
+
this.errors.push((0, errors_1.unimplementedInterfaceFieldsError)(container.typeName, (0, utils_3.kindToTypeString)(container.kind), implementationErrorsMap));
|
|
590
469
|
}
|
|
591
470
|
}
|
|
592
|
-
|
|
593
|
-
|
|
471
|
+
handleOverrideDeclaration(node, hostPath, errorMessages) {
|
|
472
|
+
const argumentNode = node.arguments[0];
|
|
473
|
+
if (argumentNode.value.kind !== graphql_1.Kind.STRING) {
|
|
474
|
+
errorMessages.push((0, errors_1.invalidDirectiveArgumentTypeErrorMessage)(true, string_constants_1.FROM, graphql_1.Kind.STRING, argumentNode.value.kind));
|
|
594
475
|
return;
|
|
595
476
|
}
|
|
596
|
-
const
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
if (this.argumentName) {
|
|
600
|
-
hostPath += `(${this.argumentName}: ...)`;
|
|
601
|
-
kind = graphql_1.Kind.ARGUMENT;
|
|
602
|
-
}
|
|
603
|
-
if (kind !== graphql_1.Kind.FIELD_DEFINITION) {
|
|
604
|
-
errorMessages.push((0, errors_1.invalidDirectiveLocationErrorMessage)(hostPath, kind, string_constants_1.OVERRIDE));
|
|
605
|
-
}
|
|
606
|
-
let targetSubgraphName = '';
|
|
607
|
-
if (node.arguments && node.arguments.length > 0) {
|
|
608
|
-
const observedArguments = new Set();
|
|
609
|
-
const handledDuplicateArguments = new Set();
|
|
610
|
-
for (const argumentNode of node.arguments) {
|
|
611
|
-
const argumentName = argumentNode.name.value;
|
|
612
|
-
if (argumentName !== string_constants_1.FROM && !observedArguments.has(argumentName)) {
|
|
613
|
-
observedArguments.add(argumentName);
|
|
614
|
-
errorMessages.push((0, errors_1.unexpectedDirectiveArgumentErrorMessage)(string_constants_1.OVERRIDE, argumentName));
|
|
615
|
-
continue;
|
|
616
|
-
}
|
|
617
|
-
// If an argument is observed more than once, it is a duplication error.
|
|
618
|
-
// However, the error should only propagate once.
|
|
619
|
-
if (observedArguments.has(argumentName)) {
|
|
620
|
-
if (!handledDuplicateArguments.has(argumentName)) {
|
|
621
|
-
errorMessages.push((0, errors_1.duplicateDirectiveArgumentDefinitionErrorMessage)(string_constants_1.OVERRIDE, hostPath, argumentName));
|
|
622
|
-
}
|
|
623
|
-
continue;
|
|
624
|
-
}
|
|
625
|
-
if (argumentNode.value.kind !== graphql_1.Kind.STRING) {
|
|
626
|
-
errorMessages.push((0, errors_1.invalidDirectiveArgumentTypeErrorMessage)(true, string_constants_1.FROM, graphql_1.Kind.STRING, argumentNode.value.kind));
|
|
627
|
-
}
|
|
628
|
-
else {
|
|
629
|
-
observedArguments.add(string_constants_1.FROM);
|
|
630
|
-
targetSubgraphName = argumentNode.value.value;
|
|
631
|
-
if (targetSubgraphName === this.subgraphName) {
|
|
632
|
-
this.errors.push((0, errors_1.equivalentSourceAndTargetOverrideError)(targetSubgraphName, hostPath));
|
|
633
|
-
}
|
|
634
|
-
}
|
|
635
|
-
}
|
|
636
|
-
if (!observedArguments.has(string_constants_1.FROM)) {
|
|
637
|
-
errorMessages.push((0, errors_1.undefinedRequiredArgumentsErrorMessage)(string_constants_1.OVERRIDE, hostPath, [string_constants_1.FROM], [string_constants_1.FROM]));
|
|
638
|
-
}
|
|
639
|
-
}
|
|
640
|
-
else {
|
|
641
|
-
errorMessages.push((0, errors_1.undefinedRequiredArgumentsErrorMessage)(string_constants_1.OVERRIDE, hostPath, [string_constants_1.FROM], []));
|
|
642
|
-
}
|
|
643
|
-
if (errorMessages.length > 0) {
|
|
644
|
-
this.errors.push((0, errors_1.invalidDirectiveError)(string_constants_1.OVERRIDE, hostPath, errorMessages));
|
|
477
|
+
const targetSubgraphName = argumentNode.value.value;
|
|
478
|
+
if (targetSubgraphName === this.subgraphName) {
|
|
479
|
+
errorMessages.push((0, errors_1.equivalentSourceAndTargetOverrideErrorMessage)(targetSubgraphName, hostPath));
|
|
645
480
|
return;
|
|
646
481
|
}
|
|
647
482
|
const overrideDataForSubgraph = (0, utils_3.getValueOrDefault)(this.overridesByTargetSubgraphName, targetSubgraphName, () => new Map());
|
|
648
483
|
const overriddenFieldNamesForParent = (0, utils_3.getValueOrDefault)(overrideDataForSubgraph, this.parentTypeName, () => new Set());
|
|
649
|
-
if (overriddenFieldNamesForParent.has(this.childName)) {
|
|
650
|
-
const handledRepeatedDirectives = this.handledRepeatedDirectivesByHostPath.get(hostPath);
|
|
651
|
-
// If the directive name exists as a value on the host path key, the repeatable error has been handled
|
|
652
|
-
if (handledRepeatedDirectives && handledRepeatedDirectives.has(string_constants_1.OVERRIDE)) {
|
|
653
|
-
return;
|
|
654
|
-
}
|
|
655
|
-
// Add the directive name to the existing set (if other invalid repeated directives exist) or a new set
|
|
656
|
-
(0, utils_3.getValueOrDefault)(this.handledRepeatedDirectivesByHostPath, hostPath, () => new Set()).add(string_constants_1.OVERRIDE);
|
|
657
|
-
// The invalid repeated directive error should propagate only once per directive per host path
|
|
658
|
-
this.errors.push((0, errors_1.invalidDirectiveError)(string_constants_1.OVERRIDE, hostPath, [(0, errors_1.invalidRepeatedDirectiveErrorMessage)(string_constants_1.OVERRIDE, hostPath)]));
|
|
659
|
-
return;
|
|
660
|
-
}
|
|
661
484
|
overriddenFieldNamesForParent.add(this.childName);
|
|
662
485
|
}
|
|
663
|
-
|
|
486
|
+
extractEventDirectivesToConfiguration(node) {
|
|
664
487
|
if (!node.directives) {
|
|
665
488
|
return;
|
|
666
489
|
}
|
|
@@ -726,584 +549,52 @@ class NormalizationFactory {
|
|
|
726
549
|
}
|
|
727
550
|
}
|
|
728
551
|
normalize(document) {
|
|
729
|
-
const factory = this;
|
|
730
552
|
/* factory.allDirectiveDefinitions is initialized with v1 directive definitions, and v2 definitions are only added
|
|
731
553
|
after the visitor has visited the entire schema and the subgraph is known to be a V2 graph. Consequently,
|
|
732
554
|
allDirectiveDefinitions cannot be used to check for duplicate definitions, and another set (below) is required */
|
|
733
|
-
const definedDirectives = new Set();
|
|
734
|
-
const handledRootTypes = new Set();
|
|
735
555
|
// Collect any renamed root types
|
|
736
|
-
(0,
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
if (
|
|
749
|
-
|
|
750
|
-
}
|
|
751
|
-
else {
|
|
752
|
-
handledRootTypes.add(operationType);
|
|
753
|
-
factory.operationTypeNames.set(newTypeName, operationType);
|
|
754
|
-
factory.schemaDefinition.operationTypes.set(operationType, node);
|
|
755
|
-
}
|
|
756
|
-
return false;
|
|
757
|
-
},
|
|
758
|
-
},
|
|
759
|
-
SchemaDefinition: {
|
|
760
|
-
enter(node) {
|
|
761
|
-
factory.extractDirectives(node, factory.schemaDefinition.directives);
|
|
762
|
-
factory.schemaDefinition.description = node.description;
|
|
763
|
-
},
|
|
764
|
-
},
|
|
765
|
-
SchemaExtension: {
|
|
766
|
-
enter(node) {
|
|
767
|
-
factory.extractDirectives(node, factory.schemaDefinition.directives);
|
|
768
|
-
},
|
|
769
|
-
},
|
|
770
|
-
});
|
|
771
|
-
(0, graphql_1.visit)(document, {
|
|
772
|
-
DirectiveDefinition: {
|
|
773
|
-
enter(node) {
|
|
774
|
-
const name = node.name.value;
|
|
775
|
-
if (definedDirectives.has(name)) {
|
|
776
|
-
factory.errors.push((0, errors_1.duplicateDirectiveDefinitionError)(name));
|
|
777
|
-
return false;
|
|
778
|
-
}
|
|
779
|
-
else {
|
|
780
|
-
definedDirectives.add(name);
|
|
781
|
-
}
|
|
782
|
-
// Normalize federation directives by replacing them with predefined definitions
|
|
783
|
-
if (constants_1.VERSION_TWO_DIRECTIVES.has(name)) {
|
|
784
|
-
factory.isSubgraphVersionTwo = true;
|
|
785
|
-
return false;
|
|
786
|
-
}
|
|
787
|
-
// The V1 directives are always injected
|
|
788
|
-
if (constants_1.VERSION_ONE_DIRECTIVES.has(name)) {
|
|
789
|
-
return false;
|
|
790
|
-
}
|
|
791
|
-
factory.allDirectiveDefinitions.set(name, node);
|
|
792
|
-
factory.customDirectiveDefinitions.set(name, node);
|
|
793
|
-
return false;
|
|
794
|
-
},
|
|
795
|
-
},
|
|
796
|
-
Directive: {
|
|
797
|
-
enter(node) {
|
|
798
|
-
const name = node.name.value;
|
|
799
|
-
factory.handleOverride(node);
|
|
800
|
-
if (constants_1.VERSION_TWO_DIRECTIVES.has(name)) {
|
|
801
|
-
factory.isSubgraphVersionTwo = true;
|
|
802
|
-
return false;
|
|
803
|
-
}
|
|
804
|
-
if (constants_1.VERSION_ONE_DIRECTIVES.has(name)) {
|
|
805
|
-
return false;
|
|
806
|
-
}
|
|
807
|
-
factory.referencedDirectives.add(name);
|
|
808
|
-
},
|
|
809
|
-
},
|
|
810
|
-
EnumTypeDefinition: {
|
|
811
|
-
enter(node) {
|
|
812
|
-
const typeName = node.name.value;
|
|
813
|
-
if (factory.parentContainerByTypeName.has(typeName)) {
|
|
814
|
-
factory.errors.push((0, errors_1.duplicateTypeDefinitionError)((0, utils_3.kindToTypeString)(node.kind), typeName));
|
|
815
|
-
return false;
|
|
816
|
-
}
|
|
817
|
-
factory.parentTypeName = typeName;
|
|
818
|
-
factory.lastParentNodeKind = node.kind;
|
|
819
|
-
const directives = factory.extractDirectivesAndAuthorization(node, new Map());
|
|
820
|
-
factory.parentContainerByTypeName.set(typeName, {
|
|
821
|
-
description: (0, utils_1.formatDescription)(node.description),
|
|
822
|
-
directives,
|
|
823
|
-
kind: node.kind,
|
|
824
|
-
name: node.name,
|
|
825
|
-
values: new Map(),
|
|
826
|
-
});
|
|
827
|
-
},
|
|
828
|
-
leave() {
|
|
829
|
-
factory.parentTypeName = '';
|
|
830
|
-
factory.lastParentNodeKind = graphql_1.Kind.NULL;
|
|
831
|
-
},
|
|
832
|
-
},
|
|
833
|
-
EnumTypeExtension: {
|
|
834
|
-
enter(node) {
|
|
835
|
-
const name = node.name.value;
|
|
836
|
-
factory.parentTypeName = name;
|
|
837
|
-
factory.lastParentNodeKind = node.kind;
|
|
838
|
-
factory.isCurrentParentExtension = true;
|
|
839
|
-
const extension = factory.extensionContainerByTypeName.get(factory.parentTypeName);
|
|
840
|
-
if (extension) {
|
|
841
|
-
if (extension.kind !== graphql_1.Kind.ENUM_TYPE_EXTENSION) {
|
|
842
|
-
factory.errors.push((0, errors_1.incompatibleExtensionKindsError)(node, extension.kind));
|
|
843
|
-
return false;
|
|
844
|
-
}
|
|
845
|
-
factory.extractDirectivesAndAuthorization(node, extension.directives);
|
|
846
|
-
return;
|
|
847
|
-
}
|
|
848
|
-
factory.extensionContainerByTypeName.set(name, {
|
|
849
|
-
directives: factory.extractDirectivesAndAuthorization(node, new Map()),
|
|
850
|
-
kind: node.kind,
|
|
851
|
-
name: node.name,
|
|
852
|
-
values: new Map(),
|
|
853
|
-
});
|
|
854
|
-
},
|
|
855
|
-
leave() {
|
|
856
|
-
factory.parentTypeName = '';
|
|
857
|
-
factory.lastParentNodeKind = graphql_1.Kind.NULL;
|
|
858
|
-
factory.isCurrentParentExtension = false;
|
|
859
|
-
},
|
|
860
|
-
},
|
|
861
|
-
EnumValueDefinition: {
|
|
862
|
-
enter(node) {
|
|
863
|
-
const name = node.name.value;
|
|
864
|
-
factory.childName = name;
|
|
865
|
-
factory.lastChildNodeKind = node.kind;
|
|
866
|
-
const parent = factory.isCurrentParentExtension
|
|
867
|
-
? (0, utils_3.getOrThrowError)(factory.extensionContainerByTypeName, factory.parentTypeName, string_constants_1.EXTENSIONS)
|
|
868
|
-
: (0, utils_3.getOrThrowError)(factory.parentContainerByTypeName, factory.parentTypeName, string_constants_1.PARENTS);
|
|
869
|
-
if (parent.kind !== graphql_1.Kind.ENUM_TYPE_DEFINITION && parent.kind !== graphql_1.Kind.ENUM_TYPE_EXTENSION) {
|
|
870
|
-
throw (0, errors_1.unexpectedKindFatalError)(name);
|
|
871
|
-
}
|
|
872
|
-
if (parent.values.has(name)) {
|
|
873
|
-
const error = factory.isCurrentParentExtension
|
|
874
|
-
? (0, errors_1.duplicateValueExtensionError)('enum', factory.parentTypeName, name)
|
|
875
|
-
: (0, errors_1.duplicateEnumValueDefinitionError)(name, factory.parentTypeName);
|
|
876
|
-
factory.errors.push(error);
|
|
877
|
-
return;
|
|
878
|
-
}
|
|
879
|
-
parent.values.set(name, {
|
|
880
|
-
directives: factory.extractDirectives(node, new Map()),
|
|
881
|
-
name,
|
|
882
|
-
node: { ...node, description: (0, utils_1.formatDescription)(node.description) },
|
|
883
|
-
});
|
|
884
|
-
},
|
|
885
|
-
leave() {
|
|
886
|
-
factory.childName = '';
|
|
887
|
-
factory.lastChildNodeKind = graphql_1.Kind.NULL;
|
|
888
|
-
},
|
|
889
|
-
},
|
|
890
|
-
FieldDefinition: {
|
|
891
|
-
enter(node) {
|
|
892
|
-
const fieldName = node.name.value;
|
|
893
|
-
if (factory.isCurrentParentRootType && (fieldName === string_constants_1.SERVICE_FIELD || fieldName === string_constants_1.ENTITIES_FIELD)) {
|
|
894
|
-
return false;
|
|
895
|
-
}
|
|
896
|
-
factory.childName = fieldName;
|
|
897
|
-
factory.lastChildNodeKind = node.kind;
|
|
898
|
-
if (factory.canContainEventDirectives()) {
|
|
899
|
-
factory.extractEventDirectives(node);
|
|
900
|
-
}
|
|
901
|
-
const fieldPath = `${factory.parentTypeName}.${fieldName}`;
|
|
902
|
-
factory.lastChildNodeKind = node.kind;
|
|
903
|
-
const fieldNamedTypeName = (0, type_merging_1.getNamedTypeForChild)(fieldPath, node.type);
|
|
904
|
-
if (!constants_1.BASE_SCALARS.has(fieldNamedTypeName)) {
|
|
905
|
-
factory.referencedTypeNames.add(fieldNamedTypeName);
|
|
906
|
-
}
|
|
907
|
-
const parent = factory.isCurrentParentExtension
|
|
908
|
-
? (0, utils_3.getOrThrowError)(factory.extensionContainerByTypeName, factory.parentTypeName, string_constants_1.EXTENSIONS)
|
|
909
|
-
: (0, utils_3.getOrThrowError)(factory.parentContainerByTypeName, factory.parentTypeName, string_constants_1.PARENTS);
|
|
910
|
-
if (parent.kind !== graphql_1.Kind.OBJECT_TYPE_DEFINITION &&
|
|
911
|
-
parent.kind !== graphql_1.Kind.OBJECT_TYPE_EXTENSION &&
|
|
912
|
-
parent.kind !== graphql_1.Kind.INTERFACE_TYPE_DEFINITION &&
|
|
913
|
-
parent.kind !== graphql_1.Kind.INTERFACE_TYPE_EXTENSION) {
|
|
914
|
-
throw (0, errors_1.unexpectedKindFatalError)(factory.parentTypeName);
|
|
915
|
-
}
|
|
916
|
-
if (parent.fields.has(fieldName)) {
|
|
917
|
-
factory.errors.push((0, errors_1.duplicateFieldDefinitionError)(fieldName, factory.parentTypeName));
|
|
918
|
-
return;
|
|
919
|
-
}
|
|
920
|
-
// recreate the node so the argument descriptions are updated
|
|
921
|
-
const fieldContainer = {
|
|
922
|
-
arguments: factory.extractArguments(node, new Map(), fieldPath),
|
|
923
|
-
directives: factory.extractDirectivesAndAuthorization(node, new Map()),
|
|
924
|
-
name: fieldName,
|
|
925
|
-
node: {
|
|
926
|
-
...node,
|
|
927
|
-
arguments: node.arguments?.map((arg) => ({
|
|
928
|
-
...arg,
|
|
929
|
-
description: (0, utils_1.formatDescription)(arg.description),
|
|
930
|
-
})),
|
|
931
|
-
},
|
|
932
|
-
};
|
|
933
|
-
parent.fields.set(fieldName, fieldContainer);
|
|
934
|
-
const entityContainer = factory.entityContainerByTypeName.get(factory.parentTypeName);
|
|
935
|
-
if (entityContainer) {
|
|
936
|
-
entityContainer.fieldNames.add(fieldName);
|
|
937
|
-
// Only entities will have an existing FieldSet
|
|
938
|
-
const existingFieldSet = factory.fieldSetContainerByTypeName.get(factory.parentTypeName);
|
|
939
|
-
if (existingFieldSet) {
|
|
940
|
-
// @requires should only be defined on a field whose parent is an entity
|
|
941
|
-
// If there is existingFieldSet, it's an entity
|
|
942
|
-
(0, utils_2.extractFieldSetValue)(fieldName, existingFieldSet.requires, fieldContainer.directives.get(string_constants_1.REQUIRES));
|
|
943
|
-
// @provides only makes sense on entities, but the field can be encountered before the type definition
|
|
944
|
-
// When the FieldSet is evaluated, it will be checked whether the field is an entity.
|
|
945
|
-
(0, utils_2.extractFieldSetValue)(fieldName, existingFieldSet.provides, fieldContainer.directives.get(string_constants_1.PROVIDES));
|
|
946
|
-
return;
|
|
947
|
-
}
|
|
948
|
-
}
|
|
949
|
-
const providesDirectives = fieldContainer.directives.get(string_constants_1.PROVIDES);
|
|
950
|
-
// Check whether the directive exists to avoid creating unnecessary fieldSet configurations
|
|
951
|
-
if (!providesDirectives) {
|
|
952
|
-
return;
|
|
953
|
-
}
|
|
954
|
-
const fieldSetContainer = (0, utils_3.getValueOrDefault)(factory.fieldSetContainerByTypeName, factory.parentTypeName, utils_2.newFieldSetContainer);
|
|
955
|
-
// @provides only makes sense on entities, but the field can be encountered before the type definition
|
|
956
|
-
// When the FieldSet is evaluated, it will be checked whether the field is an entity.
|
|
957
|
-
(0, utils_2.extractFieldSetValue)(fieldName, fieldSetContainer.provides, providesDirectives);
|
|
958
|
-
},
|
|
959
|
-
leave() {
|
|
960
|
-
factory.childName = '';
|
|
961
|
-
factory.lastChildNodeKind = graphql_1.Kind.NULL;
|
|
962
|
-
},
|
|
963
|
-
},
|
|
964
|
-
InputObjectTypeDefinition: {
|
|
965
|
-
enter(node) {
|
|
966
|
-
const name = node.name.value;
|
|
967
|
-
if (factory.parentContainerByTypeName.has(name)) {
|
|
968
|
-
factory.errors.push((0, errors_1.duplicateTypeDefinitionError)((0, utils_3.kindToTypeString)(node.kind), name));
|
|
969
|
-
return false;
|
|
970
|
-
}
|
|
971
|
-
factory.lastParentNodeKind = node.kind;
|
|
972
|
-
factory.parentTypeName = name;
|
|
973
|
-
factory.parentContainerByTypeName.set(name, {
|
|
974
|
-
description: (0, utils_1.formatDescription)(node.description),
|
|
975
|
-
directives: factory.extractDirectives(node, new Map()),
|
|
976
|
-
fields: new Map(),
|
|
977
|
-
kind: node.kind,
|
|
978
|
-
name: node.name,
|
|
979
|
-
});
|
|
980
|
-
},
|
|
981
|
-
leave() {
|
|
982
|
-
factory.lastParentNodeKind = graphql_1.Kind.NULL;
|
|
983
|
-
factory.parentTypeName = '';
|
|
984
|
-
},
|
|
985
|
-
},
|
|
986
|
-
InputObjectTypeExtension: {
|
|
987
|
-
enter(node) {
|
|
988
|
-
const name = node.name.value;
|
|
989
|
-
factory.parentTypeName = name;
|
|
990
|
-
factory.lastParentNodeKind = node.kind;
|
|
991
|
-
factory.isCurrentParentExtension = true;
|
|
992
|
-
const extension = factory.extensionContainerByTypeName.get(factory.parentTypeName);
|
|
993
|
-
if (extension) {
|
|
994
|
-
if (extension.kind !== graphql_1.Kind.INPUT_OBJECT_TYPE_EXTENSION) {
|
|
995
|
-
factory.errors.push((0, errors_1.incompatibleExtensionKindsError)(node, extension.kind));
|
|
996
|
-
return false;
|
|
997
|
-
}
|
|
998
|
-
factory.extractDirectives(node, extension.directives);
|
|
999
|
-
return;
|
|
1000
|
-
}
|
|
1001
|
-
factory.extensionContainerByTypeName.set(name, {
|
|
1002
|
-
directives: factory.extractDirectives(node, new Map()),
|
|
1003
|
-
fields: new Map(),
|
|
1004
|
-
kind: node.kind,
|
|
1005
|
-
name: node.name,
|
|
1006
|
-
});
|
|
1007
|
-
},
|
|
1008
|
-
leave() {
|
|
1009
|
-
factory.parentTypeName = '';
|
|
1010
|
-
factory.lastParentNodeKind = graphql_1.Kind.NULL;
|
|
1011
|
-
factory.isCurrentParentExtension = false;
|
|
1012
|
-
},
|
|
1013
|
-
},
|
|
1014
|
-
InputValueDefinition: {
|
|
1015
|
-
enter(node) {
|
|
1016
|
-
const name = node.name.value;
|
|
1017
|
-
// If the parent is not an object type definition/extension, this node is an argument
|
|
1018
|
-
if (factory.lastParentNodeKind !== graphql_1.Kind.INPUT_OBJECT_TYPE_DEFINITION &&
|
|
1019
|
-
factory.lastParentNodeKind !== graphql_1.Kind.INPUT_OBJECT_TYPE_EXTENSION) {
|
|
1020
|
-
factory.argumentName = name;
|
|
1021
|
-
return;
|
|
1022
|
-
}
|
|
1023
|
-
factory.childName = name;
|
|
1024
|
-
factory.lastChildNodeKind = node.kind;
|
|
1025
|
-
const valueRootTypeName = (0, type_merging_1.getNamedTypeForChild)(`${factory.parentTypeName}.${name}`, node.type);
|
|
1026
|
-
if (!constants_1.BASE_SCALARS.has(valueRootTypeName)) {
|
|
1027
|
-
factory.referencedTypeNames.add(valueRootTypeName);
|
|
1028
|
-
}
|
|
1029
|
-
const parent = factory.isCurrentParentExtension
|
|
1030
|
-
? (0, utils_3.getOrThrowError)(factory.extensionContainerByTypeName, factory.parentTypeName, string_constants_1.EXTENSIONS)
|
|
1031
|
-
: (0, utils_3.getOrThrowError)(factory.parentContainerByTypeName, factory.parentTypeName, string_constants_1.PARENTS);
|
|
1032
|
-
if (parent.kind !== graphql_1.Kind.INPUT_OBJECT_TYPE_DEFINITION && parent.kind !== graphql_1.Kind.INPUT_OBJECT_TYPE_EXTENSION) {
|
|
1033
|
-
throw (0, errors_1.unexpectedKindFatalError)(factory.parentTypeName);
|
|
1034
|
-
}
|
|
1035
|
-
if (parent.fields.has(name)) {
|
|
1036
|
-
factory.errors.push((0, errors_1.duplicateValueExtensionError)('input', factory.parentTypeName, name));
|
|
1037
|
-
return;
|
|
1038
|
-
}
|
|
1039
|
-
parent.fields.set(name, {
|
|
1040
|
-
directives: factory.extractDirectives(node, new Map()),
|
|
1041
|
-
name,
|
|
1042
|
-
node: { ...node, description: (0, utils_1.formatDescription)(node.description) },
|
|
1043
|
-
});
|
|
1044
|
-
},
|
|
1045
|
-
leave() {
|
|
1046
|
-
factory.argumentName = '';
|
|
1047
|
-
// Only reset childName and lastNodeKind if this input value was NOT an argument
|
|
1048
|
-
if (factory.lastChildNodeKind === graphql_1.Kind.INPUT_VALUE_DEFINITION) {
|
|
1049
|
-
factory.childName = '';
|
|
1050
|
-
factory.lastChildNodeKind = graphql_1.Kind.NULL;
|
|
1051
|
-
}
|
|
1052
|
-
},
|
|
1053
|
-
},
|
|
1054
|
-
InterfaceTypeDefinition: {
|
|
1055
|
-
enter(node) {
|
|
1056
|
-
const name = node.name.value;
|
|
1057
|
-
factory.parentTypeName = name;
|
|
1058
|
-
factory.lastParentNodeKind = node.kind;
|
|
1059
|
-
if ((0, utils_1.isNodeExtension)(node)) {
|
|
1060
|
-
return factory.handleObjectLikeExtension(node);
|
|
1061
|
-
}
|
|
1062
|
-
if (factory.parentContainerByTypeName.has(name)) {
|
|
1063
|
-
factory.errors.push((0, errors_1.duplicateTypeDefinitionError)((0, utils_3.kindToTypeString)(node.kind), name));
|
|
1064
|
-
return false;
|
|
1065
|
-
}
|
|
1066
|
-
const isEntity = (0, utils_1.isObjectLikeNodeEntity)(node);
|
|
1067
|
-
factory.parentContainerByTypeName.set(name, {
|
|
1068
|
-
description: (0, utils_1.formatDescription)(node.description),
|
|
1069
|
-
directives: factory.extractDirectivesAndAuthorization(node, new Map()),
|
|
1070
|
-
fields: new Map(),
|
|
1071
|
-
interfaces: (0, utils_1.extractInterfaces)(node, new Set(), factory.errors),
|
|
1072
|
-
isEntity,
|
|
1073
|
-
kind: node.kind,
|
|
1074
|
-
name: node.name,
|
|
1075
|
-
});
|
|
1076
|
-
if (!isEntity) {
|
|
1077
|
-
return;
|
|
1078
|
-
}
|
|
1079
|
-
factory.entityInterfaces.set(name, {
|
|
1080
|
-
concreteTypeNames: new Set(),
|
|
1081
|
-
interfaceFieldNames: new Set(node.fields?.map((field) => field.name.value)),
|
|
1082
|
-
interfaceObjectFieldNames: new Set(),
|
|
1083
|
-
isInterfaceObject: false,
|
|
1084
|
-
typeName: name,
|
|
1085
|
-
});
|
|
1086
|
-
(0, utils_3.upsertEntityContainerProperties)(factory.entityContainerByTypeName, {
|
|
1087
|
-
typeName: factory.parentTypeName,
|
|
1088
|
-
...(factory.subgraphName ? { subgraphNames: [factory.subgraphName] } : {}),
|
|
1089
|
-
});
|
|
1090
|
-
const fieldSetContainer = (0, utils_3.getValueOrDefault)(factory.fieldSetContainerByTypeName, name, utils_2.newFieldSetContainer);
|
|
1091
|
-
factory.extractKeyFieldSets(node, fieldSetContainer);
|
|
1092
|
-
},
|
|
1093
|
-
leave() {
|
|
1094
|
-
factory.parentTypeName = '';
|
|
1095
|
-
factory.lastParentNodeKind = graphql_1.Kind.NULL;
|
|
1096
|
-
factory.isCurrentParentExtension = false;
|
|
1097
|
-
},
|
|
1098
|
-
},
|
|
1099
|
-
InterfaceTypeExtension: {
|
|
1100
|
-
enter(node) {
|
|
1101
|
-
factory.parentTypeName = node.name.value;
|
|
1102
|
-
factory.lastParentNodeKind = node.kind;
|
|
1103
|
-
return factory.handleObjectLikeExtension(node);
|
|
1104
|
-
},
|
|
1105
|
-
leave() {
|
|
1106
|
-
factory.isCurrentParentExtension = false;
|
|
1107
|
-
factory.parentTypeName = '';
|
|
1108
|
-
factory.lastParentNodeKind = graphql_1.Kind.NULL;
|
|
1109
|
-
},
|
|
1110
|
-
},
|
|
1111
|
-
ObjectTypeDefinition: {
|
|
1112
|
-
enter(node) {
|
|
1113
|
-
const typeName = node.name.value;
|
|
1114
|
-
if (typeName === string_constants_1.SERVICE_OBJECT) {
|
|
1115
|
-
return false;
|
|
1116
|
-
}
|
|
1117
|
-
factory.isCurrentParentRootType = string_constants_1.ROOT_TYPES.has(typeName) || factory.operationTypeNames.has(typeName);
|
|
1118
|
-
factory.parentTypeName = typeName;
|
|
1119
|
-
factory.lastParentNodeKind = node.kind;
|
|
1120
|
-
(0, utils_1.addConcreteTypesForImplementedInterfaces)(node, factory.abstractToConcreteTypeNames);
|
|
1121
|
-
factory.handleInterfaceObject(node);
|
|
1122
|
-
// handling for @extends directive
|
|
1123
|
-
if ((0, utils_1.isNodeExtension)(node)) {
|
|
1124
|
-
return factory.handleObjectLikeExtension(node);
|
|
1125
|
-
}
|
|
1126
|
-
if (factory.parentContainerByTypeName.has(typeName)) {
|
|
1127
|
-
factory.errors.push((0, errors_1.duplicateTypeDefinitionError)((0, utils_3.kindToTypeString)(node.kind), typeName));
|
|
1128
|
-
return false;
|
|
1129
|
-
}
|
|
1130
|
-
const isEntity = (0, utils_1.isObjectLikeNodeEntity)(node);
|
|
1131
|
-
factory.parentContainerByTypeName.set(typeName, {
|
|
1132
|
-
description: (0, utils_1.formatDescription)(node.description),
|
|
1133
|
-
directives: factory.extractDirectivesAndAuthorization(node, new Map()),
|
|
1134
|
-
fields: new Map(),
|
|
1135
|
-
interfaces: (0, utils_1.extractInterfaces)(node, new Set(), factory.errors),
|
|
1136
|
-
isEntity,
|
|
1137
|
-
kind: node.kind,
|
|
1138
|
-
name: node.name,
|
|
1139
|
-
});
|
|
1140
|
-
if (!isEntity) {
|
|
1141
|
-
return;
|
|
1142
|
-
}
|
|
1143
|
-
const fieldSetContainer = (0, utils_3.getValueOrDefault)(factory.fieldSetContainerByTypeName, typeName, utils_2.newFieldSetContainer);
|
|
1144
|
-
factory.extractKeyFieldSets(node, fieldSetContainer);
|
|
1145
|
-
(0, utils_3.upsertEntityContainerProperties)(factory.entityContainerByTypeName, {
|
|
1146
|
-
typeName: factory.parentTypeName,
|
|
1147
|
-
keyFieldSets: fieldSetContainer.keys,
|
|
1148
|
-
...(factory.subgraphName ? { subgraphNames: [factory.subgraphName] } : {}),
|
|
1149
|
-
});
|
|
1150
|
-
},
|
|
1151
|
-
leave() {
|
|
1152
|
-
factory.isCurrentParentRootType = false;
|
|
1153
|
-
factory.isCurrentParentExtension = false;
|
|
1154
|
-
factory.parentTypeName = '';
|
|
1155
|
-
factory.lastParentNodeKind = graphql_1.Kind.NULL;
|
|
1156
|
-
},
|
|
1157
|
-
},
|
|
1158
|
-
ObjectTypeExtension: {
|
|
1159
|
-
enter(node) {
|
|
1160
|
-
const name = node.name.value;
|
|
1161
|
-
if (name === string_constants_1.SERVICE_OBJECT) {
|
|
1162
|
-
return false;
|
|
1163
|
-
}
|
|
1164
|
-
factory.isCurrentParentRootType = string_constants_1.ROOT_TYPES.has(name) || factory.operationTypeNames.has(name);
|
|
1165
|
-
factory.parentTypeName = name;
|
|
1166
|
-
factory.lastParentNodeKind = node.kind;
|
|
1167
|
-
(0, utils_1.addConcreteTypesForImplementedInterfaces)(node, factory.abstractToConcreteTypeNames);
|
|
1168
|
-
return factory.handleObjectLikeExtension(node);
|
|
1169
|
-
},
|
|
1170
|
-
leave() {
|
|
1171
|
-
factory.isCurrentParentRootType = false;
|
|
1172
|
-
factory.isCurrentParentExtension = false;
|
|
1173
|
-
factory.parentTypeName = '';
|
|
1174
|
-
factory.lastParentNodeKind = graphql_1.Kind.NULL;
|
|
1175
|
-
},
|
|
1176
|
-
},
|
|
1177
|
-
ScalarTypeDefinition: {
|
|
1178
|
-
enter(node) {
|
|
1179
|
-
const name = node.name.value;
|
|
1180
|
-
if (name === string_constants_1.ANY_SCALAR) {
|
|
1181
|
-
return false;
|
|
1182
|
-
}
|
|
1183
|
-
const parent = factory.parentContainerByTypeName.get(name);
|
|
1184
|
-
if (parent) {
|
|
1185
|
-
factory.errors.push((0, errors_1.duplicateTypeDefinitionError)((0, utils_3.kindToTypeString)(node.kind), name));
|
|
1186
|
-
return false;
|
|
1187
|
-
}
|
|
1188
|
-
factory.parentTypeName = name;
|
|
1189
|
-
factory.lastParentNodeKind = node.kind;
|
|
1190
|
-
factory.parentContainerByTypeName.set(name, {
|
|
1191
|
-
description: (0, utils_1.formatDescription)(node.description),
|
|
1192
|
-
directives: factory.extractDirectivesAndAuthorization(node, new Map()),
|
|
1193
|
-
kind: graphql_1.Kind.SCALAR_TYPE_DEFINITION,
|
|
1194
|
-
name: node.name,
|
|
1195
|
-
});
|
|
1196
|
-
},
|
|
1197
|
-
leave() {
|
|
1198
|
-
factory.parentTypeName = '';
|
|
1199
|
-
factory.lastParentNodeKind = graphql_1.Kind.NULL;
|
|
1200
|
-
},
|
|
1201
|
-
},
|
|
1202
|
-
ScalarTypeExtension: {
|
|
1203
|
-
enter(node) {
|
|
1204
|
-
const name = node.name.value;
|
|
1205
|
-
if (name === string_constants_1.ANY_SCALAR) {
|
|
1206
|
-
return false;
|
|
1207
|
-
}
|
|
1208
|
-
const extension = factory.extensionContainerByTypeName.get(name);
|
|
1209
|
-
if (extension) {
|
|
1210
|
-
if (extension.kind !== graphql_1.Kind.SCALAR_TYPE_EXTENSION) {
|
|
1211
|
-
factory.errors.push((0, errors_1.incompatibleExtensionKindsError)(node, extension.kind));
|
|
1212
|
-
return false;
|
|
1213
|
-
}
|
|
1214
|
-
factory.extractDirectivesAndAuthorization(node, extension.directives);
|
|
1215
|
-
}
|
|
1216
|
-
else {
|
|
1217
|
-
factory.parentTypeName = name;
|
|
1218
|
-
factory.lastParentNodeKind = node.kind;
|
|
1219
|
-
factory.extensionContainerByTypeName.set(name, {
|
|
1220
|
-
directives: factory.extractDirectivesAndAuthorization(node, new Map()),
|
|
1221
|
-
kind: node.kind,
|
|
1222
|
-
name: node.name,
|
|
1223
|
-
});
|
|
1224
|
-
}
|
|
1225
|
-
return false;
|
|
1226
|
-
},
|
|
1227
|
-
leave() {
|
|
1228
|
-
factory.parentTypeName = '';
|
|
1229
|
-
factory.lastParentNodeKind = graphql_1.Kind.NULL;
|
|
1230
|
-
},
|
|
1231
|
-
},
|
|
1232
|
-
UnionTypeDefinition: {
|
|
1233
|
-
enter(node) {
|
|
1234
|
-
const name = node.name.value;
|
|
1235
|
-
if (name === string_constants_1.ENTITY_UNION) {
|
|
1236
|
-
return false;
|
|
1237
|
-
}
|
|
1238
|
-
factory.parentTypeName = name;
|
|
1239
|
-
const parent = factory.parentContainerByTypeName.get(name);
|
|
1240
|
-
if (parent) {
|
|
1241
|
-
factory.errors.push((0, errors_1.duplicateTypeDefinitionError)((0, utils_3.kindToTypeString)(node.kind), name));
|
|
1242
|
-
return false;
|
|
1243
|
-
}
|
|
1244
|
-
if (!node.types) {
|
|
1245
|
-
factory.errors.push((0, errors_1.noDefinedUnionMembersError)(name));
|
|
1246
|
-
return false;
|
|
1247
|
-
}
|
|
1248
|
-
factory.lastParentNodeKind = node.kind;
|
|
1249
|
-
(0, utils_1.addConcreteTypesForUnion)(node, factory.abstractToConcreteTypeNames);
|
|
1250
|
-
factory.parentContainerByTypeName.set(name, {
|
|
1251
|
-
description: (0, utils_1.formatDescription)(node.description),
|
|
1252
|
-
directives: factory.extractDirectives(node, new Map()),
|
|
1253
|
-
kind: node.kind,
|
|
1254
|
-
name: node.name,
|
|
1255
|
-
types: factory.extractUniqueUnionMembers([...node.types], new Map()),
|
|
1256
|
-
});
|
|
1257
|
-
},
|
|
1258
|
-
leave() {
|
|
1259
|
-
factory.parentTypeName = '';
|
|
1260
|
-
factory.lastParentNodeKind = graphql_1.Kind.NULL;
|
|
1261
|
-
},
|
|
1262
|
-
},
|
|
1263
|
-
UnionTypeExtension: {
|
|
1264
|
-
enter(node) {
|
|
1265
|
-
const name = node.name.value;
|
|
1266
|
-
if (name === string_constants_1.ENTITY_UNION) {
|
|
1267
|
-
return false;
|
|
1268
|
-
}
|
|
1269
|
-
const extension = factory.extensionContainerByTypeName.get(name);
|
|
1270
|
-
if (!node.types) {
|
|
1271
|
-
factory.errors.push();
|
|
1272
|
-
return false;
|
|
1273
|
-
}
|
|
1274
|
-
factory.lastParentNodeKind = node.kind;
|
|
1275
|
-
(0, utils_1.addConcreteTypesForUnion)(node, factory.abstractToConcreteTypeNames);
|
|
1276
|
-
if (extension) {
|
|
1277
|
-
if (extension.kind !== graphql_1.Kind.UNION_TYPE_EXTENSION) {
|
|
1278
|
-
factory.errors.push((0, errors_1.incompatibleExtensionKindsError)(node, extension.kind));
|
|
1279
|
-
return false;
|
|
1280
|
-
}
|
|
1281
|
-
factory.extractDirectives(node, extension.directives);
|
|
1282
|
-
}
|
|
1283
|
-
else {
|
|
1284
|
-
factory.extensionContainerByTypeName.set(name, {
|
|
1285
|
-
directives: factory.extractDirectives(node, new Map()),
|
|
1286
|
-
kind: node.kind,
|
|
1287
|
-
name: node.name,
|
|
1288
|
-
types: factory.extractUniqueUnionMembers([...node.types], new Map()),
|
|
1289
|
-
});
|
|
556
|
+
(0, walkers_1.upsertDirectiveAndSchemaDefinitions)(this, document);
|
|
557
|
+
(0, walkers_1.upsertParentsAndChildren)(this, document);
|
|
558
|
+
(0, walkers_1.consolidateAuthorizationDirectives)(this, document);
|
|
559
|
+
for (const interfaceTypeName of this.interfaceTypeNamesWithAuthorizationDirectives) {
|
|
560
|
+
const interfaceAuthorizationData = this.authorizationDataByParentTypeName.get(interfaceTypeName);
|
|
561
|
+
if (!interfaceAuthorizationData) {
|
|
562
|
+
continue;
|
|
563
|
+
}
|
|
564
|
+
const concreteTypeNames = this.abstractToConcreteTypeNames.get(interfaceTypeName);
|
|
565
|
+
for (const concreteTypeName of concreteTypeNames || []) {
|
|
566
|
+
const concreteAuthorizationData = (0, utils_3.getValueOrDefault)(this.authorizationDataByParentTypeName, concreteTypeName, () => (0, utils_3.newAuthorizationData)(concreteTypeName));
|
|
567
|
+
for (const [fieldName, interfaceFieldAuthorizationData,] of interfaceAuthorizationData.fieldAuthorizationDataByFieldName) {
|
|
568
|
+
if (!(0, utils_3.upsertFieldAuthorizationData)(concreteAuthorizationData.fieldAuthorizationDataByFieldName, interfaceFieldAuthorizationData)) {
|
|
569
|
+
this.invalidOrScopesHostPaths.add(`${concreteTypeName}.${fieldName}`);
|
|
1290
570
|
}
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
571
|
+
}
|
|
572
|
+
}
|
|
573
|
+
}
|
|
574
|
+
// Apply inherited leaf authorization that was not applied to interface fields of that type earlier
|
|
575
|
+
for (const [typeName, fieldAuthorizationDatas] of this.heirFieldAuthorizationDataByTypeName) {
|
|
576
|
+
const authorizationData = this.authorizationDataByParentTypeName.get(typeName);
|
|
577
|
+
if (!authorizationData) {
|
|
578
|
+
continue;
|
|
579
|
+
}
|
|
580
|
+
for (const fieldAuthorizationData of fieldAuthorizationDatas) {
|
|
581
|
+
if (!(0, utils_3.mergeAuthorizationDataByAND)(authorizationData, fieldAuthorizationData)) {
|
|
582
|
+
this.invalidOrScopesHostPaths.add(`${typeName}.${fieldAuthorizationData.fieldName}`);
|
|
583
|
+
}
|
|
584
|
+
}
|
|
585
|
+
}
|
|
586
|
+
if (this.invalidOrScopesHostPaths.size > 0) {
|
|
587
|
+
this.errors.push((0, errors_1.orScopesLimitError)(utils_3.maxOrScopes, [...this.invalidOrScopesHostPaths]));
|
|
588
|
+
}
|
|
1298
589
|
const definitions = [];
|
|
1299
590
|
for (const directiveDefinition of constants_1.BASE_DIRECTIVE_DEFINITIONS) {
|
|
1300
591
|
definitions.push(directiveDefinition);
|
|
1301
592
|
}
|
|
1302
593
|
definitions.push(constants_1.FIELD_SET_SCALAR_DEFINITION);
|
|
1303
|
-
if (
|
|
594
|
+
if (this.isSubgraphVersionTwo) {
|
|
1304
595
|
for (const directiveDefinition of constants_1.VERSION_TWO_DIRECTIVE_DEFINITIONS) {
|
|
1305
596
|
definitions.push(directiveDefinition);
|
|
1306
|
-
this.
|
|
597
|
+
this.directiveDefinitionByDirectiveName.set(directiveDefinition.name.value, directiveDefinition);
|
|
1307
598
|
}
|
|
1308
599
|
definitions.push(constants_1.SCOPE_SCALAR_DEFINITION);
|
|
1309
600
|
}
|
|
@@ -1311,11 +602,11 @@ class NormalizationFactory {
|
|
|
1311
602
|
definitions.push(directiveDefinition);
|
|
1312
603
|
}
|
|
1313
604
|
if (this.schemaDefinition.operationTypes.size > 0) {
|
|
1314
|
-
definitions.push((0,
|
|
605
|
+
definitions.push((0, utils_4.getSchemaNodeByData)(this.schemaDefinition, this.errors, this.directiveDefinitionByDirectiveName));
|
|
1315
606
|
}
|
|
1316
607
|
const validExtensionOrphans = new Set();
|
|
1317
608
|
const parentsToIgnore = new Set();
|
|
1318
|
-
for (const [extensionTypeName,
|
|
609
|
+
for (const [extensionTypeName, parentExtensionData] of this.parentExtensionDataByTypeName) {
|
|
1319
610
|
const isEntity = this.entityContainerByTypeName.has(extensionTypeName);
|
|
1320
611
|
const configurationData = {
|
|
1321
612
|
fieldNames: new Set(),
|
|
@@ -1323,91 +614,91 @@ class NormalizationFactory {
|
|
|
1323
614
|
typeName: extensionTypeName,
|
|
1324
615
|
};
|
|
1325
616
|
this.configurationDataMap.set(extensionTypeName, configurationData);
|
|
1326
|
-
if (
|
|
617
|
+
if (parentExtensionData.kind === graphql_1.Kind.OBJECT_TYPE_EXTENSION) {
|
|
1327
618
|
if (this.operationTypeNames.has(extensionTypeName)) {
|
|
1328
|
-
|
|
1329
|
-
|
|
619
|
+
parentExtensionData.fieldDataByFieldName.delete(string_constants_1.SERVICE_FIELD);
|
|
620
|
+
parentExtensionData.fieldDataByFieldName.delete(string_constants_1.ENTITIES_FIELD);
|
|
1330
621
|
}
|
|
1331
|
-
(0, utils_2.addNonExternalFieldsToSet)(
|
|
622
|
+
(0, utils_2.addNonExternalFieldsToSet)(parentExtensionData.fieldDataByFieldName, configurationData.fieldNames);
|
|
1332
623
|
}
|
|
1333
|
-
const
|
|
1334
|
-
if (!
|
|
1335
|
-
if (
|
|
624
|
+
const parentDefinitionData = this.parentDefinitionDataByTypeName.get(extensionTypeName);
|
|
625
|
+
if (!parentDefinitionData) {
|
|
626
|
+
if (parentExtensionData.kind !== graphql_1.Kind.OBJECT_TYPE_EXTENSION) {
|
|
1336
627
|
this.errors.push((0, errors_1.noBaseTypeExtensionError)(extensionTypeName));
|
|
1337
628
|
}
|
|
1338
629
|
else {
|
|
1339
|
-
this.validateInterfaceImplementations(
|
|
630
|
+
this.validateInterfaceImplementations(parentExtensionData);
|
|
1340
631
|
validExtensionOrphans.add(extensionTypeName);
|
|
1341
|
-
definitions.push((0,
|
|
632
|
+
definitions.push((0, utils_4.getParentWithFieldsNodeByData)(parentExtensionData, this.errors, this.directiveDefinitionByDirectiveName, this.authorizationDataByParentTypeName));
|
|
1342
633
|
}
|
|
1343
634
|
continue;
|
|
1344
635
|
}
|
|
1345
|
-
if (!(0, utils_1.areBaseAndExtensionKindsCompatible)(
|
|
1346
|
-
this.errors.push((0, errors_1.incompatibleExtensionError)(extensionTypeName,
|
|
636
|
+
if (!(0, utils_1.areBaseAndExtensionKindsCompatible)(parentDefinitionData.kind, parentExtensionData.kind, extensionTypeName)) {
|
|
637
|
+
this.errors.push((0, errors_1.incompatibleExtensionError)(extensionTypeName, parentDefinitionData.kind, parentExtensionData.kind));
|
|
1347
638
|
continue;
|
|
1348
639
|
}
|
|
1349
|
-
switch (
|
|
640
|
+
switch (parentDefinitionData.kind) {
|
|
1350
641
|
case graphql_1.Kind.ENUM_TYPE_DEFINITION:
|
|
1351
|
-
const
|
|
1352
|
-
for (const [valueName, enumValueDefinitionNode] of
|
|
1353
|
-
if (!
|
|
1354
|
-
|
|
642
|
+
const enumExtensionData = parentExtensionData;
|
|
643
|
+
for (const [valueName, enumValueDefinitionNode] of enumExtensionData.enumValueDataByValueName) {
|
|
644
|
+
if (!parentDefinitionData.enumValueDataByValueName.has(valueName)) {
|
|
645
|
+
parentDefinitionData.enumValueDataByValueName.set(valueName, enumValueDefinitionNode);
|
|
1355
646
|
continue;
|
|
1356
647
|
}
|
|
1357
648
|
this.errors.push((0, errors_1.duplicateEnumValueDefinitionError)(valueName, extensionTypeName));
|
|
1358
649
|
}
|
|
1359
|
-
definitions.push((0,
|
|
650
|
+
definitions.push((0, utils_4.getEnumNodeByData)(parentDefinitionData, this.errors, this.directiveDefinitionByDirectiveName, this.authorizationDataByParentTypeName, enumExtensionData));
|
|
1360
651
|
break;
|
|
1361
652
|
case graphql_1.Kind.INPUT_OBJECT_TYPE_DEFINITION:
|
|
1362
|
-
const
|
|
1363
|
-
for (const [fieldName, inputValueDefinitionNode] of
|
|
1364
|
-
if (!
|
|
1365
|
-
|
|
653
|
+
const inputObjectExtensionData = parentExtensionData;
|
|
654
|
+
for (const [fieldName, inputValueDefinitionNode] of inputObjectExtensionData.inputValueDataByValueName) {
|
|
655
|
+
if (!parentDefinitionData.inputValueDataByValueName.has(fieldName)) {
|
|
656
|
+
parentDefinitionData.inputValueDataByValueName.set(fieldName, inputValueDefinitionNode);
|
|
1366
657
|
continue;
|
|
1367
658
|
}
|
|
1368
659
|
this.errors.push((0, errors_1.duplicateFieldDefinitionError)(fieldName, extensionTypeName));
|
|
1369
660
|
}
|
|
1370
|
-
definitions.push((0,
|
|
661
|
+
definitions.push((0, utils_4.getInputObjectNodeByData)(parentDefinitionData, this.errors, this.directiveDefinitionByDirectiveName, this.authorizationDataByParentTypeName, inputObjectExtensionData));
|
|
1371
662
|
break;
|
|
1372
663
|
case graphql_1.Kind.INTERFACE_TYPE_DEFINITION:
|
|
1373
664
|
// intentional fallthrough
|
|
1374
665
|
case graphql_1.Kind.OBJECT_TYPE_DEFINITION:
|
|
1375
|
-
const
|
|
666
|
+
const extensionWithFieldsData = parentExtensionData;
|
|
1376
667
|
const operationTypeNode = this.operationTypeNames.get(extensionTypeName);
|
|
1377
668
|
if (operationTypeNode) {
|
|
1378
|
-
|
|
1379
|
-
|
|
669
|
+
extensionWithFieldsData.fieldDataByFieldName.delete(string_constants_1.SERVICE_FIELD);
|
|
670
|
+
extensionWithFieldsData.fieldDataByFieldName.delete(string_constants_1.ENTITIES_FIELD);
|
|
1380
671
|
}
|
|
1381
|
-
for (const [fieldName,
|
|
1382
|
-
if (
|
|
672
|
+
for (const [fieldName, fieldData] of extensionWithFieldsData.fieldDataByFieldName) {
|
|
673
|
+
if (fieldData.argumentDataByArgumentName.size > 0) {
|
|
1383
674
|
// Arguments can only be fully validated once all parents types are known
|
|
1384
|
-
this.validateArguments(
|
|
675
|
+
this.validateArguments(fieldData, `${extensionTypeName}.${fieldName}`);
|
|
1385
676
|
}
|
|
1386
|
-
if (
|
|
677
|
+
if (parentDefinitionData.fieldDataByFieldName.has(fieldName)) {
|
|
1387
678
|
this.errors.push((0, errors_1.duplicateFieldDefinitionError)(fieldName, extensionTypeName));
|
|
1388
679
|
continue;
|
|
1389
680
|
}
|
|
1390
|
-
|
|
1391
|
-
if (!
|
|
681
|
+
parentDefinitionData.fieldDataByFieldName.set(fieldName, fieldData);
|
|
682
|
+
if (!fieldData.argumentDataByArgumentName.has(string_constants_1.EXTERNAL)) {
|
|
1392
683
|
configurationData.fieldNames.add(fieldName);
|
|
1393
684
|
}
|
|
1394
685
|
}
|
|
1395
|
-
this.mergeUniqueInterfaces(
|
|
1396
|
-
this.validateInterfaceImplementations(
|
|
1397
|
-
definitions.push((0,
|
|
686
|
+
this.mergeUniqueInterfaces(extensionWithFieldsData.implementedInterfaceTypeNames, parentDefinitionData.implementedInterfaceTypeNames, extensionTypeName);
|
|
687
|
+
this.validateInterfaceImplementations(parentDefinitionData);
|
|
688
|
+
definitions.push((0, utils_4.getParentWithFieldsNodeByData)(parentDefinitionData, this.errors, this.directiveDefinitionByDirectiveName, this.authorizationDataByParentTypeName, extensionWithFieldsData));
|
|
1398
689
|
// Interfaces and objects must define at least one field
|
|
1399
|
-
if (
|
|
1400
|
-
|
|
690
|
+
if (parentDefinitionData.fieldDataByFieldName.size < 1 &&
|
|
691
|
+
!(0, utils_2.isNodeQuery)(extensionTypeName, operationTypeNode)) {
|
|
692
|
+
this.errors.push((0, errors_1.noFieldDefinitionsError)((0, utils_3.kindToTypeString)(parentDefinitionData.kind), extensionTypeName));
|
|
1401
693
|
}
|
|
1402
694
|
// Add the non-external base type field names to the configuration data
|
|
1403
|
-
(0, utils_2.addNonExternalFieldsToSet)(
|
|
695
|
+
(0, utils_2.addNonExternalFieldsToSet)(parentDefinitionData.fieldDataByFieldName, configurationData.fieldNames);
|
|
1404
696
|
break;
|
|
1405
697
|
case graphql_1.Kind.SCALAR_TYPE_DEFINITION:
|
|
1406
|
-
definitions.push((0,
|
|
698
|
+
definitions.push((0, utils_4.getScalarNodeByData)(parentDefinitionData, this.errors, this.directiveDefinitionByDirectiveName, parentExtensionData));
|
|
1407
699
|
break;
|
|
1408
700
|
case graphql_1.Kind.UNION_TYPE_DEFINITION:
|
|
1409
|
-
|
|
1410
|
-
definitions.push((0, utils_2.unionContainerToNode)(this, baseType, unionExtension));
|
|
701
|
+
definitions.push((0, utils_4.getUnionNodeByData)(parentDefinitionData, this.errors, this.directiveDefinitionByDirectiveName, parentExtensionData));
|
|
1411
702
|
break;
|
|
1412
703
|
default:
|
|
1413
704
|
throw (0, errors_1.unexpectedKindFatalError)(extensionTypeName);
|
|
@@ -1415,16 +706,16 @@ class NormalizationFactory {
|
|
|
1415
706
|
// At this point, the base type has been dealt with, so it doesn't need to be dealt with again
|
|
1416
707
|
parentsToIgnore.add(extensionTypeName);
|
|
1417
708
|
}
|
|
1418
|
-
for (const [parentTypeName,
|
|
709
|
+
for (const [parentTypeName, parentDefinitionData] of this.parentDefinitionDataByTypeName) {
|
|
1419
710
|
if (parentsToIgnore.has(parentTypeName)) {
|
|
1420
711
|
continue;
|
|
1421
712
|
}
|
|
1422
|
-
switch (
|
|
713
|
+
switch (parentDefinitionData.kind) {
|
|
1423
714
|
case graphql_1.Kind.ENUM_TYPE_DEFINITION:
|
|
1424
|
-
definitions.push((0,
|
|
715
|
+
definitions.push((0, utils_4.getEnumNodeByData)(parentDefinitionData, this.errors, this.directiveDefinitionByDirectiveName, this.authorizationDataByParentTypeName));
|
|
1425
716
|
break;
|
|
1426
717
|
case graphql_1.Kind.INPUT_OBJECT_TYPE_DEFINITION:
|
|
1427
|
-
definitions.push((0,
|
|
718
|
+
definitions.push((0, utils_4.getInputObjectNodeByData)(parentDefinitionData, this.errors, this.directiveDefinitionByDirectiveName, this.authorizationDataByParentTypeName));
|
|
1428
719
|
break;
|
|
1429
720
|
case graphql_1.Kind.INTERFACE_TYPE_DEFINITION:
|
|
1430
721
|
// intentional fallthrough
|
|
@@ -1432,15 +723,15 @@ class NormalizationFactory {
|
|
|
1432
723
|
const isEntity = this.entityContainerByTypeName.has(parentTypeName);
|
|
1433
724
|
const operationTypeNode = this.operationTypeNames.get(parentTypeName);
|
|
1434
725
|
if (operationTypeNode) {
|
|
1435
|
-
|
|
1436
|
-
|
|
726
|
+
parentDefinitionData.fieldDataByFieldName.delete(string_constants_1.SERVICE_FIELD);
|
|
727
|
+
parentDefinitionData.fieldDataByFieldName.delete(string_constants_1.ENTITIES_FIELD);
|
|
1437
728
|
}
|
|
1438
729
|
if (this.parentsWithChildArguments.has(parentTypeName)) {
|
|
1439
|
-
if (
|
|
1440
|
-
|
|
730
|
+
if (parentDefinitionData.kind !== graphql_1.Kind.OBJECT_TYPE_DEFINITION &&
|
|
731
|
+
parentDefinitionData.kind !== graphql_1.Kind.INTERFACE_TYPE_DEFINITION) {
|
|
1441
732
|
continue;
|
|
1442
733
|
}
|
|
1443
|
-
for (const [fieldName, fieldContainer] of
|
|
734
|
+
for (const [fieldName, fieldContainer] of parentDefinitionData.fieldDataByFieldName) {
|
|
1444
735
|
// Arguments can only be fully validated once all parents types are known
|
|
1445
736
|
this.validateArguments(fieldContainer, `${parentTypeName}.${fieldName}`);
|
|
1446
737
|
}
|
|
@@ -1462,19 +753,19 @@ class NormalizationFactory {
|
|
|
1462
753
|
configurationData.events = events;
|
|
1463
754
|
}
|
|
1464
755
|
this.configurationDataMap.set(parentTypeName, configurationData);
|
|
1465
|
-
(0, utils_2.addNonExternalFieldsToSet)(
|
|
1466
|
-
this.validateInterfaceImplementations(
|
|
1467
|
-
definitions.push((0,
|
|
756
|
+
(0, utils_2.addNonExternalFieldsToSet)(parentDefinitionData.fieldDataByFieldName, configurationData.fieldNames);
|
|
757
|
+
this.validateInterfaceImplementations(parentDefinitionData);
|
|
758
|
+
definitions.push((0, utils_4.getParentWithFieldsNodeByData)(parentDefinitionData, this.errors, this.directiveDefinitionByDirectiveName, this.authorizationDataByParentTypeName));
|
|
1468
759
|
// interfaces and objects must define at least one field
|
|
1469
|
-
if (
|
|
1470
|
-
this.errors.push((0, errors_1.noFieldDefinitionsError)((0, utils_3.kindToTypeString)(
|
|
760
|
+
if (parentDefinitionData.fieldDataByFieldName.size < 1 && !(0, utils_2.isNodeQuery)(parentTypeName, operationTypeNode)) {
|
|
761
|
+
this.errors.push((0, errors_1.noFieldDefinitionsError)((0, utils_3.kindToTypeString)(parentDefinitionData.kind), parentTypeName));
|
|
1471
762
|
}
|
|
1472
763
|
break;
|
|
1473
764
|
case graphql_1.Kind.SCALAR_TYPE_DEFINITION:
|
|
1474
|
-
definitions.push((0,
|
|
765
|
+
definitions.push((0, utils_4.getScalarNodeByData)(parentDefinitionData, this.errors, this.directiveDefinitionByDirectiveName));
|
|
1475
766
|
break;
|
|
1476
767
|
case graphql_1.Kind.UNION_TYPE_DEFINITION:
|
|
1477
|
-
definitions.push((0,
|
|
768
|
+
definitions.push((0, utils_4.getUnionNodeByData)(parentDefinitionData, this.errors, this.directiveDefinitionByDirectiveName));
|
|
1478
769
|
break;
|
|
1479
770
|
default:
|
|
1480
771
|
throw (0, errors_1.unexpectedKindFatalError)(parentTypeName);
|
|
@@ -1488,12 +779,13 @@ class NormalizationFactory {
|
|
|
1488
779
|
const operationTypeName = node ? (0, type_merging_1.getNamedTypeForChild)(`schema.${operationType}`, node.type) : defaultTypeName;
|
|
1489
780
|
// If a custom type is used, the default type should not be defined
|
|
1490
781
|
if (operationTypeName !== defaultTypeName &&
|
|
1491
|
-
(this.
|
|
782
|
+
(this.parentDefinitionDataByTypeName.has(defaultTypeName) ||
|
|
783
|
+
this.parentExtensionDataByTypeName.has(defaultTypeName))) {
|
|
1492
784
|
this.errors.push((0, errors_1.invalidRootTypeDefinitionError)(operationType, operationTypeName, defaultTypeName));
|
|
1493
785
|
continue;
|
|
1494
786
|
}
|
|
1495
|
-
const object = this.
|
|
1496
|
-
const extension = this.
|
|
787
|
+
const object = this.parentDefinitionDataByTypeName.get(operationTypeName);
|
|
788
|
+
const extension = this.parentExtensionDataByTypeName.get(operationTypeName);
|
|
1497
789
|
// Node is truthy if an operation type was explicitly declared
|
|
1498
790
|
if (node) {
|
|
1499
791
|
// If the type is not defined in the schema, it's always an error
|
|
@@ -1523,12 +815,11 @@ class NormalizationFactory {
|
|
|
1523
815
|
}
|
|
1524
816
|
// Root types fields whose response type is an extension orphan could be valid through a federated graph
|
|
1525
817
|
// However, the field would have to be shareable to ever be valid TODO
|
|
1526
|
-
for (const
|
|
1527
|
-
const fieldName = fieldContainer.name;
|
|
818
|
+
for (const [fieldName, fieldData] of container.fieldDataByFieldName) {
|
|
1528
819
|
const fieldPath = `${operationTypeName}.${fieldName}`;
|
|
1529
|
-
const fieldTypeName = (0, type_merging_1.getNamedTypeForChild)(fieldPath,
|
|
820
|
+
const fieldTypeName = (0, type_merging_1.getNamedTypeForChild)(fieldPath, fieldData.node.type);
|
|
1530
821
|
if (!constants_1.BASE_SCALARS.has(fieldTypeName) &&
|
|
1531
|
-
!this.
|
|
822
|
+
!this.parentDefinitionDataByTypeName.has(fieldTypeName) &&
|
|
1532
823
|
!validExtensionOrphans.has(fieldTypeName)) {
|
|
1533
824
|
this.errors.push((0, errors_1.undefinedTypeError)(fieldTypeName));
|
|
1534
825
|
}
|
|
@@ -1536,17 +827,18 @@ class NormalizationFactory {
|
|
|
1536
827
|
}
|
|
1537
828
|
}
|
|
1538
829
|
for (const referencedTypeName of this.referencedTypeNames) {
|
|
1539
|
-
if (this.
|
|
830
|
+
if (this.parentDefinitionDataByTypeName.has(referencedTypeName) ||
|
|
1540
831
|
this.entityContainerByTypeName.has(referencedTypeName)) {
|
|
1541
832
|
continue;
|
|
1542
833
|
}
|
|
1543
|
-
const extension = this.
|
|
834
|
+
const extension = this.parentExtensionDataByTypeName.get(referencedTypeName);
|
|
1544
835
|
if (!extension || extension.kind !== graphql_1.Kind.OBJECT_TYPE_EXTENSION) {
|
|
1545
836
|
this.errors.push((0, errors_1.undefinedTypeError)(referencedTypeName));
|
|
1546
837
|
}
|
|
1547
838
|
}
|
|
1548
839
|
for (const [parentTypeName, fieldSetContainers] of this.fieldSetContainerByTypeName) {
|
|
1549
|
-
const parentContainer = this.
|
|
840
|
+
const parentContainer = this.parentDefinitionDataByTypeName.get(parentTypeName) ||
|
|
841
|
+
this.parentExtensionDataByTypeName.get(parentTypeName);
|
|
1550
842
|
if (!parentContainer ||
|
|
1551
843
|
(parentContainer.kind !== graphql_1.Kind.OBJECT_TYPE_DEFINITION &&
|
|
1552
844
|
parentContainer.kind != graphql_1.Kind.OBJECT_TYPE_EXTENSION &&
|
|
@@ -1565,7 +857,6 @@ class NormalizationFactory {
|
|
|
1565
857
|
kind: graphql_1.Kind.DOCUMENT,
|
|
1566
858
|
definitions,
|
|
1567
859
|
};
|
|
1568
|
-
(0, subgraph_1.walkSubgraphToApplyFieldAuthorization)(factory, newAST);
|
|
1569
860
|
return {
|
|
1570
861
|
normalizationResult: {
|
|
1571
862
|
authorizationDataByParentTypeName: this.authorizationDataByParentTypeName,
|
|
@@ -1574,12 +865,12 @@ class NormalizationFactory {
|
|
|
1574
865
|
configurationDataMap: this.configurationDataMap,
|
|
1575
866
|
entityContainerByTypeName: this.entityContainerByTypeName,
|
|
1576
867
|
entityInterfaces: this.entityInterfaces,
|
|
1577
|
-
|
|
868
|
+
parentExtensionDataByTypeName: this.parentExtensionDataByTypeName,
|
|
1578
869
|
isVersionTwo: this.isSubgraphVersionTwo,
|
|
1579
870
|
keyFieldNamesByParentTypeName: this.keyFieldNamesByParentTypeName,
|
|
1580
871
|
operationTypes: this.operationTypeNames,
|
|
1581
872
|
overridesByTargetSubgraphName: this.overridesByTargetSubgraphName,
|
|
1582
|
-
|
|
873
|
+
parentDataByTypeName: this.parentDefinitionDataByTypeName,
|
|
1583
874
|
subgraphAST: newAST,
|
|
1584
875
|
subgraphString: (0, graphql_1.print)(newAST),
|
|
1585
876
|
schema: (0, buildASTSchema_1.buildASTSchema)(newAST, { assumeValid: true }),
|
|
@@ -1595,10 +886,11 @@ function batchNormalize(subgraphs) {
|
|
|
1595
886
|
const allOverridesByTargetSubgraphName = new Map();
|
|
1596
887
|
const overrideSourceSubgraphNamesByFieldPath = new Map();
|
|
1597
888
|
const duplicateOverriddenFieldPaths = new Set();
|
|
1598
|
-
const
|
|
889
|
+
const parentDefinitionDataMapsBySubgraphName = new Map();
|
|
1599
890
|
const subgraphNames = new Set();
|
|
1600
891
|
const nonUniqueSubgraphNames = new Set();
|
|
1601
892
|
const invalidNameErrorMessages = [];
|
|
893
|
+
const invalidOrScopesHostPaths = new Set();
|
|
1602
894
|
const warnings = [];
|
|
1603
895
|
const validationErrors = [];
|
|
1604
896
|
// Record the subgraph names first, so that subgraph references can be validated
|
|
@@ -1622,9 +914,9 @@ function batchNormalize(subgraphs) {
|
|
|
1622
914
|
validationErrors.push((0, errors_1.subgraphValidationError)(subgraphName, [errors_1.subgraphValidationFailureError]));
|
|
1623
915
|
continue;
|
|
1624
916
|
}
|
|
1625
|
-
|
|
917
|
+
parentDefinitionDataMapsBySubgraphName.set(subgraphName, normalizationResult.parentDataByTypeName);
|
|
1626
918
|
for (const authorizationData of normalizationResult.authorizationDataByParentTypeName.values()) {
|
|
1627
|
-
(0, utils_3.upsertAuthorizationData)(authorizationDataByParentTypeName, authorizationData);
|
|
919
|
+
(0, utils_3.upsertAuthorizationData)(authorizationDataByParentTypeName, authorizationData, invalidOrScopesHostPaths);
|
|
1628
920
|
}
|
|
1629
921
|
for (const entityContainer of normalizationResult.entityContainerByTypeName.values()) {
|
|
1630
922
|
(0, utils_3.upsertEntityContainer)(entityContainerByTypeName, entityContainer);
|
|
@@ -1634,13 +926,13 @@ function batchNormalize(subgraphs) {
|
|
|
1634
926
|
configurationDataMap: normalizationResult.configurationDataMap,
|
|
1635
927
|
definitions: normalizationResult.subgraphAST,
|
|
1636
928
|
entityInterfaces: normalizationResult.entityInterfaces,
|
|
1637
|
-
|
|
929
|
+
parentExtensionDataByTypeName: normalizationResult.parentExtensionDataByTypeName,
|
|
1638
930
|
keyFieldNamesByParentTypeName: normalizationResult.keyFieldNamesByParentTypeName,
|
|
1639
931
|
isVersionTwo: normalizationResult.isVersionTwo,
|
|
1640
932
|
name: subgraphName,
|
|
1641
933
|
operationTypes: normalizationResult.operationTypes,
|
|
1642
934
|
overriddenFieldNamesByParentTypeName: new Map(),
|
|
1643
|
-
|
|
935
|
+
parentDataByTypeName: normalizationResult.parentDataByTypeName,
|
|
1644
936
|
schema: normalizationResult.schema,
|
|
1645
937
|
url: subgraph.url,
|
|
1646
938
|
});
|
|
@@ -1673,6 +965,9 @@ function batchNormalize(subgraphs) {
|
|
|
1673
965
|
}
|
|
1674
966
|
}
|
|
1675
967
|
const allErrors = [];
|
|
968
|
+
if (invalidOrScopesHostPaths.size > 0) {
|
|
969
|
+
allErrors.push((0, errors_1.orScopesLimitError)(utils_3.maxOrScopes, [...invalidOrScopesHostPaths]));
|
|
970
|
+
}
|
|
1676
971
|
if (invalidNameErrorMessages.length > 0 || nonUniqueSubgraphNames.size > 0) {
|
|
1677
972
|
allErrors.push((0, errors_1.invalidSubgraphNamesError)([...nonUniqueSubgraphNames], invalidNameErrorMessages));
|
|
1678
973
|
}
|