@wundergraph/composition 0.10.0 → 0.11.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.
@@ -1,6 +1,7 @@
1
1
  import { ConstDirectiveNode, DocumentNode, GraphQLSchema, Kind } from 'graphql';
2
2
  import { ArgumentConfigurationData } from '../subgraph/field-configuration';
3
3
  import { MutableDirectiveDefinitionNode, MutableEnumTypeDefinitionNode, MutableEnumValueDefinitionNode, MutableFieldDefinitionNode, MutableInputObjectTypeDefinitionNode, MutableInputValueDefinitionNode, MutableInterfaceTypeDefinitionNode, MutableObjectTypeDefinitionNode, MutableObjectTypeExtensionNode, MutableScalarTypeDefinitionNode, MutableUnionTypeDefinitionNode } from '../ast/ast';
4
+ import { SubgraphConfig } from '../subgraph/subgraph';
4
5
  export type FederationResultContainer = {
5
6
  errors?: Error[];
6
7
  federationResult?: FederationResult;
@@ -9,6 +10,7 @@ export type FederationResult = {
9
10
  argumentConfigurations: ArgumentConfigurationData[];
10
11
  federatedGraphAST: DocumentNode;
11
12
  federatedGraphSchema: GraphQLSchema;
13
+ subgraphConfigBySubgraphName: Map<string, SubgraphConfig>;
12
14
  };
13
15
  export type RootTypeFieldData = {
14
16
  fieldName: string;
@@ -1 +1 @@
1
- {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/federation/utils.ts"],"names":[],"mappings":";;;AAeA,gEAQmC;AAqBtB,QAAA,8BAA8B,GAAG,IAAI,GAAG,CAAS;IAC5D,8BAAW,EAAE,4CAAyB,EAAE,wCAAqB;IAC7D,wCAAqB,EAAE,iCAAc,EAAE,8BAAW,EAAE,qCAAkB;CACvE,CAAC,CAAC;AAEH,IAAY,WAIX;AAJD,WAAY,WAAW;IACrB,+CAAK,CAAA;IACL,6DAAY,CAAA;IACZ,yDAAU,CAAA;AACZ,CAAC,EAJW,WAAW,2BAAX,WAAW,QAItB;AAaD,SAAgB,+BAA+B;IAC7C,OAAO;QACL,UAAU,EAAE,EAAE;QACd,UAAU,EAAE,IAAI,GAAG,EAAgC;QACjD,IAAI,EAAE,IAAI,GAAG,EAA8B;KAC9C,CAAC;AACJ,CAAC;AAND,0EAMC"}
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/federation/utils.ts"],"names":[],"mappings":";;;AAeA,gEAQmC;AAuBtB,QAAA,8BAA8B,GAAG,IAAI,GAAG,CAAS;IAC5D,8BAAW,EAAE,4CAAyB,EAAE,wCAAqB;IAC7D,wCAAqB,EAAE,iCAAc,EAAE,8BAAW,EAAE,qCAAkB;CACvE,CAAC,CAAC;AAEH,IAAY,WAIX;AAJD,WAAY,WAAW;IACrB,+CAAK,CAAA;IACL,6DAAY,CAAA;IACZ,yDAAU,CAAA;AACZ,CAAC,EAJW,WAAW,2BAAX,WAAW,QAItB;AAaD,SAAgB,+BAA+B;IAC7C,OAAO;QACL,UAAU,EAAE,EAAE;QACd,UAAU,EAAE,IAAI,GAAG,EAAgC;QACnD,IAAI,EAAE,IAAI,GAAG,EAA8B;KAC5C,CAAC;AACJ,CAAC;AAND,0EAMC"}
@@ -1,12 +1,14 @@
1
- import { ConstDirectiveNode, DirectiveDefinitionNode, DocumentNode, EnumValueDefinitionNode, FieldDefinitionNode, GraphQLSchema, InputValueDefinitionNode, InterfaceTypeDefinitionNode, InterfaceTypeExtensionNode, Kind, NamedTypeNode, ObjectTypeDefinitionNode, ObjectTypeExtensionNode, OperationTypeNode, SchemaDefinitionNode, SchemaExtensionNode, TypeDefinitionNode, TypeExtensionNode, TypeNode } from 'graphql';
1
+ import { ConstDirectiveNode, DirectiveDefinitionNode, DirectiveNode, DocumentNode, EnumValueDefinitionNode, FieldDefinitionNode, GraphQLSchema, InputValueDefinitionNode, InterfaceTypeDefinitionNode, InterfaceTypeExtensionNode, Kind, NamedTypeNode, ObjectTypeDefinitionNode, ObjectTypeExtensionNode, OperationTypeNode, SchemaDefinitionNode, SchemaExtensionNode, TypeDefinitionNode, TypeExtensionNode, TypeNode } from 'graphql';
2
2
  import { ChildContainer, ExtensionContainer, ExtensionMap, FieldContainer, FieldSetContainer, InputValidationContainer, ObjectExtensionContainer, ObjectLikeContainer, ParentContainer, ParentMap, SchemaContainer, UnionContainer, UnionExtensionContainer } from './utils';
3
3
  import { ConfigurationData, ConfigurationDataMap } from '../subgraph/field-configuration';
4
4
  import { MutableInputValueDefinitionNode } from '../ast/ast';
5
+ import { InternalSubgraph, Subgraph } from '../subgraph/subgraph';
5
6
  export type NormalizationResult = {
6
7
  configurationDataMap: ConfigurationDataMap;
7
8
  isVersionTwo: boolean;
8
9
  keyFieldsByParentTypeName: Map<string, Set<string>>;
9
10
  operationTypes: Map<string, OperationTypeNode>;
11
+ overridesByTargetSubgraphName: Map<string, Map<string, Set<string>>>;
10
12
  schema: GraphQLSchema;
11
13
  subgraphAST: DocumentNode;
12
14
  subgraphString: string;
@@ -15,25 +17,34 @@ export type NormalizationResultContainer = {
15
17
  errors?: Error[];
16
18
  normalizationResult?: NormalizationResult;
17
19
  };
18
- export declare function normalizeSubgraphFromString(subgraph: string): NormalizationResultContainer;
20
+ export type BatchNormalizationContainer = {
21
+ errors?: Error[];
22
+ internalSubgraphsBySubgraphName: Map<string, InternalSubgraph>;
23
+ };
24
+ export declare function normalizeSubgraphFromString(subgraphSDL: string): NormalizationResultContainer;
19
25
  export declare function normalizeSubgraph(document: DocumentNode): NormalizationResultContainer;
20
26
  export declare class NormalizationFactory {
21
27
  abstractToConcreteTypeNames: Map<string, Set<string>>;
22
28
  allDirectiveDefinitions: Map<string, DirectiveDefinitionNode>;
29
+ argumentName: string;
30
+ childName: string;
23
31
  configurationDataMap: Map<string, ConfigurationData>;
24
32
  customDirectiveDefinitions: Map<string, DirectiveDefinitionNode>;
25
33
  errors: Error[];
26
34
  entities: Set<string>;
35
+ extensions: ExtensionMap;
36
+ isCurrentParentExtension: boolean;
37
+ isSubgraphVersionTwo: boolean;
27
38
  fieldSetsByParent: Map<string, FieldSetContainer>;
39
+ handledRepeatedDirectivesByHostPath: Map<string, Set<string>>;
40
+ lastParentNodeKind: Kind;
41
+ lastChildNodeKind: Kind;
28
42
  keyFieldsByParentTypeName: Map<string, Set<string>>;
29
43
  operationTypeNames: Map<string, OperationTypeNode>;
30
44
  parents: ParentMap;
31
45
  parentTypeName: string;
32
46
  parentsWithChildArguments: Set<string>;
33
- extensions: ExtensionMap;
34
- isChild: boolean;
35
- isCurrentParentExtension: boolean;
36
- isSubgraphVersionTwo: boolean;
47
+ overridesByTargetSubgraphName: Map<string, Map<string, Set<string>>>;
37
48
  schemaDefinition: SchemaContainer;
38
49
  referencedDirectives: Set<string>;
39
50
  referencedTypeNames: Set<string>;
@@ -53,6 +64,7 @@ export declare class NormalizationFactory {
53
64
  isTypeValidImplementation(originalType: TypeNode, implementationType: TypeNode): boolean;
54
65
  extractKeyFieldSets(node: ObjectTypeDefinitionNode | ObjectTypeExtensionNode, rawFieldSets: Set<string>): void;
55
66
  validateInterfaceImplementations(container: ObjectLikeContainer): void;
67
+ handleOverride(node: DirectiveNode, fieldName: string): void;
56
68
  normalize(document: DocumentNode): {
57
69
  errors: Error[];
58
70
  normalizationResult?: undefined;
@@ -62,6 +74,7 @@ export declare class NormalizationFactory {
62
74
  isVersionTwo: boolean;
63
75
  keyFieldsByParentTypeName: Map<string, Set<string>>;
64
76
  operationTypes: Map<string, OperationTypeNode>;
77
+ overridesByTargetSubgraphName: Map<string, Map<string, Set<string>>>;
65
78
  subgraphAST: DocumentNode;
66
79
  subgraphString: string;
67
80
  schema: GraphQLSchema;
@@ -69,3 +82,4 @@ export declare class NormalizationFactory {
69
82
  errors?: undefined;
70
83
  };
71
84
  }
85
+ export declare function batchNormalize(subgraphs: Subgraph[]): BatchNormalizationContainer;
@@ -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,7 @@ 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 = '';
482
558
  (0, graphql_1.visit)(document, {
483
559
  DirectiveDefinition: {
484
560
  enter(node) {
@@ -507,6 +583,7 @@ class NormalizationFactory {
507
583
  Directive: {
508
584
  enter(node) {
509
585
  const name = node.name.value;
586
+ factory.handleOverride(node, fieldName);
510
587
  if (constants_1.VERSION_TWO_DIRECTIVES.has(name)) {
511
588
  factory.isSubgraphVersionTwo = true;
512
589
  return false;
@@ -525,6 +602,7 @@ class NormalizationFactory {
525
602
  return false;
526
603
  }
527
604
  factory.parentTypeName = name;
605
+ factory.lastParentNodeKind = node.kind;
528
606
  factory.parents.set(name, {
529
607
  description: (0, utils_1.formatDescription)(node.description),
530
608
  directives: factory.extractDirectives(node, new Map()),
@@ -535,12 +613,14 @@ class NormalizationFactory {
535
613
  },
536
614
  leave() {
537
615
  factory.parentTypeName = '';
616
+ factory.lastParentNodeKind = graphql_1.Kind.NULL;
538
617
  },
539
618
  },
540
619
  EnumTypeExtension: {
541
620
  enter(node) {
542
621
  const name = node.name.value;
543
622
  factory.parentTypeName = name;
623
+ factory.lastParentNodeKind = node.kind;
544
624
  factory.isCurrentParentExtension = true;
545
625
  const extension = factory.extensions.get(factory.parentTypeName);
546
626
  if (extension) {
@@ -559,13 +639,16 @@ class NormalizationFactory {
559
639
  });
560
640
  },
561
641
  leave() {
562
- factory.isCurrentParentExtension = false;
563
642
  factory.parentTypeName = '';
643
+ factory.lastParentNodeKind = graphql_1.Kind.NULL;
644
+ factory.isCurrentParentExtension = false;
564
645
  },
565
646
  },
566
647
  EnumValueDefinition: {
567
648
  enter(node) {
568
649
  const name = node.name.value;
650
+ factory.childName = name;
651
+ factory.lastChildNodeKind = node.kind;
569
652
  const parent = factory.isCurrentParentExtension
570
653
  ? (0, utils_3.getOrThrowError)(factory.extensions, factory.parentTypeName, string_constants_1.EXTENSIONS)
571
654
  : (0, utils_3.getOrThrowError)(factory.parents, factory.parentTypeName, string_constants_1.PARENTS);
@@ -585,6 +668,10 @@ class NormalizationFactory {
585
668
  node: { ...node, description: (0, utils_1.formatDescription)(node.description) },
586
669
  });
587
670
  },
671
+ leave() {
672
+ factory.childName = '';
673
+ factory.lastChildNodeKind = graphql_1.Kind.NULL;
674
+ },
588
675
  },
589
676
  FieldDefinition: {
590
677
  enter(node) {
@@ -592,8 +679,10 @@ class NormalizationFactory {
592
679
  if (isCurrentParentRootType && (name === string_constants_1.SERVICE_FIELD || name === string_constants_1.ENTITIES_FIELD)) {
593
680
  return false;
594
681
  }
682
+ factory.childName = name;
683
+ factory.lastChildNodeKind = node.kind;
595
684
  const fieldPath = `${factory.parentTypeName}.${name}`;
596
- factory.isChild = true;
685
+ factory.lastChildNodeKind = node.kind;
597
686
  const fieldNamedTypeName = (0, type_merging_1.getNamedTypeForChild)(fieldPath, node.type);
598
687
  if (!constants_1.BASE_SCALARS.has(fieldNamedTypeName)) {
599
688
  factory.referencedTypeNames.add(fieldNamedTypeName);
@@ -647,7 +736,8 @@ class NormalizationFactory {
647
736
  (0, utils_2.extractFieldSetValue)(name, fieldSetContainer.provides, providesDirectives);
648
737
  },
649
738
  leave() {
650
- factory.isChild = false;
739
+ factory.childName = '';
740
+ factory.lastChildNodeKind = graphql_1.Kind.NULL;
651
741
  },
652
742
  },
653
743
  InputObjectTypeDefinition: {
@@ -657,6 +747,7 @@ class NormalizationFactory {
657
747
  factory.errors.push((0, errors_1.duplicateTypeDefinitionError)((0, utils_3.kindToTypeString)(node.kind), name));
658
748
  return false;
659
749
  }
750
+ factory.lastParentNodeKind = node.kind;
660
751
  factory.parentTypeName = name;
661
752
  factory.parents.set(name, {
662
753
  description: (0, utils_1.formatDescription)(node.description),
@@ -667,6 +758,7 @@ class NormalizationFactory {
667
758
  });
668
759
  },
669
760
  leave() {
761
+ factory.lastParentNodeKind = graphql_1.Kind.NULL;
670
762
  factory.parentTypeName = '';
671
763
  },
672
764
  },
@@ -674,6 +766,7 @@ class NormalizationFactory {
674
766
  enter(node) {
675
767
  const name = node.name.value;
676
768
  factory.parentTypeName = name;
769
+ factory.lastParentNodeKind = node.kind;
677
770
  factory.isCurrentParentExtension = true;
678
771
  const extension = factory.extensions.get(factory.parentTypeName);
679
772
  if (extension) {
@@ -692,16 +785,22 @@ class NormalizationFactory {
692
785
  });
693
786
  },
694
787
  leave() {
695
- factory.isCurrentParentExtension = false;
696
788
  factory.parentTypeName = '';
789
+ factory.lastParentNodeKind = graphql_1.Kind.NULL;
790
+ factory.isCurrentParentExtension = false;
697
791
  },
698
792
  },
699
793
  InputValueDefinition: {
700
794
  enter(node) {
701
- if (!factory.parentTypeName || factory.isChild) {
795
+ const name = node.name.value;
796
+ // If the parent is not an object type definition/extension, this node is an argument
797
+ if (factory.lastParentNodeKind !== graphql_1.Kind.INPUT_OBJECT_TYPE_DEFINITION
798
+ && factory.lastParentNodeKind !== graphql_1.Kind.INPUT_OBJECT_TYPE_EXTENSION) {
799
+ factory.argumentName = name;
702
800
  return;
703
801
  }
704
- const name = node.name.value;
802
+ factory.childName = name;
803
+ factory.lastChildNodeKind = node.kind;
705
804
  const valueRootTypeName = (0, type_merging_1.getNamedTypeForChild)(`${factory.parentTypeName}.${name}`, node.type);
706
805
  if (!constants_1.BASE_SCALARS.has(valueRootTypeName)) {
707
806
  factory.referencedTypeNames.add(valueRootTypeName);
@@ -722,11 +821,20 @@ class NormalizationFactory {
722
821
  node: { ...node, description: (0, utils_1.formatDescription)(node.description) },
723
822
  });
724
823
  },
824
+ leave() {
825
+ factory.argumentName = '';
826
+ // Only reset childName and lastNodeKind if this input value was NOT an argument
827
+ if (factory.lastChildNodeKind === graphql_1.Kind.INPUT_VALUE_DEFINITION) {
828
+ factory.childName = '';
829
+ factory.lastChildNodeKind = graphql_1.Kind.NULL;
830
+ }
831
+ },
725
832
  },
726
833
  InterfaceTypeDefinition: {
727
834
  enter(node) {
728
835
  const name = node.name.value;
729
836
  factory.parentTypeName = name;
837
+ factory.lastParentNodeKind = node.kind;
730
838
  if ((0, utils_1.isNodeExtension)(node)) {
731
839
  return factory.handleObjectLikeExtension(node);
732
840
  }
@@ -744,18 +852,21 @@ class NormalizationFactory {
744
852
  });
745
853
  },
746
854
  leave() {
747
- factory.isCurrentParentExtension = false;
748
855
  factory.parentTypeName = '';
856
+ factory.lastParentNodeKind = graphql_1.Kind.NULL;
857
+ factory.isCurrentParentExtension = false;
749
858
  },
750
859
  },
751
860
  InterfaceTypeExtension: {
752
861
  enter(node) {
753
862
  factory.parentTypeName = node.name.value;
863
+ factory.lastParentNodeKind = node.kind;
754
864
  return factory.handleObjectLikeExtension(node);
755
865
  },
756
866
  leave() {
757
867
  factory.isCurrentParentExtension = false;
758
868
  factory.parentTypeName = '';
869
+ factory.lastParentNodeKind = graphql_1.Kind.NULL;
759
870
  },
760
871
  },
761
872
  ObjectTypeDefinition: {
@@ -766,6 +877,7 @@ class NormalizationFactory {
766
877
  }
767
878
  isCurrentParentRootType = string_constants_1.ROOT_TYPES.has(name);
768
879
  factory.parentTypeName = name;
880
+ factory.lastParentNodeKind = node.kind;
769
881
  (0, utils_1.addConcreteTypesForImplementedInterfaces)(node, factory.abstractToConcreteTypeNames);
770
882
  // handling for @extends directive
771
883
  if ((0, utils_1.isNodeExtension)(node)) {
@@ -793,9 +905,10 @@ class NormalizationFactory {
793
905
  factory.extractKeyFieldSets(node, fieldSets.keys);
794
906
  },
795
907
  leave() {
796
- factory.isCurrentParentExtension = false;
797
908
  isCurrentParentRootType = false;
909
+ factory.isCurrentParentExtension = false;
798
910
  factory.parentTypeName = '';
911
+ factory.lastParentNodeKind = graphql_1.Kind.NULL;
799
912
  },
800
913
  },
801
914
  ObjectTypeExtension: {
@@ -806,13 +919,15 @@ class NormalizationFactory {
806
919
  }
807
920
  isCurrentParentRootType = string_constants_1.ROOT_TYPES.has(name);
808
921
  factory.parentTypeName = name;
922
+ factory.lastParentNodeKind = node.kind;
809
923
  (0, utils_1.addConcreteTypesForImplementedInterfaces)(node, factory.abstractToConcreteTypeNames);
810
924
  return factory.handleObjectLikeExtension(node);
811
925
  },
812
926
  leave() {
813
- factory.isCurrentParentExtension = false;
814
927
  isCurrentParentRootType = false;
928
+ factory.isCurrentParentExtension = false;
815
929
  factory.parentTypeName = '';
930
+ factory.lastParentNodeKind = graphql_1.Kind.NULL;
816
931
  },
817
932
  },
818
933
  OperationTypeDefinition: {
@@ -847,6 +962,8 @@ class NormalizationFactory {
847
962
  factory.errors.push((0, errors_1.duplicateTypeDefinitionError)((0, utils_3.kindToTypeString)(node.kind), name));
848
963
  return false;
849
964
  }
965
+ factory.parentTypeName = name;
966
+ factory.lastParentNodeKind = node.kind;
850
967
  factory.parents.set(name, {
851
968
  description: (0, utils_1.formatDescription)(node.description),
852
969
  directives: factory.extractDirectives(node, new Map()),
@@ -854,6 +971,10 @@ class NormalizationFactory {
854
971
  name: node.name,
855
972
  });
856
973
  },
974
+ leave() {
975
+ factory.parentTypeName = '';
976
+ factory.lastParentNodeKind = graphql_1.Kind.NULL;
977
+ },
857
978
  },
858
979
  ScalarTypeExtension: {
859
980
  enter(node) {
@@ -870,6 +991,8 @@ class NormalizationFactory {
870
991
  factory.extractDirectives(node, extension.directives);
871
992
  }
872
993
  else {
994
+ factory.parentTypeName = name;
995
+ factory.lastParentNodeKind = node.kind;
873
996
  factory.extensions.set(name, {
874
997
  directives: factory.extractDirectives(node, new Map()),
875
998
  kind: node.kind,
@@ -878,6 +1001,10 @@ class NormalizationFactory {
878
1001
  }
879
1002
  return false;
880
1003
  },
1004
+ leave() {
1005
+ factory.parentTypeName = '';
1006
+ factory.lastParentNodeKind = graphql_1.Kind.NULL;
1007
+ },
881
1008
  },
882
1009
  SchemaDefinition: {
883
1010
  enter(node) {
@@ -906,6 +1033,7 @@ class NormalizationFactory {
906
1033
  factory.errors.push((0, errors_1.noDefinedUnionMembersError)(name));
907
1034
  return false;
908
1035
  }
1036
+ factory.lastParentNodeKind = node.kind;
909
1037
  (0, utils_1.addConcreteTypesForUnion)(node, factory.abstractToConcreteTypeNames);
910
1038
  factory.parents.set(name, {
911
1039
  description: (0, utils_1.formatDescription)(node.description),
@@ -917,6 +1045,7 @@ class NormalizationFactory {
917
1045
  },
918
1046
  leave() {
919
1047
  factory.parentTypeName = '';
1048
+ factory.lastParentNodeKind = graphql_1.Kind.NULL;
920
1049
  },
921
1050
  },
922
1051
  UnionTypeExtension: {
@@ -930,6 +1059,7 @@ class NormalizationFactory {
930
1059
  factory.errors.push();
931
1060
  return false;
932
1061
  }
1062
+ factory.lastParentNodeKind = node.kind;
933
1063
  (0, utils_1.addConcreteTypesForUnion)(node, factory.abstractToConcreteTypeNames);
934
1064
  if (extension) {
935
1065
  if (extension.kind !== graphql_1.Kind.UNION_TYPE_EXTENSION) {
@@ -948,6 +1078,9 @@ class NormalizationFactory {
948
1078
  }
949
1079
  return false;
950
1080
  },
1081
+ leave() {
1082
+ factory.lastParentNodeKind = graphql_1.Kind.NULL;
1083
+ },
951
1084
  },
952
1085
  });
953
1086
  const definitions = [];
@@ -1201,6 +1334,7 @@ class NormalizationFactory {
1201
1334
  isVersionTwo: this.isSubgraphVersionTwo,
1202
1335
  keyFieldsByParentTypeName: this.keyFieldsByParentTypeName,
1203
1336
  operationTypes: this.operationTypeNames,
1337
+ overridesByTargetSubgraphName: this.overridesByTargetSubgraphName,
1204
1338
  subgraphAST: newAST,
1205
1339
  subgraphString: (0, graphql_1.print)(newAST),
1206
1340
  schema: (0, buildASTSchema_1.buildASTSchema)(newAST, { assumeValid: true }),
@@ -1209,4 +1343,110 @@ class NormalizationFactory {
1209
1343
  }
1210
1344
  }
1211
1345
  exports.NormalizationFactory = NormalizationFactory;
1346
+ function batchNormalize(subgraphs) {
1347
+ const internalSubgraphsBySubgraphName = new Map;
1348
+ const allOverridesByTargetSubgraphName = new Map();
1349
+ const overrideSourceSubgraphNamesByFieldPath = new Map();
1350
+ const duplicateOverriddenFieldPaths = new Set();
1351
+ const validationErrors = [];
1352
+ const subgraphNames = new Set();
1353
+ const nonUniqueSubgraphNames = new Set();
1354
+ const invalidNameErrorMessages = [];
1355
+ // Record the subgraph names first, so that subgraph references can be validated
1356
+ for (const subgraph of subgraphs) {
1357
+ if (subgraph.name) {
1358
+ (0, subgraph_1.recordSubgraphName)(subgraph.name, subgraphNames, nonUniqueSubgraphNames);
1359
+ }
1360
+ }
1361
+ for (let i = 0; i < subgraphs.length; i++) {
1362
+ const subgraph = subgraphs[i];
1363
+ const subgraphName = subgraph.name || `subgraph-${i}-${Date.now()}`;
1364
+ if (!subgraph.name) {
1365
+ invalidNameErrorMessages.push((0, errors_1.invalidSubgraphNameErrorMessage)(i, subgraphName));
1366
+ }
1367
+ const { errors, normalizationResult } = normalizeSubgraph(subgraph.definitions);
1368
+ if (errors) {
1369
+ validationErrors.push((0, errors_1.subgraphValidationError)(subgraphName, errors));
1370
+ continue;
1371
+ }
1372
+ if (!normalizationResult) {
1373
+ validationErrors.push((0, errors_1.subgraphValidationError)(subgraphName, [errors_1.subgraphValidationFailureError]));
1374
+ continue;
1375
+ }
1376
+ if (subgraph.name) {
1377
+ internalSubgraphsBySubgraphName.set(subgraphName, {
1378
+ configurationDataMap: normalizationResult.configurationDataMap,
1379
+ definitions: normalizationResult.subgraphAST,
1380
+ keyFieldsByParentTypeName: normalizationResult.keyFieldsByParentTypeName,
1381
+ isVersionTwo: normalizationResult.isVersionTwo,
1382
+ name: subgraphName,
1383
+ operationTypes: normalizationResult.operationTypes,
1384
+ overriddenFieldNamesByParentTypeName: new Map(),
1385
+ schema: normalizationResult.schema,
1386
+ url: subgraph.url,
1387
+ });
1388
+ }
1389
+ if (normalizationResult.overridesByTargetSubgraphName.size < 1) {
1390
+ continue;
1391
+ }
1392
+ const invalidOverrideTargetSubgraphNameErrors = [];
1393
+ for (const [targetSubgraphName, overridesData] of normalizationResult.overridesByTargetSubgraphName) {
1394
+ const isTargetValid = subgraphNames.has(targetSubgraphName);
1395
+ for (const [parentTypeName, fieldNames] of overridesData) {
1396
+ if (!isTargetValid) {
1397
+ invalidOverrideTargetSubgraphNameErrors.push((0, errors_1.invalidOverrideTargetSubgraphNameError)(targetSubgraphName, parentTypeName, [...fieldNames]));
1398
+ }
1399
+ else {
1400
+ const overridesData = (0, utils_3.getValueOrDefault)(allOverridesByTargetSubgraphName, targetSubgraphName, () => new Map());
1401
+ (0, utils_3.getValueOrDefault)(overridesData, parentTypeName, () => new Set(fieldNames));
1402
+ }
1403
+ for (const fieldName of fieldNames) {
1404
+ const fieldPath = `${parentTypeName}.${fieldName}`;
1405
+ const sourceSubgraphs = overrideSourceSubgraphNamesByFieldPath.get(fieldPath);
1406
+ if (!sourceSubgraphs) {
1407
+ overrideSourceSubgraphNamesByFieldPath.set(fieldPath, [subgraphName]);
1408
+ continue;
1409
+ }
1410
+ sourceSubgraphs.push(subgraphName);
1411
+ duplicateOverriddenFieldPaths.add(fieldPath);
1412
+ }
1413
+ }
1414
+ }
1415
+ if (invalidOverrideTargetSubgraphNameErrors.length > 0) {
1416
+ validationErrors.push((0, errors_1.subgraphValidationError)(subgraphName, invalidOverrideTargetSubgraphNameErrors));
1417
+ }
1418
+ }
1419
+ const allErrors = [];
1420
+ if (invalidNameErrorMessages.length > 0 || nonUniqueSubgraphNames.size > 0) {
1421
+ allErrors.push((0, errors_1.invalidSubgraphNamesError)([...nonUniqueSubgraphNames], invalidNameErrorMessages));
1422
+ }
1423
+ if (duplicateOverriddenFieldPaths.size > 0) {
1424
+ const duplicateOverriddenFieldErrorMessages = [];
1425
+ for (const fieldPath of duplicateOverriddenFieldPaths) {
1426
+ const sourceSubgraphNames = (0, utils_3.getOrThrowError)(overrideSourceSubgraphNamesByFieldPath, fieldPath, 'overrideSourceSubgraphNamesByFieldPath');
1427
+ duplicateOverriddenFieldErrorMessages.push((0, errors_1.duplicateOverriddenFieldErrorMessage)(fieldPath, sourceSubgraphNames));
1428
+ }
1429
+ allErrors.push((0, errors_1.duplicateOverriddenFieldsError)(duplicateOverriddenFieldErrorMessages));
1430
+ }
1431
+ allErrors.push(...validationErrors);
1432
+ if (allErrors.length > 0) {
1433
+ return { errors: allErrors, internalSubgraphsBySubgraphName };
1434
+ }
1435
+ for (const [targetSubgraphName, overridesData] of allOverridesByTargetSubgraphName) {
1436
+ const internalSubgraph = (0, utils_3.getOrThrowError)(internalSubgraphsBySubgraphName, targetSubgraphName, 'normalizedSubgraphsByName');
1437
+ internalSubgraph.overriddenFieldNamesByParentTypeName = overridesData;
1438
+ for (const [parentTypeName, fieldNames] of overridesData) {
1439
+ const configurationData = internalSubgraph.configurationDataMap.get(parentTypeName);
1440
+ if (!configurationData) {
1441
+ continue;
1442
+ }
1443
+ (0, utils_3.subtractSourceSetFromTargetSet)(fieldNames, configurationData.fieldNames);
1444
+ if (configurationData.fieldNames.size < 1) {
1445
+ internalSubgraph.configurationDataMap.delete(parentTypeName);
1446
+ }
1447
+ }
1448
+ }
1449
+ return { internalSubgraphsBySubgraphName: internalSubgraphsBySubgraphName };
1450
+ }
1451
+ exports.batchNormalize = batchNormalize;
1212
1452
  //# sourceMappingURL=normalization-factory.js.map