@wundergraph/composition 0.23.0 → 0.23.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/federation/federation-factory.d.ts +12 -5
- package/dist/federation/federation-factory.js +135 -91
- package/dist/federation/federation-factory.js.map +1 -1
- package/dist/federation/utils.d.ts +2 -1
- package/dist/federation/utils.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/utils/utils.d.ts +1 -1
- package/dist/utils/utils.js +3 -3
- package/dist/utils/utils.js.map +1 -1
- package/package.json +2 -2
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { MultiGraph } from 'graphology';
|
|
2
2
|
import { DirectiveDefinitionNode, Kind, NamedTypeNode } from 'graphql';
|
|
3
3
|
import { MutableTypeDefinitionNode } from '../schema-building/ast';
|
|
4
|
-
import { FederationResultContainer, FederationResultContainerWithContracts, InterfaceImplementationData, ParentTagData, RootTypeFieldData } from './utils';
|
|
4
|
+
import { ChildTagData, FederationResultContainer, FederationResultContainerWithContracts, InterfaceImplementationData, ParentTagData, RootTypeFieldData } from './utils';
|
|
5
5
|
import { InternalSubgraph, Subgraph } from '../subgraph/subgraph';
|
|
6
6
|
import { AuthorizationData, EntityData, EntityDataByTypeName, EntityInterfaceFederationData } from '../utils/utils';
|
|
7
7
|
import { FieldConfiguration } from '../router-configuration/router-configuration';
|
|
8
|
-
import { DefinitionWithFieldsData, EnumValueData, FieldData, InputObjectDefinitionData, InputValueData, InterfaceDefinitionData, ObjectDefinitionData, ParentDefinitionData, PersistedDirectiveDefinitionData, UnionDefinitionData } from '../schema-building/type-definition-data';
|
|
8
|
+
import { ChildData, DefinitionWithFieldsData, EnumValueData, FieldData, InputObjectDefinitionData, InputValueData, InterfaceDefinitionData, NodeData, ObjectDefinitionData, ParentDefinitionData, PersistedDirectiveDefinitionData, UnionDefinitionData } from '../schema-building/type-definition-data';
|
|
9
9
|
import { MergeMethod } from '../schema-building/utils';
|
|
10
10
|
import { ObjectExtensionData } from '../schema-building/type-extension-data';
|
|
11
11
|
export declare class FederationFactory {
|
|
@@ -49,11 +49,12 @@ export declare class FederationFactory {
|
|
|
49
49
|
getEnumValueMergeMethod(enumTypeName: string): MergeMethod;
|
|
50
50
|
generateTagData(): void;
|
|
51
51
|
evaluateRootNodeFieldsResolvability(): void;
|
|
52
|
-
upsertEnumValueData(enumValueDataByValueName: Map<string, EnumValueData>, incomingData: EnumValueData): void;
|
|
53
|
-
upsertInputValueData(inputValueDataByValueName: Map<string, InputValueData>, incomingData: InputValueData): void;
|
|
52
|
+
upsertEnumValueData(enumValueDataByValueName: Map<string, EnumValueData>, incomingData: EnumValueData, isParentInaccessible: boolean): void;
|
|
53
|
+
upsertInputValueData(inputValueDataByValueName: Map<string, InputValueData>, incomingData: InputValueData, path?: string): void;
|
|
54
54
|
handleArgumentInaccessibility(isParentInaccessible: boolean, inputValueData: InputValueData, argumentPath: string, fieldPath: string): void;
|
|
55
55
|
upsertFieldData(fieldDataByFieldName: Map<string, FieldData>, incomingData: FieldData, isParentInaccessible: boolean): void;
|
|
56
56
|
getClientSchemaUnionMembers(unionData: UnionDefinitionData): NamedTypeNode[];
|
|
57
|
+
recordTagNamesByPath(data: NodeData | ObjectExtensionData, nodePath?: string): void;
|
|
57
58
|
upsertParentDefinitionData(incomingData: ParentDefinitionData, subgraphName: string): void;
|
|
58
59
|
upsertObjectExtensionData(incomingData: ObjectExtensionData): void;
|
|
59
60
|
propagateInaccessibilityToExistingChildren(data: InputObjectDefinitionData | InterfaceDefinitionData | ObjectDefinitionData | ObjectExtensionData): void;
|
|
@@ -68,7 +69,13 @@ export declare class FederationFactory {
|
|
|
68
69
|
validateReferencesOfInaccessibleType(data: ParentDefinitionData): void;
|
|
69
70
|
validateQueryRootType(): void;
|
|
70
71
|
buildFederationResult(): FederationResultContainer;
|
|
71
|
-
|
|
72
|
+
getClientSchemaObjectBoolean(): {
|
|
73
|
+
shouldIncludeClientSchema?: undefined;
|
|
74
|
+
} | {
|
|
75
|
+
shouldIncludeClientSchema: boolean;
|
|
76
|
+
};
|
|
77
|
+
handleChildRemovalByTag(parentDefinitionData: ParentDefinitionData, children: Map<string, ChildData>, childTagDataByChildName: Map<string, ChildTagData>, tagsToExclude: Set<string>): void;
|
|
78
|
+
buildFederationContractResult(tagsToExclude: Set<string>): FederationResultContainer;
|
|
72
79
|
federateSubgraphsInternal(): FederationResultContainer;
|
|
73
80
|
}
|
|
74
81
|
export declare function federateSubgraphs(subgraphs: Subgraph[]): FederationResultContainer;
|
|
@@ -167,7 +167,7 @@ class FederationFactory {
|
|
|
167
167
|
return true;
|
|
168
168
|
}
|
|
169
169
|
if (entityAncestorName === parentTypeName) {
|
|
170
|
-
const hasOverlap = (0, utils_3.
|
|
170
|
+
const hasOverlap = (0, utils_3.doSetsIntersect)(fieldSubgraphs, (0, utils_3.getOrThrowError)(this.entityDataByTypeName, entityAncestorName, string_constants_1.ENTITIES).subgraphNames);
|
|
171
171
|
this.graphPaths.set(path, hasOverlap);
|
|
172
172
|
return hasOverlap;
|
|
173
173
|
}
|
|
@@ -244,7 +244,7 @@ class FederationFactory {
|
|
|
244
244
|
}
|
|
245
245
|
this.updateEvaluatedSubgraphOccurrences(rootTypeFieldData.subgraphs, objectData.subgraphNames, entityAncestors, parentTypeName);
|
|
246
246
|
evaluatedObjectLikes.add(parentTypeName);
|
|
247
|
-
const isFieldResolvable = (0, utils_3.
|
|
247
|
+
const isFieldResolvable = (0, utils_3.doSetsIntersect)(rootTypeFieldData.subgraphs, fieldData.subgraphNames) ||
|
|
248
248
|
this.isFieldResolvableByEntityAncestor(entityAncestors, fieldData.subgraphNames, parentTypeName);
|
|
249
249
|
const newCurrentFieldPath = currentFieldPath + (isParentAbstract ? ' ' : '.') + fieldName;
|
|
250
250
|
const entity = this.entityDataByTypeName.get(namedFieldTypeName);
|
|
@@ -314,7 +314,7 @@ class FederationFactory {
|
|
|
314
314
|
throw (0, errors_1.unexpectedParentKindErrorMessage)(concreteTypeName, 'Object', (0, utils_3.kindToTypeString)(concreteTypeData.kind));
|
|
315
315
|
}
|
|
316
316
|
// If the concrete type is unreachable through an inline fragment, it is not an error
|
|
317
|
-
if (!(0, utils_3.
|
|
317
|
+
if (!(0, utils_3.doSetsIntersect)(concreteTypeData.subgraphNames, rootTypeFieldData.subgraphs)) {
|
|
318
318
|
continue;
|
|
319
319
|
}
|
|
320
320
|
const entity = this.entityDataByTypeName.get(concreteTypeName);
|
|
@@ -560,9 +560,16 @@ class FederationFactory {
|
|
|
560
560
|
}
|
|
561
561
|
}
|
|
562
562
|
}
|
|
563
|
-
upsertEnumValueData(enumValueDataByValueName, incomingData) {
|
|
563
|
+
upsertEnumValueData(enumValueDataByValueName, incomingData, isParentInaccessible) {
|
|
564
564
|
const existingData = enumValueDataByValueName.get(incomingData.name);
|
|
565
|
-
|
|
565
|
+
const baseData = existingData || incomingData;
|
|
566
|
+
const enumValuePath = `${incomingData.parentTypeName}.${incomingData.name}`;
|
|
567
|
+
(0, utils_5.extractPersistedDirectives)(baseData.persistedDirectivesData, incomingData.directivesByDirectiveName, this.persistedDirectiveDefinitionByDirectiveName);
|
|
568
|
+
const isFieldInaccessible = (0, utils_5.isNodeDataInaccessible)(incomingData);
|
|
569
|
+
if (isParentInaccessible || isFieldInaccessible) {
|
|
570
|
+
this.inaccessiblePaths.add(enumValuePath);
|
|
571
|
+
}
|
|
572
|
+
this.recordTagNamesByPath(baseData, enumValuePath);
|
|
566
573
|
if (!existingData) {
|
|
567
574
|
incomingData.node = {
|
|
568
575
|
directives: [],
|
|
@@ -575,9 +582,12 @@ class FederationFactory {
|
|
|
575
582
|
existingData.appearances += 1;
|
|
576
583
|
(0, utils_5.setLongestDescription)(existingData, incomingData);
|
|
577
584
|
}
|
|
578
|
-
|
|
585
|
+
// To facilitate the splitting of tag paths, field arguments do not use the renamedPath property for tagNamesByPath
|
|
586
|
+
upsertInputValueData(inputValueDataByValueName, incomingData, path) {
|
|
579
587
|
const existingData = inputValueDataByValueName.get(incomingData.name);
|
|
580
|
-
|
|
588
|
+
const baseData = existingData || incomingData;
|
|
589
|
+
(0, utils_5.extractPersistedDirectives)(baseData.persistedDirectivesData, incomingData.directivesByDirectiveName, this.persistedDirectiveDefinitionByDirectiveName);
|
|
590
|
+
this.recordTagNamesByPath(baseData, path || baseData.renamedPath);
|
|
581
591
|
if (!existingData) {
|
|
582
592
|
incomingData.node = {
|
|
583
593
|
directives: [],
|
|
@@ -629,17 +639,13 @@ class FederationFactory {
|
|
|
629
639
|
(0, utils_3.getValueOrDefault)(this.pathsByNamedTypeName, incomingData.namedTypeName, () => new Set()).add(fieldPath);
|
|
630
640
|
this.namedOutputTypeNames.add(incomingData.namedTypeName);
|
|
631
641
|
const existingData = fieldDataByFieldName.get(incomingData.name);
|
|
632
|
-
|
|
642
|
+
const baseData = existingData || incomingData;
|
|
643
|
+
(0, utils_5.extractPersistedDirectives)(baseData.persistedDirectivesData, incomingData.directivesByDirectiveName, this.persistedDirectiveDefinitionByDirectiveName);
|
|
633
644
|
const isFieldInaccessible = (0, utils_5.isNodeDataInaccessible)(incomingData);
|
|
634
645
|
if (isParentInaccessible || isFieldInaccessible) {
|
|
635
646
|
this.inaccessiblePaths.add(fieldPath);
|
|
636
647
|
}
|
|
637
|
-
|
|
638
|
-
const tagNames = (0, utils_3.getValueOrDefault)(this.tagNamesByPath, fieldPath, () => new Set());
|
|
639
|
-
for (const tagName of incomingData.persistedDirectivesData.tags.keys()) {
|
|
640
|
-
tagNames.add(tagName);
|
|
641
|
-
}
|
|
642
|
-
}
|
|
648
|
+
this.recordTagNamesByPath(baseData, fieldPath);
|
|
643
649
|
if (!existingData) {
|
|
644
650
|
fieldDataByFieldName.set(incomingData.name, incomingData);
|
|
645
651
|
incomingData.node = {
|
|
@@ -656,22 +662,15 @@ class FederationFactory {
|
|
|
656
662
|
name: (0, utils_1.stringToNameNode)(inputValueData.name),
|
|
657
663
|
type: inputValueData.type,
|
|
658
664
|
};
|
|
659
|
-
const argumentPath = `${fieldPath}(${argumentName}: ... )`;
|
|
660
665
|
const namedArgumentTypeName = (0, ast_1.getTypeNodeNamedTypeName)(inputValueData.type);
|
|
661
|
-
(0, utils_3.getValueOrDefault)(this.pathsByNamedTypeName, namedArgumentTypeName, () => new Set()).add(
|
|
666
|
+
(0, utils_3.getValueOrDefault)(this.pathsByNamedTypeName, namedArgumentTypeName, () => new Set()).add(inputValueData.renamedPath);
|
|
662
667
|
this.namedInputValueTypeNames.add(namedArgumentTypeName);
|
|
663
668
|
(0, utils_5.extractPersistedDirectives)(inputValueData.persistedDirectivesData, inputValueData.directivesByDirectiveName, this.persistedDirectiveDefinitionByDirectiveName);
|
|
664
669
|
/* If either the parent or the field to which the field belongs are declared inaccessible, the nullability
|
|
665
670
|
** of the argument is not considered. However, if only the argument is declared inaccessible, it is an
|
|
666
671
|
** error. */
|
|
667
|
-
this.handleArgumentInaccessibility(isParentInaccessible || isFieldInaccessible, inputValueData,
|
|
668
|
-
|
|
669
|
-
const tagArgumentPath = `${fieldPath}.${argumentName}`;
|
|
670
|
-
const tagNames = (0, utils_3.getValueOrDefault)(this.tagNamesByPath, tagArgumentPath, () => new Set());
|
|
671
|
-
for (const tagName of inputValueData.persistedDirectivesData.tags.keys()) {
|
|
672
|
-
tagNames.add(tagName);
|
|
673
|
-
}
|
|
674
|
-
}
|
|
672
|
+
this.handleArgumentInaccessibility(isParentInaccessible || isFieldInaccessible, inputValueData, inputValueData.renamedPath, fieldPath);
|
|
673
|
+
this.recordTagNamesByPath(inputValueData, `${fieldPath}.${argumentName}`);
|
|
675
674
|
}
|
|
676
675
|
return;
|
|
677
676
|
}
|
|
@@ -686,22 +685,14 @@ class FederationFactory {
|
|
|
686
685
|
this.errors.push((0, errors_1.incompatibleChildTypesError)(fieldPath, typeErrors[0], typeErrors[1]));
|
|
687
686
|
}
|
|
688
687
|
for (const [argumentName, inputValueData] of incomingData.argumentDataByArgumentName) {
|
|
689
|
-
const argumentPath = `${fieldPath}(${argumentName}: ... )`;
|
|
690
688
|
const namedArgumentTypeName = (0, ast_1.getTypeNodeNamedTypeName)(inputValueData.type);
|
|
691
|
-
(0, utils_3.getValueOrDefault)(this.pathsByNamedTypeName, namedArgumentTypeName, () => new Set()).add(
|
|
689
|
+
(0, utils_3.getValueOrDefault)(this.pathsByNamedTypeName, namedArgumentTypeName, () => new Set()).add(inputValueData.renamedPath);
|
|
692
690
|
this.namedInputValueTypeNames.add(namedArgumentTypeName);
|
|
693
691
|
/* If either the parent or the field to which the field belongs are declared inaccessible, the nullability
|
|
694
692
|
** of the argument is not considered. However, if only the argument is declared inaccessible, it is an
|
|
695
693
|
** error. */
|
|
696
|
-
this.handleArgumentInaccessibility(isParentInaccessible || isFieldInaccessible, inputValueData,
|
|
697
|
-
|
|
698
|
-
const tagArgumentPath = `${fieldPath}.${argumentName}`;
|
|
699
|
-
const tagNames = (0, utils_3.getValueOrDefault)(this.tagNamesByPath, tagArgumentPath, () => new Set());
|
|
700
|
-
for (const tagName of inputValueData.persistedDirectivesData.tags.keys()) {
|
|
701
|
-
tagNames.add(tagName);
|
|
702
|
-
}
|
|
703
|
-
}
|
|
704
|
-
this.upsertInputValueData(existingData.argumentDataByArgumentName, inputValueData);
|
|
694
|
+
this.handleArgumentInaccessibility(isParentInaccessible || isFieldInaccessible, inputValueData, inputValueData.renamedPath, fieldPath);
|
|
695
|
+
this.upsertInputValueData(existingData.argumentDataByArgumentName, inputValueData, `${fieldPath}.${argumentName}`);
|
|
705
696
|
}
|
|
706
697
|
(0, utils_5.setLongestDescription)(existingData, incomingData);
|
|
707
698
|
existingData.isInaccessible ||= incomingData.isInaccessible;
|
|
@@ -718,21 +709,25 @@ class FederationFactory {
|
|
|
718
709
|
}
|
|
719
710
|
return members;
|
|
720
711
|
}
|
|
712
|
+
recordTagNamesByPath(data, nodePath) {
|
|
713
|
+
const path = nodePath || data.name;
|
|
714
|
+
if (data.persistedDirectivesData.tags.size > 0) {
|
|
715
|
+
const tagNames = (0, utils_3.getValueOrDefault)(this.tagNamesByPath, path, () => new Set());
|
|
716
|
+
for (const tagName of data.persistedDirectivesData.tags.keys()) {
|
|
717
|
+
tagNames.add(tagName);
|
|
718
|
+
}
|
|
719
|
+
}
|
|
720
|
+
}
|
|
721
721
|
upsertParentDefinitionData(incomingData, subgraphName) {
|
|
722
722
|
const entityInterfaceData = this.entityInterfaceFederationDataByTypeName.get(incomingData.name);
|
|
723
723
|
const existingData = this.parentDefinitionDataByTypeName.get(incomingData.name);
|
|
724
724
|
const baseData = existingData || incomingData;
|
|
725
725
|
(0, utils_5.extractPersistedDirectives)(baseData.persistedDirectivesData, incomingData.directivesByDirectiveName, this.persistedDirectiveDefinitionByDirectiveName);
|
|
726
|
+
this.recordTagNamesByPath(baseData);
|
|
726
727
|
const isParentInaccessible = (0, utils_5.isNodeDataInaccessible)(baseData);
|
|
727
728
|
if (isParentInaccessible) {
|
|
728
729
|
this.inaccessiblePaths.add(incomingData.name);
|
|
729
730
|
}
|
|
730
|
-
if (incomingData.persistedDirectivesData.tags.size > 0) {
|
|
731
|
-
const tagNames = (0, utils_3.getValueOrDefault)(this.tagNamesByPath, incomingData.name, () => new Set());
|
|
732
|
-
for (const tagName of incomingData.persistedDirectivesData.tags.keys()) {
|
|
733
|
-
tagNames.add(tagName);
|
|
734
|
-
}
|
|
735
|
-
}
|
|
736
731
|
if (!existingData) {
|
|
737
732
|
if (entityInterfaceData && entityInterfaceData.interfaceObjectSubgraphs.has(subgraphName)) {
|
|
738
733
|
incomingData.kind = graphql_1.Kind.INTERFACE_TYPE_DEFINITION;
|
|
@@ -745,14 +740,16 @@ class FederationFactory {
|
|
|
745
740
|
switch (incomingData.kind) {
|
|
746
741
|
case graphql_1.Kind.ENUM_TYPE_DEFINITION:
|
|
747
742
|
for (const [enumValueName, enumValueData] of incomingData.enumValueDataByValueName) {
|
|
743
|
+
const enumValuePath = `${incomingData.name}.${enumValueName}`;
|
|
748
744
|
enumValueData.node = {
|
|
749
745
|
directives: [],
|
|
750
746
|
kind: enumValueData.node.kind,
|
|
751
747
|
name: (0, utils_1.stringToNameNode)(enumValueData.name),
|
|
752
748
|
};
|
|
753
749
|
(0, utils_5.extractPersistedDirectives)(enumValueData.persistedDirectivesData, enumValueData.directivesByDirectiveName, this.persistedDirectiveDefinitionByDirectiveName);
|
|
750
|
+
this.recordTagNamesByPath(enumValueData, enumValuePath);
|
|
754
751
|
if ((0, utils_5.isNodeDataInaccessible)(enumValueData)) {
|
|
755
|
-
this.inaccessiblePaths.add(
|
|
752
|
+
this.inaccessiblePaths.add(enumValuePath);
|
|
756
753
|
}
|
|
757
754
|
}
|
|
758
755
|
return;
|
|
@@ -765,12 +762,12 @@ class FederationFactory {
|
|
|
765
762
|
type: inputValueData.type,
|
|
766
763
|
};
|
|
767
764
|
const namedInputFieldTypeName = (0, ast_1.getTypeNodeNamedTypeName)(inputValueData.type);
|
|
768
|
-
|
|
769
|
-
(0, utils_3.getValueOrDefault)(this.pathsByNamedTypeName, namedInputFieldTypeName, () => new Set()).add(inputFieldPath);
|
|
765
|
+
(0, utils_3.getValueOrDefault)(this.pathsByNamedTypeName, namedInputFieldTypeName, () => new Set()).add(inputValueData.renamedPath);
|
|
770
766
|
this.namedInputValueTypeNames.add(namedInputFieldTypeName);
|
|
771
767
|
(0, utils_5.extractPersistedDirectives)(inputValueData.persistedDirectivesData, inputValueData.directivesByDirectiveName, this.persistedDirectiveDefinitionByDirectiveName);
|
|
768
|
+
this.recordTagNamesByPath(inputValueData, `${incomingData.name}.${inputFieldName}`);
|
|
772
769
|
if (isParentInaccessible || (0, utils_5.isNodeDataInaccessible)(inputValueData)) {
|
|
773
|
-
this.inaccessiblePaths.add(
|
|
770
|
+
this.inaccessiblePaths.add(inputValueData.renamedPath);
|
|
774
771
|
}
|
|
775
772
|
}
|
|
776
773
|
return;
|
|
@@ -789,6 +786,7 @@ class FederationFactory {
|
|
|
789
786
|
(0, utils_3.getValueOrDefault)(this.pathsByNamedTypeName, fieldData.namedTypeName, () => new Set()).add(fieldPath);
|
|
790
787
|
this.namedOutputTypeNames.add(fieldData.namedTypeName);
|
|
791
788
|
(0, utils_5.extractPersistedDirectives)(fieldData.persistedDirectivesData, fieldData.directivesByDirectiveName, this.persistedDirectiveDefinitionByDirectiveName);
|
|
789
|
+
this.recordTagNamesByPath(fieldData, fieldPath);
|
|
792
790
|
const isFieldInaccessible = (0, utils_5.isNodeDataInaccessible)(fieldData);
|
|
793
791
|
if (isParentInaccessible || isFieldInaccessible) {
|
|
794
792
|
this.inaccessiblePaths.add(fieldPath);
|
|
@@ -801,14 +799,14 @@ class FederationFactory {
|
|
|
801
799
|
type: inputValueData.type,
|
|
802
800
|
};
|
|
803
801
|
const namedArgumentTypeName = (0, ast_1.getTypeNodeNamedTypeName)(inputValueData.type);
|
|
804
|
-
|
|
805
|
-
(0, utils_3.getValueOrDefault)(this.pathsByNamedTypeName, namedArgumentTypeName, () => new Set()).add(argumentPath);
|
|
802
|
+
(0, utils_3.getValueOrDefault)(this.pathsByNamedTypeName, namedArgumentTypeName, () => new Set()).add(inputValueData.renamedPath);
|
|
806
803
|
this.namedInputValueTypeNames.add(namedArgumentTypeName);
|
|
807
804
|
(0, utils_5.extractPersistedDirectives)(inputValueData.persistedDirectivesData, inputValueData.directivesByDirectiveName, this.persistedDirectiveDefinitionByDirectiveName);
|
|
805
|
+
this.recordTagNamesByPath(inputValueData, `${fieldPath}.${argumentName}`);
|
|
808
806
|
/* If either the parent or the field to which the field belongs are declared inaccessible, the nullability
|
|
809
807
|
** of the argument is not considered. However, if only the argument is declared inaccessible, it is an
|
|
810
808
|
** error. */
|
|
811
|
-
this.handleArgumentInaccessibility(isParentInaccessible || isFieldInaccessible, inputValueData,
|
|
809
|
+
this.handleArgumentInaccessibility(isParentInaccessible || isFieldInaccessible, inputValueData, inputValueData.renamedPath, fieldPath);
|
|
812
810
|
}
|
|
813
811
|
}
|
|
814
812
|
return;
|
|
@@ -831,7 +829,7 @@ class FederationFactory {
|
|
|
831
829
|
case graphql_1.Kind.ENUM_TYPE_DEFINITION:
|
|
832
830
|
existingData.appearances += 1;
|
|
833
831
|
for (const data of incomingData.enumValueDataByValueName.values()) {
|
|
834
|
-
this.upsertEnumValueData(existingData.enumValueDataByValueName, data);
|
|
832
|
+
this.upsertEnumValueData(existingData.enumValueDataByValueName, data, isParentInaccessible);
|
|
835
833
|
}
|
|
836
834
|
return;
|
|
837
835
|
case graphql_1.Kind.INPUT_OBJECT_TYPE_DEFINITION:
|
|
@@ -846,6 +844,7 @@ class FederationFactory {
|
|
|
846
844
|
(0, utils_3.getValueOrDefault)(this.pathsByNamedTypeName, namedInputFieldTypeName, () => new Set()).add(inputFieldPath);
|
|
847
845
|
this.namedInputValueTypeNames.add(namedInputFieldTypeName);
|
|
848
846
|
this.upsertInputValueData(existingData.inputValueDataByValueName, inputValueData);
|
|
847
|
+
this.recordTagNamesByPath(inputValueData, inputFieldPath);
|
|
849
848
|
if (isParentInaccessible || (0, utils_5.isNodeDataInaccessible)(inputValueData)) {
|
|
850
849
|
this.inaccessiblePaths.add(inputFieldPath);
|
|
851
850
|
}
|
|
@@ -857,16 +856,10 @@ class FederationFactory {
|
|
|
857
856
|
if (isParentInaccessible && !existingData.isInaccessible) {
|
|
858
857
|
this.propagateInaccessibilityToExistingChildren(existingData);
|
|
859
858
|
}
|
|
860
|
-
const
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
tagNames.add(tagName);
|
|
865
|
-
}
|
|
866
|
-
}
|
|
867
|
-
(0, utils_3.addIterableValuesToSet)(objectData.implementedInterfaceTypeNames, existingData.implementedInterfaceTypeNames);
|
|
868
|
-
(0, utils_3.addIterableValuesToSet)(objectData.subgraphNames, existingData.subgraphNames);
|
|
869
|
-
for (const fieldData of objectData.fieldDataByFieldName.values()) {
|
|
859
|
+
const definitionWithFieldsData = incomingData;
|
|
860
|
+
(0, utils_3.addIterableValuesToSet)(definitionWithFieldsData.implementedInterfaceTypeNames, existingData.implementedInterfaceTypeNames);
|
|
861
|
+
(0, utils_3.addIterableValuesToSet)(definitionWithFieldsData.subgraphNames, existingData.subgraphNames);
|
|
862
|
+
for (const fieldData of definitionWithFieldsData.fieldDataByFieldName.values()) {
|
|
870
863
|
this.upsertFieldData(existingData.fieldDataByFieldName, fieldData, isParentInaccessible || existingData.isInaccessible);
|
|
871
864
|
}
|
|
872
865
|
return;
|
|
@@ -882,6 +875,7 @@ class FederationFactory {
|
|
|
882
875
|
const existingData = this.objectExtensionDataByTypeName.get(incomingData.name);
|
|
883
876
|
const baseData = existingData || incomingData;
|
|
884
877
|
(0, utils_5.extractPersistedDirectives)(baseData.persistedDirectivesData, incomingData.directivesByDirectiveName, this.persistedDirectiveDefinitionByDirectiveName);
|
|
878
|
+
this.recordTagNamesByPath(baseData);
|
|
885
879
|
const isParentInaccessible = (0, utils_5.isNodeDataInaccessible)(baseData);
|
|
886
880
|
if (isParentInaccessible) {
|
|
887
881
|
this.inaccessiblePaths.add(incomingData.name);
|
|
@@ -903,6 +897,7 @@ class FederationFactory {
|
|
|
903
897
|
(0, utils_3.getValueOrDefault)(this.pathsByNamedTypeName, fieldData.namedTypeName, () => new Set()).add(fieldPath);
|
|
904
898
|
this.namedOutputTypeNames.add(fieldData.namedTypeName);
|
|
905
899
|
(0, utils_5.extractPersistedDirectives)(fieldData.persistedDirectivesData, fieldData.directivesByDirectiveName, this.persistedDirectiveDefinitionByDirectiveName);
|
|
900
|
+
this.recordTagNamesByPath(fieldData, fieldPath);
|
|
906
901
|
const isFieldInaccessible = (0, utils_5.isNodeDataInaccessible)(fieldData);
|
|
907
902
|
if (isParentInaccessible || isFieldInaccessible) {
|
|
908
903
|
this.inaccessiblePaths.add(fieldPath);
|
|
@@ -915,11 +910,11 @@ class FederationFactory {
|
|
|
915
910
|
type: inputValueData.type,
|
|
916
911
|
};
|
|
917
912
|
const namedArgumentTypeName = (0, ast_1.getTypeNodeNamedTypeName)(inputValueData.type);
|
|
918
|
-
|
|
919
|
-
(0, utils_3.getValueOrDefault)(this.pathsByNamedTypeName, namedArgumentTypeName, () => new Set()).add(argumentPath);
|
|
913
|
+
(0, utils_3.getValueOrDefault)(this.pathsByNamedTypeName, namedArgumentTypeName, () => new Set()).add(inputValueData.renamedPath);
|
|
920
914
|
this.namedInputValueTypeNames.add(namedArgumentTypeName);
|
|
921
915
|
(0, utils_5.extractPersistedDirectives)(inputValueData.persistedDirectivesData, inputValueData.directivesByDirectiveName, this.persistedDirectiveDefinitionByDirectiveName);
|
|
922
|
-
this.
|
|
916
|
+
this.recordTagNamesByPath(inputValueData, `${incomingData.name}.${argumentName}`);
|
|
917
|
+
this.handleArgumentInaccessibility(isParentInaccessible || isFieldInaccessible, inputValueData, inputValueData.renamedPath, fieldPath);
|
|
923
918
|
}
|
|
924
919
|
}
|
|
925
920
|
this.objectExtensionDataByTypeName.set(incomingData.name, incomingData);
|
|
@@ -947,8 +942,7 @@ class FederationFactory {
|
|
|
947
942
|
const fieldPath = `${fieldData.renamedParentTypeName}.${fieldName}`;
|
|
948
943
|
this.inaccessiblePaths.add(fieldPath);
|
|
949
944
|
for (const [argumentName, inputValueData] of fieldData.argumentDataByArgumentName) {
|
|
950
|
-
|
|
951
|
-
this.inaccessiblePaths.add(argumentPath);
|
|
945
|
+
this.inaccessiblePaths.add(inputValueData.renamedPath);
|
|
952
946
|
}
|
|
953
947
|
}
|
|
954
948
|
}
|
|
@@ -1258,7 +1252,7 @@ class FederationFactory {
|
|
|
1258
1252
|
invalidFieldNames.add(fieldName);
|
|
1259
1253
|
}
|
|
1260
1254
|
fieldNodes.push((0, utils_5.getNodeWithPersistedDirectivesByFieldData)(fieldData, this.persistedDirectiveDefinitionByDirectiveName, argumentNodes, this.errors));
|
|
1261
|
-
if (
|
|
1255
|
+
if ((0, utils_5.isNodeDataInaccessible)(fieldData)) {
|
|
1262
1256
|
continue;
|
|
1263
1257
|
}
|
|
1264
1258
|
clientSchemaFieldNodes.push((0, utils_5.getClientSchemaFieldNodeByFieldData)(fieldData));
|
|
@@ -1436,10 +1430,10 @@ class FederationFactory {
|
|
|
1436
1430
|
kind: graphql_1.Kind.DOCUMENT,
|
|
1437
1431
|
definitions: this.routerDefinitions,
|
|
1438
1432
|
};
|
|
1439
|
-
const
|
|
1433
|
+
const newClientSchema = (0, graphql_1.buildASTSchema)({
|
|
1440
1434
|
kind: graphql_1.Kind.DOCUMENT,
|
|
1441
1435
|
definitions: this.clientDefinitions,
|
|
1442
|
-
};
|
|
1436
|
+
});
|
|
1443
1437
|
const subgraphConfigBySubgraphName = new Map();
|
|
1444
1438
|
for (const subgraph of this.internalSubgraphBySubgraphName.values()) {
|
|
1445
1439
|
subgraphConfigBySubgraphName.set(subgraph.name, {
|
|
@@ -1456,24 +1450,61 @@ class FederationFactory {
|
|
|
1456
1450
|
subgraphConfigBySubgraphName,
|
|
1457
1451
|
federatedGraphAST: newRouterAST,
|
|
1458
1452
|
federatedGraphSchema: (0, graphql_1.buildASTSchema)(newRouterAST),
|
|
1459
|
-
federatedGraphClientSchema:
|
|
1453
|
+
federatedGraphClientSchema: newClientSchema,
|
|
1454
|
+
...this.getClientSchemaObjectBoolean(),
|
|
1460
1455
|
},
|
|
1461
1456
|
...warnings,
|
|
1462
1457
|
};
|
|
1463
1458
|
}
|
|
1464
|
-
|
|
1459
|
+
getClientSchemaObjectBoolean() {
|
|
1460
|
+
// If the schema does not implement @tag nor @inaccessible, an empty object will be spread
|
|
1461
|
+
if (this.inaccessiblePaths.size < 1 && this.tagNamesByPath.size < 1) {
|
|
1462
|
+
return {};
|
|
1463
|
+
}
|
|
1464
|
+
// otherwise, the object is spread in as true
|
|
1465
|
+
return { shouldIncludeClientSchema: true };
|
|
1466
|
+
}
|
|
1467
|
+
handleChildRemovalByTag(parentDefinitionData, children, childTagDataByChildName, tagsToExclude) {
|
|
1468
|
+
let accessibleChildren = children.size;
|
|
1469
|
+
for (const [childName, childTagData] of childTagDataByChildName) {
|
|
1470
|
+
const childData = (0, utils_3.getOrThrowError)(children, childName, `${parentDefinitionData.name}.childDataByChildName`);
|
|
1471
|
+
if ((0, utils_5.isNodeDataInaccessible)(childData)) {
|
|
1472
|
+
accessibleChildren -= 1;
|
|
1473
|
+
continue;
|
|
1474
|
+
}
|
|
1475
|
+
if ((0, utils_3.doSetsIntersect)(tagsToExclude, childTagData.tagNames)) {
|
|
1476
|
+
(0, utils_3.getValueOrDefault)(childData.persistedDirectivesData.directives, string_constants_1.INACCESSIBLE, () => [
|
|
1477
|
+
(0, utils_3.generateSimpleDirective)(string_constants_1.INACCESSIBLE),
|
|
1478
|
+
]);
|
|
1479
|
+
this.inaccessiblePaths.add(`${parentDefinitionData.name}.${childName}`);
|
|
1480
|
+
accessibleChildren -= 1;
|
|
1481
|
+
}
|
|
1482
|
+
}
|
|
1483
|
+
if (accessibleChildren < 1) {
|
|
1484
|
+
parentDefinitionData.persistedDirectivesData.directives.set(string_constants_1.INACCESSIBLE, [
|
|
1485
|
+
(0, utils_3.generateSimpleDirective)(string_constants_1.INACCESSIBLE),
|
|
1486
|
+
]);
|
|
1487
|
+
this.inaccessiblePaths.add(parentDefinitionData.name);
|
|
1488
|
+
}
|
|
1489
|
+
}
|
|
1490
|
+
buildFederationContractResult(tagsToExclude) {
|
|
1465
1491
|
if (!this.isVersionTwo) {
|
|
1466
1492
|
/* If all the subgraphs are version one, the @inaccessible directive won't be present.
|
|
1467
1493
|
** However, contracts require @inaccessible to exclude applicable tagged types. */
|
|
1468
1494
|
this.routerDefinitions.push(constants_1.INACCESSIBLE_DEFINITION);
|
|
1469
1495
|
}
|
|
1470
|
-
for (const [
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1496
|
+
for (const [parentTypeName, parentTagData] of this.parentTagDataByTypeName) {
|
|
1497
|
+
const parentDefinitionData = (0, utils_3.getOrThrowError)(this.parentDefinitionDataByTypeName, parentTypeName, string_constants_1.PARENT_DEFINITION_DATA);
|
|
1498
|
+
if ((0, utils_5.isNodeDataInaccessible)(parentDefinitionData)) {
|
|
1499
|
+
continue;
|
|
1500
|
+
}
|
|
1501
|
+
if ((0, utils_3.doSetsIntersect)(tagsToExclude, parentTagData.tagNames)) {
|
|
1502
|
+
parentDefinitionData.persistedDirectivesData.directives.set(string_constants_1.INACCESSIBLE, [
|
|
1475
1503
|
(0, utils_3.generateSimpleDirective)(string_constants_1.INACCESSIBLE),
|
|
1476
1504
|
]);
|
|
1505
|
+
this.inaccessiblePaths.add(parentTypeName);
|
|
1506
|
+
// If the parent is inaccessible, there is no need to assess further
|
|
1507
|
+
continue;
|
|
1477
1508
|
}
|
|
1478
1509
|
if (parentTagData.childTagDataByChildName.size < 1) {
|
|
1479
1510
|
continue;
|
|
@@ -1481,37 +1512,49 @@ class FederationFactory {
|
|
|
1481
1512
|
switch (parentDefinitionData.kind) {
|
|
1482
1513
|
case graphql_1.Kind.SCALAR_TYPE_DEFINITION:
|
|
1483
1514
|
// intentional fallthrough
|
|
1484
|
-
case graphql_1.Kind.ENUM_TYPE_DEFINITION:
|
|
1485
|
-
// intentional fallthrough
|
|
1486
1515
|
case graphql_1.Kind.UNION_TYPE_DEFINITION:
|
|
1487
1516
|
continue;
|
|
1517
|
+
case graphql_1.Kind.ENUM_TYPE_DEFINITION:
|
|
1518
|
+
this.handleChildRemovalByTag(parentDefinitionData, parentDefinitionData.enumValueDataByValueName, parentTagData.childTagDataByChildName, tagsToExclude);
|
|
1519
|
+
break;
|
|
1488
1520
|
case graphql_1.Kind.INPUT_OBJECT_TYPE_DEFINITION:
|
|
1489
|
-
|
|
1490
|
-
const inputValueData = (0, utils_3.getOrThrowError)(parentDefinitionData.inputValueDataByValueName, inputFieldName, 'parentDefinitionData.inputValueDataByValueName');
|
|
1491
|
-
if ((0, utils_3.doSetsHaveAnyOverlap)(tagExclusions, childTagData.tagNames)) {
|
|
1492
|
-
(0, utils_3.getValueOrDefault)(inputValueData.persistedDirectivesData.directives, string_constants_1.INACCESSIBLE, () => [
|
|
1493
|
-
(0, utils_3.generateSimpleDirective)(string_constants_1.INACCESSIBLE),
|
|
1494
|
-
]);
|
|
1495
|
-
}
|
|
1496
|
-
}
|
|
1521
|
+
this.handleChildRemovalByTag(parentDefinitionData, parentDefinitionData.inputValueDataByValueName, parentTagData.childTagDataByChildName, tagsToExclude);
|
|
1497
1522
|
break;
|
|
1498
1523
|
default:
|
|
1524
|
+
let accessibleFields = parentDefinitionData.fieldDataByFieldName.size;
|
|
1499
1525
|
for (const [fieldName, childTagData] of parentTagData.childTagDataByChildName) {
|
|
1500
|
-
const fieldData = (0, utils_3.getOrThrowError)(parentDefinitionData.fieldDataByFieldName, fieldName,
|
|
1501
|
-
if ((0,
|
|
1526
|
+
const fieldData = (0, utils_3.getOrThrowError)(parentDefinitionData.fieldDataByFieldName, fieldName, `${parentTypeName}.fieldDataByFieldName`);
|
|
1527
|
+
if ((0, utils_5.isNodeDataInaccessible)(fieldData)) {
|
|
1528
|
+
accessibleFields -= 1;
|
|
1529
|
+
continue;
|
|
1530
|
+
}
|
|
1531
|
+
if ((0, utils_3.doSetsIntersect)(tagsToExclude, childTagData.tagNames)) {
|
|
1502
1532
|
(0, utils_3.getValueOrDefault)(fieldData.persistedDirectivesData.directives, string_constants_1.INACCESSIBLE, () => [
|
|
1503
1533
|
(0, utils_3.generateSimpleDirective)(string_constants_1.INACCESSIBLE),
|
|
1504
1534
|
]);
|
|
1535
|
+
this.inaccessiblePaths.add(`${parentTypeName}.${fieldName}`);
|
|
1536
|
+
accessibleFields -= 1;
|
|
1537
|
+
continue;
|
|
1505
1538
|
}
|
|
1506
1539
|
for (const [argumentName, tagNames] of childTagData.tagNamesByArgumentName) {
|
|
1507
|
-
const inputValueData = (0, utils_3.getOrThrowError)(fieldData.argumentDataByArgumentName, argumentName,
|
|
1508
|
-
if ((0,
|
|
1540
|
+
const inputValueData = (0, utils_3.getOrThrowError)(fieldData.argumentDataByArgumentName, argumentName, `${fieldName}.argumentDataByArgumentName`);
|
|
1541
|
+
if ((0, utils_5.isNodeDataInaccessible)(inputValueData)) {
|
|
1542
|
+
continue;
|
|
1543
|
+
}
|
|
1544
|
+
if ((0, utils_3.doSetsIntersect)(tagsToExclude, tagNames)) {
|
|
1509
1545
|
(0, utils_3.getValueOrDefault)(inputValueData.persistedDirectivesData.directives, string_constants_1.INACCESSIBLE, () => [
|
|
1510
1546
|
(0, utils_3.generateSimpleDirective)(string_constants_1.INACCESSIBLE),
|
|
1511
1547
|
]);
|
|
1548
|
+
this.inaccessiblePaths.add(inputValueData.renamedPath);
|
|
1512
1549
|
}
|
|
1513
1550
|
}
|
|
1514
1551
|
}
|
|
1552
|
+
if (accessibleFields < 1) {
|
|
1553
|
+
parentDefinitionData.persistedDirectivesData.directives.set(string_constants_1.INACCESSIBLE, [
|
|
1554
|
+
(0, utils_3.generateSimpleDirective)(string_constants_1.INACCESSIBLE),
|
|
1555
|
+
]);
|
|
1556
|
+
this.inaccessiblePaths.add(parentTypeName);
|
|
1557
|
+
}
|
|
1515
1558
|
}
|
|
1516
1559
|
}
|
|
1517
1560
|
for (const data of this.potentialPersistedDirectiveDefinitionDataByDirectiveName.values()) {
|
|
@@ -1529,10 +1572,10 @@ class FederationFactory {
|
|
|
1529
1572
|
kind: graphql_1.Kind.DOCUMENT,
|
|
1530
1573
|
definitions: this.routerDefinitions,
|
|
1531
1574
|
};
|
|
1532
|
-
const
|
|
1575
|
+
const newClientSchema = (0, graphql_1.buildASTSchema)({
|
|
1533
1576
|
kind: graphql_1.Kind.DOCUMENT,
|
|
1534
1577
|
definitions: this.clientDefinitions,
|
|
1535
|
-
};
|
|
1578
|
+
});
|
|
1536
1579
|
const subgraphConfigBySubgraphName = new Map();
|
|
1537
1580
|
for (const subgraph of this.internalSubgraphBySubgraphName.values()) {
|
|
1538
1581
|
subgraphConfigBySubgraphName.set(subgraph.name, {
|
|
@@ -1549,7 +1592,8 @@ class FederationFactory {
|
|
|
1549
1592
|
subgraphConfigBySubgraphName,
|
|
1550
1593
|
federatedGraphAST: newRouterAST,
|
|
1551
1594
|
federatedGraphSchema: (0, graphql_1.buildASTSchema)(newRouterAST),
|
|
1552
|
-
federatedGraphClientSchema:
|
|
1595
|
+
federatedGraphClientSchema: newClientSchema,
|
|
1596
|
+
...this.getClientSchemaObjectBoolean(),
|
|
1553
1597
|
},
|
|
1554
1598
|
warnings,
|
|
1555
1599
|
};
|