@depup/graphql-tools__delegate 12.0.13-depup.0 → 12.1.0-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 +470 -50
- package/dist/index.d.cts +4 -2
- package/dist/index.d.ts +4 -2
- package/dist/index.js +471 -51
- 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
|
}
|
|
@@ -1986,10 +2354,18 @@ function createRequest({
|
|
|
1986
2354
|
const existingArgNode = fieldNode?.arguments?.find(
|
|
1987
2355
|
(argNode) => argNode.name.value === argName
|
|
1988
2356
|
);
|
|
1989
|
-
if (existingArgNode?.value.kind === graphql.Kind.VARIABLE) {
|
|
2357
|
+
if (existingArgNode?.value.kind === graphql.Kind.VARIABLE && argInstance) {
|
|
1990
2358
|
const varName = existingArgNode.value.name.value;
|
|
1991
2359
|
const varValue = newVariables[varName];
|
|
1992
|
-
|
|
2360
|
+
const variableDefinition = variableDefinitions.find(
|
|
2361
|
+
(definition) => definition.variable.name.value === varName
|
|
2362
|
+
);
|
|
2363
|
+
const variableType = variableDefinition && targetSchema ? graphql.typeFromAST(info?.schema ?? targetSchema, variableDefinition.type) : void 0;
|
|
2364
|
+
if (varValue === argValue && variableType && graphql.isTypeSubTypeOf(
|
|
2365
|
+
info?.schema ?? targetSchema,
|
|
2366
|
+
variableType,
|
|
2367
|
+
argInstance.type
|
|
2368
|
+
)) {
|
|
1993
2369
|
argNodes.push(existingArgNode);
|
|
1994
2370
|
continue;
|
|
1995
2371
|
}
|
|
@@ -2010,6 +2386,16 @@ function createRequest({
|
|
|
2010
2386
|
varName = `_${i++}_${rootFieldName}_${argName}`;
|
|
2011
2387
|
}
|
|
2012
2388
|
}
|
|
2389
|
+
if (existingArgNode?.value.kind === graphql.Kind.VARIABLE) {
|
|
2390
|
+
const existingVarName = existingArgNode.value.name.value;
|
|
2391
|
+
const existingVarIndex = variableDefinitions.findIndex(
|
|
2392
|
+
(definition) => definition.variable.name.value === existingVarName
|
|
2393
|
+
);
|
|
2394
|
+
if (existingVarIndex !== -1) {
|
|
2395
|
+
variableDefinitions.splice(existingVarIndex, 1);
|
|
2396
|
+
delete newVariables[existingVarName];
|
|
2397
|
+
}
|
|
2398
|
+
}
|
|
2013
2399
|
variableDefinitions.push({
|
|
2014
2400
|
kind: graphql.Kind.VARIABLE_DEFINITION,
|
|
2015
2401
|
variable: {
|
|
@@ -2181,6 +2567,9 @@ function defaultMergedResolver(parent, args, context, info) {
|
|
|
2181
2567
|
}
|
|
2182
2568
|
return deferred.promise;
|
|
2183
2569
|
}
|
|
2570
|
+
if (Object.prototype.hasOwnProperty.call(parent, info.fieldName)) {
|
|
2571
|
+
return graphql.defaultFieldResolver(parent, args, context, info);
|
|
2572
|
+
}
|
|
2184
2573
|
return void 0;
|
|
2185
2574
|
}
|
|
2186
2575
|
return handleResult(parent, responseKey, context, info);
|
|
@@ -2609,7 +2998,7 @@ function delegateToSchema(options) {
|
|
|
2609
2998
|
const request = createRequest({
|
|
2610
2999
|
subgraphName: schema.name,
|
|
2611
3000
|
fragments,
|
|
2612
|
-
targetSchema,
|
|
3001
|
+
targetSchema: targetSchema.getQueryType()?.getFields()[fieldName] == null && isSubschemaConfig(schema) ? schema.schema : targetSchema,
|
|
2613
3002
|
rootValue,
|
|
2614
3003
|
targetOperationName: operationName,
|
|
2615
3004
|
targetOperation: operation,
|
|
@@ -2647,9 +3036,9 @@ function delegateRequest(options) {
|
|
|
2647
3036
|
() => getExecutor(delegationContext)(processedRequest),
|
|
2648
3037
|
function handleExecutorResult(executorResult) {
|
|
2649
3038
|
if (utils.isAsyncIterable(executorResult)) {
|
|
2650
|
-
if (delegationContext.operation === "query" && graphql.isListType(delegationContext.returnType)) {
|
|
3039
|
+
if (delegationContext.operation === "query" && graphql.isListType(graphql.getNullableType(delegationContext.returnType))) {
|
|
2651
3040
|
return new repeater.Repeater(async (push, stop) => {
|
|
2652
|
-
|
|
3041
|
+
let pushedCount = 0;
|
|
2653
3042
|
let stopped = false;
|
|
2654
3043
|
stop.finally(() => {
|
|
2655
3044
|
stopped = true;
|
|
@@ -2681,15 +3070,12 @@ function delegateRequest(options) {
|
|
|
2681
3070
|
}
|
|
2682
3071
|
const transformedResult = await transformer.transformResult(result);
|
|
2683
3072
|
if (Array.isArray(transformedResult)) {
|
|
2684
|
-
for (
|
|
3073
|
+
for (let i = pushedCount; i < transformedResult.length; i++) {
|
|
2685
3074
|
if (stopped) {
|
|
2686
3075
|
break;
|
|
2687
3076
|
}
|
|
2688
|
-
|
|
2689
|
-
|
|
2690
|
-
pushed.add(individualResult);
|
|
2691
|
-
await push(individualResult);
|
|
2692
|
-
}
|
|
3077
|
+
await push(await transformedResult[i]);
|
|
3078
|
+
pushedCount = i + 1;
|
|
2693
3079
|
}
|
|
2694
3080
|
} else {
|
|
2695
3081
|
await push(await transformedResult);
|
|
@@ -2765,7 +3151,9 @@ function getDelegationContext({
|
|
|
2765
3151
|
),
|
|
2766
3152
|
transforms,
|
|
2767
3153
|
transformedSchema: transformedSchema ?? subschemaOrSubschemaConfig,
|
|
2768
|
-
skipTypeMerging
|
|
3154
|
+
skipTypeMerging,
|
|
3155
|
+
onLocatedError,
|
|
3156
|
+
args
|
|
2769
3157
|
};
|
|
2770
3158
|
}
|
|
2771
3159
|
function validateRequest(delegationContext, document) {
|
|
@@ -2896,6 +3284,7 @@ function extractUnavailableFieldsFromSelectionSet(schema, fieldType, fieldSelect
|
|
|
2896
3284
|
});
|
|
2897
3285
|
}
|
|
2898
3286
|
} else if (graphql.isObjectType(subFieldType) || graphql.isInterfaceType(subFieldType)) {
|
|
3287
|
+
const unavailableSubSelections = [];
|
|
2899
3288
|
const subFieldTypeFields = subFieldType.getFields();
|
|
2900
3289
|
for (const subSelection of selection.selectionSet.selections) {
|
|
2901
3290
|
if (subSelection.kind === graphql.Kind.FIELD) {
|
|
@@ -2906,11 +3295,20 @@ function extractUnavailableFieldsFromSelectionSet(schema, fieldType, fieldSelect
|
|
|
2906
3295
|
const subSelectionField = subFieldTypeFields[subSelection.name.value];
|
|
2907
3296
|
if (!subSelectionField) {
|
|
2908
3297
|
if (shouldAdd(subFieldType, subSelection)) {
|
|
2909
|
-
|
|
3298
|
+
unavailableSubSelections.push(subSelection);
|
|
2910
3299
|
}
|
|
2911
3300
|
}
|
|
2912
3301
|
}
|
|
2913
3302
|
}
|
|
3303
|
+
if (unavailableSubSelections.length) {
|
|
3304
|
+
unavailableSelections.push({
|
|
3305
|
+
...selection,
|
|
3306
|
+
selectionSet: {
|
|
3307
|
+
kind: graphql.Kind.SELECTION_SET,
|
|
3308
|
+
selections: unavailableSubSelections
|
|
3309
|
+
}
|
|
3310
|
+
});
|
|
3311
|
+
}
|
|
2914
3312
|
}
|
|
2915
3313
|
} else if (selection.kind === graphql.Kind.FRAGMENT_SPREAD) {
|
|
2916
3314
|
const fragment = fragments[selection.name.value];
|
|
@@ -2958,7 +3356,7 @@ function extractUnavailableFields(schema, field, fieldNode, shouldAdd, fragments
|
|
|
2958
3356
|
}
|
|
2959
3357
|
return [];
|
|
2960
3358
|
}
|
|
2961
|
-
function subtractSelectionSets(selectionSetA, selectionSetB) {
|
|
3359
|
+
function subtractSelectionSets(selectionSetA, selectionSetB, fragments = {}) {
|
|
2962
3360
|
const newSelections = [];
|
|
2963
3361
|
for (const selectionA of selectionSetA.selections) {
|
|
2964
3362
|
switch (selectionA.kind) {
|
|
@@ -2974,7 +3372,7 @@ function subtractSelectionSets(selectionSetA, selectionSetB) {
|
|
|
2974
3372
|
);
|
|
2975
3373
|
if (fieldsInOtherSelectionSet.length > 0 && fieldA.selectionSet?.selections?.length) {
|
|
2976
3374
|
const newSubSelection = fieldsInOtherSelectionSet.reduce(
|
|
2977
|
-
(acc, fieldB) => fieldB.selectionSet ? subtractSelectionSets(acc, fieldB.selectionSet) : acc,
|
|
3375
|
+
(acc, fieldB) => fieldB.selectionSet ? subtractSelectionSets(acc, fieldB.selectionSet, fragments) : acc,
|
|
2978
3376
|
{
|
|
2979
3377
|
kind: graphql.Kind.SELECTION_SET,
|
|
2980
3378
|
selections: fieldA.selectionSet.selections
|
|
@@ -3004,7 +3402,11 @@ function subtractSelectionSets(selectionSetA, selectionSetB) {
|
|
|
3004
3402
|
);
|
|
3005
3403
|
if (inlineFragmentsFromB.length > 0) {
|
|
3006
3404
|
const newSubSelection = inlineFragmentsFromB.reduce(
|
|
3007
|
-
(acc, subselectionB) => subselectionB.selectionSet ? subtractSelectionSets(
|
|
3405
|
+
(acc, subselectionB) => subselectionB.selectionSet ? subtractSelectionSets(
|
|
3406
|
+
acc,
|
|
3407
|
+
subselectionB.selectionSet,
|
|
3408
|
+
fragments
|
|
3409
|
+
) : acc,
|
|
3008
3410
|
{
|
|
3009
3411
|
kind: graphql.Kind.SELECTION_SET,
|
|
3010
3412
|
selections: inlineFragmentA.selectionSet.selections
|
|
@@ -3032,7 +3434,25 @@ function subtractSelectionSets(selectionSetA, selectionSetB) {
|
|
|
3032
3434
|
}
|
|
3033
3435
|
case graphql.Kind.FRAGMENT_SPREAD: {
|
|
3034
3436
|
const fragmentSpreadA = selectionA;
|
|
3035
|
-
|
|
3437
|
+
const fragment = fragments[fragmentSpreadA.name.value];
|
|
3438
|
+
if (fragment) {
|
|
3439
|
+
const newSubSelection = subtractSelectionSets(
|
|
3440
|
+
fragment.selectionSet,
|
|
3441
|
+
selectionSetB,
|
|
3442
|
+
fragments
|
|
3443
|
+
);
|
|
3444
|
+
if (newSubSelection.selections.length) {
|
|
3445
|
+
newSelections.push({
|
|
3446
|
+
kind: graphql.Kind.INLINE_FRAGMENT,
|
|
3447
|
+
typeCondition: fragment.typeCondition,
|
|
3448
|
+
directives: [
|
|
3449
|
+
...fragment.directives ?? [],
|
|
3450
|
+
...fragmentSpreadA.directives ?? []
|
|
3451
|
+
],
|
|
3452
|
+
selectionSet: newSubSelection
|
|
3453
|
+
});
|
|
3454
|
+
}
|
|
3455
|
+
} else if (!selectionSetB.selections.some(
|
|
3036
3456
|
(subselectionB) => subselectionB.kind === graphql.Kind.FRAGMENT_SPREAD && subselectionB.name.value === fragmentSpreadA.name.value
|
|
3037
3457
|
)) {
|
|
3038
3458
|
newSelections.push(selectionA);
|