@depup/graphql-tools__delegate 12.0.13-depup.0 → 12.1.1-depup.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.
- package/README.md +7 -5
- package/changes.json +12 -4
- package/dist/index.cjs +488 -49
- package/dist/index.d.cts +4 -2
- package/dist/index.d.ts +4 -2
- package/dist/index.js +489 -50
- package/package.json +20 -12
package/dist/index.cjs
CHANGED
|
@@ -382,7 +382,7 @@ function resolveExternalObject(type, object, unpathedErrors, subschema, context,
|
|
|
382
382
|
sourceSubschema,
|
|
383
383
|
targetSubschemas
|
|
384
384
|
] of potentialMergedTypeInfo.targetSubschemas) {
|
|
385
|
-
if (targetSubschemas.length && sourceSubschema.name === subschema.name) {
|
|
385
|
+
if (targetSubschemas.length && sourceSubschema.name != null && sourceSubschema.name === subschema.name) {
|
|
386
386
|
subschema = sourceSubschema;
|
|
387
387
|
mergedTypeInfo = potentialMergedTypeInfo;
|
|
388
388
|
}
|
|
@@ -590,7 +590,7 @@ const handleOverrideByDelegation = utils.memoize3(
|
|
|
590
590
|
}
|
|
591
591
|
);
|
|
592
592
|
|
|
593
|
-
function finalizeGatewayDocument(targetSchema, fragments, operations, onOverlappingAliases, delegationContext) {
|
|
593
|
+
function finalizeGatewayDocument(targetSchema, originalDocument, fragments, operations, onOverlappingAliases, delegationContext) {
|
|
594
594
|
let usedVariables = [];
|
|
595
595
|
let usedFragments = [];
|
|
596
596
|
const newOperations = [];
|
|
@@ -682,47 +682,128 @@ function finalizeGatewayDocument(targetSchema, fragments, operations, onOverlapp
|
|
|
682
682
|
}
|
|
683
683
|
);
|
|
684
684
|
}
|
|
685
|
+
const includedFragmentNames = new Set(newFragments.map((f) => f.name.value));
|
|
686
|
+
const hasDroppedFragments = includedFragmentNames.size < usedFragments.length;
|
|
685
687
|
let newDocument = {
|
|
686
688
|
kind: graphql.Kind.DOCUMENT,
|
|
687
689
|
definitions: [...newOperations, ...newFragments]
|
|
688
690
|
};
|
|
689
691
|
const stitchingInfo = delegationContext.info?.schema?.extensions?.["stitchingInfo"];
|
|
690
|
-
if (stitchingInfo != null
|
|
692
|
+
if (stitchingInfo != null && subschemaHasProvidedSelections(
|
|
693
|
+
stitchingInfo,
|
|
694
|
+
delegationContext.subschema
|
|
695
|
+
)) {
|
|
696
|
+
const {
|
|
697
|
+
selectionSetsByPath: originalFieldSelectionSetsByPath,
|
|
698
|
+
fragments: originalFragmentsByName
|
|
699
|
+
} = collectFieldSelectionSetsByPath(originalDocument);
|
|
691
700
|
const typeInfo = getTypeInfo(targetSchema);
|
|
701
|
+
const pathStack = [];
|
|
702
|
+
const inlineFragmentCounterStack = [];
|
|
692
703
|
newDocument = graphql.visit(
|
|
693
704
|
newDocument,
|
|
694
705
|
graphql.visitWithTypeInfo(typeInfo, {
|
|
695
|
-
[graphql.Kind.
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
706
|
+
[graphql.Kind.SELECTION_SET]: {
|
|
707
|
+
enter() {
|
|
708
|
+
inlineFragmentCounterStack.push(/* @__PURE__ */ new Map());
|
|
709
|
+
},
|
|
710
|
+
leave() {
|
|
711
|
+
inlineFragmentCounterStack.pop();
|
|
712
|
+
}
|
|
713
|
+
},
|
|
714
|
+
[graphql.Kind.OPERATION_DEFINITION]: {
|
|
715
|
+
enter(node) {
|
|
716
|
+
pathStack.push(`op:${node.operation}:${node.name?.value ?? ""}`);
|
|
717
|
+
},
|
|
718
|
+
leave() {
|
|
719
|
+
pathStack.pop();
|
|
720
|
+
}
|
|
721
|
+
},
|
|
722
|
+
[graphql.Kind.FRAGMENT_DEFINITION]: {
|
|
723
|
+
enter(node) {
|
|
724
|
+
pathStack.push(`frag:${node.name.value}`);
|
|
725
|
+
},
|
|
726
|
+
leave() {
|
|
727
|
+
pathStack.pop();
|
|
728
|
+
}
|
|
729
|
+
},
|
|
730
|
+
[graphql.Kind.INLINE_FRAGMENT]: {
|
|
731
|
+
enter(node) {
|
|
732
|
+
pathStack.push(
|
|
733
|
+
nextInlineFragmentPathSegment(
|
|
734
|
+
node,
|
|
735
|
+
inlineFragmentCounterStack[inlineFragmentCounterStack.length - 1]
|
|
736
|
+
)
|
|
737
|
+
);
|
|
738
|
+
},
|
|
739
|
+
leave() {
|
|
740
|
+
pathStack.pop();
|
|
741
|
+
}
|
|
742
|
+
},
|
|
743
|
+
[graphql.Kind.FIELD]: {
|
|
744
|
+
enter(fieldNode) {
|
|
745
|
+
pathStack.push(fieldNode.alias?.value ?? fieldNode.name.value);
|
|
746
|
+
},
|
|
747
|
+
leave(fieldNode) {
|
|
748
|
+
try {
|
|
749
|
+
const parentType = typeInfo.getParentType();
|
|
750
|
+
if (!parentType) {
|
|
751
|
+
return void 0;
|
|
752
|
+
}
|
|
753
|
+
const typeConfig = stitchingInfo?.mergedTypes?.[parentType.name];
|
|
701
754
|
const providedSelectionsByField = typeConfig?.providedSelectionsByField?.get(
|
|
702
755
|
delegationContext.subschema
|
|
703
756
|
);
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
return {
|
|
708
|
-
...fieldNode,
|
|
709
|
-
selectionSet: {
|
|
710
|
-
kind: graphql.Kind.SELECTION_SET,
|
|
711
|
-
selections: [
|
|
712
|
-
...providedSelection.selections,
|
|
713
|
-
...fieldNode.selectionSet?.selections ?? []
|
|
714
|
-
]
|
|
715
|
-
}
|
|
716
|
-
};
|
|
717
|
-
}
|
|
757
|
+
const providedSelection = providedSelectionsByField?.[fieldNode.name.value];
|
|
758
|
+
if (!providedSelection) {
|
|
759
|
+
return void 0;
|
|
718
760
|
}
|
|
761
|
+
const originalSelectionSet = lookupOriginalSelectionSet(
|
|
762
|
+
pathStack,
|
|
763
|
+
fieldNode,
|
|
764
|
+
originalFieldSelectionSetsByPath
|
|
765
|
+
);
|
|
766
|
+
const requestedProvidedSelections = intersectProvidedSelections(
|
|
767
|
+
providedSelection.selections,
|
|
768
|
+
originalSelectionSet,
|
|
769
|
+
originalFragmentsByName
|
|
770
|
+
);
|
|
771
|
+
if (!requestedProvidedSelections.length) {
|
|
772
|
+
return void 0;
|
|
773
|
+
}
|
|
774
|
+
return {
|
|
775
|
+
...fieldNode,
|
|
776
|
+
selectionSet: {
|
|
777
|
+
kind: graphql.Kind.SELECTION_SET,
|
|
778
|
+
selections: [
|
|
779
|
+
...requestedProvidedSelections,
|
|
780
|
+
...fieldNode.selectionSet?.selections ?? []
|
|
781
|
+
]
|
|
782
|
+
}
|
|
783
|
+
};
|
|
784
|
+
} finally {
|
|
785
|
+
pathStack.pop();
|
|
719
786
|
}
|
|
720
787
|
}
|
|
721
|
-
return fieldNode;
|
|
722
788
|
}
|
|
723
789
|
})
|
|
724
790
|
);
|
|
725
791
|
}
|
|
792
|
+
if (hasDroppedFragments) {
|
|
793
|
+
const ops = newDocument.definitions.filter(
|
|
794
|
+
(d) => d.kind === graphql.Kind.OPERATION_DEFINITION
|
|
795
|
+
);
|
|
796
|
+
const frags = newDocument.definitions.filter(
|
|
797
|
+
(d) => d.kind === graphql.Kind.FRAGMENT_DEFINITION
|
|
798
|
+
);
|
|
799
|
+
newDocument = {
|
|
800
|
+
kind: graphql.Kind.DOCUMENT,
|
|
801
|
+
definitions: [
|
|
802
|
+
...removeDeadFragmentSpreads(ops, includedFragmentNames),
|
|
803
|
+
...frags
|
|
804
|
+
]
|
|
805
|
+
};
|
|
806
|
+
}
|
|
726
807
|
return {
|
|
727
808
|
usedVariables,
|
|
728
809
|
newDocument
|
|
@@ -733,6 +814,7 @@ function finalizeGatewayRequest(originalRequest, delegationContext, onOverlappin
|
|
|
733
814
|
const { targetSchema } = delegationContext;
|
|
734
815
|
const { usedVariables, newDocument } = finalizeGatewayDocument(
|
|
735
816
|
targetSchema,
|
|
817
|
+
originalRequest.document,
|
|
736
818
|
fragments,
|
|
737
819
|
operations,
|
|
738
820
|
onOverlappingAliases,
|
|
@@ -758,9 +840,293 @@ function finalizeGatewayRequest(originalRequest, delegationContext, onOverlappin
|
|
|
758
840
|
variables: newVariables
|
|
759
841
|
};
|
|
760
842
|
}
|
|
843
|
+
function removeDeadFragmentSpreads(operations, included) {
|
|
844
|
+
function cleanSelections(selections) {
|
|
845
|
+
const out = [];
|
|
846
|
+
for (const sel of selections) {
|
|
847
|
+
if (sel.kind === graphql.Kind.FRAGMENT_SPREAD) {
|
|
848
|
+
if (included.has(sel.name.value)) {
|
|
849
|
+
out.push(sel);
|
|
850
|
+
}
|
|
851
|
+
} else if ((sel.kind === graphql.Kind.FIELD || sel.kind === graphql.Kind.INLINE_FRAGMENT) && sel.selectionSet) {
|
|
852
|
+
const cleaned = cleanSelections(sel.selectionSet.selections);
|
|
853
|
+
if (cleaned.length === 0 && sel.kind === graphql.Kind.INLINE_FRAGMENT) {
|
|
854
|
+
continue;
|
|
855
|
+
}
|
|
856
|
+
if (cleaned.length === 0 && sel.kind === graphql.Kind.FIELD) {
|
|
857
|
+
continue;
|
|
858
|
+
}
|
|
859
|
+
out.push(
|
|
860
|
+
cleaned === sel.selectionSet.selections ? sel : {
|
|
861
|
+
...sel,
|
|
862
|
+
selectionSet: {
|
|
863
|
+
kind: graphql.Kind.SELECTION_SET,
|
|
864
|
+
selections: cleaned
|
|
865
|
+
}
|
|
866
|
+
}
|
|
867
|
+
);
|
|
868
|
+
} else {
|
|
869
|
+
out.push(sel);
|
|
870
|
+
}
|
|
871
|
+
}
|
|
872
|
+
return out;
|
|
873
|
+
}
|
|
874
|
+
return operations.map((op) => ({
|
|
875
|
+
...op,
|
|
876
|
+
selectionSet: {
|
|
877
|
+
...op.selectionSet,
|
|
878
|
+
selections: cleanSelections(op.selectionSet.selections)
|
|
879
|
+
}
|
|
880
|
+
}));
|
|
881
|
+
}
|
|
761
882
|
function isTypeNameField(selection) {
|
|
762
883
|
return selection.kind === graphql.Kind.FIELD && !selection.alias && selection.name.value === "__typename";
|
|
763
884
|
}
|
|
885
|
+
function collectFieldSelectionSetsByPathImpl(document) {
|
|
886
|
+
const selectionSetsByPath = /* @__PURE__ */ new Map();
|
|
887
|
+
const fragments = /* @__PURE__ */ new Map();
|
|
888
|
+
for (const def of document.definitions) {
|
|
889
|
+
if (def.kind === graphql.Kind.FRAGMENT_DEFINITION) {
|
|
890
|
+
fragments.set(def.name.value, def);
|
|
891
|
+
}
|
|
892
|
+
}
|
|
893
|
+
const pathStack = [];
|
|
894
|
+
const inlineFragmentCounterStack = [];
|
|
895
|
+
graphql.visit(document, {
|
|
896
|
+
[graphql.Kind.SELECTION_SET]: {
|
|
897
|
+
enter() {
|
|
898
|
+
inlineFragmentCounterStack.push(/* @__PURE__ */ new Map());
|
|
899
|
+
},
|
|
900
|
+
leave() {
|
|
901
|
+
inlineFragmentCounterStack.pop();
|
|
902
|
+
}
|
|
903
|
+
},
|
|
904
|
+
[graphql.Kind.OPERATION_DEFINITION]: {
|
|
905
|
+
enter(node) {
|
|
906
|
+
pathStack.push(`op:${node.operation}:${node.name?.value ?? ""}`);
|
|
907
|
+
},
|
|
908
|
+
leave() {
|
|
909
|
+
pathStack.pop();
|
|
910
|
+
}
|
|
911
|
+
},
|
|
912
|
+
[graphql.Kind.FRAGMENT_DEFINITION]: {
|
|
913
|
+
enter(node) {
|
|
914
|
+
pathStack.push(`frag:${node.name.value}`);
|
|
915
|
+
},
|
|
916
|
+
leave() {
|
|
917
|
+
pathStack.pop();
|
|
918
|
+
}
|
|
919
|
+
},
|
|
920
|
+
[graphql.Kind.INLINE_FRAGMENT]: {
|
|
921
|
+
enter(node) {
|
|
922
|
+
pathStack.push(
|
|
923
|
+
nextInlineFragmentPathSegment(
|
|
924
|
+
node,
|
|
925
|
+
inlineFragmentCounterStack[inlineFragmentCounterStack.length - 1]
|
|
926
|
+
)
|
|
927
|
+
);
|
|
928
|
+
},
|
|
929
|
+
leave() {
|
|
930
|
+
pathStack.pop();
|
|
931
|
+
}
|
|
932
|
+
},
|
|
933
|
+
[graphql.Kind.FIELD]: {
|
|
934
|
+
enter(node) {
|
|
935
|
+
pathStack.push(node.alias?.value ?? node.name.value);
|
|
936
|
+
if (node.selectionSet) {
|
|
937
|
+
selectionSetsByPath.set(pathStack.join(">"), node.selectionSet);
|
|
938
|
+
if (node.alias) {
|
|
939
|
+
const namePath = [...pathStack.slice(0, -1), node.name.value].join(
|
|
940
|
+
">"
|
|
941
|
+
);
|
|
942
|
+
if (!selectionSetsByPath.has(namePath)) {
|
|
943
|
+
selectionSetsByPath.set(namePath, node.selectionSet);
|
|
944
|
+
}
|
|
945
|
+
}
|
|
946
|
+
}
|
|
947
|
+
},
|
|
948
|
+
leave() {
|
|
949
|
+
pathStack.pop();
|
|
950
|
+
}
|
|
951
|
+
}
|
|
952
|
+
});
|
|
953
|
+
return { selectionSetsByPath, fragments };
|
|
954
|
+
}
|
|
955
|
+
const collectFieldSelectionSetsByPath = utils.memoize1(
|
|
956
|
+
collectFieldSelectionSetsByPathImpl
|
|
957
|
+
);
|
|
958
|
+
function nextInlineFragmentPathSegment(node, counter) {
|
|
959
|
+
const typeName = node.typeCondition?.name.value ?? "";
|
|
960
|
+
if (!counter) {
|
|
961
|
+
return `inline:${typeName}:0`;
|
|
962
|
+
}
|
|
963
|
+
const idx = counter.get(typeName) ?? 0;
|
|
964
|
+
counter.set(typeName, idx + 1);
|
|
965
|
+
return `inline:${typeName}:${idx}`;
|
|
966
|
+
}
|
|
967
|
+
function subschemaHasProvidedSelectionsImpl(stitchingInfo, subschema) {
|
|
968
|
+
const mergedTypes = stitchingInfo.mergedTypes;
|
|
969
|
+
if (!mergedTypes) {
|
|
970
|
+
return false;
|
|
971
|
+
}
|
|
972
|
+
for (const typeConfig of Object.values(mergedTypes)) {
|
|
973
|
+
if (typeConfig?.providedSelectionsByField?.has(subschema)) {
|
|
974
|
+
return true;
|
|
975
|
+
}
|
|
976
|
+
}
|
|
977
|
+
return false;
|
|
978
|
+
}
|
|
979
|
+
const subschemaHasProvidedSelections = utils.memoize2(
|
|
980
|
+
subschemaHasProvidedSelectionsImpl
|
|
981
|
+
);
|
|
982
|
+
function lookupOriginalSelectionSet(pathStack, fieldNode, selectionSetsByPath) {
|
|
983
|
+
const exact = selectionSetsByPath.get(pathStack.join(">"));
|
|
984
|
+
if (exact || !fieldNode.alias) {
|
|
985
|
+
return exact;
|
|
986
|
+
}
|
|
987
|
+
const fallback = [...pathStack.slice(0, -1), fieldNode.name.value].join(">");
|
|
988
|
+
return selectionSetsByPath.get(fallback);
|
|
989
|
+
}
|
|
990
|
+
function intersectProvidedSelections(providedSelections, originalSelectionSet, fragments) {
|
|
991
|
+
if (!originalSelectionSet) {
|
|
992
|
+
return [];
|
|
993
|
+
}
|
|
994
|
+
const providedFieldsByName = /* @__PURE__ */ new Map();
|
|
995
|
+
const otherProvided = [];
|
|
996
|
+
for (const provided of providedSelections) {
|
|
997
|
+
if (provided.kind === graphql.Kind.FIELD) {
|
|
998
|
+
providedFieldsByName.set(provided.name.value, provided);
|
|
999
|
+
} else {
|
|
1000
|
+
otherProvided.push(provided);
|
|
1001
|
+
}
|
|
1002
|
+
}
|
|
1003
|
+
const result = [];
|
|
1004
|
+
collectMatchingOriginalSelections(
|
|
1005
|
+
originalSelectionSet,
|
|
1006
|
+
providedFieldsByName,
|
|
1007
|
+
fragments,
|
|
1008
|
+
/* @__PURE__ */ new Set(),
|
|
1009
|
+
/* @__PURE__ */ new Set(),
|
|
1010
|
+
result
|
|
1011
|
+
);
|
|
1012
|
+
return [...result, ...otherProvided];
|
|
1013
|
+
}
|
|
1014
|
+
function collectMatchingOriginalSelections(selectionSet, providedFieldsByName, fragments, seenFieldNames, seenFragmentNames, result) {
|
|
1015
|
+
for (const sel of selectionSet.selections) {
|
|
1016
|
+
if (sel.kind === graphql.Kind.FIELD) {
|
|
1017
|
+
const provided = providedFieldsByName.get(sel.name.value);
|
|
1018
|
+
if (!provided) {
|
|
1019
|
+
continue;
|
|
1020
|
+
}
|
|
1021
|
+
const dedupKey = sel.alias?.value ?? sel.name.value;
|
|
1022
|
+
if (seenFieldNames.has(dedupKey)) {
|
|
1023
|
+
continue;
|
|
1024
|
+
}
|
|
1025
|
+
seenFieldNames.add(dedupKey);
|
|
1026
|
+
if (provided.selectionSet && sel.selectionSet) {
|
|
1027
|
+
const nested = intersectProvidedSelections(
|
|
1028
|
+
provided.selectionSet.selections,
|
|
1029
|
+
sel.selectionSet,
|
|
1030
|
+
fragments
|
|
1031
|
+
);
|
|
1032
|
+
if (!nested.length) {
|
|
1033
|
+
continue;
|
|
1034
|
+
}
|
|
1035
|
+
result.push({
|
|
1036
|
+
...sel,
|
|
1037
|
+
selectionSet: {
|
|
1038
|
+
kind: graphql.Kind.SELECTION_SET,
|
|
1039
|
+
selections: nested
|
|
1040
|
+
}
|
|
1041
|
+
});
|
|
1042
|
+
} else {
|
|
1043
|
+
result.push(sel);
|
|
1044
|
+
}
|
|
1045
|
+
} else if (sel.kind === graphql.Kind.INLINE_FRAGMENT && sel.selectionSet) {
|
|
1046
|
+
const hasDirectives = (sel.directives?.length ?? 0) > 0;
|
|
1047
|
+
const hasTypeCondition = sel.typeCondition != null;
|
|
1048
|
+
if (hasDirectives || hasTypeCondition) {
|
|
1049
|
+
const inner = [];
|
|
1050
|
+
collectMatchingOriginalSelections(
|
|
1051
|
+
sel.selectionSet,
|
|
1052
|
+
providedFieldsByName,
|
|
1053
|
+
fragments,
|
|
1054
|
+
/* @__PURE__ */ new Set(),
|
|
1055
|
+
/* @__PURE__ */ new Set(),
|
|
1056
|
+
inner
|
|
1057
|
+
);
|
|
1058
|
+
if (inner.length === 0) {
|
|
1059
|
+
continue;
|
|
1060
|
+
}
|
|
1061
|
+
result.push({
|
|
1062
|
+
kind: graphql.Kind.INLINE_FRAGMENT,
|
|
1063
|
+
typeCondition: sel.typeCondition,
|
|
1064
|
+
directives: sel.directives,
|
|
1065
|
+
selectionSet: {
|
|
1066
|
+
kind: graphql.Kind.SELECTION_SET,
|
|
1067
|
+
selections: inner
|
|
1068
|
+
}
|
|
1069
|
+
});
|
|
1070
|
+
} else {
|
|
1071
|
+
collectMatchingOriginalSelections(
|
|
1072
|
+
sel.selectionSet,
|
|
1073
|
+
providedFieldsByName,
|
|
1074
|
+
fragments,
|
|
1075
|
+
seenFieldNames,
|
|
1076
|
+
seenFragmentNames,
|
|
1077
|
+
result
|
|
1078
|
+
);
|
|
1079
|
+
}
|
|
1080
|
+
} else if (sel.kind === graphql.Kind.FRAGMENT_SPREAD) {
|
|
1081
|
+
const fragmentDef = fragments.get(sel.name.value);
|
|
1082
|
+
if (!fragmentDef) {
|
|
1083
|
+
continue;
|
|
1084
|
+
}
|
|
1085
|
+
const hasSpreadDirectives = (sel.directives?.length ?? 0) > 0;
|
|
1086
|
+
const hasFragmentDirectives = (fragmentDef.directives?.length ?? 0) > 0;
|
|
1087
|
+
if (hasSpreadDirectives || hasFragmentDirectives) {
|
|
1088
|
+
const inner = [];
|
|
1089
|
+
collectMatchingOriginalSelections(
|
|
1090
|
+
fragmentDef.selectionSet,
|
|
1091
|
+
providedFieldsByName,
|
|
1092
|
+
fragments,
|
|
1093
|
+
/* @__PURE__ */ new Set(),
|
|
1094
|
+
/* @__PURE__ */ new Set(),
|
|
1095
|
+
inner
|
|
1096
|
+
);
|
|
1097
|
+
if (inner.length === 0) {
|
|
1098
|
+
continue;
|
|
1099
|
+
}
|
|
1100
|
+
const combinedDirectives = [
|
|
1101
|
+
...sel.directives ?? [],
|
|
1102
|
+
...fragmentDef.directives ?? []
|
|
1103
|
+
];
|
|
1104
|
+
result.push({
|
|
1105
|
+
kind: graphql.Kind.INLINE_FRAGMENT,
|
|
1106
|
+
typeCondition: fragmentDef.typeCondition,
|
|
1107
|
+
directives: combinedDirectives.length > 0 ? combinedDirectives : void 0,
|
|
1108
|
+
selectionSet: {
|
|
1109
|
+
kind: graphql.Kind.SELECTION_SET,
|
|
1110
|
+
selections: inner
|
|
1111
|
+
}
|
|
1112
|
+
});
|
|
1113
|
+
} else {
|
|
1114
|
+
if (seenFragmentNames.has(sel.name.value)) {
|
|
1115
|
+
continue;
|
|
1116
|
+
}
|
|
1117
|
+
seenFragmentNames.add(sel.name.value);
|
|
1118
|
+
collectMatchingOriginalSelections(
|
|
1119
|
+
fragmentDef.selectionSet,
|
|
1120
|
+
providedFieldsByName,
|
|
1121
|
+
fragments,
|
|
1122
|
+
seenFieldNames,
|
|
1123
|
+
seenFragmentNames,
|
|
1124
|
+
result
|
|
1125
|
+
);
|
|
1126
|
+
}
|
|
1127
|
+
}
|
|
1128
|
+
}
|
|
1129
|
+
}
|
|
764
1130
|
function filterTypenameFields(selections) {
|
|
765
1131
|
let hasTypeNameField = false;
|
|
766
1132
|
const filteredSelections = selections.filter((selection) => {
|
|
@@ -809,15 +1175,17 @@ function collectFragmentVariables(targetSchema, fragmentSet, validFragments, val
|
|
|
809
1175
|
usedVariables = union(usedVariables, fragmentUsedVariables);
|
|
810
1176
|
if (name && !(name in fragmentSet)) {
|
|
811
1177
|
fragmentSet[name] = true;
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
1178
|
+
if (selectionSet.selections.length > 0) {
|
|
1179
|
+
newFragments.push({
|
|
1180
|
+
kind: graphql.Kind.FRAGMENT_DEFINITION,
|
|
1181
|
+
name: {
|
|
1182
|
+
kind: graphql.Kind.NAME,
|
|
1183
|
+
value: name
|
|
1184
|
+
},
|
|
1185
|
+
typeCondition: fragment.typeCondition,
|
|
1186
|
+
selectionSet
|
|
1187
|
+
});
|
|
1188
|
+
}
|
|
821
1189
|
}
|
|
822
1190
|
}
|
|
823
1191
|
}
|
|
@@ -1976,6 +2344,7 @@ function createRequest({
|
|
|
1976
2344
|
const newVariables = info?.variableValues ? { ...info.variableValues } : {};
|
|
1977
2345
|
const variableDefinitions = info?.operation.variableDefinitions ? [...info.operation.variableDefinitions] : [];
|
|
1978
2346
|
const argNodes = [];
|
|
2347
|
+
const replacedVariableNames = /* @__PURE__ */ new Set();
|
|
1979
2348
|
if (args != null) {
|
|
1980
2349
|
const rootType = targetSchema != null ? utils.getDefinedRootType(targetSchema, targetOperation) : void 0;
|
|
1981
2350
|
const rootField = rootType?.getFields()[rootFieldName];
|
|
@@ -1986,10 +2355,22 @@ function createRequest({
|
|
|
1986
2355
|
const existingArgNode = fieldNode?.arguments?.find(
|
|
1987
2356
|
(argNode) => argNode.name.value === argName
|
|
1988
2357
|
);
|
|
2358
|
+
if (existingArgNode && !argInstance) {
|
|
2359
|
+
argNodes.push(existingArgNode);
|
|
2360
|
+
continue;
|
|
2361
|
+
}
|
|
1989
2362
|
if (existingArgNode?.value.kind === graphql.Kind.VARIABLE) {
|
|
1990
2363
|
const varName = existingArgNode.value.name.value;
|
|
1991
2364
|
const varValue = newVariables[varName];
|
|
1992
|
-
|
|
2365
|
+
const variableDefinition = variableDefinitions.find(
|
|
2366
|
+
(definition) => definition.variable.name.value === varName
|
|
2367
|
+
);
|
|
2368
|
+
const variableType = variableDefinition && targetSchema ? graphql.typeFromAST(info?.schema ?? targetSchema, variableDefinition.type) : void 0;
|
|
2369
|
+
if (varValue === argValue && variableType && argInstance && graphql.isTypeSubTypeOf(
|
|
2370
|
+
info?.schema ?? targetSchema,
|
|
2371
|
+
variableType,
|
|
2372
|
+
argInstance.type
|
|
2373
|
+
)) {
|
|
1993
2374
|
argNodes.push(existingArgNode);
|
|
1994
2375
|
continue;
|
|
1995
2376
|
}
|
|
@@ -2010,6 +2391,9 @@ function createRequest({
|
|
|
2010
2391
|
varName = `_${i++}_${rootFieldName}_${argName}`;
|
|
2011
2392
|
}
|
|
2012
2393
|
}
|
|
2394
|
+
if (existingArgNode?.value.kind === graphql.Kind.VARIABLE) {
|
|
2395
|
+
replacedVariableNames.add(existingArgNode.value.name.value);
|
|
2396
|
+
}
|
|
2013
2397
|
variableDefinitions.push({
|
|
2014
2398
|
kind: graphql.Kind.VARIABLE_DEFINITION,
|
|
2015
2399
|
variable: {
|
|
@@ -2086,6 +2470,26 @@ function createRequest({
|
|
|
2086
2470
|
kind: graphql.Kind.DOCUMENT,
|
|
2087
2471
|
definitions
|
|
2088
2472
|
};
|
|
2473
|
+
if (replacedVariableNames.size > 0) {
|
|
2474
|
+
const usedVariableNames = /* @__PURE__ */ new Set();
|
|
2475
|
+
graphql.visit(document, {
|
|
2476
|
+
VariableDefinition: () => false,
|
|
2477
|
+
Variable: (variableNode) => {
|
|
2478
|
+
usedVariableNames.add(variableNode.name.value);
|
|
2479
|
+
}
|
|
2480
|
+
});
|
|
2481
|
+
for (const variableName of replacedVariableNames) {
|
|
2482
|
+
if (!usedVariableNames.has(variableName)) {
|
|
2483
|
+
const variableIndex = variableDefinitions.findIndex(
|
|
2484
|
+
(definition) => definition.variable.name.value === variableName
|
|
2485
|
+
);
|
|
2486
|
+
if (variableIndex !== -1) {
|
|
2487
|
+
variableDefinitions.splice(variableIndex, 1);
|
|
2488
|
+
delete newVariables[variableName];
|
|
2489
|
+
}
|
|
2490
|
+
}
|
|
2491
|
+
}
|
|
2492
|
+
}
|
|
2089
2493
|
return {
|
|
2090
2494
|
subgraphName,
|
|
2091
2495
|
document,
|
|
@@ -2181,6 +2585,9 @@ function defaultMergedResolver(parent, args, context, info) {
|
|
|
2181
2585
|
}
|
|
2182
2586
|
return deferred.promise;
|
|
2183
2587
|
}
|
|
2588
|
+
if (Object.prototype.hasOwnProperty.call(parent, info.fieldName)) {
|
|
2589
|
+
return graphql.defaultFieldResolver(parent, args, context, info);
|
|
2590
|
+
}
|
|
2184
2591
|
return void 0;
|
|
2185
2592
|
}
|
|
2186
2593
|
return handleResult(parent, responseKey, context, info);
|
|
@@ -2606,10 +3013,11 @@ function delegateToSchema(options) {
|
|
|
2606
3013
|
}
|
|
2607
3014
|
}
|
|
2608
3015
|
const fragments = info ? getFragmentDefinitions(info) : void 0;
|
|
3016
|
+
const targetRootType = operation === graphql.OperationTypeNode.MUTATION ? targetSchema.getMutationType() : operation === graphql.OperationTypeNode.SUBSCRIPTION ? targetSchema.getSubscriptionType() : targetSchema.getQueryType();
|
|
2609
3017
|
const request = createRequest({
|
|
2610
3018
|
subgraphName: schema.name,
|
|
2611
3019
|
fragments,
|
|
2612
|
-
targetSchema,
|
|
3020
|
+
targetSchema: targetRootType?.getFields()[fieldName] == null && isSubschemaConfig(schema) ? schema.schema : targetSchema,
|
|
2613
3021
|
rootValue,
|
|
2614
3022
|
targetOperationName: operationName,
|
|
2615
3023
|
targetOperation: operation,
|
|
@@ -2647,9 +3055,9 @@ function delegateRequest(options) {
|
|
|
2647
3055
|
() => getExecutor(delegationContext)(processedRequest),
|
|
2648
3056
|
function handleExecutorResult(executorResult) {
|
|
2649
3057
|
if (utils.isAsyncIterable(executorResult)) {
|
|
2650
|
-
if (delegationContext.operation === "query" && graphql.isListType(delegationContext.returnType)) {
|
|
3058
|
+
if (delegationContext.operation === "query" && graphql.isListType(graphql.getNullableType(delegationContext.returnType))) {
|
|
2651
3059
|
return new repeater.Repeater(async (push, stop) => {
|
|
2652
|
-
|
|
3060
|
+
let pushedCount = 0;
|
|
2653
3061
|
let stopped = false;
|
|
2654
3062
|
stop.finally(() => {
|
|
2655
3063
|
stopped = true;
|
|
@@ -2681,15 +3089,12 @@ function delegateRequest(options) {
|
|
|
2681
3089
|
}
|
|
2682
3090
|
const transformedResult = await transformer.transformResult(result);
|
|
2683
3091
|
if (Array.isArray(transformedResult)) {
|
|
2684
|
-
for (
|
|
3092
|
+
for (let i = pushedCount; i < transformedResult.length; i++) {
|
|
2685
3093
|
if (stopped) {
|
|
2686
3094
|
break;
|
|
2687
3095
|
}
|
|
2688
|
-
|
|
2689
|
-
|
|
2690
|
-
pushed.add(individualResult);
|
|
2691
|
-
await push(individualResult);
|
|
2692
|
-
}
|
|
3096
|
+
await push(await transformedResult[i]);
|
|
3097
|
+
pushedCount = i + 1;
|
|
2693
3098
|
}
|
|
2694
3099
|
} else {
|
|
2695
3100
|
await push(await transformedResult);
|
|
@@ -2765,7 +3170,9 @@ function getDelegationContext({
|
|
|
2765
3170
|
),
|
|
2766
3171
|
transforms,
|
|
2767
3172
|
transformedSchema: transformedSchema ?? subschemaOrSubschemaConfig,
|
|
2768
|
-
skipTypeMerging
|
|
3173
|
+
skipTypeMerging,
|
|
3174
|
+
onLocatedError,
|
|
3175
|
+
args
|
|
2769
3176
|
};
|
|
2770
3177
|
}
|
|
2771
3178
|
function validateRequest(delegationContext, document) {
|
|
@@ -2896,6 +3303,7 @@ function extractUnavailableFieldsFromSelectionSet(schema, fieldType, fieldSelect
|
|
|
2896
3303
|
});
|
|
2897
3304
|
}
|
|
2898
3305
|
} else if (graphql.isObjectType(subFieldType) || graphql.isInterfaceType(subFieldType)) {
|
|
3306
|
+
const unavailableSubSelections = [];
|
|
2899
3307
|
const subFieldTypeFields = subFieldType.getFields();
|
|
2900
3308
|
for (const subSelection of selection.selectionSet.selections) {
|
|
2901
3309
|
if (subSelection.kind === graphql.Kind.FIELD) {
|
|
@@ -2906,11 +3314,20 @@ function extractUnavailableFieldsFromSelectionSet(schema, fieldType, fieldSelect
|
|
|
2906
3314
|
const subSelectionField = subFieldTypeFields[subSelection.name.value];
|
|
2907
3315
|
if (!subSelectionField) {
|
|
2908
3316
|
if (shouldAdd(subFieldType, subSelection)) {
|
|
2909
|
-
|
|
3317
|
+
unavailableSubSelections.push(subSelection);
|
|
2910
3318
|
}
|
|
2911
3319
|
}
|
|
2912
3320
|
}
|
|
2913
3321
|
}
|
|
3322
|
+
if (unavailableSubSelections.length) {
|
|
3323
|
+
unavailableSelections.push({
|
|
3324
|
+
...selection,
|
|
3325
|
+
selectionSet: {
|
|
3326
|
+
kind: graphql.Kind.SELECTION_SET,
|
|
3327
|
+
selections: unavailableSubSelections
|
|
3328
|
+
}
|
|
3329
|
+
});
|
|
3330
|
+
}
|
|
2914
3331
|
}
|
|
2915
3332
|
} else if (selection.kind === graphql.Kind.FRAGMENT_SPREAD) {
|
|
2916
3333
|
const fragment = fragments[selection.name.value];
|
|
@@ -2958,7 +3375,7 @@ function extractUnavailableFields(schema, field, fieldNode, shouldAdd, fragments
|
|
|
2958
3375
|
}
|
|
2959
3376
|
return [];
|
|
2960
3377
|
}
|
|
2961
|
-
function subtractSelectionSets(selectionSetA, selectionSetB) {
|
|
3378
|
+
function subtractSelectionSets(selectionSetA, selectionSetB, fragments = {}) {
|
|
2962
3379
|
const newSelections = [];
|
|
2963
3380
|
for (const selectionA of selectionSetA.selections) {
|
|
2964
3381
|
switch (selectionA.kind) {
|
|
@@ -2974,7 +3391,7 @@ function subtractSelectionSets(selectionSetA, selectionSetB) {
|
|
|
2974
3391
|
);
|
|
2975
3392
|
if (fieldsInOtherSelectionSet.length > 0 && fieldA.selectionSet?.selections?.length) {
|
|
2976
3393
|
const newSubSelection = fieldsInOtherSelectionSet.reduce(
|
|
2977
|
-
(acc, fieldB) => fieldB.selectionSet ? subtractSelectionSets(acc, fieldB.selectionSet) : acc,
|
|
3394
|
+
(acc, fieldB) => fieldB.selectionSet ? subtractSelectionSets(acc, fieldB.selectionSet, fragments) : acc,
|
|
2978
3395
|
{
|
|
2979
3396
|
kind: graphql.Kind.SELECTION_SET,
|
|
2980
3397
|
selections: fieldA.selectionSet.selections
|
|
@@ -3004,7 +3421,11 @@ function subtractSelectionSets(selectionSetA, selectionSetB) {
|
|
|
3004
3421
|
);
|
|
3005
3422
|
if (inlineFragmentsFromB.length > 0) {
|
|
3006
3423
|
const newSubSelection = inlineFragmentsFromB.reduce(
|
|
3007
|
-
(acc, subselectionB) => subselectionB.selectionSet ? subtractSelectionSets(
|
|
3424
|
+
(acc, subselectionB) => subselectionB.selectionSet ? subtractSelectionSets(
|
|
3425
|
+
acc,
|
|
3426
|
+
subselectionB.selectionSet,
|
|
3427
|
+
fragments
|
|
3428
|
+
) : acc,
|
|
3008
3429
|
{
|
|
3009
3430
|
kind: graphql.Kind.SELECTION_SET,
|
|
3010
3431
|
selections: inlineFragmentA.selectionSet.selections
|
|
@@ -3032,7 +3453,25 @@ function subtractSelectionSets(selectionSetA, selectionSetB) {
|
|
|
3032
3453
|
}
|
|
3033
3454
|
case graphql.Kind.FRAGMENT_SPREAD: {
|
|
3034
3455
|
const fragmentSpreadA = selectionA;
|
|
3035
|
-
|
|
3456
|
+
const fragment = fragments[fragmentSpreadA.name.value];
|
|
3457
|
+
if (fragment) {
|
|
3458
|
+
const newSubSelection = subtractSelectionSets(
|
|
3459
|
+
fragment.selectionSet,
|
|
3460
|
+
selectionSetB,
|
|
3461
|
+
fragments
|
|
3462
|
+
);
|
|
3463
|
+
if (newSubSelection.selections.length) {
|
|
3464
|
+
newSelections.push({
|
|
3465
|
+
kind: graphql.Kind.INLINE_FRAGMENT,
|
|
3466
|
+
typeCondition: fragment.typeCondition,
|
|
3467
|
+
directives: [
|
|
3468
|
+
...fragment.directives ?? [],
|
|
3469
|
+
...fragmentSpreadA.directives ?? []
|
|
3470
|
+
],
|
|
3471
|
+
selectionSet: newSubSelection
|
|
3472
|
+
});
|
|
3473
|
+
}
|
|
3474
|
+
} else if (!selectionSetB.selections.some(
|
|
3036
3475
|
(subselectionB) => subselectionB.kind === graphql.Kind.FRAGMENT_SPREAD && subselectionB.name.value === fragmentSpreadA.name.value
|
|
3037
3476
|
)) {
|
|
3038
3477
|
newSelections.push(selectionA);
|