@graphql-tools/stitching-directives 3.0.2 → 3.1.1

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