@wundergraph/composition 0.15.0 → 0.16.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.
@@ -36,28 +36,28 @@ class NormalizationFactory {
36
36
  configurationDataMap = new Map();
37
37
  customDirectiveDefinitions = new Map();
38
38
  errors = [];
39
- entities = new Set();
39
+ entityContainerByTypeName = new Map();
40
40
  entityInterfaces = new Map();
41
- extensions = new Map();
41
+ extensionContainerByTypeName = new Map();
42
42
  isCurrentParentExtension = false;
43
43
  isCurrentParentRootType = false;
44
44
  isSubgraphVersionTwo = false;
45
- fieldSetsByParent = new Map();
45
+ fieldSetContainerByTypeName = new Map();
46
46
  handledRepeatedDirectivesByHostPath = new Map();
47
47
  lastParentNodeKind = graphql_1.Kind.NULL;
48
48
  lastChildNodeKind = graphql_1.Kind.NULL;
49
49
  keyFieldNamesByParentTypeName = new Map();
50
50
  operationTypeNames = new Map();
51
- parents = new Map();
51
+ parentContainerByTypeName = new Map();
52
52
  parentTypeName = '';
53
53
  parentsWithChildArguments = new Set();
54
54
  eventsConfigurations = new Map();
55
55
  overridesByTargetSubgraphName = new Map();
56
56
  schemaDefinition;
57
- subgraphName;
58
57
  referencedDirectives = new Set();
59
58
  referencedTypeNames = new Set();
60
59
  warnings = [];
60
+ subgraphName;
61
61
  constructor(subgraphName) {
62
62
  for (const baseDirectiveDefinition of constants_1.BASE_DIRECTIVE_DEFINITIONS) {
63
63
  this.allDirectiveDefinitions.set(baseDirectiveDefinition.name.value, baseDirectiveDefinition);
@@ -74,7 +74,7 @@ class NormalizationFactory {
74
74
  if (constants_1.BASE_SCALARS.has(namedType)) {
75
75
  return { hasUnhandledError: false, typeString: '' };
76
76
  }
77
- const parentContainer = this.parents.get(namedType);
77
+ const parentContainer = this.parentContainerByTypeName.get(namedType);
78
78
  if (!parentContainer) {
79
79
  this.errors.push((0, errors_1.undefinedTypeError)(namedType));
80
80
  return { hasUnhandledError: false, typeString: '' };
@@ -282,7 +282,7 @@ class NormalizationFactory {
282
282
  }
283
283
  handleObjectLikeExtension(node) {
284
284
  this.isCurrentParentExtension = true;
285
- const extension = this.extensions.get(this.parentTypeName);
285
+ const extension = this.extensionContainerByTypeName.get(this.parentTypeName);
286
286
  const convertedKind = this.convertKindForExtension(node);
287
287
  if (extension) {
288
288
  if (extension.kind !== convertedKind) {
@@ -294,7 +294,7 @@ class NormalizationFactory {
294
294
  return;
295
295
  }
296
296
  const isEntity = (0, utils_1.isObjectLikeNodeEntity)(node);
297
- this.extensions.set(this.parentTypeName, {
297
+ this.extensionContainerByTypeName.set(this.parentTypeName, {
298
298
  directives: this.extractDirectives(node, new Map()),
299
299
  fields: new Map(),
300
300
  interfaces: (0, utils_1.extractInterfaces)(node, new Set(), this.errors),
@@ -305,9 +305,13 @@ class NormalizationFactory {
305
305
  if (node.kind === graphql_1.Kind.INTERFACE_TYPE_DEFINITION || node.kind === graphql_1.Kind.INTERFACE_TYPE_EXTENSION || !isEntity) {
306
306
  return;
307
307
  }
308
- this.entities.add(this.parentTypeName);
309
- const fieldSets = (0, utils_3.getValueOrDefault)(this.fieldSetsByParent, this.parentTypeName, utils_2.newFieldSetContainer);
310
- this.extractKeyFieldSets(node, fieldSets.keys);
308
+ const fieldSetContainer = (0, utils_3.getValueOrDefault)(this.fieldSetContainerByTypeName, this.parentTypeName, utils_2.newFieldSetContainer);
309
+ this.extractKeyFieldSets(node, fieldSetContainer);
310
+ (0, utils_3.upsertEntityContainerProperties)(this.entityContainerByTypeName, {
311
+ typeName: this.parentTypeName,
312
+ keyFieldSets: fieldSetContainer.keys,
313
+ ...(this.subgraphName ? { subgraphNames: [this.subgraphName] } : {}),
314
+ });
311
315
  }
312
316
  validateChildDirectives(child, hostPath) {
313
317
  const childKind = child.node.kind;
@@ -395,7 +399,8 @@ class NormalizationFactory {
395
399
  operationTypeNode === graphql_1.OperationTypeNode.MUTATION ||
396
400
  operationTypeNode === graphql_1.OperationTypeNode.SUBSCRIPTION);
397
401
  }
398
- extractKeyFieldSets(node, rawFieldSets) {
402
+ extractKeyFieldSets(node, fieldSetContainer) {
403
+ const rawFieldSets = fieldSetContainer.keys;
399
404
  const parentTypeName = node.name.value;
400
405
  if (!node.directives?.length) {
401
406
  // This should never happen
@@ -414,6 +419,9 @@ class NormalizationFactory {
414
419
  for (const arg of directive.arguments) {
415
420
  const argumentName = arg.name.value;
416
421
  if (arg.name.value === string_constants_1.RESOLVABLE) {
422
+ if (arg.value.kind === graphql_1.Kind.BOOLEAN && !arg.value.value) {
423
+ fieldSetContainer.disableEntityResolver = true;
424
+ }
417
425
  continue;
418
426
  }
419
427
  if (arg.name.value !== string_constants_1.FIELDS) {
@@ -437,7 +445,7 @@ class NormalizationFactory {
437
445
  }
438
446
  const implementationErrorsMap = new Map();
439
447
  for (const interfaceName of container.interfaces) {
440
- const interfaceContainer = (0, utils_3.getOrThrowError)(this.parents, interfaceName, string_constants_1.PARENTS);
448
+ const interfaceContainer = (0, utils_3.getOrThrowError)(this.parentContainerByTypeName, interfaceName, string_constants_1.PARENTS);
441
449
  if (interfaceContainer.kind !== graphql_1.Kind.INTERFACE_TYPE_DEFINITION) {
442
450
  throw (0, errors_1.incompatibleParentKindFatalError)(interfaceName, graphql_1.Kind.INTERFACE_TYPE_DEFINITION, interfaceContainer.kind);
443
451
  }
@@ -510,7 +518,7 @@ class NormalizationFactory {
510
518
  this.errors.push((0, errors_1.unimplementedInterfaceFieldsError)(container.name.value, (0, utils_3.kindToTypeString)(container.kind), implementationErrorsMap));
511
519
  }
512
520
  }
513
- handleOverride(node, fieldName) {
521
+ handleOverride(node) {
514
522
  if (node.name.value !== string_constants_1.OVERRIDE) {
515
523
  return;
516
524
  }
@@ -652,7 +660,6 @@ class NormalizationFactory {
652
660
  after the visitor has visited the entire schema and the subgraph is known to be a V2 graph. Consequently,
653
661
  allDirectiveDefinitions cannot be used to check for duplicate definitions, and another set (below) is required */
654
662
  const definedDirectives = new Set();
655
- let fieldName = '';
656
663
  const handledRootTypes = new Set();
657
664
  // Collect any renamed root types
658
665
  (0, graphql_1.visit)(document, {
@@ -718,7 +725,7 @@ class NormalizationFactory {
718
725
  Directive: {
719
726
  enter(node) {
720
727
  const name = node.name.value;
721
- factory.handleOverride(node, fieldName);
728
+ factory.handleOverride(node);
722
729
  if (constants_1.VERSION_TWO_DIRECTIVES.has(name)) {
723
730
  factory.isSubgraphVersionTwo = true;
724
731
  return false;
@@ -732,13 +739,13 @@ class NormalizationFactory {
732
739
  EnumTypeDefinition: {
733
740
  enter(node) {
734
741
  const name = node.name.value;
735
- if (factory.parents.has(name)) {
742
+ if (factory.parentContainerByTypeName.has(name)) {
736
743
  factory.errors.push((0, errors_1.duplicateTypeDefinitionError)((0, utils_3.kindToTypeString)(node.kind), name));
737
744
  return false;
738
745
  }
739
746
  factory.parentTypeName = name;
740
747
  factory.lastParentNodeKind = node.kind;
741
- factory.parents.set(name, {
748
+ factory.parentContainerByTypeName.set(name, {
742
749
  description: (0, utils_1.formatDescription)(node.description),
743
750
  directives: factory.extractDirectives(node, new Map()),
744
751
  kind: node.kind,
@@ -757,7 +764,7 @@ class NormalizationFactory {
757
764
  factory.parentTypeName = name;
758
765
  factory.lastParentNodeKind = node.kind;
759
766
  factory.isCurrentParentExtension = true;
760
- const extension = factory.extensions.get(factory.parentTypeName);
767
+ const extension = factory.extensionContainerByTypeName.get(factory.parentTypeName);
761
768
  if (extension) {
762
769
  if (extension.kind !== graphql_1.Kind.ENUM_TYPE_EXTENSION) {
763
770
  factory.errors.push((0, errors_1.incompatibleExtensionKindsError)(node, extension.kind));
@@ -766,7 +773,7 @@ class NormalizationFactory {
766
773
  factory.extractDirectives(node, extension.directives);
767
774
  return;
768
775
  }
769
- factory.extensions.set(name, {
776
+ factory.extensionContainerByTypeName.set(name, {
770
777
  directives: factory.extractDirectives(node, new Map()),
771
778
  kind: node.kind,
772
779
  name: node.name,
@@ -785,8 +792,8 @@ class NormalizationFactory {
785
792
  factory.childName = name;
786
793
  factory.lastChildNodeKind = node.kind;
787
794
  const parent = factory.isCurrentParentExtension
788
- ? (0, utils_3.getOrThrowError)(factory.extensions, factory.parentTypeName, string_constants_1.EXTENSIONS)
789
- : (0, utils_3.getOrThrowError)(factory.parents, factory.parentTypeName, string_constants_1.PARENTS);
795
+ ? (0, utils_3.getOrThrowError)(factory.extensionContainerByTypeName, factory.parentTypeName, string_constants_1.EXTENSIONS)
796
+ : (0, utils_3.getOrThrowError)(factory.parentContainerByTypeName, factory.parentTypeName, string_constants_1.PARENTS);
790
797
  if (parent.kind !== graphql_1.Kind.ENUM_TYPE_DEFINITION && parent.kind !== graphql_1.Kind.ENUM_TYPE_EXTENSION) {
791
798
  throw (0, errors_1.unexpectedKindFatalError)(name);
792
799
  }
@@ -810,39 +817,39 @@ class NormalizationFactory {
810
817
  },
811
818
  FieldDefinition: {
812
819
  enter(node) {
813
- const name = node.name.value;
814
- if (factory.isCurrentParentRootType && (name === string_constants_1.SERVICE_FIELD || name === string_constants_1.ENTITIES_FIELD)) {
820
+ const fieldName = node.name.value;
821
+ if (factory.isCurrentParentRootType && (fieldName === string_constants_1.SERVICE_FIELD || fieldName === string_constants_1.ENTITIES_FIELD)) {
815
822
  return false;
816
823
  }
817
- factory.childName = name;
824
+ factory.childName = fieldName;
818
825
  factory.lastChildNodeKind = node.kind;
819
826
  if (factory.canContainEventDirectives()) {
820
827
  factory.extractEventDirectives(node);
821
828
  }
822
- const fieldPath = `${factory.parentTypeName}.${name}`;
829
+ const fieldPath = `${factory.parentTypeName}.${fieldName}`;
823
830
  factory.lastChildNodeKind = node.kind;
824
831
  const fieldNamedTypeName = (0, type_merging_1.getNamedTypeForChild)(fieldPath, node.type);
825
832
  if (!constants_1.BASE_SCALARS.has(fieldNamedTypeName)) {
826
833
  factory.referencedTypeNames.add(fieldNamedTypeName);
827
834
  }
828
835
  const parent = factory.isCurrentParentExtension
829
- ? (0, utils_3.getOrThrowError)(factory.extensions, factory.parentTypeName, string_constants_1.EXTENSIONS)
830
- : (0, utils_3.getOrThrowError)(factory.parents, factory.parentTypeName, string_constants_1.PARENTS);
836
+ ? (0, utils_3.getOrThrowError)(factory.extensionContainerByTypeName, factory.parentTypeName, string_constants_1.EXTENSIONS)
837
+ : (0, utils_3.getOrThrowError)(factory.parentContainerByTypeName, factory.parentTypeName, string_constants_1.PARENTS);
831
838
  if (parent.kind !== graphql_1.Kind.OBJECT_TYPE_DEFINITION &&
832
839
  parent.kind !== graphql_1.Kind.OBJECT_TYPE_EXTENSION &&
833
840
  parent.kind !== graphql_1.Kind.INTERFACE_TYPE_DEFINITION &&
834
841
  parent.kind !== graphql_1.Kind.INTERFACE_TYPE_EXTENSION) {
835
842
  throw (0, errors_1.unexpectedKindFatalError)(factory.parentTypeName);
836
843
  }
837
- if (parent.fields.has(name)) {
838
- factory.errors.push((0, errors_1.duplicateFieldDefinitionError)(name, factory.parentTypeName));
844
+ if (parent.fields.has(fieldName)) {
845
+ factory.errors.push((0, errors_1.duplicateFieldDefinitionError)(fieldName, factory.parentTypeName));
839
846
  return;
840
847
  }
841
848
  // recreate the node so the argument descriptions are updated
842
849
  const fieldContainer = {
843
850
  arguments: factory.extractArguments(node, new Map(), fieldPath),
844
851
  directives: factory.extractDirectives(node, new Map()),
845
- name,
852
+ name: fieldName,
846
853
  node: {
847
854
  ...node,
848
855
  arguments: node.arguments?.map((arg) => ({
@@ -851,27 +858,31 @@ class NormalizationFactory {
851
858
  })),
852
859
  },
853
860
  };
854
- parent.fields.set(name, fieldContainer);
855
- // Only entities will have an existing FieldSet
856
- const existingFieldSet = factory.fieldSetsByParent.get(factory.parentTypeName);
857
- if (existingFieldSet) {
858
- // @requires should only be defined on a field whose parent is an entity
859
- // If there is existingFieldSet, it's an entity
860
- (0, utils_2.extractFieldSetValue)(name, existingFieldSet.requires, fieldContainer.directives.get(string_constants_1.REQUIRES));
861
- // @provides only makes sense on entities, but the field can be encountered before the type definition
862
- // When the FieldSet is evaluated, it will be checked whether the field is an entity.
863
- (0, utils_2.extractFieldSetValue)(name, existingFieldSet.provides, fieldContainer.directives.get(string_constants_1.PROVIDES));
864
- return;
861
+ parent.fields.set(fieldName, fieldContainer);
862
+ const entityContainer = factory.entityContainerByTypeName.get(factory.parentTypeName);
863
+ if (entityContainer) {
864
+ entityContainer.fieldNames.add(fieldName);
865
+ // Only entities will have an existing FieldSet
866
+ const existingFieldSet = factory.fieldSetContainerByTypeName.get(factory.parentTypeName);
867
+ if (existingFieldSet) {
868
+ // @requires should only be defined on a field whose parent is an entity
869
+ // If there is existingFieldSet, it's an entity
870
+ (0, utils_2.extractFieldSetValue)(fieldName, existingFieldSet.requires, fieldContainer.directives.get(string_constants_1.REQUIRES));
871
+ // @provides only makes sense on entities, but the field can be encountered before the type definition
872
+ // When the FieldSet is evaluated, it will be checked whether the field is an entity.
873
+ (0, utils_2.extractFieldSetValue)(fieldName, existingFieldSet.provides, fieldContainer.directives.get(string_constants_1.PROVIDES));
874
+ return;
875
+ }
865
876
  }
866
877
  const providesDirectives = fieldContainer.directives.get(string_constants_1.PROVIDES);
867
878
  // Check whether the directive exists to avoid creating unnecessary fieldSet configurations
868
879
  if (!providesDirectives) {
869
880
  return;
870
881
  }
871
- const fieldSetContainer = (0, utils_3.getValueOrDefault)(factory.fieldSetsByParent, factory.parentTypeName, utils_2.newFieldSetContainer);
882
+ const fieldSetContainer = (0, utils_3.getValueOrDefault)(factory.fieldSetContainerByTypeName, factory.parentTypeName, utils_2.newFieldSetContainer);
872
883
  // @provides only makes sense on entities, but the field can be encountered before the type definition
873
884
  // When the FieldSet is evaluated, it will be checked whether the field is an entity.
874
- (0, utils_2.extractFieldSetValue)(name, fieldSetContainer.provides, providesDirectives);
885
+ (0, utils_2.extractFieldSetValue)(fieldName, fieldSetContainer.provides, providesDirectives);
875
886
  },
876
887
  leave() {
877
888
  factory.childName = '';
@@ -881,13 +892,13 @@ class NormalizationFactory {
881
892
  InputObjectTypeDefinition: {
882
893
  enter(node) {
883
894
  const name = node.name.value;
884
- if (factory.parents.has(name)) {
895
+ if (factory.parentContainerByTypeName.has(name)) {
885
896
  factory.errors.push((0, errors_1.duplicateTypeDefinitionError)((0, utils_3.kindToTypeString)(node.kind), name));
886
897
  return false;
887
898
  }
888
899
  factory.lastParentNodeKind = node.kind;
889
900
  factory.parentTypeName = name;
890
- factory.parents.set(name, {
901
+ factory.parentContainerByTypeName.set(name, {
891
902
  description: (0, utils_1.formatDescription)(node.description),
892
903
  directives: factory.extractDirectives(node, new Map()),
893
904
  fields: new Map(),
@@ -906,7 +917,7 @@ class NormalizationFactory {
906
917
  factory.parentTypeName = name;
907
918
  factory.lastParentNodeKind = node.kind;
908
919
  factory.isCurrentParentExtension = true;
909
- const extension = factory.extensions.get(factory.parentTypeName);
920
+ const extension = factory.extensionContainerByTypeName.get(factory.parentTypeName);
910
921
  if (extension) {
911
922
  if (extension.kind !== graphql_1.Kind.INPUT_OBJECT_TYPE_EXTENSION) {
912
923
  factory.errors.push((0, errors_1.incompatibleExtensionKindsError)(node, extension.kind));
@@ -915,7 +926,7 @@ class NormalizationFactory {
915
926
  factory.extractDirectives(node, extension.directives);
916
927
  return;
917
928
  }
918
- factory.extensions.set(name, {
929
+ factory.extensionContainerByTypeName.set(name, {
919
930
  directives: factory.extractDirectives(node, new Map()),
920
931
  fields: new Map(),
921
932
  kind: node.kind,
@@ -944,8 +955,8 @@ class NormalizationFactory {
944
955
  factory.referencedTypeNames.add(valueRootTypeName);
945
956
  }
946
957
  const parent = factory.isCurrentParentExtension
947
- ? (0, utils_3.getOrThrowError)(factory.extensions, factory.parentTypeName, string_constants_1.EXTENSIONS)
948
- : (0, utils_3.getOrThrowError)(factory.parents, factory.parentTypeName, string_constants_1.PARENTS);
958
+ ? (0, utils_3.getOrThrowError)(factory.extensionContainerByTypeName, factory.parentTypeName, string_constants_1.EXTENSIONS)
959
+ : (0, utils_3.getOrThrowError)(factory.parentContainerByTypeName, factory.parentTypeName, string_constants_1.PARENTS);
949
960
  if (parent.kind !== graphql_1.Kind.INPUT_OBJECT_TYPE_DEFINITION && parent.kind !== graphql_1.Kind.INPUT_OBJECT_TYPE_EXTENSION) {
950
961
  throw (0, errors_1.unexpectedKindFatalError)(factory.parentTypeName);
951
962
  }
@@ -976,21 +987,12 @@ class NormalizationFactory {
976
987
  if ((0, utils_1.isNodeExtension)(node)) {
977
988
  return factory.handleObjectLikeExtension(node);
978
989
  }
979
- if (factory.parents.has(name)) {
990
+ if (factory.parentContainerByTypeName.has(name)) {
980
991
  factory.errors.push((0, errors_1.duplicateTypeDefinitionError)((0, utils_3.kindToTypeString)(node.kind), name));
981
992
  return false;
982
993
  }
983
994
  const isEntity = (0, utils_1.isObjectLikeNodeEntity)(node);
984
- if (isEntity) {
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, {
995
+ factory.parentContainerByTypeName.set(name, {
994
996
  description: (0, utils_1.formatDescription)(node.description),
995
997
  directives: factory.extractDirectives(node, new Map()),
996
998
  fields: new Map(),
@@ -1002,9 +1004,19 @@ class NormalizationFactory {
1002
1004
  if (!isEntity) {
1003
1005
  return;
1004
1006
  }
1005
- factory.entities.add(name);
1006
- const fieldSets = (0, utils_3.getValueOrDefault)(factory.fieldSetsByParent, name, utils_2.newFieldSetContainer);
1007
- factory.extractKeyFieldSets(node, fieldSets.keys);
1007
+ factory.entityInterfaces.set(name, {
1008
+ concreteTypeNames: new Set(),
1009
+ interfaceFieldNames: new Set(node.fields?.map((field) => field.name.value)),
1010
+ interfaceObjectFieldNames: new Set(),
1011
+ isInterfaceObject: false,
1012
+ typeName: name,
1013
+ });
1014
+ (0, utils_3.upsertEntityContainerProperties)(factory.entityContainerByTypeName, {
1015
+ typeName: factory.parentTypeName,
1016
+ ...(factory.subgraphName ? { subgraphNames: [factory.subgraphName] } : {}),
1017
+ });
1018
+ const fieldSetContainer = (0, utils_3.getValueOrDefault)(factory.fieldSetContainerByTypeName, name, utils_2.newFieldSetContainer);
1019
+ factory.extractKeyFieldSets(node, fieldSetContainer);
1008
1020
  },
1009
1021
  leave() {
1010
1022
  factory.parentTypeName = '';
@@ -1026,12 +1038,12 @@ class NormalizationFactory {
1026
1038
  },
1027
1039
  ObjectTypeDefinition: {
1028
1040
  enter(node) {
1029
- const name = node.name.value;
1030
- if (name === string_constants_1.SERVICE_OBJECT) {
1041
+ const typeName = node.name.value;
1042
+ if (typeName === string_constants_1.SERVICE_OBJECT) {
1031
1043
  return false;
1032
1044
  }
1033
- factory.isCurrentParentRootType = string_constants_1.ROOT_TYPES.has(name) || factory.operationTypeNames.has(name);
1034
- factory.parentTypeName = name;
1045
+ factory.isCurrentParentRootType = string_constants_1.ROOT_TYPES.has(typeName) || factory.operationTypeNames.has(typeName);
1046
+ factory.parentTypeName = typeName;
1035
1047
  factory.lastParentNodeKind = node.kind;
1036
1048
  (0, utils_1.addConcreteTypesForImplementedInterfaces)(node, factory.abstractToConcreteTypeNames);
1037
1049
  factory.handleInterfaceObject(node);
@@ -1039,12 +1051,12 @@ class NormalizationFactory {
1039
1051
  if ((0, utils_1.isNodeExtension)(node)) {
1040
1052
  return factory.handleObjectLikeExtension(node);
1041
1053
  }
1042
- if (factory.parents.has(name)) {
1043
- factory.errors.push((0, errors_1.duplicateTypeDefinitionError)((0, utils_3.kindToTypeString)(node.kind), name));
1054
+ if (factory.parentContainerByTypeName.has(typeName)) {
1055
+ factory.errors.push((0, errors_1.duplicateTypeDefinitionError)((0, utils_3.kindToTypeString)(node.kind), typeName));
1044
1056
  return false;
1045
1057
  }
1046
1058
  const isEntity = (0, utils_1.isObjectLikeNodeEntity)(node);
1047
- factory.parents.set(name, {
1059
+ factory.parentContainerByTypeName.set(typeName, {
1048
1060
  description: (0, utils_1.formatDescription)(node.description),
1049
1061
  directives: factory.extractDirectives(node, new Map()),
1050
1062
  fields: new Map(),
@@ -1056,9 +1068,13 @@ class NormalizationFactory {
1056
1068
  if (!isEntity) {
1057
1069
  return;
1058
1070
  }
1059
- factory.entities.add(name);
1060
- const fieldSets = (0, utils_3.getValueOrDefault)(factory.fieldSetsByParent, name, utils_2.newFieldSetContainer);
1061
- factory.extractKeyFieldSets(node, fieldSets.keys);
1071
+ const fieldSetContainer = (0, utils_3.getValueOrDefault)(factory.fieldSetContainerByTypeName, typeName, utils_2.newFieldSetContainer);
1072
+ factory.extractKeyFieldSets(node, fieldSetContainer);
1073
+ (0, utils_3.upsertEntityContainerProperties)(factory.entityContainerByTypeName, {
1074
+ typeName: factory.parentTypeName,
1075
+ keyFieldSets: fieldSetContainer.keys,
1076
+ ...(factory.subgraphName ? { subgraphNames: [factory.subgraphName] } : {}),
1077
+ });
1062
1078
  },
1063
1079
  leave() {
1064
1080
  factory.isCurrentParentRootType = false;
@@ -1092,14 +1108,14 @@ class NormalizationFactory {
1092
1108
  if (name === string_constants_1.ANY_SCALAR) {
1093
1109
  return false;
1094
1110
  }
1095
- const parent = factory.parents.get(name);
1111
+ const parent = factory.parentContainerByTypeName.get(name);
1096
1112
  if (parent) {
1097
1113
  factory.errors.push((0, errors_1.duplicateTypeDefinitionError)((0, utils_3.kindToTypeString)(node.kind), name));
1098
1114
  return false;
1099
1115
  }
1100
1116
  factory.parentTypeName = name;
1101
1117
  factory.lastParentNodeKind = node.kind;
1102
- factory.parents.set(name, {
1118
+ factory.parentContainerByTypeName.set(name, {
1103
1119
  description: (0, utils_1.formatDescription)(node.description),
1104
1120
  directives: factory.extractDirectives(node, new Map()),
1105
1121
  kind: graphql_1.Kind.SCALAR_TYPE_DEFINITION,
@@ -1117,7 +1133,7 @@ class NormalizationFactory {
1117
1133
  if (name === string_constants_1.ANY_SCALAR) {
1118
1134
  return false;
1119
1135
  }
1120
- const extension = factory.extensions.get(name);
1136
+ const extension = factory.extensionContainerByTypeName.get(name);
1121
1137
  if (extension) {
1122
1138
  if (extension.kind !== graphql_1.Kind.SCALAR_TYPE_EXTENSION) {
1123
1139
  factory.errors.push((0, errors_1.incompatibleExtensionKindsError)(node, extension.kind));
@@ -1128,7 +1144,7 @@ class NormalizationFactory {
1128
1144
  else {
1129
1145
  factory.parentTypeName = name;
1130
1146
  factory.lastParentNodeKind = node.kind;
1131
- factory.extensions.set(name, {
1147
+ factory.extensionContainerByTypeName.set(name, {
1132
1148
  directives: factory.extractDirectives(node, new Map()),
1133
1149
  kind: node.kind,
1134
1150
  name: node.name,
@@ -1148,7 +1164,7 @@ class NormalizationFactory {
1148
1164
  return false;
1149
1165
  }
1150
1166
  factory.parentTypeName = name;
1151
- const parent = factory.parents.get(name);
1167
+ const parent = factory.parentContainerByTypeName.get(name);
1152
1168
  if (parent) {
1153
1169
  factory.errors.push((0, errors_1.duplicateTypeDefinitionError)((0, utils_3.kindToTypeString)(node.kind), name));
1154
1170
  return false;
@@ -1159,7 +1175,7 @@ class NormalizationFactory {
1159
1175
  }
1160
1176
  factory.lastParentNodeKind = node.kind;
1161
1177
  (0, utils_1.addConcreteTypesForUnion)(node, factory.abstractToConcreteTypeNames);
1162
- factory.parents.set(name, {
1178
+ factory.parentContainerByTypeName.set(name, {
1163
1179
  description: (0, utils_1.formatDescription)(node.description),
1164
1180
  directives: factory.extractDirectives(node, new Map()),
1165
1181
  kind: node.kind,
@@ -1178,7 +1194,7 @@ class NormalizationFactory {
1178
1194
  if (name === string_constants_1.ENTITY_UNION) {
1179
1195
  return false;
1180
1196
  }
1181
- const extension = factory.extensions.get(name);
1197
+ const extension = factory.extensionContainerByTypeName.get(name);
1182
1198
  if (!node.types) {
1183
1199
  factory.errors.push();
1184
1200
  return false;
@@ -1193,7 +1209,7 @@ class NormalizationFactory {
1193
1209
  factory.extractDirectives(node, extension.directives);
1194
1210
  }
1195
1211
  else {
1196
- factory.extensions.set(name, {
1212
+ factory.extensionContainerByTypeName.set(name, {
1197
1213
  directives: factory.extractDirectives(node, new Map()),
1198
1214
  kind: node.kind,
1199
1215
  name: node.name,
@@ -1226,8 +1242,8 @@ class NormalizationFactory {
1226
1242
  }
1227
1243
  const validExtensionOrphans = new Set();
1228
1244
  const parentsToIgnore = new Set();
1229
- for (const [extensionTypeName, extensionContainer] of this.extensions) {
1230
- const isEntity = this.entities.has(extensionTypeName);
1245
+ for (const [extensionTypeName, extensionContainer] of this.extensionContainerByTypeName) {
1246
+ const isEntity = this.entityContainerByTypeName.has(extensionTypeName);
1231
1247
  const configurationData = {
1232
1248
  fieldNames: new Set(),
1233
1249
  isRootNode: isEntity,
@@ -1241,7 +1257,7 @@ class NormalizationFactory {
1241
1257
  }
1242
1258
  (0, utils_2.addNonExternalFieldsToSet)(extensionContainer.fields, configurationData.fieldNames);
1243
1259
  }
1244
- const baseType = this.parents.get(extensionTypeName);
1260
+ const baseType = this.parentContainerByTypeName.get(extensionTypeName);
1245
1261
  if (!baseType) {
1246
1262
  if (extensionContainer.kind !== graphql_1.Kind.OBJECT_TYPE_EXTENSION) {
1247
1263
  this.errors.push((0, errors_1.noBaseTypeExtensionError)(extensionTypeName));
@@ -1306,10 +1322,12 @@ class NormalizationFactory {
1306
1322
  this.mergeUniqueInterfaces(objectLikeExtension.interfaces, baseType.interfaces, extensionTypeName);
1307
1323
  this.validateInterfaceImplementations(baseType);
1308
1324
  definitions.push((0, utils_2.objectLikeContainerToNode)(this, baseType, objectLikeExtension));
1309
- // interfaces and objects must define at least one field
1325
+ // Interfaces and objects must define at least one field
1310
1326
  if (baseType.fields.size < 1 && !(0, utils_2.isNodeQuery)(extensionTypeName, operationTypeNode)) {
1311
1327
  this.errors.push((0, errors_1.noFieldDefinitionsError)((0, utils_3.kindToTypeString)(baseType.kind), extensionTypeName));
1312
1328
  }
1329
+ // Add the non-external base type field names to the configuration data
1330
+ (0, utils_2.addNonExternalFieldsToSet)(baseType.fields, configurationData.fieldNames);
1313
1331
  break;
1314
1332
  case graphql_1.Kind.SCALAR_TYPE_DEFINITION:
1315
1333
  definitions.push((0, utils_2.scalarContainerToNode)(this, baseType, extensionContainer));
@@ -1324,7 +1342,7 @@ class NormalizationFactory {
1324
1342
  // At this point, the base type has been dealt with, so it doesn't need to be dealt with again
1325
1343
  parentsToIgnore.add(extensionTypeName);
1326
1344
  }
1327
- for (const [parentTypeName, parentContainer] of this.parents) {
1345
+ for (const [parentTypeName, parentContainer] of this.parentContainerByTypeName) {
1328
1346
  if (parentsToIgnore.has(parentTypeName)) {
1329
1347
  continue;
1330
1348
  }
@@ -1338,7 +1356,7 @@ class NormalizationFactory {
1338
1356
  case graphql_1.Kind.INTERFACE_TYPE_DEFINITION:
1339
1357
  // intentional fallthrough
1340
1358
  case graphql_1.Kind.OBJECT_TYPE_DEFINITION:
1341
- const isEntity = this.entities.has(parentTypeName);
1359
+ const isEntity = this.entityContainerByTypeName.has(parentTypeName);
1342
1360
  const operationTypeNode = this.operationTypeNames.get(parentTypeName);
1343
1361
  if (operationTypeNode) {
1344
1362
  parentContainer.fields.delete(string_constants_1.SERVICE_FIELD);
@@ -1397,12 +1415,12 @@ class NormalizationFactory {
1397
1415
  const operationTypeName = node ? (0, type_merging_1.getNamedTypeForChild)(`schema.${operationType}`, node.type) : defaultTypeName;
1398
1416
  // If a custom type is used, the default type should not be defined
1399
1417
  if (operationTypeName !== defaultTypeName &&
1400
- (this.parents.has(defaultTypeName) || this.extensions.has(defaultTypeName))) {
1418
+ (this.parentContainerByTypeName.has(defaultTypeName) || this.extensionContainerByTypeName.has(defaultTypeName))) {
1401
1419
  this.errors.push((0, errors_1.invalidRootTypeDefinitionError)(operationType, operationTypeName, defaultTypeName));
1402
1420
  continue;
1403
1421
  }
1404
- const object = this.parents.get(operationTypeName);
1405
- const extension = this.extensions.get(operationTypeName);
1422
+ const object = this.parentContainerByTypeName.get(operationTypeName);
1423
+ const extension = this.extensionContainerByTypeName.get(operationTypeName);
1406
1424
  // Node is truthy if an operation type was explicitly declared
1407
1425
  if (node) {
1408
1426
  // If the type is not defined in the schema, it's always an error
@@ -1437,7 +1455,7 @@ class NormalizationFactory {
1437
1455
  const fieldPath = `${operationTypeName}.${fieldName}`;
1438
1456
  const fieldTypeName = (0, type_merging_1.getNamedTypeForChild)(fieldPath, fieldContainer.node.type);
1439
1457
  if (!constants_1.BASE_SCALARS.has(fieldTypeName) &&
1440
- !this.parents.has(fieldTypeName) &&
1458
+ !this.parentContainerByTypeName.has(fieldTypeName) &&
1441
1459
  !validExtensionOrphans.has(fieldTypeName)) {
1442
1460
  this.errors.push((0, errors_1.undefinedTypeError)(fieldTypeName));
1443
1461
  }
@@ -1445,16 +1463,17 @@ class NormalizationFactory {
1445
1463
  }
1446
1464
  }
1447
1465
  for (const referencedTypeName of this.referencedTypeNames) {
1448
- if (this.parents.has(referencedTypeName) || this.entities.has(referencedTypeName)) {
1466
+ if (this.parentContainerByTypeName.has(referencedTypeName) ||
1467
+ this.entityContainerByTypeName.has(referencedTypeName)) {
1449
1468
  continue;
1450
1469
  }
1451
- const extension = this.extensions.get(referencedTypeName);
1470
+ const extension = this.extensionContainerByTypeName.get(referencedTypeName);
1452
1471
  if (!extension || extension.kind !== graphql_1.Kind.OBJECT_TYPE_EXTENSION) {
1453
1472
  this.errors.push((0, errors_1.undefinedTypeError)(referencedTypeName));
1454
1473
  }
1455
1474
  }
1456
- for (const [parentTypeName, fieldSets] of this.fieldSetsByParent) {
1457
- const parentContainer = this.parents.get(parentTypeName) || this.extensions.get(parentTypeName);
1475
+ for (const [parentTypeName, fieldSetContainers] of this.fieldSetContainerByTypeName) {
1476
+ const parentContainer = this.parentContainerByTypeName.get(parentTypeName) || this.extensionContainerByTypeName.get(parentTypeName);
1458
1477
  if (!parentContainer ||
1459
1478
  (parentContainer.kind !== graphql_1.Kind.OBJECT_TYPE_DEFINITION &&
1460
1479
  parentContainer.kind != graphql_1.Kind.OBJECT_TYPE_EXTENSION &&
@@ -1464,7 +1483,7 @@ class NormalizationFactory {
1464
1483
  continue;
1465
1484
  }
1466
1485
  // this is where keys, provides, and requires are added to the ConfigurationData
1467
- (0, utils_2.validateAndAddDirectivesWithFieldSetToConfigurationData)(this, parentContainer, fieldSets);
1486
+ (0, utils_2.validateAndAddDirectivesWithFieldSetToConfigurationData)(this, parentContainer, fieldSetContainers);
1468
1487
  }
1469
1488
  if (this.errors.length > 0) {
1470
1489
  return { errors: this.errors };
@@ -1478,11 +1497,14 @@ class NormalizationFactory {
1478
1497
  // configurationDataMap is map of ConfigurationData per type name.
1479
1498
  // It is an Intermediate configuration object that will be converted to an engine configuration in the router
1480
1499
  configurationDataMap: this.configurationDataMap,
1500
+ entityContainerByTypeName: this.entityContainerByTypeName,
1481
1501
  entityInterfaces: this.entityInterfaces,
1502
+ extensionContainerByTypeName: this.extensionContainerByTypeName,
1482
1503
  isVersionTwo: this.isSubgraphVersionTwo,
1483
1504
  keyFieldNamesByParentTypeName: this.keyFieldNamesByParentTypeName,
1484
1505
  operationTypes: this.operationTypeNames,
1485
1506
  overridesByTargetSubgraphName: this.overridesByTargetSubgraphName,
1507
+ parentContainerByTypeName: this.parentContainerByTypeName,
1486
1508
  subgraphAST: newAST,
1487
1509
  subgraphString: (0, graphql_1.print)(newAST),
1488
1510
  schema: (0, buildASTSchema_1.buildASTSchema)(newAST, { assumeValid: true }),
@@ -1492,15 +1514,17 @@ class NormalizationFactory {
1492
1514
  }
1493
1515
  exports.NormalizationFactory = NormalizationFactory;
1494
1516
  function batchNormalize(subgraphs) {
1517
+ const entityContainersByTypeName = new Map();
1495
1518
  const internalSubgraphsBySubgraphName = new Map();
1496
1519
  const allOverridesByTargetSubgraphName = new Map();
1497
1520
  const overrideSourceSubgraphNamesByFieldPath = new Map();
1498
1521
  const duplicateOverriddenFieldPaths = new Set();
1499
- const validationErrors = [];
1522
+ const parentContainerMapsBySubgraphName = new Map();
1500
1523
  const subgraphNames = new Set();
1501
1524
  const nonUniqueSubgraphNames = new Set();
1502
1525
  const invalidNameErrorMessages = [];
1503
1526
  const warnings = [];
1527
+ const validationErrors = [];
1504
1528
  // Record the subgraph names first, so that subgraph references can be validated
1505
1529
  for (const subgraph of subgraphs) {
1506
1530
  if (subgraph.name) {
@@ -1522,16 +1546,22 @@ function batchNormalize(subgraphs) {
1522
1546
  validationErrors.push((0, errors_1.subgraphValidationError)(subgraphName, [errors_1.subgraphValidationFailureError]));
1523
1547
  continue;
1524
1548
  }
1549
+ parentContainerMapsBySubgraphName.set(subgraphName, normalizationResult.parentContainerByTypeName);
1550
+ for (const entityContainer of normalizationResult.entityContainerByTypeName.values()) {
1551
+ (0, utils_3.upsertEntityContainer)(entityContainersByTypeName, entityContainer);
1552
+ }
1525
1553
  if (subgraph.name) {
1526
1554
  internalSubgraphsBySubgraphName.set(subgraphName, {
1527
1555
  configurationDataMap: normalizationResult.configurationDataMap,
1528
1556
  definitions: normalizationResult.subgraphAST,
1529
1557
  entityInterfaces: normalizationResult.entityInterfaces,
1558
+ extensionContainerByTypeName: normalizationResult.extensionContainerByTypeName,
1530
1559
  keyFieldNamesByParentTypeName: normalizationResult.keyFieldNamesByParentTypeName,
1531
1560
  isVersionTwo: normalizationResult.isVersionTwo,
1532
1561
  name: subgraphName,
1533
1562
  operationTypes: normalizationResult.operationTypes,
1534
1563
  overriddenFieldNamesByParentTypeName: new Map(),
1564
+ parentContainerByTypeName: normalizationResult.parentContainerByTypeName,
1535
1565
  schema: normalizationResult.schema,
1536
1566
  url: subgraph.url,
1537
1567
  });
@@ -1576,9 +1606,13 @@ function batchNormalize(subgraphs) {
1576
1606
  allErrors.push((0, errors_1.duplicateOverriddenFieldsError)(duplicateOverriddenFieldErrorMessages));
1577
1607
  }
1578
1608
  allErrors.push(...validationErrors);
1579
- const warningsToPropagate = warnings.length > 0 ? warnings : undefined;
1580
1609
  if (allErrors.length > 0) {
1581
- return { errors: allErrors, internalSubgraphsBySubgraphName, warnings: warningsToPropagate };
1610
+ return {
1611
+ entityContainerByTypeName: entityContainersByTypeName,
1612
+ errors: allErrors,
1613
+ internalSubgraphBySubgraphName: internalSubgraphsBySubgraphName,
1614
+ ...(warnings.length > 0 ? { warnings } : {}),
1615
+ };
1582
1616
  }
1583
1617
  for (const [targetSubgraphName, overridesData] of allOverridesByTargetSubgraphName) {
1584
1618
  const internalSubgraph = (0, utils_3.getOrThrowError)(internalSubgraphsBySubgraphName, targetSubgraphName, 'normalizedSubgraphsByName');
@@ -1595,8 +1629,9 @@ function batchNormalize(subgraphs) {
1595
1629
  }
1596
1630
  }
1597
1631
  return {
1598
- internalSubgraphsBySubgraphName: internalSubgraphsBySubgraphName,
1599
- warnings: warningsToPropagate,
1632
+ entityContainerByTypeName: entityContainersByTypeName,
1633
+ internalSubgraphBySubgraphName: internalSubgraphsBySubgraphName,
1634
+ ...(warnings.length > 0 ? { warnings } : {}),
1600
1635
  };
1601
1636
  }
1602
1637
  exports.batchNormalize = batchNormalize;