@wundergraph/composition 0.10.1 → 0.11.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.NormalizationFactory = exports.normalizeSubgraph = exports.normalizeSubgraphFromString = void 0;
3
+ exports.batchNormalize = exports.NormalizationFactory = exports.normalizeSubgraph = exports.normalizeSubgraphFromString = void 0;
4
4
  const graphql_1 = require("graphql");
5
5
  const utils_1 = require("../ast/utils");
6
6
  const utils_2 = require("./utils");
@@ -12,8 +12,9 @@ const string_constants_1 = require("../utils/string-constants");
12
12
  const buildASTSchema_1 = require("../buildASTSchema/buildASTSchema");
13
13
  const merge_1 = require("@graphql-tools/merge");
14
14
  const ast_1 = require("../ast/ast");
15
- function normalizeSubgraphFromString(subgraph) {
16
- const { error, documentNode } = (0, utils_1.safeParse)(subgraph);
15
+ const subgraph_1 = require("../subgraph/subgraph");
16
+ function normalizeSubgraphFromString(subgraphSDL) {
17
+ const { error, documentNode } = (0, utils_1.safeParse)(subgraphSDL);
17
18
  if (error || !documentNode) {
18
19
  return { errors: [(0, errors_1.subgraphInvalidSyntaxError)(error)] };
19
20
  }
@@ -29,20 +30,25 @@ exports.normalizeSubgraph = normalizeSubgraph;
29
30
  class NormalizationFactory {
30
31
  abstractToConcreteTypeNames = new Map();
31
32
  allDirectiveDefinitions = new Map();
33
+ argumentName = '';
34
+ childName = '';
32
35
  configurationDataMap = new Map();
33
36
  customDirectiveDefinitions = new Map();
34
37
  errors = [];
35
38
  entities = new Set();
39
+ extensions = new Map();
40
+ isCurrentParentExtension = false;
41
+ isSubgraphVersionTwo = false;
36
42
  fieldSetsByParent = new Map();
43
+ handledRepeatedDirectivesByHostPath = new Map();
44
+ lastParentNodeKind = graphql_1.Kind.NULL;
45
+ lastChildNodeKind = graphql_1.Kind.NULL;
37
46
  keyFieldsByParentTypeName = new Map();
38
47
  operationTypeNames = new Map();
39
48
  parents = new Map();
40
49
  parentTypeName = '';
41
50
  parentsWithChildArguments = new Set();
42
- extensions = new Map();
43
- isChild = false;
44
- isCurrentParentExtension = false;
45
- isSubgraphVersionTwo = false;
51
+ overridesByTargetSubgraphName = new Map();
46
52
  schemaDefinition;
47
53
  referencedDirectives = new Set();
48
54
  referencedTypeNames = new Set();
@@ -472,6 +478,75 @@ class NormalizationFactory {
472
478
  this.errors.push((0, errors_1.unimplementedInterfaceFieldsError)(container.name.value, (0, utils_3.kindToTypeString)(container.kind), implementationErrorsMap));
473
479
  }
474
480
  }
481
+ handleOverride(node, fieldName) {
482
+ if (node.name.value !== string_constants_1.OVERRIDE) {
483
+ return;
484
+ }
485
+ const errorMessages = [];
486
+ let hostPath = `${this.parentTypeName}.${this.childName}`;
487
+ let kind = this.lastChildNodeKind === graphql_1.Kind.NULL ? this.lastParentNodeKind : this.lastChildNodeKind;
488
+ if (this.argumentName) {
489
+ hostPath += `(${this.argumentName}: ...)`;
490
+ kind = graphql_1.Kind.ARGUMENT;
491
+ }
492
+ if (kind !== graphql_1.Kind.FIELD_DEFINITION) {
493
+ errorMessages.push((0, errors_1.invalidDirectiveLocationErrorMessage)(hostPath, kind, string_constants_1.OVERRIDE));
494
+ }
495
+ let targetSubgraphName = '';
496
+ if (node.arguments && node.arguments.length > 0) {
497
+ const observedArguments = new Set();
498
+ const handledDuplicateArguments = new Set();
499
+ for (const argumentNode of node.arguments) {
500
+ const argumentName = argumentNode.name.value;
501
+ if (argumentName !== string_constants_1.FROM && !observedArguments.has(argumentName)) {
502
+ observedArguments.add(argumentName);
503
+ errorMessages.push((0, errors_1.unexpectedDirectiveArgumentErrorMessage)(string_constants_1.OVERRIDE, argumentName));
504
+ continue;
505
+ }
506
+ // If an argument is observed more than once, it is a duplication error.
507
+ // However, the error should only propagate once.
508
+ if (observedArguments.has(argumentName)) {
509
+ if (!handledDuplicateArguments.has(argumentName)) {
510
+ errorMessages.push((0, errors_1.duplicateDirectiveArgumentDefinitionErrorMessage)(string_constants_1.OVERRIDE, hostPath, argumentName));
511
+ }
512
+ continue;
513
+ }
514
+ if (argumentNode.value.kind !== graphql_1.Kind.STRING) {
515
+ errorMessages.push((0, errors_1.invalidDirectiveArgumentTypeErrorMessage)(true, string_constants_1.FROM, graphql_1.Kind.STRING, argumentNode.value.kind));
516
+ }
517
+ else {
518
+ observedArguments.add(string_constants_1.FROM);
519
+ targetSubgraphName = argumentNode.value.value;
520
+ }
521
+ }
522
+ if (!observedArguments.has(string_constants_1.FROM)) {
523
+ errorMessages.push((0, errors_1.undefinedRequiredArgumentsErrorMessage)(string_constants_1.OVERRIDE, hostPath, [string_constants_1.FROM], [string_constants_1.FROM]));
524
+ }
525
+ }
526
+ else {
527
+ errorMessages.push((0, errors_1.undefinedRequiredArgumentsErrorMessage)(string_constants_1.OVERRIDE, hostPath, [string_constants_1.FROM], []));
528
+ }
529
+ if (errorMessages.length > 0) {
530
+ this.errors.push((0, errors_1.invalidDirectiveError)(string_constants_1.OVERRIDE, hostPath, errorMessages));
531
+ return;
532
+ }
533
+ const overrideDataForSubgraph = (0, utils_3.getValueOrDefault)(this.overridesByTargetSubgraphName, targetSubgraphName, () => new Map());
534
+ const overriddenFieldNamesForParent = (0, utils_3.getValueOrDefault)(overrideDataForSubgraph, this.parentTypeName, () => new Set());
535
+ if (overriddenFieldNamesForParent.has(this.childName)) {
536
+ const handledRepeatedDirectives = this.handledRepeatedDirectivesByHostPath.get(hostPath);
537
+ // If the directive name exists as a value on the host path key, the repeatable error has been handled
538
+ if (handledRepeatedDirectives && handledRepeatedDirectives.has(string_constants_1.OVERRIDE)) {
539
+ return;
540
+ }
541
+ // Add the directive name to the existing set (if other invalid repeated directives exist) or a new set
542
+ (0, utils_3.getValueOrDefault)(this.handledRepeatedDirectivesByHostPath, hostPath, () => new Set())
543
+ .add(string_constants_1.OVERRIDE);
544
+ // The invalid repeated directive error should propagate only once per directive per host path
545
+ this.errors.push((0, errors_1.invalidDirectiveError)(string_constants_1.OVERRIDE, hostPath, [(0, errors_1.invalidRepeatedDirectiveErrorMessage)(string_constants_1.OVERRIDE, hostPath)]));
546
+ return;
547
+ }
548
+ overriddenFieldNamesForParent.add(this.childName);
549
+ }
475
550
  normalize(document) {
476
551
  const factory = this;
477
552
  /* factory.allDirectiveDefinitions is initialized with v1 directive definitions, and v2 definitions are only added
@@ -479,6 +554,42 @@ class NormalizationFactory {
479
554
  allDirectiveDefinitions cannot be used to check for duplicate definitions, and another set (below) is required */
480
555
  const definedDirectives = new Set();
481
556
  let isCurrentParentRootType = false;
557
+ let fieldName = '';
558
+ // Collect any renamed root types
559
+ (0, graphql_1.visit)(document, {
560
+ OperationTypeDefinition: {
561
+ enter(node) {
562
+ const operationType = node.operation;
563
+ const operationPath = `${factory.parentTypeName}.${operationType}`;
564
+ const definitionNode = factory.schemaDefinition.operationTypes.get(operationType);
565
+ const newTypeName = (0, type_merging_1.getNamedTypeForChild)(operationPath, node.type);
566
+ if (definitionNode) {
567
+ (0, errors_1.duplicateOperationTypeDefinitionError)(operationType, newTypeName, (0, type_merging_1.getNamedTypeForChild)(operationPath, definitionNode.type));
568
+ return false;
569
+ }
570
+ const existingOperationType = factory.operationTypeNames.get(newTypeName);
571
+ if (existingOperationType) {
572
+ factory.errors.push((0, errors_1.invalidOperationTypeDefinitionError)(existingOperationType, newTypeName, operationType));
573
+ }
574
+ else {
575
+ factory.operationTypeNames.set(newTypeName, operationType);
576
+ factory.schemaDefinition.operationTypes.set(operationType, node);
577
+ }
578
+ return false;
579
+ },
580
+ },
581
+ SchemaDefinition: {
582
+ enter(node) {
583
+ factory.extractDirectives(node, factory.schemaDefinition.directives);
584
+ factory.schemaDefinition.description = node.description;
585
+ },
586
+ },
587
+ SchemaExtension: {
588
+ enter(node) {
589
+ factory.extractDirectives(node, factory.schemaDefinition.directives);
590
+ },
591
+ },
592
+ });
482
593
  (0, graphql_1.visit)(document, {
483
594
  DirectiveDefinition: {
484
595
  enter(node) {
@@ -507,6 +618,7 @@ class NormalizationFactory {
507
618
  Directive: {
508
619
  enter(node) {
509
620
  const name = node.name.value;
621
+ factory.handleOverride(node, fieldName);
510
622
  if (constants_1.VERSION_TWO_DIRECTIVES.has(name)) {
511
623
  factory.isSubgraphVersionTwo = true;
512
624
  return false;
@@ -525,6 +637,7 @@ class NormalizationFactory {
525
637
  return false;
526
638
  }
527
639
  factory.parentTypeName = name;
640
+ factory.lastParentNodeKind = node.kind;
528
641
  factory.parents.set(name, {
529
642
  description: (0, utils_1.formatDescription)(node.description),
530
643
  directives: factory.extractDirectives(node, new Map()),
@@ -535,12 +648,14 @@ class NormalizationFactory {
535
648
  },
536
649
  leave() {
537
650
  factory.parentTypeName = '';
651
+ factory.lastParentNodeKind = graphql_1.Kind.NULL;
538
652
  },
539
653
  },
540
654
  EnumTypeExtension: {
541
655
  enter(node) {
542
656
  const name = node.name.value;
543
657
  factory.parentTypeName = name;
658
+ factory.lastParentNodeKind = node.kind;
544
659
  factory.isCurrentParentExtension = true;
545
660
  const extension = factory.extensions.get(factory.parentTypeName);
546
661
  if (extension) {
@@ -559,13 +674,16 @@ class NormalizationFactory {
559
674
  });
560
675
  },
561
676
  leave() {
562
- factory.isCurrentParentExtension = false;
563
677
  factory.parentTypeName = '';
678
+ factory.lastParentNodeKind = graphql_1.Kind.NULL;
679
+ factory.isCurrentParentExtension = false;
564
680
  },
565
681
  },
566
682
  EnumValueDefinition: {
567
683
  enter(node) {
568
684
  const name = node.name.value;
685
+ factory.childName = name;
686
+ factory.lastChildNodeKind = node.kind;
569
687
  const parent = factory.isCurrentParentExtension
570
688
  ? (0, utils_3.getOrThrowError)(factory.extensions, factory.parentTypeName, string_constants_1.EXTENSIONS)
571
689
  : (0, utils_3.getOrThrowError)(factory.parents, factory.parentTypeName, string_constants_1.PARENTS);
@@ -585,6 +703,10 @@ class NormalizationFactory {
585
703
  node: { ...node, description: (0, utils_1.formatDescription)(node.description) },
586
704
  });
587
705
  },
706
+ leave() {
707
+ factory.childName = '';
708
+ factory.lastChildNodeKind = graphql_1.Kind.NULL;
709
+ },
588
710
  },
589
711
  FieldDefinition: {
590
712
  enter(node) {
@@ -592,8 +714,10 @@ class NormalizationFactory {
592
714
  if (isCurrentParentRootType && (name === string_constants_1.SERVICE_FIELD || name === string_constants_1.ENTITIES_FIELD)) {
593
715
  return false;
594
716
  }
717
+ factory.childName = name;
718
+ factory.lastChildNodeKind = node.kind;
595
719
  const fieldPath = `${factory.parentTypeName}.${name}`;
596
- factory.isChild = true;
720
+ factory.lastChildNodeKind = node.kind;
597
721
  const fieldNamedTypeName = (0, type_merging_1.getNamedTypeForChild)(fieldPath, node.type);
598
722
  if (!constants_1.BASE_SCALARS.has(fieldNamedTypeName)) {
599
723
  factory.referencedTypeNames.add(fieldNamedTypeName);
@@ -647,7 +771,8 @@ class NormalizationFactory {
647
771
  (0, utils_2.extractFieldSetValue)(name, fieldSetContainer.provides, providesDirectives);
648
772
  },
649
773
  leave() {
650
- factory.isChild = false;
774
+ factory.childName = '';
775
+ factory.lastChildNodeKind = graphql_1.Kind.NULL;
651
776
  },
652
777
  },
653
778
  InputObjectTypeDefinition: {
@@ -657,6 +782,7 @@ class NormalizationFactory {
657
782
  factory.errors.push((0, errors_1.duplicateTypeDefinitionError)((0, utils_3.kindToTypeString)(node.kind), name));
658
783
  return false;
659
784
  }
785
+ factory.lastParentNodeKind = node.kind;
660
786
  factory.parentTypeName = name;
661
787
  factory.parents.set(name, {
662
788
  description: (0, utils_1.formatDescription)(node.description),
@@ -667,6 +793,7 @@ class NormalizationFactory {
667
793
  });
668
794
  },
669
795
  leave() {
796
+ factory.lastParentNodeKind = graphql_1.Kind.NULL;
670
797
  factory.parentTypeName = '';
671
798
  },
672
799
  },
@@ -674,6 +801,7 @@ class NormalizationFactory {
674
801
  enter(node) {
675
802
  const name = node.name.value;
676
803
  factory.parentTypeName = name;
804
+ factory.lastParentNodeKind = node.kind;
677
805
  factory.isCurrentParentExtension = true;
678
806
  const extension = factory.extensions.get(factory.parentTypeName);
679
807
  if (extension) {
@@ -692,16 +820,22 @@ class NormalizationFactory {
692
820
  });
693
821
  },
694
822
  leave() {
695
- factory.isCurrentParentExtension = false;
696
823
  factory.parentTypeName = '';
824
+ factory.lastParentNodeKind = graphql_1.Kind.NULL;
825
+ factory.isCurrentParentExtension = false;
697
826
  },
698
827
  },
699
828
  InputValueDefinition: {
700
829
  enter(node) {
701
- if (!factory.parentTypeName || factory.isChild) {
830
+ const name = node.name.value;
831
+ // If the parent is not an object type definition/extension, this node is an argument
832
+ if (factory.lastParentNodeKind !== graphql_1.Kind.INPUT_OBJECT_TYPE_DEFINITION
833
+ && factory.lastParentNodeKind !== graphql_1.Kind.INPUT_OBJECT_TYPE_EXTENSION) {
834
+ factory.argumentName = name;
702
835
  return;
703
836
  }
704
- const name = node.name.value;
837
+ factory.childName = name;
838
+ factory.lastChildNodeKind = node.kind;
705
839
  const valueRootTypeName = (0, type_merging_1.getNamedTypeForChild)(`${factory.parentTypeName}.${name}`, node.type);
706
840
  if (!constants_1.BASE_SCALARS.has(valueRootTypeName)) {
707
841
  factory.referencedTypeNames.add(valueRootTypeName);
@@ -722,11 +856,20 @@ class NormalizationFactory {
722
856
  node: { ...node, description: (0, utils_1.formatDescription)(node.description) },
723
857
  });
724
858
  },
859
+ leave() {
860
+ factory.argumentName = '';
861
+ // Only reset childName and lastNodeKind if this input value was NOT an argument
862
+ if (factory.lastChildNodeKind === graphql_1.Kind.INPUT_VALUE_DEFINITION) {
863
+ factory.childName = '';
864
+ factory.lastChildNodeKind = graphql_1.Kind.NULL;
865
+ }
866
+ },
725
867
  },
726
868
  InterfaceTypeDefinition: {
727
869
  enter(node) {
728
870
  const name = node.name.value;
729
871
  factory.parentTypeName = name;
872
+ factory.lastParentNodeKind = node.kind;
730
873
  if ((0, utils_1.isNodeExtension)(node)) {
731
874
  return factory.handleObjectLikeExtension(node);
732
875
  }
@@ -744,18 +887,21 @@ class NormalizationFactory {
744
887
  });
745
888
  },
746
889
  leave() {
747
- factory.isCurrentParentExtension = false;
748
890
  factory.parentTypeName = '';
891
+ factory.lastParentNodeKind = graphql_1.Kind.NULL;
892
+ factory.isCurrentParentExtension = false;
749
893
  },
750
894
  },
751
895
  InterfaceTypeExtension: {
752
896
  enter(node) {
753
897
  factory.parentTypeName = node.name.value;
898
+ factory.lastParentNodeKind = node.kind;
754
899
  return factory.handleObjectLikeExtension(node);
755
900
  },
756
901
  leave() {
757
902
  factory.isCurrentParentExtension = false;
758
903
  factory.parentTypeName = '';
904
+ factory.lastParentNodeKind = graphql_1.Kind.NULL;
759
905
  },
760
906
  },
761
907
  ObjectTypeDefinition: {
@@ -764,8 +910,9 @@ class NormalizationFactory {
764
910
  if (name === string_constants_1.SERVICE_OBJECT) {
765
911
  return false;
766
912
  }
767
- isCurrentParentRootType = string_constants_1.ROOT_TYPES.has(name);
913
+ isCurrentParentRootType = string_constants_1.ROOT_TYPES.has(name) || factory.operationTypeNames.has(name);
768
914
  factory.parentTypeName = name;
915
+ factory.lastParentNodeKind = node.kind;
769
916
  (0, utils_1.addConcreteTypesForImplementedInterfaces)(node, factory.abstractToConcreteTypeNames);
770
917
  // handling for @extends directive
771
918
  if ((0, utils_1.isNodeExtension)(node)) {
@@ -793,9 +940,10 @@ class NormalizationFactory {
793
940
  factory.extractKeyFieldSets(node, fieldSets.keys);
794
941
  },
795
942
  leave() {
796
- factory.isCurrentParentExtension = false;
797
943
  isCurrentParentRootType = false;
944
+ factory.isCurrentParentExtension = false;
798
945
  factory.parentTypeName = '';
946
+ factory.lastParentNodeKind = graphql_1.Kind.NULL;
799
947
  },
800
948
  },
801
949
  ObjectTypeExtension: {
@@ -804,36 +952,17 @@ class NormalizationFactory {
804
952
  if (name === string_constants_1.SERVICE_OBJECT) {
805
953
  return false;
806
954
  }
807
- isCurrentParentRootType = string_constants_1.ROOT_TYPES.has(name);
955
+ isCurrentParentRootType = string_constants_1.ROOT_TYPES.has(name) || factory.operationTypeNames.has(name);
808
956
  factory.parentTypeName = name;
957
+ factory.lastParentNodeKind = node.kind;
809
958
  (0, utils_1.addConcreteTypesForImplementedInterfaces)(node, factory.abstractToConcreteTypeNames);
810
959
  return factory.handleObjectLikeExtension(node);
811
960
  },
812
961
  leave() {
813
- factory.isCurrentParentExtension = false;
814
962
  isCurrentParentRootType = false;
963
+ factory.isCurrentParentExtension = false;
815
964
  factory.parentTypeName = '';
816
- },
817
- },
818
- OperationTypeDefinition: {
819
- enter(node) {
820
- const operationType = node.operation;
821
- const operationPath = `${factory.parentTypeName}.${operationType}`;
822
- const definitionNode = factory.schemaDefinition.operationTypes.get(operationType);
823
- const newTypeName = (0, type_merging_1.getNamedTypeForChild)(operationPath, node.type);
824
- if (definitionNode) {
825
- (0, errors_1.duplicateOperationTypeDefinitionError)(operationType, newTypeName, (0, type_merging_1.getNamedTypeForChild)(operationPath, definitionNode.type));
826
- return false;
827
- }
828
- const existingOperationType = factory.operationTypeNames.get(newTypeName);
829
- if (existingOperationType) {
830
- factory.errors.push((0, errors_1.invalidOperationTypeDefinitionError)(existingOperationType, newTypeName, operationType));
831
- }
832
- else {
833
- factory.operationTypeNames.set(newTypeName, operationType);
834
- factory.schemaDefinition.operationTypes.set(operationType, node);
835
- }
836
- return false;
965
+ factory.lastParentNodeKind = graphql_1.Kind.NULL;
837
966
  },
838
967
  },
839
968
  ScalarTypeDefinition: {
@@ -847,6 +976,8 @@ class NormalizationFactory {
847
976
  factory.errors.push((0, errors_1.duplicateTypeDefinitionError)((0, utils_3.kindToTypeString)(node.kind), name));
848
977
  return false;
849
978
  }
979
+ factory.parentTypeName = name;
980
+ factory.lastParentNodeKind = node.kind;
850
981
  factory.parents.set(name, {
851
982
  description: (0, utils_1.formatDescription)(node.description),
852
983
  directives: factory.extractDirectives(node, new Map()),
@@ -854,6 +985,10 @@ class NormalizationFactory {
854
985
  name: node.name,
855
986
  });
856
987
  },
988
+ leave() {
989
+ factory.parentTypeName = '';
990
+ factory.lastParentNodeKind = graphql_1.Kind.NULL;
991
+ },
857
992
  },
858
993
  ScalarTypeExtension: {
859
994
  enter(node) {
@@ -870,6 +1005,8 @@ class NormalizationFactory {
870
1005
  factory.extractDirectives(node, extension.directives);
871
1006
  }
872
1007
  else {
1008
+ factory.parentTypeName = name;
1009
+ factory.lastParentNodeKind = node.kind;
873
1010
  factory.extensions.set(name, {
874
1011
  directives: factory.extractDirectives(node, new Map()),
875
1012
  kind: node.kind,
@@ -878,16 +1015,9 @@ class NormalizationFactory {
878
1015
  }
879
1016
  return false;
880
1017
  },
881
- },
882
- SchemaDefinition: {
883
- enter(node) {
884
- factory.extractDirectives(node, factory.schemaDefinition.directives);
885
- factory.schemaDefinition.description = node.description;
886
- },
887
- },
888
- SchemaExtension: {
889
- enter(node) {
890
- factory.extractDirectives(node, factory.schemaDefinition.directives);
1018
+ leave() {
1019
+ factory.parentTypeName = '';
1020
+ factory.lastParentNodeKind = graphql_1.Kind.NULL;
891
1021
  },
892
1022
  },
893
1023
  UnionTypeDefinition: {
@@ -906,6 +1036,7 @@ class NormalizationFactory {
906
1036
  factory.errors.push((0, errors_1.noDefinedUnionMembersError)(name));
907
1037
  return false;
908
1038
  }
1039
+ factory.lastParentNodeKind = node.kind;
909
1040
  (0, utils_1.addConcreteTypesForUnion)(node, factory.abstractToConcreteTypeNames);
910
1041
  factory.parents.set(name, {
911
1042
  description: (0, utils_1.formatDescription)(node.description),
@@ -917,6 +1048,7 @@ class NormalizationFactory {
917
1048
  },
918
1049
  leave() {
919
1050
  factory.parentTypeName = '';
1051
+ factory.lastParentNodeKind = graphql_1.Kind.NULL;
920
1052
  },
921
1053
  },
922
1054
  UnionTypeExtension: {
@@ -930,6 +1062,7 @@ class NormalizationFactory {
930
1062
  factory.errors.push();
931
1063
  return false;
932
1064
  }
1065
+ factory.lastParentNodeKind = node.kind;
933
1066
  (0, utils_1.addConcreteTypesForUnion)(node, factory.abstractToConcreteTypeNames);
934
1067
  if (extension) {
935
1068
  if (extension.kind !== graphql_1.Kind.UNION_TYPE_EXTENSION) {
@@ -948,6 +1081,9 @@ class NormalizationFactory {
948
1081
  }
949
1082
  return false;
950
1083
  },
1084
+ leave() {
1085
+ factory.lastParentNodeKind = graphql_1.Kind.NULL;
1086
+ },
951
1087
  },
952
1088
  });
953
1089
  const definitions = [];
@@ -1201,6 +1337,7 @@ class NormalizationFactory {
1201
1337
  isVersionTwo: this.isSubgraphVersionTwo,
1202
1338
  keyFieldsByParentTypeName: this.keyFieldsByParentTypeName,
1203
1339
  operationTypes: this.operationTypeNames,
1340
+ overridesByTargetSubgraphName: this.overridesByTargetSubgraphName,
1204
1341
  subgraphAST: newAST,
1205
1342
  subgraphString: (0, graphql_1.print)(newAST),
1206
1343
  schema: (0, buildASTSchema_1.buildASTSchema)(newAST, { assumeValid: true }),
@@ -1209,4 +1346,110 @@ class NormalizationFactory {
1209
1346
  }
1210
1347
  }
1211
1348
  exports.NormalizationFactory = NormalizationFactory;
1349
+ function batchNormalize(subgraphs) {
1350
+ const internalSubgraphsBySubgraphName = new Map;
1351
+ const allOverridesByTargetSubgraphName = new Map();
1352
+ const overrideSourceSubgraphNamesByFieldPath = new Map();
1353
+ const duplicateOverriddenFieldPaths = new Set();
1354
+ const validationErrors = [];
1355
+ const subgraphNames = new Set();
1356
+ const nonUniqueSubgraphNames = new Set();
1357
+ const invalidNameErrorMessages = [];
1358
+ // Record the subgraph names first, so that subgraph references can be validated
1359
+ for (const subgraph of subgraphs) {
1360
+ if (subgraph.name) {
1361
+ (0, subgraph_1.recordSubgraphName)(subgraph.name, subgraphNames, nonUniqueSubgraphNames);
1362
+ }
1363
+ }
1364
+ for (let i = 0; i < subgraphs.length; i++) {
1365
+ const subgraph = subgraphs[i];
1366
+ const subgraphName = subgraph.name || `subgraph-${i}-${Date.now()}`;
1367
+ if (!subgraph.name) {
1368
+ invalidNameErrorMessages.push((0, errors_1.invalidSubgraphNameErrorMessage)(i, subgraphName));
1369
+ }
1370
+ const { errors, normalizationResult } = normalizeSubgraph(subgraph.definitions);
1371
+ if (errors) {
1372
+ validationErrors.push((0, errors_1.subgraphValidationError)(subgraphName, errors));
1373
+ continue;
1374
+ }
1375
+ if (!normalizationResult) {
1376
+ validationErrors.push((0, errors_1.subgraphValidationError)(subgraphName, [errors_1.subgraphValidationFailureError]));
1377
+ continue;
1378
+ }
1379
+ if (subgraph.name) {
1380
+ internalSubgraphsBySubgraphName.set(subgraphName, {
1381
+ configurationDataMap: normalizationResult.configurationDataMap,
1382
+ definitions: normalizationResult.subgraphAST,
1383
+ keyFieldsByParentTypeName: normalizationResult.keyFieldsByParentTypeName,
1384
+ isVersionTwo: normalizationResult.isVersionTwo,
1385
+ name: subgraphName,
1386
+ operationTypes: normalizationResult.operationTypes,
1387
+ overriddenFieldNamesByParentTypeName: new Map(),
1388
+ schema: normalizationResult.schema,
1389
+ url: subgraph.url,
1390
+ });
1391
+ }
1392
+ if (normalizationResult.overridesByTargetSubgraphName.size < 1) {
1393
+ continue;
1394
+ }
1395
+ const invalidOverrideTargetSubgraphNameErrors = [];
1396
+ for (const [targetSubgraphName, overridesData] of normalizationResult.overridesByTargetSubgraphName) {
1397
+ const isTargetValid = subgraphNames.has(targetSubgraphName);
1398
+ for (const [parentTypeName, fieldNames] of overridesData) {
1399
+ if (!isTargetValid) {
1400
+ invalidOverrideTargetSubgraphNameErrors.push((0, errors_1.invalidOverrideTargetSubgraphNameError)(targetSubgraphName, parentTypeName, [...fieldNames]));
1401
+ }
1402
+ else {
1403
+ const overridesData = (0, utils_3.getValueOrDefault)(allOverridesByTargetSubgraphName, targetSubgraphName, () => new Map());
1404
+ (0, utils_3.getValueOrDefault)(overridesData, parentTypeName, () => new Set(fieldNames));
1405
+ }
1406
+ for (const fieldName of fieldNames) {
1407
+ const fieldPath = `${parentTypeName}.${fieldName}`;
1408
+ const sourceSubgraphs = overrideSourceSubgraphNamesByFieldPath.get(fieldPath);
1409
+ if (!sourceSubgraphs) {
1410
+ overrideSourceSubgraphNamesByFieldPath.set(fieldPath, [subgraphName]);
1411
+ continue;
1412
+ }
1413
+ sourceSubgraphs.push(subgraphName);
1414
+ duplicateOverriddenFieldPaths.add(fieldPath);
1415
+ }
1416
+ }
1417
+ }
1418
+ if (invalidOverrideTargetSubgraphNameErrors.length > 0) {
1419
+ validationErrors.push((0, errors_1.subgraphValidationError)(subgraphName, invalidOverrideTargetSubgraphNameErrors));
1420
+ }
1421
+ }
1422
+ const allErrors = [];
1423
+ if (invalidNameErrorMessages.length > 0 || nonUniqueSubgraphNames.size > 0) {
1424
+ allErrors.push((0, errors_1.invalidSubgraphNamesError)([...nonUniqueSubgraphNames], invalidNameErrorMessages));
1425
+ }
1426
+ if (duplicateOverriddenFieldPaths.size > 0) {
1427
+ const duplicateOverriddenFieldErrorMessages = [];
1428
+ for (const fieldPath of duplicateOverriddenFieldPaths) {
1429
+ const sourceSubgraphNames = (0, utils_3.getOrThrowError)(overrideSourceSubgraphNamesByFieldPath, fieldPath, 'overrideSourceSubgraphNamesByFieldPath');
1430
+ duplicateOverriddenFieldErrorMessages.push((0, errors_1.duplicateOverriddenFieldErrorMessage)(fieldPath, sourceSubgraphNames));
1431
+ }
1432
+ allErrors.push((0, errors_1.duplicateOverriddenFieldsError)(duplicateOverriddenFieldErrorMessages));
1433
+ }
1434
+ allErrors.push(...validationErrors);
1435
+ if (allErrors.length > 0) {
1436
+ return { errors: allErrors, internalSubgraphsBySubgraphName };
1437
+ }
1438
+ for (const [targetSubgraphName, overridesData] of allOverridesByTargetSubgraphName) {
1439
+ const internalSubgraph = (0, utils_3.getOrThrowError)(internalSubgraphsBySubgraphName, targetSubgraphName, 'normalizedSubgraphsByName');
1440
+ internalSubgraph.overriddenFieldNamesByParentTypeName = overridesData;
1441
+ for (const [parentTypeName, fieldNames] of overridesData) {
1442
+ const configurationData = internalSubgraph.configurationDataMap.get(parentTypeName);
1443
+ if (!configurationData) {
1444
+ continue;
1445
+ }
1446
+ (0, utils_3.subtractSourceSetFromTargetSet)(fieldNames, configurationData.fieldNames);
1447
+ if (configurationData.fieldNames.size < 1) {
1448
+ internalSubgraph.configurationDataMap.delete(parentTypeName);
1449
+ }
1450
+ }
1451
+ }
1452
+ return { internalSubgraphsBySubgraphName: internalSubgraphsBySubgraphName };
1453
+ }
1454
+ exports.batchNormalize = batchNormalize;
1212
1455
  //# sourceMappingURL=normalization-factory.js.map