@graphql-tools/stitching-directives 3.0.2 → 3.1.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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": {