@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.
Files changed (36) hide show
  1. package/dist/ast/utils.d.ts +9 -2
  2. package/dist/ast/utils.js.map +1 -1
  3. package/dist/errors/errors.js +1 -2
  4. package/dist/errors/errors.js.map +1 -1
  5. package/dist/federation/federation-factory.d.ts +18 -14
  6. package/dist/federation/federation-factory.js +246 -83
  7. package/dist/federation/federation-factory.js.map +1 -1
  8. package/dist/federation/utils.d.ts +7 -11
  9. package/dist/federation/utils.js.map +1 -1
  10. package/dist/index.d.ts +6 -6
  11. package/dist/index.js +6 -6
  12. package/dist/index.js.map +1 -1
  13. package/dist/normalization/normalization-factory.d.ts +24 -14
  14. package/dist/normalization/normalization-factory.js +236 -120
  15. package/dist/normalization/normalization-factory.js.map +1 -1
  16. package/dist/normalization/utils.d.ts +3 -2
  17. package/dist/normalization/utils.js +21 -11
  18. package/dist/normalization/utils.js.map +1 -1
  19. package/dist/{subgraph/field-configuration.d.ts → router-configuration/router-configuration.d.ts} +13 -10
  20. package/dist/{subgraph/field-configuration.js → router-configuration/router-configuration.js} +1 -1
  21. package/dist/router-configuration/router-configuration.js.map +1 -0
  22. package/dist/subgraph/subgraph.d.ts +8 -4
  23. package/dist/subgraph/subgraph.js +81 -78
  24. package/dist/subgraph/subgraph.js.map +1 -1
  25. package/dist/tsconfig.tsbuildinfo +1 -1
  26. package/dist/utils/constants.d.ts +2 -1
  27. package/dist/utils/constants.js +82 -27
  28. package/dist/utils/constants.js.map +1 -1
  29. package/dist/utils/string-constants.d.ts +8 -2
  30. package/dist/utils/string-constants.js +10 -4
  31. package/dist/utils/string-constants.js.map +1 -1
  32. package/dist/utils/utils.d.ts +42 -1
  33. package/dist/utils/utils.js +156 -1
  34. package/dist/utils/utils.js.map +1 -1
  35. package/package.json +2 -2
  36. 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
- entities = new Set();
40
+ entityContainerByTypeName = new Map();
40
41
  entityInterfaces = new Map();
41
- extensions = new Map();
42
+ extensionContainerByTypeName = new Map();
42
43
  isCurrentParentExtension = false;
43
44
  isCurrentParentRootType = false;
44
45
  isSubgraphVersionTwo = false;
45
- fieldSetsByParent = new Map();
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
- parents = new Map();
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.parents.get(namedType);
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.extensions.get(this.parentTypeName);
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.extractDirectives(node, extension.directives);
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.extensions.set(this.parentTypeName, {
298
- directives: this.extractDirectives(node, new Map()),
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
- 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);
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, rawFieldSets) {
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.parents, interfaceName, string_constants_1.PARENTS);
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, fieldName) {
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, fieldName);
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 name = node.name.value;
735
- if (factory.parents.has(name)) {
736
- factory.errors.push((0, errors_1.duplicateTypeDefinitionError)((0, utils_3.kindToTypeString)(node.kind), name));
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 = name;
817
+ factory.parentTypeName = typeName;
740
818
  factory.lastParentNodeKind = node.kind;
741
- factory.parents.set(name, {
819
+ const directives = factory.extractDirectivesAndAuthorization(node, new Map());
820
+ factory.parentContainerByTypeName.set(typeName, {
742
821
  description: (0, utils_1.formatDescription)(node.description),
743
- directives: factory.extractDirectives(node, new Map()),
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.extensions.get(factory.parentTypeName);
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.extractDirectives(node, extension.directives);
845
+ factory.extractDirectivesAndAuthorization(node, extension.directives);
767
846
  return;
768
847
  }
769
- factory.extensions.set(name, {
770
- directives: factory.extractDirectives(node, new Map()),
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.extensions, factory.parentTypeName, string_constants_1.EXTENSIONS)
789
- : (0, utils_3.getOrThrowError)(factory.parents, factory.parentTypeName, string_constants_1.PARENTS);
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 name = node.name.value;
814
- if (factory.isCurrentParentRootType && (name === string_constants_1.SERVICE_FIELD || name === string_constants_1.ENTITIES_FIELD)) {
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 = name;
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}.${name}`;
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.extensions, factory.parentTypeName, string_constants_1.EXTENSIONS)
830
- : (0, utils_3.getOrThrowError)(factory.parents, factory.parentTypeName, string_constants_1.PARENTS);
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(name)) {
838
- factory.errors.push((0, errors_1.duplicateFieldDefinitionError)(name, factory.parentTypeName));
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.extractDirectives(node, new Map()),
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(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;
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.fieldSetsByParent, factory.parentTypeName, utils_2.newFieldSetContainer);
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)(name, fieldSetContainer.provides, providesDirectives);
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.parents.has(name)) {
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.parents.set(name, {
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.extensions.get(factory.parentTypeName);
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.extensions.set(name, {
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.extensions, factory.parentTypeName, string_constants_1.EXTENSIONS)
948
- : (0, utils_3.getOrThrowError)(factory.parents, factory.parentTypeName, string_constants_1.PARENTS);
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.parents.has(name)) {
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
- 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, {
1067
+ factory.parentContainerByTypeName.set(name, {
994
1068
  description: (0, utils_1.formatDescription)(node.description),
995
- directives: factory.extractDirectives(node, new Map()),
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.entities.add(name);
1006
- const fieldSets = (0, utils_3.getValueOrDefault)(factory.fieldSetsByParent, name, utils_2.newFieldSetContainer);
1007
- factory.extractKeyFieldSets(node, fieldSets.keys);
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 name = node.name.value;
1030
- if (name === string_constants_1.SERVICE_OBJECT) {
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(name) || factory.operationTypeNames.has(name);
1034
- factory.parentTypeName = name;
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.parents.has(name)) {
1043
- factory.errors.push((0, errors_1.duplicateTypeDefinitionError)((0, utils_3.kindToTypeString)(node.kind), name));
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.parents.set(name, {
1131
+ factory.parentContainerByTypeName.set(typeName, {
1048
1132
  description: (0, utils_1.formatDescription)(node.description),
1049
- directives: factory.extractDirectives(node, new Map()),
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.entities.add(name);
1060
- const fieldSets = (0, utils_3.getValueOrDefault)(factory.fieldSetsByParent, name, utils_2.newFieldSetContainer);
1061
- factory.extractKeyFieldSets(node, fieldSets.keys);
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.parents.get(name);
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.parents.set(name, {
1190
+ factory.parentContainerByTypeName.set(name, {
1103
1191
  description: (0, utils_1.formatDescription)(node.description),
1104
- directives: factory.extractDirectives(node, new Map()),
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.extensions.get(name);
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.extractDirectives(node, extension.directives);
1214
+ factory.extractDirectivesAndAuthorization(node, extension.directives);
1127
1215
  }
1128
1216
  else {
1129
1217
  factory.parentTypeName = name;
1130
1218
  factory.lastParentNodeKind = node.kind;
1131
- factory.extensions.set(name, {
1132
- directives: factory.extractDirectives(node, new Map()),
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.parents.get(name);
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.parents.set(name, {
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.extensions.get(name);
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.extensions.set(name, {
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.FIELD_SET_DEFINITION);
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.extensions) {
1230
- const isEntity = this.entities.has(extensionTypeName);
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.parents.get(extensionTypeName);
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
- // interfaces and objects must define at least one field
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.parents) {
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.entities.has(parentTypeName);
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.parents.has(defaultTypeName) || this.extensions.has(defaultTypeName))) {
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.parents.get(operationTypeName);
1405
- const extension = this.extensions.get(operationTypeName);
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.parents.has(fieldTypeName) &&
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.parents.has(referencedTypeName) || this.entities.has(referencedTypeName)) {
1539
+ if (this.parentContainerByTypeName.has(referencedTypeName) ||
1540
+ this.entityContainerByTypeName.has(referencedTypeName)) {
1449
1541
  continue;
1450
1542
  }
1451
- const extension = this.extensions.get(referencedTypeName);
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, fieldSets] of this.fieldSetsByParent) {
1457
- const parentContainer = this.parents.get(parentTypeName) || this.extensions.get(parentTypeName);
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, fieldSets);
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 internalSubgraphsBySubgraphName = new Map();
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 validationErrors = [];
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
- internalSubgraphsBySubgraphName.set(subgraphName, {
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 { errors: allErrors, internalSubgraphsBySubgraphName, warnings: warningsToPropagate };
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)(internalSubgraphsBySubgraphName, targetSubgraphName, 'normalizedSubgraphsByName');
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
- internalSubgraphsBySubgraphName: internalSubgraphsBySubgraphName,
1599
- warnings: warningsToPropagate,
1712
+ authorizationDataByParentTypeName,
1713
+ entityContainerByTypeName: entityContainerByTypeName,
1714
+ internalSubgraphBySubgraphName: internalSubgraphBySubgraphName,
1715
+ ...(warnings.length > 0 ? { warnings } : {}),
1600
1716
  };
1601
1717
  }
1602
1718
  exports.batchNormalize = batchNormalize;