@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/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.FIELD](fieldNode) {
696
- const parentType = typeInfo.getParentType();
697
- if (parentType) {
698
- const parentTypeName = parentType.name;
699
- const typeConfig = stitchingInfo?.mergedTypes?.[parentTypeName];
700
- if (typeConfig) {
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
- if (providedSelectionsByField) {
705
- const providedSelection = providedSelectionsByField[fieldNode.name.value];
706
- if (providedSelection) {
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
- newFragments.push({
813
- kind: graphql.Kind.FRAGMENT_DEFINITION,
814
- name: {
815
- kind: graphql.Kind.NAME,
816
- value: name
817
- },
818
- typeCondition: fragment.typeCondition,
819
- selectionSet
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
- if (varValue === argValue) {
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
- const pushed = /* @__PURE__ */ new WeakSet();
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 (const individualResult$ of transformedResult) {
3092
+ for (let i = pushedCount; i < transformedResult.length; i++) {
2685
3093
  if (stopped) {
2686
3094
  break;
2687
3095
  }
2688
- const individualResult = await individualResult$;
2689
- if (!pushed.has(individualResult)) {
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
- unavailableSelections.push(subSelection);
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(acc, subselectionB.selectionSet) : acc,
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
- if (!selectionSetB.selections.some(
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);