@wundergraph/composition 0.15.0 → 0.17.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/ast/utils.d.ts +9 -2
- package/dist/ast/utils.js.map +1 -1
- package/dist/errors/errors.js +1 -2
- package/dist/errors/errors.js.map +1 -1
- package/dist/federation/federation-factory.d.ts +18 -14
- package/dist/federation/federation-factory.js +246 -83
- package/dist/federation/federation-factory.js.map +1 -1
- package/dist/federation/utils.d.ts +7 -11
- package/dist/federation/utils.js.map +1 -1
- package/dist/index.d.ts +6 -6
- package/dist/index.js +6 -6
- package/dist/index.js.map +1 -1
- package/dist/normalization/normalization-factory.d.ts +24 -14
- package/dist/normalization/normalization-factory.js +236 -120
- package/dist/normalization/normalization-factory.js.map +1 -1
- package/dist/normalization/utils.d.ts +3 -2
- package/dist/normalization/utils.js +21 -11
- package/dist/normalization/utils.js.map +1 -1
- package/dist/{subgraph/field-configuration.d.ts → router-configuration/router-configuration.d.ts} +13 -10
- package/dist/{subgraph/field-configuration.js → router-configuration/router-configuration.js} +1 -1
- package/dist/router-configuration/router-configuration.js.map +1 -0
- package/dist/subgraph/subgraph.d.ts +8 -4
- package/dist/subgraph/subgraph.js +81 -78
- package/dist/subgraph/subgraph.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/utils/constants.d.ts +2 -1
- package/dist/utils/constants.js +82 -27
- package/dist/utils/constants.js.map +1 -1
- package/dist/utils/string-constants.d.ts +8 -2
- package/dist/utils/string-constants.js +10 -4
- package/dist/utils/string-constants.js.map +1 -1
- package/dist/utils/utils.d.ts +42 -1
- package/dist/utils/utils.js +156 -1
- package/dist/utils/utils.js.map +1 -1
- package/package.json +2 -2
- package/dist/subgraph/field-configuration.js.map +0 -1
|
@@ -32,32 +32,34 @@ class NormalizationFactory {
|
|
|
32
32
|
abstractToConcreteTypeNames = new Map();
|
|
33
33
|
allDirectiveDefinitions = new Map();
|
|
34
34
|
argumentName = '';
|
|
35
|
+
authorizationDataByParentTypeName = new Map();
|
|
35
36
|
childName = '';
|
|
36
37
|
configurationDataMap = new Map();
|
|
37
38
|
customDirectiveDefinitions = new Map();
|
|
38
39
|
errors = [];
|
|
39
|
-
|
|
40
|
+
entityContainerByTypeName = new Map();
|
|
40
41
|
entityInterfaces = new Map();
|
|
41
|
-
|
|
42
|
+
extensionContainerByTypeName = new Map();
|
|
42
43
|
isCurrentParentExtension = false;
|
|
43
44
|
isCurrentParentRootType = false;
|
|
44
45
|
isSubgraphVersionTwo = false;
|
|
45
|
-
|
|
46
|
+
fieldSetContainerByTypeName = new Map();
|
|
46
47
|
handledRepeatedDirectivesByHostPath = new Map();
|
|
47
48
|
lastParentNodeKind = graphql_1.Kind.NULL;
|
|
48
49
|
lastChildNodeKind = graphql_1.Kind.NULL;
|
|
50
|
+
leafTypeNamesWithAuthorizationDirectives = new Set();
|
|
49
51
|
keyFieldNamesByParentTypeName = new Map();
|
|
50
52
|
operationTypeNames = new Map();
|
|
51
|
-
|
|
53
|
+
parentContainerByTypeName = new Map();
|
|
52
54
|
parentTypeName = '';
|
|
53
55
|
parentsWithChildArguments = new Set();
|
|
54
56
|
eventsConfigurations = new Map();
|
|
55
57
|
overridesByTargetSubgraphName = new Map();
|
|
56
58
|
schemaDefinition;
|
|
57
|
-
subgraphName;
|
|
58
59
|
referencedDirectives = new Set();
|
|
59
60
|
referencedTypeNames = new Set();
|
|
60
61
|
warnings = [];
|
|
62
|
+
subgraphName;
|
|
61
63
|
constructor(subgraphName) {
|
|
62
64
|
for (const baseDirectiveDefinition of constants_1.BASE_DIRECTIVE_DEFINITIONS) {
|
|
63
65
|
this.allDirectiveDefinitions.set(baseDirectiveDefinition.name.value, baseDirectiveDefinition);
|
|
@@ -74,7 +76,7 @@ class NormalizationFactory {
|
|
|
74
76
|
if (constants_1.BASE_SCALARS.has(namedType)) {
|
|
75
77
|
return { hasUnhandledError: false, typeString: '' };
|
|
76
78
|
}
|
|
77
|
-
const parentContainer = this.
|
|
79
|
+
const parentContainer = this.parentContainerByTypeName.get(namedType);
|
|
78
80
|
if (!parentContainer) {
|
|
79
81
|
this.errors.push((0, errors_1.undefinedTypeError)(namedType));
|
|
80
82
|
return { hasUnhandledError: false, typeString: '' };
|
|
@@ -138,6 +140,75 @@ class NormalizationFactory {
|
|
|
138
140
|
}
|
|
139
141
|
return map;
|
|
140
142
|
}
|
|
143
|
+
extractDirectivesAndAuthorization(node, map) {
|
|
144
|
+
if (!node.directives) {
|
|
145
|
+
return map;
|
|
146
|
+
}
|
|
147
|
+
const authorizationDirectives = [];
|
|
148
|
+
for (const directive of node.directives) {
|
|
149
|
+
const directiveName = directive.name.value;
|
|
150
|
+
if (directiveName === string_constants_1.EXTENDS) {
|
|
151
|
+
continue;
|
|
152
|
+
}
|
|
153
|
+
if (directiveName === string_constants_1.AUTHENTICATED || directiveName === string_constants_1.REQUIRES_SCOPES) {
|
|
154
|
+
authorizationDirectives.push(directive);
|
|
155
|
+
}
|
|
156
|
+
const existingDirectives = map.get(directiveName);
|
|
157
|
+
if (existingDirectives) {
|
|
158
|
+
existingDirectives.push(directive);
|
|
159
|
+
continue;
|
|
160
|
+
}
|
|
161
|
+
map.set(directiveName, [directive]);
|
|
162
|
+
}
|
|
163
|
+
if (authorizationDirectives.length < 1) {
|
|
164
|
+
return map;
|
|
165
|
+
}
|
|
166
|
+
if (node.kind === graphql_1.Kind.ENUM_TYPE_DEFINITION ||
|
|
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) {
|
|
170
|
+
this.leafTypeNamesWithAuthorizationDirectives.add(this.parentTypeName);
|
|
171
|
+
}
|
|
172
|
+
const parentAuthorizationData = (0, utils_3.getValueOrDefault)(this.authorizationDataByParentTypeName, this.parentTypeName, () => (0, utils_3.newAuthorizationData)(this.parentTypeName));
|
|
173
|
+
const authorizationData = (0, utils_3.getAuthorizationDataToUpdate)(parentAuthorizationData, node, this.childName);
|
|
174
|
+
for (const directiveNode of authorizationDirectives) {
|
|
175
|
+
const directiveName = directiveNode.name.value;
|
|
176
|
+
if (directiveName === string_constants_1.AUTHENTICATED) {
|
|
177
|
+
authorizationData.requiresAuthentication = true;
|
|
178
|
+
continue;
|
|
179
|
+
}
|
|
180
|
+
if (!directiveNode.arguments || directiveNode.arguments.length !== 1) {
|
|
181
|
+
break;
|
|
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) {
|
|
192
|
+
continue;
|
|
193
|
+
}
|
|
194
|
+
for (const scopes of orScopes) {
|
|
195
|
+
if (scopes.kind !== graphql_1.Kind.LIST) {
|
|
196
|
+
return map;
|
|
197
|
+
}
|
|
198
|
+
const andScopes = new Set();
|
|
199
|
+
for (const scope of scopes.values) {
|
|
200
|
+
if (scope.kind !== graphql_1.Kind.STRING) {
|
|
201
|
+
return map;
|
|
202
|
+
}
|
|
203
|
+
andScopes.add(scope.value);
|
|
204
|
+
}
|
|
205
|
+
if (andScopes.size) {
|
|
206
|
+
authorizationData.requiredScopes.push(andScopes);
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
return map;
|
|
211
|
+
}
|
|
141
212
|
extractUniqueUnionMembers(members, map) {
|
|
142
213
|
for (const member of members) {
|
|
143
214
|
const name = member.name.value;
|
|
@@ -282,20 +353,20 @@ class NormalizationFactory {
|
|
|
282
353
|
}
|
|
283
354
|
handleObjectLikeExtension(node) {
|
|
284
355
|
this.isCurrentParentExtension = true;
|
|
285
|
-
const extension = this.
|
|
356
|
+
const extension = this.extensionContainerByTypeName.get(this.parentTypeName);
|
|
286
357
|
const convertedKind = this.convertKindForExtension(node);
|
|
287
358
|
if (extension) {
|
|
288
359
|
if (extension.kind !== convertedKind) {
|
|
289
360
|
this.errors.push((0, errors_1.incompatibleExtensionKindsError)(node, extension.kind));
|
|
290
361
|
return false;
|
|
291
362
|
}
|
|
292
|
-
this.
|
|
363
|
+
this.extractDirectivesAndAuthorization(node, extension.directives);
|
|
293
364
|
(0, utils_1.extractInterfaces)(node, extension.interfaces, this.errors);
|
|
294
365
|
return;
|
|
295
366
|
}
|
|
296
367
|
const isEntity = (0, utils_1.isObjectLikeNodeEntity)(node);
|
|
297
|
-
this.
|
|
298
|
-
directives: this.
|
|
368
|
+
this.extensionContainerByTypeName.set(this.parentTypeName, {
|
|
369
|
+
directives: this.extractDirectivesAndAuthorization(node, new Map()),
|
|
299
370
|
fields: new Map(),
|
|
300
371
|
interfaces: (0, utils_1.extractInterfaces)(node, new Set(), this.errors),
|
|
301
372
|
isEntity,
|
|
@@ -305,9 +376,13 @@ class NormalizationFactory {
|
|
|
305
376
|
if (node.kind === graphql_1.Kind.INTERFACE_TYPE_DEFINITION || node.kind === graphql_1.Kind.INTERFACE_TYPE_EXTENSION || !isEntity) {
|
|
306
377
|
return;
|
|
307
378
|
}
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
379
|
+
const fieldSetContainer = (0, utils_3.getValueOrDefault)(this.fieldSetContainerByTypeName, this.parentTypeName, utils_2.newFieldSetContainer);
|
|
380
|
+
this.extractKeyFieldSets(node, fieldSetContainer);
|
|
381
|
+
(0, utils_3.upsertEntityContainerProperties)(this.entityContainerByTypeName, {
|
|
382
|
+
typeName: this.parentTypeName,
|
|
383
|
+
keyFieldSets: fieldSetContainer.keys,
|
|
384
|
+
...(this.subgraphName ? { subgraphNames: [this.subgraphName] } : {}),
|
|
385
|
+
});
|
|
311
386
|
}
|
|
312
387
|
validateChildDirectives(child, hostPath) {
|
|
313
388
|
const childKind = child.node.kind;
|
|
@@ -395,7 +470,8 @@ class NormalizationFactory {
|
|
|
395
470
|
operationTypeNode === graphql_1.OperationTypeNode.MUTATION ||
|
|
396
471
|
operationTypeNode === graphql_1.OperationTypeNode.SUBSCRIPTION);
|
|
397
472
|
}
|
|
398
|
-
extractKeyFieldSets(node,
|
|
473
|
+
extractKeyFieldSets(node, fieldSetContainer) {
|
|
474
|
+
const rawFieldSets = fieldSetContainer.keys;
|
|
399
475
|
const parentTypeName = node.name.value;
|
|
400
476
|
if (!node.directives?.length) {
|
|
401
477
|
// This should never happen
|
|
@@ -414,6 +490,9 @@ class NormalizationFactory {
|
|
|
414
490
|
for (const arg of directive.arguments) {
|
|
415
491
|
const argumentName = arg.name.value;
|
|
416
492
|
if (arg.name.value === string_constants_1.RESOLVABLE) {
|
|
493
|
+
if (arg.value.kind === graphql_1.Kind.BOOLEAN && !arg.value.value) {
|
|
494
|
+
fieldSetContainer.disableEntityResolver = true;
|
|
495
|
+
}
|
|
417
496
|
continue;
|
|
418
497
|
}
|
|
419
498
|
if (arg.name.value !== string_constants_1.FIELDS) {
|
|
@@ -437,7 +516,7 @@ class NormalizationFactory {
|
|
|
437
516
|
}
|
|
438
517
|
const implementationErrorsMap = new Map();
|
|
439
518
|
for (const interfaceName of container.interfaces) {
|
|
440
|
-
const interfaceContainer = (0, utils_3.getOrThrowError)(this.
|
|
519
|
+
const interfaceContainer = (0, utils_3.getOrThrowError)(this.parentContainerByTypeName, interfaceName, string_constants_1.PARENTS);
|
|
441
520
|
if (interfaceContainer.kind !== graphql_1.Kind.INTERFACE_TYPE_DEFINITION) {
|
|
442
521
|
throw (0, errors_1.incompatibleParentKindFatalError)(interfaceName, graphql_1.Kind.INTERFACE_TYPE_DEFINITION, interfaceContainer.kind);
|
|
443
522
|
}
|
|
@@ -510,7 +589,7 @@ class NormalizationFactory {
|
|
|
510
589
|
this.errors.push((0, errors_1.unimplementedInterfaceFieldsError)(container.name.value, (0, utils_3.kindToTypeString)(container.kind), implementationErrorsMap));
|
|
511
590
|
}
|
|
512
591
|
}
|
|
513
|
-
handleOverride(node
|
|
592
|
+
handleOverride(node) {
|
|
514
593
|
if (node.name.value !== string_constants_1.OVERRIDE) {
|
|
515
594
|
return;
|
|
516
595
|
}
|
|
@@ -652,7 +731,6 @@ class NormalizationFactory {
|
|
|
652
731
|
after the visitor has visited the entire schema and the subgraph is known to be a V2 graph. Consequently,
|
|
653
732
|
allDirectiveDefinitions cannot be used to check for duplicate definitions, and another set (below) is required */
|
|
654
733
|
const definedDirectives = new Set();
|
|
655
|
-
let fieldName = '';
|
|
656
734
|
const handledRootTypes = new Set();
|
|
657
735
|
// Collect any renamed root types
|
|
658
736
|
(0, graphql_1.visit)(document, {
|
|
@@ -718,7 +796,7 @@ class NormalizationFactory {
|
|
|
718
796
|
Directive: {
|
|
719
797
|
enter(node) {
|
|
720
798
|
const name = node.name.value;
|
|
721
|
-
factory.handleOverride(node
|
|
799
|
+
factory.handleOverride(node);
|
|
722
800
|
if (constants_1.VERSION_TWO_DIRECTIVES.has(name)) {
|
|
723
801
|
factory.isSubgraphVersionTwo = true;
|
|
724
802
|
return false;
|
|
@@ -731,16 +809,17 @@ class NormalizationFactory {
|
|
|
731
809
|
},
|
|
732
810
|
EnumTypeDefinition: {
|
|
733
811
|
enter(node) {
|
|
734
|
-
const
|
|
735
|
-
if (factory.
|
|
736
|
-
factory.errors.push((0, errors_1.duplicateTypeDefinitionError)((0, utils_3.kindToTypeString)(node.kind),
|
|
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));
|
|
737
815
|
return false;
|
|
738
816
|
}
|
|
739
|
-
factory.parentTypeName =
|
|
817
|
+
factory.parentTypeName = typeName;
|
|
740
818
|
factory.lastParentNodeKind = node.kind;
|
|
741
|
-
factory.
|
|
819
|
+
const directives = factory.extractDirectivesAndAuthorization(node, new Map());
|
|
820
|
+
factory.parentContainerByTypeName.set(typeName, {
|
|
742
821
|
description: (0, utils_1.formatDescription)(node.description),
|
|
743
|
-
directives
|
|
822
|
+
directives,
|
|
744
823
|
kind: node.kind,
|
|
745
824
|
name: node.name,
|
|
746
825
|
values: new Map(),
|
|
@@ -757,17 +836,17 @@ class NormalizationFactory {
|
|
|
757
836
|
factory.parentTypeName = name;
|
|
758
837
|
factory.lastParentNodeKind = node.kind;
|
|
759
838
|
factory.isCurrentParentExtension = true;
|
|
760
|
-
const extension = factory.
|
|
839
|
+
const extension = factory.extensionContainerByTypeName.get(factory.parentTypeName);
|
|
761
840
|
if (extension) {
|
|
762
841
|
if (extension.kind !== graphql_1.Kind.ENUM_TYPE_EXTENSION) {
|
|
763
842
|
factory.errors.push((0, errors_1.incompatibleExtensionKindsError)(node, extension.kind));
|
|
764
843
|
return false;
|
|
765
844
|
}
|
|
766
|
-
factory.
|
|
845
|
+
factory.extractDirectivesAndAuthorization(node, extension.directives);
|
|
767
846
|
return;
|
|
768
847
|
}
|
|
769
|
-
factory.
|
|
770
|
-
directives: factory.
|
|
848
|
+
factory.extensionContainerByTypeName.set(name, {
|
|
849
|
+
directives: factory.extractDirectivesAndAuthorization(node, new Map()),
|
|
771
850
|
kind: node.kind,
|
|
772
851
|
name: node.name,
|
|
773
852
|
values: new Map(),
|
|
@@ -785,8 +864,8 @@ class NormalizationFactory {
|
|
|
785
864
|
factory.childName = name;
|
|
786
865
|
factory.lastChildNodeKind = node.kind;
|
|
787
866
|
const parent = factory.isCurrentParentExtension
|
|
788
|
-
? (0, utils_3.getOrThrowError)(factory.
|
|
789
|
-
: (0, utils_3.getOrThrowError)(factory.
|
|
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);
|
|
790
869
|
if (parent.kind !== graphql_1.Kind.ENUM_TYPE_DEFINITION && parent.kind !== graphql_1.Kind.ENUM_TYPE_EXTENSION) {
|
|
791
870
|
throw (0, errors_1.unexpectedKindFatalError)(name);
|
|
792
871
|
}
|
|
@@ -810,39 +889,39 @@ class NormalizationFactory {
|
|
|
810
889
|
},
|
|
811
890
|
FieldDefinition: {
|
|
812
891
|
enter(node) {
|
|
813
|
-
const
|
|
814
|
-
if (factory.isCurrentParentRootType && (
|
|
892
|
+
const fieldName = node.name.value;
|
|
893
|
+
if (factory.isCurrentParentRootType && (fieldName === string_constants_1.SERVICE_FIELD || fieldName === string_constants_1.ENTITIES_FIELD)) {
|
|
815
894
|
return false;
|
|
816
895
|
}
|
|
817
|
-
factory.childName =
|
|
896
|
+
factory.childName = fieldName;
|
|
818
897
|
factory.lastChildNodeKind = node.kind;
|
|
819
898
|
if (factory.canContainEventDirectives()) {
|
|
820
899
|
factory.extractEventDirectives(node);
|
|
821
900
|
}
|
|
822
|
-
const fieldPath = `${factory.parentTypeName}.${
|
|
901
|
+
const fieldPath = `${factory.parentTypeName}.${fieldName}`;
|
|
823
902
|
factory.lastChildNodeKind = node.kind;
|
|
824
903
|
const fieldNamedTypeName = (0, type_merging_1.getNamedTypeForChild)(fieldPath, node.type);
|
|
825
904
|
if (!constants_1.BASE_SCALARS.has(fieldNamedTypeName)) {
|
|
826
905
|
factory.referencedTypeNames.add(fieldNamedTypeName);
|
|
827
906
|
}
|
|
828
907
|
const parent = factory.isCurrentParentExtension
|
|
829
|
-
? (0, utils_3.getOrThrowError)(factory.
|
|
830
|
-
: (0, utils_3.getOrThrowError)(factory.
|
|
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);
|
|
831
910
|
if (parent.kind !== graphql_1.Kind.OBJECT_TYPE_DEFINITION &&
|
|
832
911
|
parent.kind !== graphql_1.Kind.OBJECT_TYPE_EXTENSION &&
|
|
833
912
|
parent.kind !== graphql_1.Kind.INTERFACE_TYPE_DEFINITION &&
|
|
834
913
|
parent.kind !== graphql_1.Kind.INTERFACE_TYPE_EXTENSION) {
|
|
835
914
|
throw (0, errors_1.unexpectedKindFatalError)(factory.parentTypeName);
|
|
836
915
|
}
|
|
837
|
-
if (parent.fields.has(
|
|
838
|
-
factory.errors.push((0, errors_1.duplicateFieldDefinitionError)(
|
|
916
|
+
if (parent.fields.has(fieldName)) {
|
|
917
|
+
factory.errors.push((0, errors_1.duplicateFieldDefinitionError)(fieldName, factory.parentTypeName));
|
|
839
918
|
return;
|
|
840
919
|
}
|
|
841
920
|
// recreate the node so the argument descriptions are updated
|
|
842
921
|
const fieldContainer = {
|
|
843
922
|
arguments: factory.extractArguments(node, new Map(), fieldPath),
|
|
844
|
-
directives: factory.
|
|
845
|
-
name,
|
|
923
|
+
directives: factory.extractDirectivesAndAuthorization(node, new Map()),
|
|
924
|
+
name: fieldName,
|
|
846
925
|
node: {
|
|
847
926
|
...node,
|
|
848
927
|
arguments: node.arguments?.map((arg) => ({
|
|
@@ -851,27 +930,31 @@ class NormalizationFactory {
|
|
|
851
930
|
})),
|
|
852
931
|
},
|
|
853
932
|
};
|
|
854
|
-
parent.fields.set(
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
//
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
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
|
+
}
|
|
865
948
|
}
|
|
866
949
|
const providesDirectives = fieldContainer.directives.get(string_constants_1.PROVIDES);
|
|
867
950
|
// Check whether the directive exists to avoid creating unnecessary fieldSet configurations
|
|
868
951
|
if (!providesDirectives) {
|
|
869
952
|
return;
|
|
870
953
|
}
|
|
871
|
-
const fieldSetContainer = (0, utils_3.getValueOrDefault)(factory.
|
|
954
|
+
const fieldSetContainer = (0, utils_3.getValueOrDefault)(factory.fieldSetContainerByTypeName, factory.parentTypeName, utils_2.newFieldSetContainer);
|
|
872
955
|
// @provides only makes sense on entities, but the field can be encountered before the type definition
|
|
873
956
|
// When the FieldSet is evaluated, it will be checked whether the field is an entity.
|
|
874
|
-
(0, utils_2.extractFieldSetValue)(
|
|
957
|
+
(0, utils_2.extractFieldSetValue)(fieldName, fieldSetContainer.provides, providesDirectives);
|
|
875
958
|
},
|
|
876
959
|
leave() {
|
|
877
960
|
factory.childName = '';
|
|
@@ -881,13 +964,13 @@ class NormalizationFactory {
|
|
|
881
964
|
InputObjectTypeDefinition: {
|
|
882
965
|
enter(node) {
|
|
883
966
|
const name = node.name.value;
|
|
884
|
-
if (factory.
|
|
967
|
+
if (factory.parentContainerByTypeName.has(name)) {
|
|
885
968
|
factory.errors.push((0, errors_1.duplicateTypeDefinitionError)((0, utils_3.kindToTypeString)(node.kind), name));
|
|
886
969
|
return false;
|
|
887
970
|
}
|
|
888
971
|
factory.lastParentNodeKind = node.kind;
|
|
889
972
|
factory.parentTypeName = name;
|
|
890
|
-
factory.
|
|
973
|
+
factory.parentContainerByTypeName.set(name, {
|
|
891
974
|
description: (0, utils_1.formatDescription)(node.description),
|
|
892
975
|
directives: factory.extractDirectives(node, new Map()),
|
|
893
976
|
fields: new Map(),
|
|
@@ -906,7 +989,7 @@ class NormalizationFactory {
|
|
|
906
989
|
factory.parentTypeName = name;
|
|
907
990
|
factory.lastParentNodeKind = node.kind;
|
|
908
991
|
factory.isCurrentParentExtension = true;
|
|
909
|
-
const extension = factory.
|
|
992
|
+
const extension = factory.extensionContainerByTypeName.get(factory.parentTypeName);
|
|
910
993
|
if (extension) {
|
|
911
994
|
if (extension.kind !== graphql_1.Kind.INPUT_OBJECT_TYPE_EXTENSION) {
|
|
912
995
|
factory.errors.push((0, errors_1.incompatibleExtensionKindsError)(node, extension.kind));
|
|
@@ -915,7 +998,7 @@ class NormalizationFactory {
|
|
|
915
998
|
factory.extractDirectives(node, extension.directives);
|
|
916
999
|
return;
|
|
917
1000
|
}
|
|
918
|
-
factory.
|
|
1001
|
+
factory.extensionContainerByTypeName.set(name, {
|
|
919
1002
|
directives: factory.extractDirectives(node, new Map()),
|
|
920
1003
|
fields: new Map(),
|
|
921
1004
|
kind: node.kind,
|
|
@@ -944,8 +1027,8 @@ class NormalizationFactory {
|
|
|
944
1027
|
factory.referencedTypeNames.add(valueRootTypeName);
|
|
945
1028
|
}
|
|
946
1029
|
const parent = factory.isCurrentParentExtension
|
|
947
|
-
? (0, utils_3.getOrThrowError)(factory.
|
|
948
|
-
: (0, utils_3.getOrThrowError)(factory.
|
|
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);
|
|
949
1032
|
if (parent.kind !== graphql_1.Kind.INPUT_OBJECT_TYPE_DEFINITION && parent.kind !== graphql_1.Kind.INPUT_OBJECT_TYPE_EXTENSION) {
|
|
950
1033
|
throw (0, errors_1.unexpectedKindFatalError)(factory.parentTypeName);
|
|
951
1034
|
}
|
|
@@ -976,23 +1059,14 @@ class NormalizationFactory {
|
|
|
976
1059
|
if ((0, utils_1.isNodeExtension)(node)) {
|
|
977
1060
|
return factory.handleObjectLikeExtension(node);
|
|
978
1061
|
}
|
|
979
|
-
if (factory.
|
|
1062
|
+
if (factory.parentContainerByTypeName.has(name)) {
|
|
980
1063
|
factory.errors.push((0, errors_1.duplicateTypeDefinitionError)((0, utils_3.kindToTypeString)(node.kind), name));
|
|
981
1064
|
return false;
|
|
982
1065
|
}
|
|
983
1066
|
const isEntity = (0, utils_1.isObjectLikeNodeEntity)(node);
|
|
984
|
-
|
|
985
|
-
factory.entityInterfaces.set(name, {
|
|
986
|
-
concreteTypeNames: new Set(),
|
|
987
|
-
interfaceFieldNames: new Set(node.fields?.map((field) => field.name.value)),
|
|
988
|
-
interfaceObjectFieldNames: new Set(),
|
|
989
|
-
isInterfaceObject: false,
|
|
990
|
-
typeName: name,
|
|
991
|
-
});
|
|
992
|
-
}
|
|
993
|
-
factory.parents.set(name, {
|
|
1067
|
+
factory.parentContainerByTypeName.set(name, {
|
|
994
1068
|
description: (0, utils_1.formatDescription)(node.description),
|
|
995
|
-
directives: factory.
|
|
1069
|
+
directives: factory.extractDirectivesAndAuthorization(node, new Map()),
|
|
996
1070
|
fields: new Map(),
|
|
997
1071
|
interfaces: (0, utils_1.extractInterfaces)(node, new Set(), factory.errors),
|
|
998
1072
|
isEntity,
|
|
@@ -1002,9 +1076,19 @@ class NormalizationFactory {
|
|
|
1002
1076
|
if (!isEntity) {
|
|
1003
1077
|
return;
|
|
1004
1078
|
}
|
|
1005
|
-
factory.
|
|
1006
|
-
|
|
1007
|
-
|
|
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);
|
|
1008
1092
|
},
|
|
1009
1093
|
leave() {
|
|
1010
1094
|
factory.parentTypeName = '';
|
|
@@ -1026,12 +1110,12 @@ class NormalizationFactory {
|
|
|
1026
1110
|
},
|
|
1027
1111
|
ObjectTypeDefinition: {
|
|
1028
1112
|
enter(node) {
|
|
1029
|
-
const
|
|
1030
|
-
if (
|
|
1113
|
+
const typeName = node.name.value;
|
|
1114
|
+
if (typeName === string_constants_1.SERVICE_OBJECT) {
|
|
1031
1115
|
return false;
|
|
1032
1116
|
}
|
|
1033
|
-
factory.isCurrentParentRootType = string_constants_1.ROOT_TYPES.has(
|
|
1034
|
-
factory.parentTypeName =
|
|
1117
|
+
factory.isCurrentParentRootType = string_constants_1.ROOT_TYPES.has(typeName) || factory.operationTypeNames.has(typeName);
|
|
1118
|
+
factory.parentTypeName = typeName;
|
|
1035
1119
|
factory.lastParentNodeKind = node.kind;
|
|
1036
1120
|
(0, utils_1.addConcreteTypesForImplementedInterfaces)(node, factory.abstractToConcreteTypeNames);
|
|
1037
1121
|
factory.handleInterfaceObject(node);
|
|
@@ -1039,14 +1123,14 @@ class NormalizationFactory {
|
|
|
1039
1123
|
if ((0, utils_1.isNodeExtension)(node)) {
|
|
1040
1124
|
return factory.handleObjectLikeExtension(node);
|
|
1041
1125
|
}
|
|
1042
|
-
if (factory.
|
|
1043
|
-
factory.errors.push((0, errors_1.duplicateTypeDefinitionError)((0, utils_3.kindToTypeString)(node.kind),
|
|
1126
|
+
if (factory.parentContainerByTypeName.has(typeName)) {
|
|
1127
|
+
factory.errors.push((0, errors_1.duplicateTypeDefinitionError)((0, utils_3.kindToTypeString)(node.kind), typeName));
|
|
1044
1128
|
return false;
|
|
1045
1129
|
}
|
|
1046
1130
|
const isEntity = (0, utils_1.isObjectLikeNodeEntity)(node);
|
|
1047
|
-
factory.
|
|
1131
|
+
factory.parentContainerByTypeName.set(typeName, {
|
|
1048
1132
|
description: (0, utils_1.formatDescription)(node.description),
|
|
1049
|
-
directives: factory.
|
|
1133
|
+
directives: factory.extractDirectivesAndAuthorization(node, new Map()),
|
|
1050
1134
|
fields: new Map(),
|
|
1051
1135
|
interfaces: (0, utils_1.extractInterfaces)(node, new Set(), factory.errors),
|
|
1052
1136
|
isEntity,
|
|
@@ -1056,9 +1140,13 @@ class NormalizationFactory {
|
|
|
1056
1140
|
if (!isEntity) {
|
|
1057
1141
|
return;
|
|
1058
1142
|
}
|
|
1059
|
-
factory.
|
|
1060
|
-
|
|
1061
|
-
|
|
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
|
+
});
|
|
1062
1150
|
},
|
|
1063
1151
|
leave() {
|
|
1064
1152
|
factory.isCurrentParentRootType = false;
|
|
@@ -1092,16 +1180,16 @@ class NormalizationFactory {
|
|
|
1092
1180
|
if (name === string_constants_1.ANY_SCALAR) {
|
|
1093
1181
|
return false;
|
|
1094
1182
|
}
|
|
1095
|
-
const parent = factory.
|
|
1183
|
+
const parent = factory.parentContainerByTypeName.get(name);
|
|
1096
1184
|
if (parent) {
|
|
1097
1185
|
factory.errors.push((0, errors_1.duplicateTypeDefinitionError)((0, utils_3.kindToTypeString)(node.kind), name));
|
|
1098
1186
|
return false;
|
|
1099
1187
|
}
|
|
1100
1188
|
factory.parentTypeName = name;
|
|
1101
1189
|
factory.lastParentNodeKind = node.kind;
|
|
1102
|
-
factory.
|
|
1190
|
+
factory.parentContainerByTypeName.set(name, {
|
|
1103
1191
|
description: (0, utils_1.formatDescription)(node.description),
|
|
1104
|
-
directives: factory.
|
|
1192
|
+
directives: factory.extractDirectivesAndAuthorization(node, new Map()),
|
|
1105
1193
|
kind: graphql_1.Kind.SCALAR_TYPE_DEFINITION,
|
|
1106
1194
|
name: node.name,
|
|
1107
1195
|
});
|
|
@@ -1117,19 +1205,19 @@ class NormalizationFactory {
|
|
|
1117
1205
|
if (name === string_constants_1.ANY_SCALAR) {
|
|
1118
1206
|
return false;
|
|
1119
1207
|
}
|
|
1120
|
-
const extension = factory.
|
|
1208
|
+
const extension = factory.extensionContainerByTypeName.get(name);
|
|
1121
1209
|
if (extension) {
|
|
1122
1210
|
if (extension.kind !== graphql_1.Kind.SCALAR_TYPE_EXTENSION) {
|
|
1123
1211
|
factory.errors.push((0, errors_1.incompatibleExtensionKindsError)(node, extension.kind));
|
|
1124
1212
|
return false;
|
|
1125
1213
|
}
|
|
1126
|
-
factory.
|
|
1214
|
+
factory.extractDirectivesAndAuthorization(node, extension.directives);
|
|
1127
1215
|
}
|
|
1128
1216
|
else {
|
|
1129
1217
|
factory.parentTypeName = name;
|
|
1130
1218
|
factory.lastParentNodeKind = node.kind;
|
|
1131
|
-
factory.
|
|
1132
|
-
directives: factory.
|
|
1219
|
+
factory.extensionContainerByTypeName.set(name, {
|
|
1220
|
+
directives: factory.extractDirectivesAndAuthorization(node, new Map()),
|
|
1133
1221
|
kind: node.kind,
|
|
1134
1222
|
name: node.name,
|
|
1135
1223
|
});
|
|
@@ -1148,7 +1236,7 @@ class NormalizationFactory {
|
|
|
1148
1236
|
return false;
|
|
1149
1237
|
}
|
|
1150
1238
|
factory.parentTypeName = name;
|
|
1151
|
-
const parent = factory.
|
|
1239
|
+
const parent = factory.parentContainerByTypeName.get(name);
|
|
1152
1240
|
if (parent) {
|
|
1153
1241
|
factory.errors.push((0, errors_1.duplicateTypeDefinitionError)((0, utils_3.kindToTypeString)(node.kind), name));
|
|
1154
1242
|
return false;
|
|
@@ -1159,7 +1247,7 @@ class NormalizationFactory {
|
|
|
1159
1247
|
}
|
|
1160
1248
|
factory.lastParentNodeKind = node.kind;
|
|
1161
1249
|
(0, utils_1.addConcreteTypesForUnion)(node, factory.abstractToConcreteTypeNames);
|
|
1162
|
-
factory.
|
|
1250
|
+
factory.parentContainerByTypeName.set(name, {
|
|
1163
1251
|
description: (0, utils_1.formatDescription)(node.description),
|
|
1164
1252
|
directives: factory.extractDirectives(node, new Map()),
|
|
1165
1253
|
kind: node.kind,
|
|
@@ -1178,7 +1266,7 @@ class NormalizationFactory {
|
|
|
1178
1266
|
if (name === string_constants_1.ENTITY_UNION) {
|
|
1179
1267
|
return false;
|
|
1180
1268
|
}
|
|
1181
|
-
const extension = factory.
|
|
1269
|
+
const extension = factory.extensionContainerByTypeName.get(name);
|
|
1182
1270
|
if (!node.types) {
|
|
1183
1271
|
factory.errors.push();
|
|
1184
1272
|
return false;
|
|
@@ -1193,7 +1281,7 @@ class NormalizationFactory {
|
|
|
1193
1281
|
factory.extractDirectives(node, extension.directives);
|
|
1194
1282
|
}
|
|
1195
1283
|
else {
|
|
1196
|
-
factory.
|
|
1284
|
+
factory.extensionContainerByTypeName.set(name, {
|
|
1197
1285
|
directives: factory.extractDirectives(node, new Map()),
|
|
1198
1286
|
kind: node.kind,
|
|
1199
1287
|
name: node.name,
|
|
@@ -1211,12 +1299,13 @@ class NormalizationFactory {
|
|
|
1211
1299
|
for (const directiveDefinition of constants_1.BASE_DIRECTIVE_DEFINITIONS) {
|
|
1212
1300
|
definitions.push(directiveDefinition);
|
|
1213
1301
|
}
|
|
1214
|
-
definitions.push(constants_1.
|
|
1302
|
+
definitions.push(constants_1.FIELD_SET_SCALAR_DEFINITION);
|
|
1215
1303
|
if (factory.isSubgraphVersionTwo) {
|
|
1216
1304
|
for (const directiveDefinition of constants_1.VERSION_TWO_DIRECTIVE_DEFINITIONS) {
|
|
1217
1305
|
definitions.push(directiveDefinition);
|
|
1218
1306
|
this.allDirectiveDefinitions.set(directiveDefinition.name.value, directiveDefinition);
|
|
1219
1307
|
}
|
|
1308
|
+
definitions.push(constants_1.SCOPE_SCALAR_DEFINITION);
|
|
1220
1309
|
}
|
|
1221
1310
|
for (const directiveDefinition of this.customDirectiveDefinitions.values()) {
|
|
1222
1311
|
definitions.push(directiveDefinition);
|
|
@@ -1226,8 +1315,8 @@ class NormalizationFactory {
|
|
|
1226
1315
|
}
|
|
1227
1316
|
const validExtensionOrphans = new Set();
|
|
1228
1317
|
const parentsToIgnore = new Set();
|
|
1229
|
-
for (const [extensionTypeName, extensionContainer] of this.
|
|
1230
|
-
const isEntity = this.
|
|
1318
|
+
for (const [extensionTypeName, extensionContainer] of this.extensionContainerByTypeName) {
|
|
1319
|
+
const isEntity = this.entityContainerByTypeName.has(extensionTypeName);
|
|
1231
1320
|
const configurationData = {
|
|
1232
1321
|
fieldNames: new Set(),
|
|
1233
1322
|
isRootNode: isEntity,
|
|
@@ -1241,7 +1330,7 @@ class NormalizationFactory {
|
|
|
1241
1330
|
}
|
|
1242
1331
|
(0, utils_2.addNonExternalFieldsToSet)(extensionContainer.fields, configurationData.fieldNames);
|
|
1243
1332
|
}
|
|
1244
|
-
const baseType = this.
|
|
1333
|
+
const baseType = this.parentContainerByTypeName.get(extensionTypeName);
|
|
1245
1334
|
if (!baseType) {
|
|
1246
1335
|
if (extensionContainer.kind !== graphql_1.Kind.OBJECT_TYPE_EXTENSION) {
|
|
1247
1336
|
this.errors.push((0, errors_1.noBaseTypeExtensionError)(extensionTypeName));
|
|
@@ -1306,10 +1395,12 @@ class NormalizationFactory {
|
|
|
1306
1395
|
this.mergeUniqueInterfaces(objectLikeExtension.interfaces, baseType.interfaces, extensionTypeName);
|
|
1307
1396
|
this.validateInterfaceImplementations(baseType);
|
|
1308
1397
|
definitions.push((0, utils_2.objectLikeContainerToNode)(this, baseType, objectLikeExtension));
|
|
1309
|
-
//
|
|
1398
|
+
// Interfaces and objects must define at least one field
|
|
1310
1399
|
if (baseType.fields.size < 1 && !(0, utils_2.isNodeQuery)(extensionTypeName, operationTypeNode)) {
|
|
1311
1400
|
this.errors.push((0, errors_1.noFieldDefinitionsError)((0, utils_3.kindToTypeString)(baseType.kind), extensionTypeName));
|
|
1312
1401
|
}
|
|
1402
|
+
// Add the non-external base type field names to the configuration data
|
|
1403
|
+
(0, utils_2.addNonExternalFieldsToSet)(baseType.fields, configurationData.fieldNames);
|
|
1313
1404
|
break;
|
|
1314
1405
|
case graphql_1.Kind.SCALAR_TYPE_DEFINITION:
|
|
1315
1406
|
definitions.push((0, utils_2.scalarContainerToNode)(this, baseType, extensionContainer));
|
|
@@ -1324,7 +1415,7 @@ class NormalizationFactory {
|
|
|
1324
1415
|
// At this point, the base type has been dealt with, so it doesn't need to be dealt with again
|
|
1325
1416
|
parentsToIgnore.add(extensionTypeName);
|
|
1326
1417
|
}
|
|
1327
|
-
for (const [parentTypeName, parentContainer] of this.
|
|
1418
|
+
for (const [parentTypeName, parentContainer] of this.parentContainerByTypeName) {
|
|
1328
1419
|
if (parentsToIgnore.has(parentTypeName)) {
|
|
1329
1420
|
continue;
|
|
1330
1421
|
}
|
|
@@ -1338,7 +1429,7 @@ class NormalizationFactory {
|
|
|
1338
1429
|
case graphql_1.Kind.INTERFACE_TYPE_DEFINITION:
|
|
1339
1430
|
// intentional fallthrough
|
|
1340
1431
|
case graphql_1.Kind.OBJECT_TYPE_DEFINITION:
|
|
1341
|
-
const isEntity = this.
|
|
1432
|
+
const isEntity = this.entityContainerByTypeName.has(parentTypeName);
|
|
1342
1433
|
const operationTypeNode = this.operationTypeNames.get(parentTypeName);
|
|
1343
1434
|
if (operationTypeNode) {
|
|
1344
1435
|
parentContainer.fields.delete(string_constants_1.SERVICE_FIELD);
|
|
@@ -1397,12 +1488,12 @@ class NormalizationFactory {
|
|
|
1397
1488
|
const operationTypeName = node ? (0, type_merging_1.getNamedTypeForChild)(`schema.${operationType}`, node.type) : defaultTypeName;
|
|
1398
1489
|
// If a custom type is used, the default type should not be defined
|
|
1399
1490
|
if (operationTypeName !== defaultTypeName &&
|
|
1400
|
-
(this.
|
|
1491
|
+
(this.parentContainerByTypeName.has(defaultTypeName) || this.extensionContainerByTypeName.has(defaultTypeName))) {
|
|
1401
1492
|
this.errors.push((0, errors_1.invalidRootTypeDefinitionError)(operationType, operationTypeName, defaultTypeName));
|
|
1402
1493
|
continue;
|
|
1403
1494
|
}
|
|
1404
|
-
const object = this.
|
|
1405
|
-
const extension = this.
|
|
1495
|
+
const object = this.parentContainerByTypeName.get(operationTypeName);
|
|
1496
|
+
const extension = this.extensionContainerByTypeName.get(operationTypeName);
|
|
1406
1497
|
// Node is truthy if an operation type was explicitly declared
|
|
1407
1498
|
if (node) {
|
|
1408
1499
|
// If the type is not defined in the schema, it's always an error
|
|
@@ -1437,7 +1528,7 @@ class NormalizationFactory {
|
|
|
1437
1528
|
const fieldPath = `${operationTypeName}.${fieldName}`;
|
|
1438
1529
|
const fieldTypeName = (0, type_merging_1.getNamedTypeForChild)(fieldPath, fieldContainer.node.type);
|
|
1439
1530
|
if (!constants_1.BASE_SCALARS.has(fieldTypeName) &&
|
|
1440
|
-
!this.
|
|
1531
|
+
!this.parentContainerByTypeName.has(fieldTypeName) &&
|
|
1441
1532
|
!validExtensionOrphans.has(fieldTypeName)) {
|
|
1442
1533
|
this.errors.push((0, errors_1.undefinedTypeError)(fieldTypeName));
|
|
1443
1534
|
}
|
|
@@ -1445,16 +1536,17 @@ class NormalizationFactory {
|
|
|
1445
1536
|
}
|
|
1446
1537
|
}
|
|
1447
1538
|
for (const referencedTypeName of this.referencedTypeNames) {
|
|
1448
|
-
if (this.
|
|
1539
|
+
if (this.parentContainerByTypeName.has(referencedTypeName) ||
|
|
1540
|
+
this.entityContainerByTypeName.has(referencedTypeName)) {
|
|
1449
1541
|
continue;
|
|
1450
1542
|
}
|
|
1451
|
-
const extension = this.
|
|
1543
|
+
const extension = this.extensionContainerByTypeName.get(referencedTypeName);
|
|
1452
1544
|
if (!extension || extension.kind !== graphql_1.Kind.OBJECT_TYPE_EXTENSION) {
|
|
1453
1545
|
this.errors.push((0, errors_1.undefinedTypeError)(referencedTypeName));
|
|
1454
1546
|
}
|
|
1455
1547
|
}
|
|
1456
|
-
for (const [parentTypeName,
|
|
1457
|
-
const parentContainer = this.
|
|
1548
|
+
for (const [parentTypeName, fieldSetContainers] of this.fieldSetContainerByTypeName) {
|
|
1549
|
+
const parentContainer = this.parentContainerByTypeName.get(parentTypeName) || this.extensionContainerByTypeName.get(parentTypeName);
|
|
1458
1550
|
if (!parentContainer ||
|
|
1459
1551
|
(parentContainer.kind !== graphql_1.Kind.OBJECT_TYPE_DEFINITION &&
|
|
1460
1552
|
parentContainer.kind != graphql_1.Kind.OBJECT_TYPE_EXTENSION &&
|
|
@@ -1464,7 +1556,7 @@ class NormalizationFactory {
|
|
|
1464
1556
|
continue;
|
|
1465
1557
|
}
|
|
1466
1558
|
// this is where keys, provides, and requires are added to the ConfigurationData
|
|
1467
|
-
(0, utils_2.validateAndAddDirectivesWithFieldSetToConfigurationData)(this, parentContainer,
|
|
1559
|
+
(0, utils_2.validateAndAddDirectivesWithFieldSetToConfigurationData)(this, parentContainer, fieldSetContainers);
|
|
1468
1560
|
}
|
|
1469
1561
|
if (this.errors.length > 0) {
|
|
1470
1562
|
return { errors: this.errors };
|
|
@@ -1473,16 +1565,21 @@ class NormalizationFactory {
|
|
|
1473
1565
|
kind: graphql_1.Kind.DOCUMENT,
|
|
1474
1566
|
definitions,
|
|
1475
1567
|
};
|
|
1568
|
+
(0, subgraph_1.walkSubgraphToApplyFieldAuthorization)(factory, newAST);
|
|
1476
1569
|
return {
|
|
1477
1570
|
normalizationResult: {
|
|
1571
|
+
authorizationDataByParentTypeName: this.authorizationDataByParentTypeName,
|
|
1478
1572
|
// configurationDataMap is map of ConfigurationData per type name.
|
|
1479
1573
|
// It is an Intermediate configuration object that will be converted to an engine configuration in the router
|
|
1480
1574
|
configurationDataMap: this.configurationDataMap,
|
|
1575
|
+
entityContainerByTypeName: this.entityContainerByTypeName,
|
|
1481
1576
|
entityInterfaces: this.entityInterfaces,
|
|
1577
|
+
extensionContainerByTypeName: this.extensionContainerByTypeName,
|
|
1482
1578
|
isVersionTwo: this.isSubgraphVersionTwo,
|
|
1483
1579
|
keyFieldNamesByParentTypeName: this.keyFieldNamesByParentTypeName,
|
|
1484
1580
|
operationTypes: this.operationTypeNames,
|
|
1485
1581
|
overridesByTargetSubgraphName: this.overridesByTargetSubgraphName,
|
|
1582
|
+
parentContainerByTypeName: this.parentContainerByTypeName,
|
|
1486
1583
|
subgraphAST: newAST,
|
|
1487
1584
|
subgraphString: (0, graphql_1.print)(newAST),
|
|
1488
1585
|
schema: (0, buildASTSchema_1.buildASTSchema)(newAST, { assumeValid: true }),
|
|
@@ -1492,15 +1589,18 @@ class NormalizationFactory {
|
|
|
1492
1589
|
}
|
|
1493
1590
|
exports.NormalizationFactory = NormalizationFactory;
|
|
1494
1591
|
function batchNormalize(subgraphs) {
|
|
1495
|
-
const
|
|
1592
|
+
const authorizationDataByParentTypeName = new Map();
|
|
1593
|
+
const entityContainerByTypeName = new Map();
|
|
1594
|
+
const internalSubgraphBySubgraphName = new Map();
|
|
1496
1595
|
const allOverridesByTargetSubgraphName = new Map();
|
|
1497
1596
|
const overrideSourceSubgraphNamesByFieldPath = new Map();
|
|
1498
1597
|
const duplicateOverriddenFieldPaths = new Set();
|
|
1499
|
-
const
|
|
1598
|
+
const parentContainerMapsBySubgraphName = new Map();
|
|
1500
1599
|
const subgraphNames = new Set();
|
|
1501
1600
|
const nonUniqueSubgraphNames = new Set();
|
|
1502
1601
|
const invalidNameErrorMessages = [];
|
|
1503
1602
|
const warnings = [];
|
|
1603
|
+
const validationErrors = [];
|
|
1504
1604
|
// Record the subgraph names first, so that subgraph references can be validated
|
|
1505
1605
|
for (const subgraph of subgraphs) {
|
|
1506
1606
|
if (subgraph.name) {
|
|
@@ -1522,16 +1622,25 @@ function batchNormalize(subgraphs) {
|
|
|
1522
1622
|
validationErrors.push((0, errors_1.subgraphValidationError)(subgraphName, [errors_1.subgraphValidationFailureError]));
|
|
1523
1623
|
continue;
|
|
1524
1624
|
}
|
|
1625
|
+
parentContainerMapsBySubgraphName.set(subgraphName, normalizationResult.parentContainerByTypeName);
|
|
1626
|
+
for (const authorizationData of normalizationResult.authorizationDataByParentTypeName.values()) {
|
|
1627
|
+
(0, utils_3.upsertAuthorizationData)(authorizationDataByParentTypeName, authorizationData);
|
|
1628
|
+
}
|
|
1629
|
+
for (const entityContainer of normalizationResult.entityContainerByTypeName.values()) {
|
|
1630
|
+
(0, utils_3.upsertEntityContainer)(entityContainerByTypeName, entityContainer);
|
|
1631
|
+
}
|
|
1525
1632
|
if (subgraph.name) {
|
|
1526
|
-
|
|
1633
|
+
internalSubgraphBySubgraphName.set(subgraphName, {
|
|
1527
1634
|
configurationDataMap: normalizationResult.configurationDataMap,
|
|
1528
1635
|
definitions: normalizationResult.subgraphAST,
|
|
1529
1636
|
entityInterfaces: normalizationResult.entityInterfaces,
|
|
1637
|
+
extensionContainerByTypeName: normalizationResult.extensionContainerByTypeName,
|
|
1530
1638
|
keyFieldNamesByParentTypeName: normalizationResult.keyFieldNamesByParentTypeName,
|
|
1531
1639
|
isVersionTwo: normalizationResult.isVersionTwo,
|
|
1532
1640
|
name: subgraphName,
|
|
1533
1641
|
operationTypes: normalizationResult.operationTypes,
|
|
1534
1642
|
overriddenFieldNamesByParentTypeName: new Map(),
|
|
1643
|
+
parentContainerByTypeName: normalizationResult.parentContainerByTypeName,
|
|
1535
1644
|
schema: normalizationResult.schema,
|
|
1536
1645
|
url: subgraph.url,
|
|
1537
1646
|
});
|
|
@@ -1576,12 +1685,17 @@ function batchNormalize(subgraphs) {
|
|
|
1576
1685
|
allErrors.push((0, errors_1.duplicateOverriddenFieldsError)(duplicateOverriddenFieldErrorMessages));
|
|
1577
1686
|
}
|
|
1578
1687
|
allErrors.push(...validationErrors);
|
|
1579
|
-
const warningsToPropagate = warnings.length > 0 ? warnings : undefined;
|
|
1580
1688
|
if (allErrors.length > 0) {
|
|
1581
|
-
return {
|
|
1689
|
+
return {
|
|
1690
|
+
authorizationDataByParentTypeName,
|
|
1691
|
+
entityContainerByTypeName,
|
|
1692
|
+
errors: allErrors,
|
|
1693
|
+
internalSubgraphBySubgraphName,
|
|
1694
|
+
...(warnings.length > 0 ? { warnings } : {}),
|
|
1695
|
+
};
|
|
1582
1696
|
}
|
|
1583
1697
|
for (const [targetSubgraphName, overridesData] of allOverridesByTargetSubgraphName) {
|
|
1584
|
-
const internalSubgraph = (0, utils_3.getOrThrowError)(
|
|
1698
|
+
const internalSubgraph = (0, utils_3.getOrThrowError)(internalSubgraphBySubgraphName, targetSubgraphName, 'internalSubgraphBySubgraphName');
|
|
1585
1699
|
internalSubgraph.overriddenFieldNamesByParentTypeName = overridesData;
|
|
1586
1700
|
for (const [parentTypeName, fieldNames] of overridesData) {
|
|
1587
1701
|
const configurationData = internalSubgraph.configurationDataMap.get(parentTypeName);
|
|
@@ -1595,8 +1709,10 @@ function batchNormalize(subgraphs) {
|
|
|
1595
1709
|
}
|
|
1596
1710
|
}
|
|
1597
1711
|
return {
|
|
1598
|
-
|
|
1599
|
-
|
|
1712
|
+
authorizationDataByParentTypeName,
|
|
1713
|
+
entityContainerByTypeName: entityContainerByTypeName,
|
|
1714
|
+
internalSubgraphBySubgraphName: internalSubgraphBySubgraphName,
|
|
1715
|
+
...(warnings.length > 0 ? { warnings } : {}),
|
|
1600
1716
|
};
|
|
1601
1717
|
}
|
|
1602
1718
|
exports.batchNormalize = batchNormalize;
|