@graphql-tools/delegate 9.0.0-alpha-8ae2f1b1.0 → 9.0.0-alpha-be1b2ebd.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.
@@ -1,8 +1,8 @@
1
1
  import { FieldNode, GraphQLResolveInfo, GraphQLSchema } from 'graphql';
2
2
  import { ExternalObject, MergedTypeInfo } from './types';
3
3
  import { Subschema } from './Subschema';
4
- export declare function getMergedParent(parent: ExternalObject, context: Record<string, any>, info: GraphQLResolveInfo): Promise<ExternalObject>;
5
- export declare const buildDelegationPlan: (mergedTypeInfo: MergedTypeInfo, schema: GraphQLSchema, sourceSubschema: Subschema, ...fieldNodeArrays: Array<ReadonlyArray<FieldNode>>) => {
4
+ export declare function getMergedParent(parent: ExternalObject, context: Record<string, any>, info: GraphQLResolveInfo): ExternalObject | Promise<ExternalObject>;
5
+ export declare const buildDelegationPlan: (mergedTypeInfo: MergedTypeInfo, gatewaySchema: GraphQLSchema, sourceSubschema: Subschema, ...fieldNodeArrays: Array<ReadonlyArray<FieldNode>>) => {
6
6
  requiredKeys: Record<string, Set<string>>;
7
7
  delegationMaps: Array<Map<Subschema, Array<FieldNode>>>;
8
8
  stageMap: Record<string, number>;
package/index.js CHANGED
@@ -6,8 +6,8 @@ function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'defau
6
6
 
7
7
  const graphql = require('graphql');
8
8
  const utils = require('@graphql-tools/utils');
9
- const DataLoader = _interopDefault(require('dataloader'));
10
9
  const valueOrPromise = require('value-or-promise');
10
+ const DataLoader = _interopDefault(require('dataloader'));
11
11
  const batchExecute = require('@graphql-tools/batch-execute');
12
12
 
13
13
  function applySchemaTransforms(originalWrappingSchema, subschemaConfig, transformedSchema) {
@@ -1043,7 +1043,22 @@ function getReturnType(info) {
1043
1043
  return info.returnType;
1044
1044
  }
1045
1045
 
1046
- const getMergeDetails = utils.memoize1(function getMergeDetails(info) {
1046
+ const loaders = new WeakMap();
1047
+ function getMergedParent(parent, context, info) {
1048
+ // In the stitching context, all subschemas are compiled Subschema objects rather than SubschemaConfig objects
1049
+ const sourceSubschema = getObjectSubchema(parent);
1050
+ const mergedTypeInfo = getMergedTypeInfo(info);
1051
+ if (mergedTypeInfo === undefined) {
1052
+ return parent;
1053
+ }
1054
+ let loader = loaders.get(parent);
1055
+ if (loader === undefined) {
1056
+ loader = new DataLoader(fieldNodeArrays => getMergedParentsFromFieldNodes(parent, context, info.schema, fieldNodeArrays, mergedTypeInfo, sourceSubschema));
1057
+ loaders.set(parent, loader);
1058
+ }
1059
+ return loader.load(info.fieldNodes).then(promise => promise);
1060
+ }
1061
+ const getMergedTypeInfo = utils.memoize1(function getMergedTypeInfo(info) {
1047
1062
  var _a;
1048
1063
  const schema = info.schema;
1049
1064
  const stitchingInfo = (_a = schema.extensions) === null || _a === void 0 ? void 0 : _a['stitchingInfo'];
@@ -1055,60 +1070,37 @@ const getMergeDetails = utils.memoize1(function getMergeDetails(info) {
1055
1070
  if (mergedTypeInfo === undefined) {
1056
1071
  return;
1057
1072
  }
1058
- return {
1059
- stitchingInfo,
1060
- mergedTypeInfo,
1061
- };
1073
+ return mergedTypeInfo;
1062
1074
  });
1063
- const loaders = new WeakMap();
1064
- async function getMergedParent(parent, context, info) {
1065
- const mergeDetails = getMergeDetails(info);
1066
- if (!mergeDetails) {
1067
- return parent;
1068
- }
1069
- const { mergedTypeInfo } = mergeDetails;
1070
- // In the stitching context, all subschemas are compiled Subschema objects rather than SubschemaConfig objects
1071
- const sourceSubschema = getObjectSubchema(parent);
1072
- const targetSubschemas = mergedTypeInfo.targetSubschemas.get(sourceSubschema);
1073
- if (targetSubschemas === undefined || targetSubschemas.length === 0) {
1074
- return parent;
1075
- }
1076
- let loader = loaders.get(parent);
1077
- if (loader === undefined) {
1078
- loader = new DataLoader(infos => getMergedParentsFromInfos(parent, context, infos, mergedTypeInfo, sourceSubschema));
1079
- loaders.set(parent, loader);
1080
- }
1081
- return loader.load(info);
1082
- }
1083
- async function getMergedParentsFromInfos(parent, context, infos, mergedTypeInfo, sourceSubschema) {
1084
- const { requiredKeys, delegationMaps, stageMap } = buildDelegationPlan(mergedTypeInfo, infos[0].schema, sourceSubschema, ...infos.map(info => info.fieldNodes));
1075
+ async function getMergedParentsFromFieldNodes(parent, context, gatewaySchema, fieldNodeArrays, mergedTypeInfo, sourceSubschema) {
1076
+ const { requiredKeys, delegationMaps, stageMap } = buildDelegationPlan(mergedTypeInfo, gatewaySchema, sourceSubschema, ...fieldNodeArrays);
1085
1077
  if (!delegationMaps.length) {
1086
- return Array(infos.length).fill(parent);
1078
+ return Array(fieldNodeArrays.length).fill(parent);
1087
1079
  }
1088
1080
  const promises = [];
1089
1081
  const parentInfo = getInfo(parent);
1090
- const schema = parentInfo.schema;
1091
- const type = schema.getType(parent.__typename);
1082
+ const type = gatewaySchema.getType(parent.__typename);
1092
1083
  const parentPath = graphql.responsePathAsArray(parentInfo.path);
1093
- let promise = executeDelegationStage(delegationMaps[0], schema, type, mergedTypeInfo, context, parent, parentInfo, parentPath).then(() => parent);
1084
+ let promise = executeDelegationStage(delegationMaps[0], gatewaySchema, type, mergedTypeInfo, context, parent, parentInfo, parentPath);
1094
1085
  promises.push(promise);
1095
1086
  for (let i = 1, delegationStage = delegationMaps[i]; i < delegationMaps.length; i++) {
1096
- promise = promise.then(parent => executeDelegationStage(delegationStage, schema, type, mergedTypeInfo, context, parent, parentInfo, parentPath).then(() => parent));
1087
+ promise = promise.then(parent => executeDelegationStage(delegationStage, gatewaySchema, type, mergedTypeInfo, context, parent, parentInfo, parentPath));
1097
1088
  promises.push(promise);
1098
1089
  }
1099
- return infos.map(info => {
1100
- const keys = requiredKeys[info.fieldName];
1090
+ return fieldNodeArrays.map(fieldNodeArray => {
1091
+ const fieldName = fieldNodeArray[0].name.value;
1092
+ const keys = requiredKeys[fieldName];
1101
1093
  if (keys === undefined) {
1102
- const delegationStage = stageMap[info.fieldName];
1094
+ const delegationStage = stageMap[fieldName];
1103
1095
  if (delegationStage !== undefined) {
1104
- return promises[delegationStage].then(() => parent);
1096
+ return promises[delegationStage];
1105
1097
  }
1106
1098
  return Promise.resolve(parent);
1107
1099
  }
1108
1100
  return Promise.all(Array.from(keys.values()).map(fieldName => {
1109
1101
  const delegationStage = stageMap[fieldName];
1110
1102
  if (delegationStage !== undefined) {
1111
- return promises[delegationStage].then(() => parent);
1103
+ return promises[delegationStage];
1112
1104
  }
1113
1105
  return Promise.resolve(parent);
1114
1106
  })).then(() => parent);
@@ -1155,12 +1147,12 @@ function calculateDelegationStage(mergedTypeInfo, sourceSubschemas, targetSubsch
1155
1147
  unproxiableFieldNodes,
1156
1148
  };
1157
1149
  }
1158
- const buildDelegationPlan = utils.memoize4ofMany(function buildDelegationPlan(mergedTypeInfo, schema, sourceSubschema, ...fieldNodeArrays) {
1150
+ const buildDelegationPlan = utils.memoize4ofMany(function buildDelegationPlan(mergedTypeInfo, gatewaySchema, sourceSubschema, ...fieldNodeArrays) {
1159
1151
  var _a, _b, _c;
1160
1152
  const requiredKeys = Object.create(null);
1161
1153
  const delegationMaps = [];
1162
1154
  const stageMap = Object.create(null);
1163
- const stitchingInfo = (_a = schema.extensions) === null || _a === void 0 ? void 0 : _a['stitchingInfo'];
1155
+ const stitchingInfo = (_a = gatewaySchema.extensions) === null || _a === void 0 ? void 0 : _a['stitchingInfo'];
1164
1156
  if (stitchingInfo == null) {
1165
1157
  return { requiredKeys, delegationMaps, stageMap };
1166
1158
  }
@@ -1337,20 +1329,21 @@ async function executeDelegationStage(delegationMap, schema, type, mergedTypeInf
1337
1329
  }
1338
1330
  source = nullResult;
1339
1331
  }
1340
- // TODO: fold this assign into loop below?
1341
- Object.assign(object, source);
1342
1332
  // TODO: is this check necessary or just to make TS happy?
1343
1333
  if (!isExternalObject(source)) {
1344
- return;
1334
+ Object.assign(object, source);
1335
+ return object;
1345
1336
  }
1346
1337
  const objectSubschema = getObjectSubchema(source);
1347
1338
  const subschemaMap = getSubschemaMap(source);
1348
1339
  for (const responseKey in source) {
1340
+ object[responseKey] = source[responseKey];
1349
1341
  newSubschemaMap[responseKey] = (_a = subschemaMap === null || subschemaMap === void 0 ? void 0 : subschemaMap[responseKey]) !== null && _a !== void 0 ? _a : objectSubschema;
1350
1342
  }
1351
1343
  unpathedErrors.push(...getUnpathedErrors(source));
1352
1344
  }
1353
1345
  }));
1346
+ return object;
1354
1347
  }
1355
1348
  const subschemaTypesContainSelectionSet = utils.memoize3(function subschemaTypesContainSelectionSet(mergedTypeInfo, sourceSubschemas, selectionSet) {
1356
1349
  return typesContainSelectionSet(sourceSubschemas.map(sourceSubschema => sourceSubschema.transformedSchema.getType(mergedTypeInfo.typeName)), selectionSet);
@@ -1391,7 +1384,7 @@ function defaultMergedResolver(parent, args, context, info) {
1391
1384
  const initialPossibleFields = getInitialPossibleFields(parent);
1392
1385
  if (initialPossibleFields === undefined) {
1393
1386
  // TODO: can this be removed in the next major release?
1394
- // legacy use of delegation without setting transformedSchema
1387
+ // legacy use of delegation without setting transformedSchema
1395
1388
  const data = parent[responseKey];
1396
1389
  if (data !== undefined) {
1397
1390
  return resolveField(parent, responseKey, context, info);
@@ -1400,7 +1393,9 @@ function defaultMergedResolver(parent, args, context, info) {
1400
1393
  else if (info.fieldName in initialPossibleFields) {
1401
1394
  return resolveField(parent, responseKey, context, info);
1402
1395
  }
1403
- return getMergedParent(parent, context, info).then(mergedParent => resolveField(mergedParent, responseKey, context, info));
1396
+ return new valueOrPromise.ValueOrPromise(() => getMergedParent(parent, context, info))
1397
+ .then(mergedParent => resolveField(mergedParent, responseKey, context, info))
1398
+ .resolve();
1404
1399
  }
1405
1400
  function resolveField(parent, responseKey, context, info) {
1406
1401
  const initialPath = getInitialPath(parent);
package/index.mjs CHANGED
@@ -1,7 +1,7 @@
1
1
  import { Kind, isAbstractType, isInterfaceType, TypeInfo, visit, visitWithTypeInfo, getNamedType, isObjectType, versionInfo, TypeNameMetaFieldDef, typeFromAST, locatedError, responsePathAsArray, getNullableType, GraphQLError, isCompositeType, isListType, defaultFieldResolver, getOperationAST, GraphQLSchema, isSchema, validate, subscribe, execute } from 'graphql';
2
2
  import { memoize2, implementsAbstractType, getRootTypeNames, getDefinedRootType, createVariableNameGenerator, updateArgument, serializeInputValue, inspect, relocatedError, AggregateError, memoize1, memoize4ofMany, collectFields, memoize3, getResponseKeyFromInfo, isAsyncIterable, mapAsyncIterator } from '@graphql-tools/utils';
3
- import DataLoader from 'dataloader';
4
3
  import { ValueOrPromise } from 'value-or-promise';
4
+ import DataLoader from 'dataloader';
5
5
  import { getBatchingExecutor } from '@graphql-tools/batch-execute';
6
6
 
7
7
  function applySchemaTransforms(originalWrappingSchema, subschemaConfig, transformedSchema) {
@@ -1037,7 +1037,22 @@ function getReturnType(info) {
1037
1037
  return info.returnType;
1038
1038
  }
1039
1039
 
1040
- const getMergeDetails = memoize1(function getMergeDetails(info) {
1040
+ const loaders = new WeakMap();
1041
+ function getMergedParent(parent, context, info) {
1042
+ // In the stitching context, all subschemas are compiled Subschema objects rather than SubschemaConfig objects
1043
+ const sourceSubschema = getObjectSubchema(parent);
1044
+ const mergedTypeInfo = getMergedTypeInfo(info);
1045
+ if (mergedTypeInfo === undefined) {
1046
+ return parent;
1047
+ }
1048
+ let loader = loaders.get(parent);
1049
+ if (loader === undefined) {
1050
+ loader = new DataLoader(fieldNodeArrays => getMergedParentsFromFieldNodes(parent, context, info.schema, fieldNodeArrays, mergedTypeInfo, sourceSubschema));
1051
+ loaders.set(parent, loader);
1052
+ }
1053
+ return loader.load(info.fieldNodes).then(promise => promise);
1054
+ }
1055
+ const getMergedTypeInfo = memoize1(function getMergedTypeInfo(info) {
1041
1056
  var _a;
1042
1057
  const schema = info.schema;
1043
1058
  const stitchingInfo = (_a = schema.extensions) === null || _a === void 0 ? void 0 : _a['stitchingInfo'];
@@ -1049,60 +1064,37 @@ const getMergeDetails = memoize1(function getMergeDetails(info) {
1049
1064
  if (mergedTypeInfo === undefined) {
1050
1065
  return;
1051
1066
  }
1052
- return {
1053
- stitchingInfo,
1054
- mergedTypeInfo,
1055
- };
1067
+ return mergedTypeInfo;
1056
1068
  });
1057
- const loaders = new WeakMap();
1058
- async function getMergedParent(parent, context, info) {
1059
- const mergeDetails = getMergeDetails(info);
1060
- if (!mergeDetails) {
1061
- return parent;
1062
- }
1063
- const { mergedTypeInfo } = mergeDetails;
1064
- // In the stitching context, all subschemas are compiled Subschema objects rather than SubschemaConfig objects
1065
- const sourceSubschema = getObjectSubchema(parent);
1066
- const targetSubschemas = mergedTypeInfo.targetSubschemas.get(sourceSubschema);
1067
- if (targetSubschemas === undefined || targetSubschemas.length === 0) {
1068
- return parent;
1069
- }
1070
- let loader = loaders.get(parent);
1071
- if (loader === undefined) {
1072
- loader = new DataLoader(infos => getMergedParentsFromInfos(parent, context, infos, mergedTypeInfo, sourceSubschema));
1073
- loaders.set(parent, loader);
1074
- }
1075
- return loader.load(info);
1076
- }
1077
- async function getMergedParentsFromInfos(parent, context, infos, mergedTypeInfo, sourceSubschema) {
1078
- const { requiredKeys, delegationMaps, stageMap } = buildDelegationPlan(mergedTypeInfo, infos[0].schema, sourceSubschema, ...infos.map(info => info.fieldNodes));
1069
+ async function getMergedParentsFromFieldNodes(parent, context, gatewaySchema, fieldNodeArrays, mergedTypeInfo, sourceSubschema) {
1070
+ const { requiredKeys, delegationMaps, stageMap } = buildDelegationPlan(mergedTypeInfo, gatewaySchema, sourceSubschema, ...fieldNodeArrays);
1079
1071
  if (!delegationMaps.length) {
1080
- return Array(infos.length).fill(parent);
1072
+ return Array(fieldNodeArrays.length).fill(parent);
1081
1073
  }
1082
1074
  const promises = [];
1083
1075
  const parentInfo = getInfo(parent);
1084
- const schema = parentInfo.schema;
1085
- const type = schema.getType(parent.__typename);
1076
+ const type = gatewaySchema.getType(parent.__typename);
1086
1077
  const parentPath = responsePathAsArray(parentInfo.path);
1087
- let promise = executeDelegationStage(delegationMaps[0], schema, type, mergedTypeInfo, context, parent, parentInfo, parentPath).then(() => parent);
1078
+ let promise = executeDelegationStage(delegationMaps[0], gatewaySchema, type, mergedTypeInfo, context, parent, parentInfo, parentPath);
1088
1079
  promises.push(promise);
1089
1080
  for (let i = 1, delegationStage = delegationMaps[i]; i < delegationMaps.length; i++) {
1090
- promise = promise.then(parent => executeDelegationStage(delegationStage, schema, type, mergedTypeInfo, context, parent, parentInfo, parentPath).then(() => parent));
1081
+ promise = promise.then(parent => executeDelegationStage(delegationStage, gatewaySchema, type, mergedTypeInfo, context, parent, parentInfo, parentPath));
1091
1082
  promises.push(promise);
1092
1083
  }
1093
- return infos.map(info => {
1094
- const keys = requiredKeys[info.fieldName];
1084
+ return fieldNodeArrays.map(fieldNodeArray => {
1085
+ const fieldName = fieldNodeArray[0].name.value;
1086
+ const keys = requiredKeys[fieldName];
1095
1087
  if (keys === undefined) {
1096
- const delegationStage = stageMap[info.fieldName];
1088
+ const delegationStage = stageMap[fieldName];
1097
1089
  if (delegationStage !== undefined) {
1098
- return promises[delegationStage].then(() => parent);
1090
+ return promises[delegationStage];
1099
1091
  }
1100
1092
  return Promise.resolve(parent);
1101
1093
  }
1102
1094
  return Promise.all(Array.from(keys.values()).map(fieldName => {
1103
1095
  const delegationStage = stageMap[fieldName];
1104
1096
  if (delegationStage !== undefined) {
1105
- return promises[delegationStage].then(() => parent);
1097
+ return promises[delegationStage];
1106
1098
  }
1107
1099
  return Promise.resolve(parent);
1108
1100
  })).then(() => parent);
@@ -1149,12 +1141,12 @@ function calculateDelegationStage(mergedTypeInfo, sourceSubschemas, targetSubsch
1149
1141
  unproxiableFieldNodes,
1150
1142
  };
1151
1143
  }
1152
- const buildDelegationPlan = memoize4ofMany(function buildDelegationPlan(mergedTypeInfo, schema, sourceSubschema, ...fieldNodeArrays) {
1144
+ const buildDelegationPlan = memoize4ofMany(function buildDelegationPlan(mergedTypeInfo, gatewaySchema, sourceSubschema, ...fieldNodeArrays) {
1153
1145
  var _a, _b, _c;
1154
1146
  const requiredKeys = Object.create(null);
1155
1147
  const delegationMaps = [];
1156
1148
  const stageMap = Object.create(null);
1157
- const stitchingInfo = (_a = schema.extensions) === null || _a === void 0 ? void 0 : _a['stitchingInfo'];
1149
+ const stitchingInfo = (_a = gatewaySchema.extensions) === null || _a === void 0 ? void 0 : _a['stitchingInfo'];
1158
1150
  if (stitchingInfo == null) {
1159
1151
  return { requiredKeys, delegationMaps, stageMap };
1160
1152
  }
@@ -1331,20 +1323,21 @@ async function executeDelegationStage(delegationMap, schema, type, mergedTypeInf
1331
1323
  }
1332
1324
  source = nullResult;
1333
1325
  }
1334
- // TODO: fold this assign into loop below?
1335
- Object.assign(object, source);
1336
1326
  // TODO: is this check necessary or just to make TS happy?
1337
1327
  if (!isExternalObject(source)) {
1338
- return;
1328
+ Object.assign(object, source);
1329
+ return object;
1339
1330
  }
1340
1331
  const objectSubschema = getObjectSubchema(source);
1341
1332
  const subschemaMap = getSubschemaMap(source);
1342
1333
  for (const responseKey in source) {
1334
+ object[responseKey] = source[responseKey];
1343
1335
  newSubschemaMap[responseKey] = (_a = subschemaMap === null || subschemaMap === void 0 ? void 0 : subschemaMap[responseKey]) !== null && _a !== void 0 ? _a : objectSubschema;
1344
1336
  }
1345
1337
  unpathedErrors.push(...getUnpathedErrors(source));
1346
1338
  }
1347
1339
  }));
1340
+ return object;
1348
1341
  }
1349
1342
  const subschemaTypesContainSelectionSet = memoize3(function subschemaTypesContainSelectionSet(mergedTypeInfo, sourceSubschemas, selectionSet) {
1350
1343
  return typesContainSelectionSet(sourceSubschemas.map(sourceSubschema => sourceSubschema.transformedSchema.getType(mergedTypeInfo.typeName)), selectionSet);
@@ -1385,7 +1378,7 @@ function defaultMergedResolver(parent, args, context, info) {
1385
1378
  const initialPossibleFields = getInitialPossibleFields(parent);
1386
1379
  if (initialPossibleFields === undefined) {
1387
1380
  // TODO: can this be removed in the next major release?
1388
- // legacy use of delegation without setting transformedSchema
1381
+ // legacy use of delegation without setting transformedSchema
1389
1382
  const data = parent[responseKey];
1390
1383
  if (data !== undefined) {
1391
1384
  return resolveField(parent, responseKey, context, info);
@@ -1394,7 +1387,9 @@ function defaultMergedResolver(parent, args, context, info) {
1394
1387
  else if (info.fieldName in initialPossibleFields) {
1395
1388
  return resolveField(parent, responseKey, context, info);
1396
1389
  }
1397
- return getMergedParent(parent, context, info).then(mergedParent => resolveField(mergedParent, responseKey, context, info));
1390
+ return new ValueOrPromise(() => getMergedParent(parent, context, info))
1391
+ .then(mergedParent => resolveField(mergedParent, responseKey, context, info))
1392
+ .resolve();
1398
1393
  }
1399
1394
  function resolveField(parent, responseKey, context, info) {
1400
1395
  const initialPath = getInitialPath(parent);
package/package.json CHANGED
@@ -1,15 +1,15 @@
1
1
  {
2
2
  "name": "@graphql-tools/delegate",
3
- "version": "9.0.0-alpha-8ae2f1b1.0",
3
+ "version": "9.0.0-alpha-be1b2ebd.0",
4
4
  "description": "A set of utils for faster development of GraphQL tools",
5
5
  "sideEffects": false,
6
6
  "peerDependencies": {
7
7
  "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0"
8
8
  },
9
9
  "dependencies": {
10
- "@graphql-tools/batch-execute": "8.1.1-alpha-8ae2f1b1.0",
11
- "@graphql-tools/schema": "8.2.1-alpha-8ae2f1b1.0",
12
- "@graphql-tools/utils": "9.0.0-alpha-8ae2f1b1.0",
10
+ "@graphql-tools/batch-execute": "8.1.1-alpha-be1b2ebd.0",
11
+ "@graphql-tools/schema": "8.2.1-alpha-be1b2ebd.0",
12
+ "@graphql-tools/utils": "9.0.0-alpha-be1b2ebd.0",
13
13
  "dataloader": "2.0.0",
14
14
  "tslib": "~2.3.0",
15
15
  "value-or-promise": "1.0.10"