@graphql-tools/delegate 12.0.16 → 12.0.17-alpha-96a4674a514e93d69c299c07916e06f49feed477
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/CHANGELOG.md +26 -0
- package/dist/index.cjs +203 -22
- package/dist/index.js +203 -22
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,31 @@
|
|
|
1
1
|
# @graphql-tools/delegate
|
|
2
2
|
|
|
3
|
+
## 12.0.17-alpha-96a4674a514e93d69c299c07916e06f49feed477
|
|
4
|
+
### Patch Changes
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
- [#2351](https://github.com/graphql-hive/gateway/pull/2351) [`96a4674`](https://github.com/graphql-hive/gateway/commit/96a4674a514e93d69c299c07916e06f49feed477) Thanks [@ardatan](https://github.com/ardatan)! - Fix `@provides` so the gateway only requests the provided fields the client actually selected.
|
|
9
|
+
|
|
10
|
+
Previously, when a subgraph declared `@provides(fields: "...")` on a query field, the gateway would forward **every** field listed in the `@provides` argument to that subgraph, even when the client never asked for those fields. For example with:
|
|
11
|
+
|
|
12
|
+
```graphql
|
|
13
|
+
# subgraph B
|
|
14
|
+
type Query {
|
|
15
|
+
entity: Entity @provides(fields: "name description")
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
type Entity @key(fields: "id") {
|
|
19
|
+
id: ID!
|
|
20
|
+
name: String! @external
|
|
21
|
+
description: String! @external
|
|
22
|
+
}
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
a client query of `{ entity { id name } }` would still cause the gateway to ask subgraph B for `description`. After this fix the gateway only forwards `name` (because that is what the client asked for and what `@provides` allows the subgraph to resolve directly), bringing the behavior in line with Federation's `@provides` semantics where it acts as a hint that the providing subgraph **can** resolve those fields locally — not a directive to always fetch them.
|
|
26
|
+
|
|
27
|
+
Aliases, fragments, fragment spreads, and nested `@provides` selections are preserved.
|
|
28
|
+
|
|
3
29
|
## 12.0.16
|
|
4
30
|
### Patch Changes
|
|
5
31
|
|
package/dist/index.cjs
CHANGED
|
@@ -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 = [];
|
|
@@ -688,37 +688,82 @@ function finalizeGatewayDocument(targetSchema, fragments, operations, onOverlapp
|
|
|
688
688
|
};
|
|
689
689
|
const stitchingInfo = delegationContext.info?.schema?.extensions?.["stitchingInfo"];
|
|
690
690
|
if (stitchingInfo != null) {
|
|
691
|
+
const {
|
|
692
|
+
selectionSetsByPath: originalFieldSelectionSetsByPath,
|
|
693
|
+
fragments: originalFragmentsByName
|
|
694
|
+
} = collectFieldSelectionSetsByPath(originalDocument);
|
|
691
695
|
const typeInfo = getTypeInfo(targetSchema);
|
|
696
|
+
const pathStack = [];
|
|
692
697
|
newDocument = graphql.visit(
|
|
693
698
|
newDocument,
|
|
694
699
|
graphql.visitWithTypeInfo(typeInfo, {
|
|
695
|
-
[graphql.Kind.
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
700
|
+
[graphql.Kind.OPERATION_DEFINITION]: {
|
|
701
|
+
enter(node) {
|
|
702
|
+
pathStack.push(`op:${node.operation}:${node.name?.value ?? ""}`);
|
|
703
|
+
},
|
|
704
|
+
leave() {
|
|
705
|
+
pathStack.pop();
|
|
706
|
+
}
|
|
707
|
+
},
|
|
708
|
+
[graphql.Kind.FRAGMENT_DEFINITION]: {
|
|
709
|
+
enter(node) {
|
|
710
|
+
pathStack.push(`frag:${node.name.value}`);
|
|
711
|
+
},
|
|
712
|
+
leave() {
|
|
713
|
+
pathStack.pop();
|
|
714
|
+
}
|
|
715
|
+
},
|
|
716
|
+
[graphql.Kind.INLINE_FRAGMENT]: {
|
|
717
|
+
enter(node) {
|
|
718
|
+
pathStack.push(`inline:${node.typeCondition?.name.value ?? ""}`);
|
|
719
|
+
},
|
|
720
|
+
leave() {
|
|
721
|
+
pathStack.pop();
|
|
722
|
+
}
|
|
723
|
+
},
|
|
724
|
+
[graphql.Kind.FIELD]: {
|
|
725
|
+
enter(fieldNode) {
|
|
726
|
+
pathStack.push(fieldNode.alias?.value ?? fieldNode.name.value);
|
|
727
|
+
},
|
|
728
|
+
leave(fieldNode) {
|
|
729
|
+
try {
|
|
730
|
+
const parentType = typeInfo.getParentType();
|
|
731
|
+
if (!parentType) {
|
|
732
|
+
return void 0;
|
|
733
|
+
}
|
|
734
|
+
const typeConfig = stitchingInfo?.mergedTypes?.[parentType.name];
|
|
701
735
|
const providedSelectionsByField = typeConfig?.providedSelectionsByField?.get(
|
|
702
736
|
delegationContext.subschema
|
|
703
737
|
);
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
738
|
+
const providedSelection = providedSelectionsByField?.[fieldNode.name.value];
|
|
739
|
+
if (!providedSelection) {
|
|
740
|
+
return void 0;
|
|
741
|
+
}
|
|
742
|
+
const originalSelectionSet = originalFieldSelectionSetsByPath.get(
|
|
743
|
+
pathStack.join(">")
|
|
744
|
+
);
|
|
745
|
+
const requestedProvidedSelections = intersectProvidedSelections(
|
|
746
|
+
providedSelection.selections,
|
|
747
|
+
originalSelectionSet,
|
|
748
|
+
originalFragmentsByName
|
|
749
|
+
);
|
|
750
|
+
if (!requestedProvidedSelections.length) {
|
|
751
|
+
return void 0;
|
|
718
752
|
}
|
|
753
|
+
return {
|
|
754
|
+
...fieldNode,
|
|
755
|
+
selectionSet: {
|
|
756
|
+
kind: graphql.Kind.SELECTION_SET,
|
|
757
|
+
selections: [
|
|
758
|
+
...requestedProvidedSelections,
|
|
759
|
+
...fieldNode.selectionSet?.selections ?? []
|
|
760
|
+
]
|
|
761
|
+
}
|
|
762
|
+
};
|
|
763
|
+
} finally {
|
|
764
|
+
pathStack.pop();
|
|
719
765
|
}
|
|
720
766
|
}
|
|
721
|
-
return fieldNode;
|
|
722
767
|
}
|
|
723
768
|
})
|
|
724
769
|
);
|
|
@@ -733,6 +778,7 @@ function finalizeGatewayRequest(originalRequest, delegationContext, onOverlappin
|
|
|
733
778
|
const { targetSchema } = delegationContext;
|
|
734
779
|
const { usedVariables, newDocument } = finalizeGatewayDocument(
|
|
735
780
|
targetSchema,
|
|
781
|
+
originalRequest.document,
|
|
736
782
|
fragments,
|
|
737
783
|
operations,
|
|
738
784
|
onOverlappingAliases,
|
|
@@ -761,6 +807,141 @@ function finalizeGatewayRequest(originalRequest, delegationContext, onOverlappin
|
|
|
761
807
|
function isTypeNameField(selection) {
|
|
762
808
|
return selection.kind === graphql.Kind.FIELD && !selection.alias && selection.name.value === "__typename";
|
|
763
809
|
}
|
|
810
|
+
function collectFieldSelectionSetsByPath(document) {
|
|
811
|
+
const selectionSetsByPath = /* @__PURE__ */ new Map();
|
|
812
|
+
const fragments = /* @__PURE__ */ new Map();
|
|
813
|
+
for (const def of document.definitions) {
|
|
814
|
+
if (def.kind === graphql.Kind.FRAGMENT_DEFINITION) {
|
|
815
|
+
fragments.set(def.name.value, def);
|
|
816
|
+
}
|
|
817
|
+
}
|
|
818
|
+
const pathStack = [];
|
|
819
|
+
graphql.visit(document, {
|
|
820
|
+
[graphql.Kind.OPERATION_DEFINITION]: {
|
|
821
|
+
enter(node) {
|
|
822
|
+
pathStack.push(`op:${node.operation}:${node.name?.value ?? ""}`);
|
|
823
|
+
},
|
|
824
|
+
leave() {
|
|
825
|
+
pathStack.pop();
|
|
826
|
+
}
|
|
827
|
+
},
|
|
828
|
+
[graphql.Kind.FRAGMENT_DEFINITION]: {
|
|
829
|
+
enter(node) {
|
|
830
|
+
pathStack.push(`frag:${node.name.value}`);
|
|
831
|
+
},
|
|
832
|
+
leave() {
|
|
833
|
+
pathStack.pop();
|
|
834
|
+
}
|
|
835
|
+
},
|
|
836
|
+
[graphql.Kind.INLINE_FRAGMENT]: {
|
|
837
|
+
enter(node) {
|
|
838
|
+
pathStack.push(`inline:${node.typeCondition?.name.value ?? ""}`);
|
|
839
|
+
},
|
|
840
|
+
leave() {
|
|
841
|
+
pathStack.pop();
|
|
842
|
+
}
|
|
843
|
+
},
|
|
844
|
+
[graphql.Kind.FIELD]: {
|
|
845
|
+
enter(node) {
|
|
846
|
+
pathStack.push(node.alias?.value ?? node.name.value);
|
|
847
|
+
if (node.selectionSet) {
|
|
848
|
+
selectionSetsByPath.set(pathStack.join(">"), node.selectionSet);
|
|
849
|
+
}
|
|
850
|
+
},
|
|
851
|
+
leave() {
|
|
852
|
+
pathStack.pop();
|
|
853
|
+
}
|
|
854
|
+
}
|
|
855
|
+
});
|
|
856
|
+
return { selectionSetsByPath, fragments };
|
|
857
|
+
}
|
|
858
|
+
function intersectProvidedSelections(providedSelections, originalSelectionSet, fragments) {
|
|
859
|
+
if (!originalSelectionSet) {
|
|
860
|
+
return [];
|
|
861
|
+
}
|
|
862
|
+
const providedFieldsByName = /* @__PURE__ */ new Map();
|
|
863
|
+
const otherProvided = [];
|
|
864
|
+
for (const provided of providedSelections) {
|
|
865
|
+
if (provided.kind === graphql.Kind.FIELD) {
|
|
866
|
+
providedFieldsByName.set(provided.name.value, provided);
|
|
867
|
+
} else {
|
|
868
|
+
otherProvided.push(provided);
|
|
869
|
+
}
|
|
870
|
+
}
|
|
871
|
+
const result = [];
|
|
872
|
+
const seenFieldNames = /* @__PURE__ */ new Set();
|
|
873
|
+
const seenFragmentNames = /* @__PURE__ */ new Set();
|
|
874
|
+
collectMatchingOriginalSelections(
|
|
875
|
+
originalSelectionSet,
|
|
876
|
+
providedFieldsByName,
|
|
877
|
+
fragments,
|
|
878
|
+
seenFieldNames,
|
|
879
|
+
seenFragmentNames,
|
|
880
|
+
result
|
|
881
|
+
);
|
|
882
|
+
return [...result, ...otherProvided];
|
|
883
|
+
}
|
|
884
|
+
function collectMatchingOriginalSelections(selectionSet, providedFieldsByName, fragments, seenFieldNames, seenFragmentNames, result) {
|
|
885
|
+
for (const sel of selectionSet.selections) {
|
|
886
|
+
if (sel.kind === graphql.Kind.FIELD) {
|
|
887
|
+
const provided = providedFieldsByName.get(sel.name.value);
|
|
888
|
+
if (!provided) {
|
|
889
|
+
continue;
|
|
890
|
+
}
|
|
891
|
+
const dedupKey = sel.alias?.value ?? sel.name.value;
|
|
892
|
+
if (seenFieldNames.has(dedupKey)) {
|
|
893
|
+
continue;
|
|
894
|
+
}
|
|
895
|
+
seenFieldNames.add(dedupKey);
|
|
896
|
+
if (provided.selectionSet && sel.selectionSet) {
|
|
897
|
+
const nested = intersectProvidedSelections(
|
|
898
|
+
provided.selectionSet.selections,
|
|
899
|
+
sel.selectionSet,
|
|
900
|
+
fragments
|
|
901
|
+
);
|
|
902
|
+
if (!nested.length) {
|
|
903
|
+
continue;
|
|
904
|
+
}
|
|
905
|
+
result.push({
|
|
906
|
+
...sel,
|
|
907
|
+
selectionSet: {
|
|
908
|
+
kind: graphql.Kind.SELECTION_SET,
|
|
909
|
+
selections: nested
|
|
910
|
+
}
|
|
911
|
+
});
|
|
912
|
+
} else {
|
|
913
|
+
result.push(sel);
|
|
914
|
+
}
|
|
915
|
+
} else if (sel.kind === graphql.Kind.INLINE_FRAGMENT && sel.selectionSet) {
|
|
916
|
+
collectMatchingOriginalSelections(
|
|
917
|
+
sel.selectionSet,
|
|
918
|
+
providedFieldsByName,
|
|
919
|
+
fragments,
|
|
920
|
+
seenFieldNames,
|
|
921
|
+
seenFragmentNames,
|
|
922
|
+
result
|
|
923
|
+
);
|
|
924
|
+
} else if (sel.kind === graphql.Kind.FRAGMENT_SPREAD) {
|
|
925
|
+
const fragmentName = sel.name.value;
|
|
926
|
+
if (seenFragmentNames.has(fragmentName)) {
|
|
927
|
+
continue;
|
|
928
|
+
}
|
|
929
|
+
seenFragmentNames.add(fragmentName);
|
|
930
|
+
const fragmentDef = fragments.get(fragmentName);
|
|
931
|
+
if (!fragmentDef) {
|
|
932
|
+
continue;
|
|
933
|
+
}
|
|
934
|
+
collectMatchingOriginalSelections(
|
|
935
|
+
fragmentDef.selectionSet,
|
|
936
|
+
providedFieldsByName,
|
|
937
|
+
fragments,
|
|
938
|
+
seenFieldNames,
|
|
939
|
+
seenFragmentNames,
|
|
940
|
+
result
|
|
941
|
+
);
|
|
942
|
+
}
|
|
943
|
+
}
|
|
944
|
+
}
|
|
764
945
|
function filterTypenameFields(selections) {
|
|
765
946
|
let hasTypeNameField = false;
|
|
766
947
|
const filteredSelections = selections.filter((selection) => {
|
package/dist/index.js
CHANGED
|
@@ -590,7 +590,7 @@ const handleOverrideByDelegation = 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 = [];
|
|
@@ -688,37 +688,82 @@ function finalizeGatewayDocument(targetSchema, fragments, operations, onOverlapp
|
|
|
688
688
|
};
|
|
689
689
|
const stitchingInfo = delegationContext.info?.schema?.extensions?.["stitchingInfo"];
|
|
690
690
|
if (stitchingInfo != null) {
|
|
691
|
+
const {
|
|
692
|
+
selectionSetsByPath: originalFieldSelectionSetsByPath,
|
|
693
|
+
fragments: originalFragmentsByName
|
|
694
|
+
} = collectFieldSelectionSetsByPath(originalDocument);
|
|
691
695
|
const typeInfo = getTypeInfo(targetSchema);
|
|
696
|
+
const pathStack = [];
|
|
692
697
|
newDocument = visit(
|
|
693
698
|
newDocument,
|
|
694
699
|
visitWithTypeInfo(typeInfo, {
|
|
695
|
-
[Kind.
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
700
|
+
[Kind.OPERATION_DEFINITION]: {
|
|
701
|
+
enter(node) {
|
|
702
|
+
pathStack.push(`op:${node.operation}:${node.name?.value ?? ""}`);
|
|
703
|
+
},
|
|
704
|
+
leave() {
|
|
705
|
+
pathStack.pop();
|
|
706
|
+
}
|
|
707
|
+
},
|
|
708
|
+
[Kind.FRAGMENT_DEFINITION]: {
|
|
709
|
+
enter(node) {
|
|
710
|
+
pathStack.push(`frag:${node.name.value}`);
|
|
711
|
+
},
|
|
712
|
+
leave() {
|
|
713
|
+
pathStack.pop();
|
|
714
|
+
}
|
|
715
|
+
},
|
|
716
|
+
[Kind.INLINE_FRAGMENT]: {
|
|
717
|
+
enter(node) {
|
|
718
|
+
pathStack.push(`inline:${node.typeCondition?.name.value ?? ""}`);
|
|
719
|
+
},
|
|
720
|
+
leave() {
|
|
721
|
+
pathStack.pop();
|
|
722
|
+
}
|
|
723
|
+
},
|
|
724
|
+
[Kind.FIELD]: {
|
|
725
|
+
enter(fieldNode) {
|
|
726
|
+
pathStack.push(fieldNode.alias?.value ?? fieldNode.name.value);
|
|
727
|
+
},
|
|
728
|
+
leave(fieldNode) {
|
|
729
|
+
try {
|
|
730
|
+
const parentType = typeInfo.getParentType();
|
|
731
|
+
if (!parentType) {
|
|
732
|
+
return void 0;
|
|
733
|
+
}
|
|
734
|
+
const typeConfig = stitchingInfo?.mergedTypes?.[parentType.name];
|
|
701
735
|
const providedSelectionsByField = typeConfig?.providedSelectionsByField?.get(
|
|
702
736
|
delegationContext.subschema
|
|
703
737
|
);
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
738
|
+
const providedSelection = providedSelectionsByField?.[fieldNode.name.value];
|
|
739
|
+
if (!providedSelection) {
|
|
740
|
+
return void 0;
|
|
741
|
+
}
|
|
742
|
+
const originalSelectionSet = originalFieldSelectionSetsByPath.get(
|
|
743
|
+
pathStack.join(">")
|
|
744
|
+
);
|
|
745
|
+
const requestedProvidedSelections = intersectProvidedSelections(
|
|
746
|
+
providedSelection.selections,
|
|
747
|
+
originalSelectionSet,
|
|
748
|
+
originalFragmentsByName
|
|
749
|
+
);
|
|
750
|
+
if (!requestedProvidedSelections.length) {
|
|
751
|
+
return void 0;
|
|
718
752
|
}
|
|
753
|
+
return {
|
|
754
|
+
...fieldNode,
|
|
755
|
+
selectionSet: {
|
|
756
|
+
kind: Kind.SELECTION_SET,
|
|
757
|
+
selections: [
|
|
758
|
+
...requestedProvidedSelections,
|
|
759
|
+
...fieldNode.selectionSet?.selections ?? []
|
|
760
|
+
]
|
|
761
|
+
}
|
|
762
|
+
};
|
|
763
|
+
} finally {
|
|
764
|
+
pathStack.pop();
|
|
719
765
|
}
|
|
720
766
|
}
|
|
721
|
-
return fieldNode;
|
|
722
767
|
}
|
|
723
768
|
})
|
|
724
769
|
);
|
|
@@ -733,6 +778,7 @@ function finalizeGatewayRequest(originalRequest, delegationContext, onOverlappin
|
|
|
733
778
|
const { targetSchema } = delegationContext;
|
|
734
779
|
const { usedVariables, newDocument } = finalizeGatewayDocument(
|
|
735
780
|
targetSchema,
|
|
781
|
+
originalRequest.document,
|
|
736
782
|
fragments,
|
|
737
783
|
operations,
|
|
738
784
|
onOverlappingAliases,
|
|
@@ -761,6 +807,141 @@ function finalizeGatewayRequest(originalRequest, delegationContext, onOverlappin
|
|
|
761
807
|
function isTypeNameField(selection) {
|
|
762
808
|
return selection.kind === Kind.FIELD && !selection.alias && selection.name.value === "__typename";
|
|
763
809
|
}
|
|
810
|
+
function collectFieldSelectionSetsByPath(document) {
|
|
811
|
+
const selectionSetsByPath = /* @__PURE__ */ new Map();
|
|
812
|
+
const fragments = /* @__PURE__ */ new Map();
|
|
813
|
+
for (const def of document.definitions) {
|
|
814
|
+
if (def.kind === Kind.FRAGMENT_DEFINITION) {
|
|
815
|
+
fragments.set(def.name.value, def);
|
|
816
|
+
}
|
|
817
|
+
}
|
|
818
|
+
const pathStack = [];
|
|
819
|
+
visit(document, {
|
|
820
|
+
[Kind.OPERATION_DEFINITION]: {
|
|
821
|
+
enter(node) {
|
|
822
|
+
pathStack.push(`op:${node.operation}:${node.name?.value ?? ""}`);
|
|
823
|
+
},
|
|
824
|
+
leave() {
|
|
825
|
+
pathStack.pop();
|
|
826
|
+
}
|
|
827
|
+
},
|
|
828
|
+
[Kind.FRAGMENT_DEFINITION]: {
|
|
829
|
+
enter(node) {
|
|
830
|
+
pathStack.push(`frag:${node.name.value}`);
|
|
831
|
+
},
|
|
832
|
+
leave() {
|
|
833
|
+
pathStack.pop();
|
|
834
|
+
}
|
|
835
|
+
},
|
|
836
|
+
[Kind.INLINE_FRAGMENT]: {
|
|
837
|
+
enter(node) {
|
|
838
|
+
pathStack.push(`inline:${node.typeCondition?.name.value ?? ""}`);
|
|
839
|
+
},
|
|
840
|
+
leave() {
|
|
841
|
+
pathStack.pop();
|
|
842
|
+
}
|
|
843
|
+
},
|
|
844
|
+
[Kind.FIELD]: {
|
|
845
|
+
enter(node) {
|
|
846
|
+
pathStack.push(node.alias?.value ?? node.name.value);
|
|
847
|
+
if (node.selectionSet) {
|
|
848
|
+
selectionSetsByPath.set(pathStack.join(">"), node.selectionSet);
|
|
849
|
+
}
|
|
850
|
+
},
|
|
851
|
+
leave() {
|
|
852
|
+
pathStack.pop();
|
|
853
|
+
}
|
|
854
|
+
}
|
|
855
|
+
});
|
|
856
|
+
return { selectionSetsByPath, fragments };
|
|
857
|
+
}
|
|
858
|
+
function intersectProvidedSelections(providedSelections, originalSelectionSet, fragments) {
|
|
859
|
+
if (!originalSelectionSet) {
|
|
860
|
+
return [];
|
|
861
|
+
}
|
|
862
|
+
const providedFieldsByName = /* @__PURE__ */ new Map();
|
|
863
|
+
const otherProvided = [];
|
|
864
|
+
for (const provided of providedSelections) {
|
|
865
|
+
if (provided.kind === Kind.FIELD) {
|
|
866
|
+
providedFieldsByName.set(provided.name.value, provided);
|
|
867
|
+
} else {
|
|
868
|
+
otherProvided.push(provided);
|
|
869
|
+
}
|
|
870
|
+
}
|
|
871
|
+
const result = [];
|
|
872
|
+
const seenFieldNames = /* @__PURE__ */ new Set();
|
|
873
|
+
const seenFragmentNames = /* @__PURE__ */ new Set();
|
|
874
|
+
collectMatchingOriginalSelections(
|
|
875
|
+
originalSelectionSet,
|
|
876
|
+
providedFieldsByName,
|
|
877
|
+
fragments,
|
|
878
|
+
seenFieldNames,
|
|
879
|
+
seenFragmentNames,
|
|
880
|
+
result
|
|
881
|
+
);
|
|
882
|
+
return [...result, ...otherProvided];
|
|
883
|
+
}
|
|
884
|
+
function collectMatchingOriginalSelections(selectionSet, providedFieldsByName, fragments, seenFieldNames, seenFragmentNames, result) {
|
|
885
|
+
for (const sel of selectionSet.selections) {
|
|
886
|
+
if (sel.kind === Kind.FIELD) {
|
|
887
|
+
const provided = providedFieldsByName.get(sel.name.value);
|
|
888
|
+
if (!provided) {
|
|
889
|
+
continue;
|
|
890
|
+
}
|
|
891
|
+
const dedupKey = sel.alias?.value ?? sel.name.value;
|
|
892
|
+
if (seenFieldNames.has(dedupKey)) {
|
|
893
|
+
continue;
|
|
894
|
+
}
|
|
895
|
+
seenFieldNames.add(dedupKey);
|
|
896
|
+
if (provided.selectionSet && sel.selectionSet) {
|
|
897
|
+
const nested = intersectProvidedSelections(
|
|
898
|
+
provided.selectionSet.selections,
|
|
899
|
+
sel.selectionSet,
|
|
900
|
+
fragments
|
|
901
|
+
);
|
|
902
|
+
if (!nested.length) {
|
|
903
|
+
continue;
|
|
904
|
+
}
|
|
905
|
+
result.push({
|
|
906
|
+
...sel,
|
|
907
|
+
selectionSet: {
|
|
908
|
+
kind: Kind.SELECTION_SET,
|
|
909
|
+
selections: nested
|
|
910
|
+
}
|
|
911
|
+
});
|
|
912
|
+
} else {
|
|
913
|
+
result.push(sel);
|
|
914
|
+
}
|
|
915
|
+
} else if (sel.kind === Kind.INLINE_FRAGMENT && sel.selectionSet) {
|
|
916
|
+
collectMatchingOriginalSelections(
|
|
917
|
+
sel.selectionSet,
|
|
918
|
+
providedFieldsByName,
|
|
919
|
+
fragments,
|
|
920
|
+
seenFieldNames,
|
|
921
|
+
seenFragmentNames,
|
|
922
|
+
result
|
|
923
|
+
);
|
|
924
|
+
} else if (sel.kind === Kind.FRAGMENT_SPREAD) {
|
|
925
|
+
const fragmentName = sel.name.value;
|
|
926
|
+
if (seenFragmentNames.has(fragmentName)) {
|
|
927
|
+
continue;
|
|
928
|
+
}
|
|
929
|
+
seenFragmentNames.add(fragmentName);
|
|
930
|
+
const fragmentDef = fragments.get(fragmentName);
|
|
931
|
+
if (!fragmentDef) {
|
|
932
|
+
continue;
|
|
933
|
+
}
|
|
934
|
+
collectMatchingOriginalSelections(
|
|
935
|
+
fragmentDef.selectionSet,
|
|
936
|
+
providedFieldsByName,
|
|
937
|
+
fragments,
|
|
938
|
+
seenFieldNames,
|
|
939
|
+
seenFragmentNames,
|
|
940
|
+
result
|
|
941
|
+
);
|
|
942
|
+
}
|
|
943
|
+
}
|
|
944
|
+
}
|
|
764
945
|
function filterTypenameFields(selections) {
|
|
765
946
|
let hasTypeNameField = false;
|
|
766
947
|
const filteredSelections = selections.filter((selection) => {
|
package/package.json
CHANGED