@graphql-tools/stitching-directives 3.0.2 → 3.1.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.
@@ -19,6 +19,8 @@ function stitchingDirectivesTransformer(options = {}) {
19
19
  const computedFieldSelectionSets = Object.create(null);
20
20
  const mergedTypesResolversInfo = Object.create(null);
21
21
  const canonicalTypesInfo = Object.create(null);
22
+ const selectionSetsByTypeAndEntryField = Object.create(null);
23
+ const mergedTypesResolversInfoByEntryField = Object.create(null);
22
24
  const schema = subschemaConfig.schema;
23
25
  // gateway should also run validation
24
26
  (0, stitchingDirectivesValidator_js_1.stitchingDirectivesValidator)(options)(schema);
@@ -69,8 +71,16 @@ function stitchingDirectivesTransformer(options = {}) {
69
71
  const returnType = (0, graphql_1.getNamedType)(fieldConfig.type);
70
72
  forEachConcreteType(schema, returnType, typeNames, typeName => {
71
73
  if (typeNames == null || typeNames.includes(typeName)) {
72
- const existingSelectionSet = selectionSetsByType[typeName];
73
- selectionSetsByType[typeName] = existingSelectionSet
74
+ let existingEntryFieldMap = selectionSetsByTypeAndEntryField[typeName];
75
+ if (existingEntryFieldMap == null) {
76
+ existingEntryFieldMap = Object.create(null);
77
+ selectionSetsByTypeAndEntryField[typeName] = existingEntryFieldMap;
78
+ }
79
+ let existingSelectionSet = existingEntryFieldMap[fieldName];
80
+ if (existingSelectionSet == null) {
81
+ existingSelectionSet = selectionSetsByType[typeName];
82
+ }
83
+ existingEntryFieldMap[fieldName] = existingSelectionSet
74
84
  ? mergeSelectionSets(existingSelectionSet, selectionSet)
75
85
  : selectionSet;
76
86
  }
@@ -207,9 +217,16 @@ function stitchingDirectivesTransformer(options = {}) {
207
217
  }
208
218
  const typeNames = mergeDirective['types'];
209
219
  forEachConcreteTypeName(namedType, schema, typeNames, function generateResolveInfo(typeName) {
220
+ const mergedSelectionSets = [];
221
+ if (allSelectionSetsByType[typeName]) {
222
+ mergedSelectionSets.push(...allSelectionSetsByType[typeName]);
223
+ }
224
+ if (selectionSetsByTypeAndEntryField[typeName]?.[fieldName]) {
225
+ mergedSelectionSets.push(selectionSetsByTypeAndEntryField[typeName][fieldName]);
226
+ }
210
227
  const parsedMergeArgsExpr = (0, parseMergeArgsExpr_js_1.parseMergeArgsExpr)(mergeArgsExpr, allSelectionSetsByType[typeName] == null
211
228
  ? undefined
212
- : mergeSelectionSets(...allSelectionSetsByType[typeName]));
229
+ : mergeSelectionSets(...mergedSelectionSets));
213
230
  const additionalArgs = mergeDirective['additionalArgs'];
214
231
  if (additionalArgs != null) {
215
232
  parsedMergeArgsExpr.args = (0, utils_1.mergeDeep)([
@@ -217,11 +234,22 @@ function stitchingDirectivesTransformer(options = {}) {
217
234
  (0, graphql_1.valueFromASTUntyped)((0, graphql_1.parseValue)(`{ ${additionalArgs} }`, { noLocation: true })),
218
235
  ]);
219
236
  }
220
- mergedTypesResolversInfo[typeName] = {
221
- fieldName,
222
- returnsList,
223
- ...parsedMergeArgsExpr,
224
- };
237
+ if (selectionSetsByTypeAndEntryField[typeName]?.[fieldName] != null) {
238
+ const typeConfigByField = (mergedTypesResolversInfoByEntryField[typeName] ||=
239
+ Object.create(null));
240
+ typeConfigByField[fieldName] = {
241
+ fieldName,
242
+ returnsList,
243
+ ...parsedMergeArgsExpr,
244
+ };
245
+ }
246
+ else {
247
+ mergedTypesResolversInfo[typeName] = {
248
+ fieldName,
249
+ returnsList,
250
+ ...parsedMergeArgsExpr,
251
+ };
252
+ }
225
253
  });
226
254
  }
227
255
  return undefined;
@@ -294,6 +322,40 @@ function stitchingDirectivesTransformer(options = {}) {
294
322
  }
295
323
  }
296
324
  }
325
+ for (const typeName in mergedTypesResolversInfoByEntryField) {
326
+ const entryPoints = [];
327
+ const existingMergeConfig = newSubschemaConfig.merge?.[typeName];
328
+ const newMergeConfig = (newSubschemaConfig.merge ||= Object.create(null));
329
+ if (existingMergeConfig) {
330
+ const { fields, canonical, ...baseEntryPoint } = existingMergeConfig;
331
+ newMergeConfig[typeName] = {
332
+ fields,
333
+ canonical,
334
+ entryPoints,
335
+ };
336
+ entryPoints.push(baseEntryPoint);
337
+ }
338
+ else {
339
+ newMergeConfig[typeName] = {
340
+ entryPoints,
341
+ };
342
+ }
343
+ for (const fieldName in mergedTypesResolversInfoByEntryField[typeName]) {
344
+ const mergedTypeResolverInfo = mergedTypesResolversInfoByEntryField[typeName][fieldName];
345
+ const newEntryPoint = {
346
+ fieldName,
347
+ selectionSet: (0, graphql_1.print)(selectionSetsByTypeAndEntryField[typeName][fieldName]),
348
+ };
349
+ if (mergedTypeResolverInfo.returnsList) {
350
+ newEntryPoint.key = generateKeyFn(mergedTypeResolverInfo);
351
+ newEntryPoint.argsFromKeys = generateArgsFromKeysFn(mergedTypeResolverInfo);
352
+ }
353
+ else {
354
+ newEntryPoint.args = generateArgsFn(mergedTypeResolverInfo);
355
+ }
356
+ entryPoints.push(newEntryPoint);
357
+ }
358
+ }
297
359
  return newSubschemaConfig;
298
360
  };
299
361
  }
@@ -16,6 +16,8 @@ export function stitchingDirectivesTransformer(options = {}) {
16
16
  const computedFieldSelectionSets = Object.create(null);
17
17
  const mergedTypesResolversInfo = Object.create(null);
18
18
  const canonicalTypesInfo = Object.create(null);
19
+ const selectionSetsByTypeAndEntryField = Object.create(null);
20
+ const mergedTypesResolversInfoByEntryField = Object.create(null);
19
21
  const schema = subschemaConfig.schema;
20
22
  // gateway should also run validation
21
23
  stitchingDirectivesValidator(options)(schema);
@@ -66,8 +68,16 @@ export function stitchingDirectivesTransformer(options = {}) {
66
68
  const returnType = getNamedType(fieldConfig.type);
67
69
  forEachConcreteType(schema, returnType, typeNames, typeName => {
68
70
  if (typeNames == null || typeNames.includes(typeName)) {
69
- const existingSelectionSet = selectionSetsByType[typeName];
70
- selectionSetsByType[typeName] = existingSelectionSet
71
+ let existingEntryFieldMap = selectionSetsByTypeAndEntryField[typeName];
72
+ if (existingEntryFieldMap == null) {
73
+ existingEntryFieldMap = Object.create(null);
74
+ selectionSetsByTypeAndEntryField[typeName] = existingEntryFieldMap;
75
+ }
76
+ let existingSelectionSet = existingEntryFieldMap[fieldName];
77
+ if (existingSelectionSet == null) {
78
+ existingSelectionSet = selectionSetsByType[typeName];
79
+ }
80
+ existingEntryFieldMap[fieldName] = existingSelectionSet
71
81
  ? mergeSelectionSets(existingSelectionSet, selectionSet)
72
82
  : selectionSet;
73
83
  }
@@ -204,9 +214,16 @@ export function stitchingDirectivesTransformer(options = {}) {
204
214
  }
205
215
  const typeNames = mergeDirective['types'];
206
216
  forEachConcreteTypeName(namedType, schema, typeNames, function generateResolveInfo(typeName) {
217
+ const mergedSelectionSets = [];
218
+ if (allSelectionSetsByType[typeName]) {
219
+ mergedSelectionSets.push(...allSelectionSetsByType[typeName]);
220
+ }
221
+ if (selectionSetsByTypeAndEntryField[typeName]?.[fieldName]) {
222
+ mergedSelectionSets.push(selectionSetsByTypeAndEntryField[typeName][fieldName]);
223
+ }
207
224
  const parsedMergeArgsExpr = parseMergeArgsExpr(mergeArgsExpr, allSelectionSetsByType[typeName] == null
208
225
  ? undefined
209
- : mergeSelectionSets(...allSelectionSetsByType[typeName]));
226
+ : mergeSelectionSets(...mergedSelectionSets));
210
227
  const additionalArgs = mergeDirective['additionalArgs'];
211
228
  if (additionalArgs != null) {
212
229
  parsedMergeArgsExpr.args = mergeDeep([
@@ -214,11 +231,22 @@ export function stitchingDirectivesTransformer(options = {}) {
214
231
  valueFromASTUntyped(parseValue(`{ ${additionalArgs} }`, { noLocation: true })),
215
232
  ]);
216
233
  }
217
- mergedTypesResolversInfo[typeName] = {
218
- fieldName,
219
- returnsList,
220
- ...parsedMergeArgsExpr,
221
- };
234
+ if (selectionSetsByTypeAndEntryField[typeName]?.[fieldName] != null) {
235
+ const typeConfigByField = (mergedTypesResolversInfoByEntryField[typeName] ||=
236
+ Object.create(null));
237
+ typeConfigByField[fieldName] = {
238
+ fieldName,
239
+ returnsList,
240
+ ...parsedMergeArgsExpr,
241
+ };
242
+ }
243
+ else {
244
+ mergedTypesResolversInfo[typeName] = {
245
+ fieldName,
246
+ returnsList,
247
+ ...parsedMergeArgsExpr,
248
+ };
249
+ }
222
250
  });
223
251
  }
224
252
  return undefined;
@@ -291,6 +319,40 @@ export function stitchingDirectivesTransformer(options = {}) {
291
319
  }
292
320
  }
293
321
  }
322
+ for (const typeName in mergedTypesResolversInfoByEntryField) {
323
+ const entryPoints = [];
324
+ const existingMergeConfig = newSubschemaConfig.merge?.[typeName];
325
+ const newMergeConfig = (newSubschemaConfig.merge ||= Object.create(null));
326
+ if (existingMergeConfig) {
327
+ const { fields, canonical, ...baseEntryPoint } = existingMergeConfig;
328
+ newMergeConfig[typeName] = {
329
+ fields,
330
+ canonical,
331
+ entryPoints,
332
+ };
333
+ entryPoints.push(baseEntryPoint);
334
+ }
335
+ else {
336
+ newMergeConfig[typeName] = {
337
+ entryPoints,
338
+ };
339
+ }
340
+ for (const fieldName in mergedTypesResolversInfoByEntryField[typeName]) {
341
+ const mergedTypeResolverInfo = mergedTypesResolversInfoByEntryField[typeName][fieldName];
342
+ const newEntryPoint = {
343
+ fieldName,
344
+ selectionSet: print(selectionSetsByTypeAndEntryField[typeName][fieldName]),
345
+ };
346
+ if (mergedTypeResolverInfo.returnsList) {
347
+ newEntryPoint.key = generateKeyFn(mergedTypeResolverInfo);
348
+ newEntryPoint.argsFromKeys = generateArgsFromKeysFn(mergedTypeResolverInfo);
349
+ }
350
+ else {
351
+ newEntryPoint.args = generateArgsFn(mergedTypeResolverInfo);
352
+ }
353
+ entryPoints.push(newEntryPoint);
354
+ }
355
+ }
294
356
  return newSubschemaConfig;
295
357
  };
296
358
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@graphql-tools/stitching-directives",
3
- "version": "3.0.2",
3
+ "version": "3.1.0",
4
4
  "description": "A set of utils for faster development of GraphQL tools",
5
5
  "sideEffects": false,
6
6
  "peerDependencies": {