@graphql-tools/stitching-directives 3.1.13 → 3.1.14-alpha-c1f969d9556b274c8e1313a3d2a4742f231bc03a

Sign up to get free protection for your applications and to get access to all the features.
Files changed (59) hide show
  1. package/CHANGELOG.md +929 -0
  2. package/dist/index.cjs +1196 -0
  3. package/dist/index.d.cts +58 -0
  4. package/dist/index.d.ts +58 -0
  5. package/dist/index.js +1193 -0
  6. package/package.json +32 -42
  7. package/cjs/defaultStitchingDirectiveOptions.js +0 -10
  8. package/cjs/extractVariables.js +0 -52
  9. package/cjs/federationToStitchingSDL.js +0 -116
  10. package/cjs/getSourcePaths.js +0 -25
  11. package/cjs/index.js +0 -6
  12. package/cjs/package.json +0 -1
  13. package/cjs/parseMergeArgsExpr.js +0 -77
  14. package/cjs/pathsFromSelectionSet.js +0 -29
  15. package/cjs/preparseMergeArgsExpr.js +0 -31
  16. package/cjs/properties.js +0 -70
  17. package/cjs/stitchingDirectives.js +0 -78
  18. package/cjs/stitchingDirectivesTransformer.js +0 -490
  19. package/cjs/stitchingDirectivesValidator.js +0 -119
  20. package/cjs/types.js +0 -0
  21. package/esm/defaultStitchingDirectiveOptions.js +0 -7
  22. package/esm/extractVariables.js +0 -48
  23. package/esm/federationToStitchingSDL.js +0 -112
  24. package/esm/getSourcePaths.js +0 -21
  25. package/esm/index.js +0 -3
  26. package/esm/parseMergeArgsExpr.js +0 -73
  27. package/esm/pathsFromSelectionSet.js +0 -25
  28. package/esm/preparseMergeArgsExpr.js +0 -27
  29. package/esm/properties.js +0 -63
  30. package/esm/stitchingDirectives.js +0 -74
  31. package/esm/stitchingDirectivesTransformer.js +0 -486
  32. package/esm/stitchingDirectivesValidator.js +0 -115
  33. package/esm/types.js +0 -0
  34. package/typings/defaultStitchingDirectiveOptions.d.cts +0 -2
  35. package/typings/defaultStitchingDirectiveOptions.d.ts +0 -2
  36. package/typings/extractVariables.d.cts +0 -7
  37. package/typings/extractVariables.d.ts +0 -7
  38. package/typings/federationToStitchingSDL.d.cts +0 -2
  39. package/typings/federationToStitchingSDL.d.ts +0 -2
  40. package/typings/getSourcePaths.d.cts +0 -3
  41. package/typings/getSourcePaths.d.ts +0 -3
  42. package/typings/index.d.cts +0 -3
  43. package/typings/index.d.ts +0 -3
  44. package/typings/parseMergeArgsExpr.d.cts +0 -3
  45. package/typings/parseMergeArgsExpr.d.ts +0 -3
  46. package/typings/pathsFromSelectionSet.d.cts +0 -2
  47. package/typings/pathsFromSelectionSet.d.ts +0 -2
  48. package/typings/preparseMergeArgsExpr.d.cts +0 -6
  49. package/typings/preparseMergeArgsExpr.d.ts +0 -6
  50. package/typings/properties.d.cts +0 -5
  51. package/typings/properties.d.ts +0 -5
  52. package/typings/stitchingDirectives.d.cts +0 -19
  53. package/typings/stitchingDirectives.d.ts +0 -19
  54. package/typings/stitchingDirectivesTransformer.d.cts +0 -3
  55. package/typings/stitchingDirectivesTransformer.d.ts +0 -3
  56. package/typings/stitchingDirectivesValidator.d.cts +0 -3
  57. package/typings/stitchingDirectivesValidator.d.ts +0 -3
  58. package/typings/types.d.cts +0 -35
  59. package/typings/types.d.ts +0 -35
@@ -1,486 +0,0 @@
1
- import { getNamedType, getNullableType, isInterfaceType, isListType, isObjectType, isUnionType, Kind, parseValue, print, valueFromASTUntyped, } from 'graphql';
2
- import { cloneSubschemaConfig, } from '@graphql-tools/delegate';
3
- import { getDirective, getImplementingTypes, MapperKind, mapSchema, mergeDeep, parseSelectionSet, } from '@graphql-tools/utils';
4
- import { defaultStitchingDirectiveOptions } from './defaultStitchingDirectiveOptions.js';
5
- import { parseMergeArgsExpr } from './parseMergeArgsExpr.js';
6
- import { addProperty, getProperties, getProperty } from './properties.js';
7
- export function stitchingDirectivesTransformer(options = {}) {
8
- const { keyDirectiveName, computedDirectiveName, mergeDirectiveName, canonicalDirectiveName, pathToDirectivesInExtensions, } = {
9
- ...defaultStitchingDirectiveOptions,
10
- ...options,
11
- };
12
- return (subschemaConfig) => {
13
- const newSubschemaConfig = cloneSubschemaConfig(subschemaConfig);
14
- const selectionSetsByType = Object.create(null);
15
- const computedFieldSelectionSets = Object.create(null);
16
- const mergedTypesResolversInfo = Object.create(null);
17
- const canonicalTypesInfo = Object.create(null);
18
- const selectionSetsByTypeAndEntryField = Object.create(null);
19
- const mergedTypesResolversInfoByEntryField = Object.create(null);
20
- const schema = subschemaConfig.schema;
21
- function setCanonicalDefinition(typeName, fieldName) {
22
- canonicalTypesInfo[typeName] = canonicalTypesInfo[typeName] || Object.create(null);
23
- if (fieldName) {
24
- const fields = canonicalTypesInfo[typeName].fields ?? Object.create(null);
25
- canonicalTypesInfo[typeName].fields = fields;
26
- fields[fieldName] = true;
27
- }
28
- else {
29
- canonicalTypesInfo[typeName].canonical = true;
30
- }
31
- }
32
- mapSchema(schema, {
33
- [MapperKind.OBJECT_TYPE]: type => {
34
- const keyDirective = getDirective(schema, type, keyDirectiveName, pathToDirectivesInExtensions)?.[0];
35
- if (keyDirective != null) {
36
- const selectionSet = parseSelectionSet(keyDirective['selectionSet'], {
37
- noLocation: true,
38
- });
39
- selectionSetsByType[type.name] = selectionSet;
40
- }
41
- const canonicalDirective = getDirective(schema, type, canonicalDirectiveName, pathToDirectivesInExtensions)?.[0];
42
- if (canonicalDirective != null) {
43
- setCanonicalDefinition(type.name);
44
- }
45
- return undefined;
46
- },
47
- [MapperKind.OBJECT_FIELD]: (fieldConfig, fieldName, typeName) => {
48
- const computedDirective = getDirective(schema, fieldConfig, computedDirectiveName, pathToDirectivesInExtensions)?.[0];
49
- if (computedDirective != null) {
50
- const selectionSet = parseSelectionSet(computedDirective['selectionSet'], {
51
- noLocation: true,
52
- });
53
- if (!computedFieldSelectionSets[typeName]) {
54
- computedFieldSelectionSets[typeName] = Object.create(null);
55
- }
56
- computedFieldSelectionSets[typeName][fieldName] = selectionSet;
57
- }
58
- const mergeDirective = getDirective(schema, fieldConfig, mergeDirectiveName, pathToDirectivesInExtensions)?.[0];
59
- if (mergeDirective?.['keyField'] != null) {
60
- const mergeDirectiveKeyField = mergeDirective['keyField'];
61
- const selectionSet = parseSelectionSet(`{ ${mergeDirectiveKeyField}}`, {
62
- noLocation: true,
63
- });
64
- const typeNames = mergeDirective['types'];
65
- const returnType = getNamedType(fieldConfig.type);
66
- forEachConcreteType(schema, returnType, typeNames, typeName => {
67
- if (typeNames == null || typeNames.includes(typeName)) {
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
78
- ? mergeSelectionSets(existingSelectionSet, selectionSet)
79
- : selectionSet;
80
- }
81
- });
82
- }
83
- const canonicalDirective = getDirective(schema, fieldConfig, canonicalDirectiveName, pathToDirectivesInExtensions)?.[0];
84
- if (canonicalDirective != null) {
85
- setCanonicalDefinition(typeName, fieldName);
86
- }
87
- return undefined;
88
- },
89
- [MapperKind.INTERFACE_TYPE]: type => {
90
- const canonicalDirective = getDirective(schema, type, canonicalDirectiveName, pathToDirectivesInExtensions)?.[0];
91
- if (canonicalDirective) {
92
- setCanonicalDefinition(type.name);
93
- }
94
- return undefined;
95
- },
96
- [MapperKind.INTERFACE_FIELD]: (fieldConfig, fieldName, typeName) => {
97
- const canonicalDirective = getDirective(schema, fieldConfig, canonicalDirectiveName, pathToDirectivesInExtensions)?.[0];
98
- if (canonicalDirective) {
99
- setCanonicalDefinition(typeName, fieldName);
100
- }
101
- return undefined;
102
- },
103
- [MapperKind.INPUT_OBJECT_TYPE]: type => {
104
- const canonicalDirective = getDirective(schema, type, canonicalDirectiveName, pathToDirectivesInExtensions)?.[0];
105
- if (canonicalDirective) {
106
- setCanonicalDefinition(type.name);
107
- }
108
- return undefined;
109
- },
110
- [MapperKind.INPUT_OBJECT_FIELD]: (inputFieldConfig, fieldName, typeName) => {
111
- const canonicalDirective = getDirective(schema, inputFieldConfig, canonicalDirectiveName, pathToDirectivesInExtensions)?.[0];
112
- if (canonicalDirective != null) {
113
- setCanonicalDefinition(typeName, fieldName);
114
- }
115
- return undefined;
116
- },
117
- [MapperKind.UNION_TYPE]: type => {
118
- const canonicalDirective = getDirective(schema, type, canonicalDirectiveName, pathToDirectivesInExtensions)?.[0];
119
- if (canonicalDirective != null) {
120
- setCanonicalDefinition(type.name);
121
- }
122
- return undefined;
123
- },
124
- [MapperKind.ENUM_TYPE]: type => {
125
- const canonicalDirective = getDirective(schema, type, canonicalDirectiveName, pathToDirectivesInExtensions)?.[0];
126
- if (canonicalDirective != null) {
127
- setCanonicalDefinition(type.name);
128
- }
129
- return undefined;
130
- },
131
- [MapperKind.SCALAR_TYPE]: type => {
132
- const canonicalDirective = getDirective(schema, type, canonicalDirectiveName, pathToDirectivesInExtensions)?.[0];
133
- if (canonicalDirective != null) {
134
- setCanonicalDefinition(type.name);
135
- }
136
- return undefined;
137
- },
138
- });
139
- if (subschemaConfig.merge) {
140
- for (const typeName in subschemaConfig.merge) {
141
- const mergedTypeConfig = subschemaConfig.merge[typeName];
142
- if (mergedTypeConfig.selectionSet) {
143
- const selectionSet = parseSelectionSet(mergedTypeConfig.selectionSet, {
144
- noLocation: true,
145
- });
146
- if (selectionSet) {
147
- if (selectionSetsByType[typeName]) {
148
- selectionSetsByType[typeName] = mergeSelectionSets(selectionSetsByType[typeName], selectionSet);
149
- }
150
- else {
151
- selectionSetsByType[typeName] = selectionSet;
152
- }
153
- }
154
- }
155
- if (mergedTypeConfig.fields) {
156
- for (const fieldName in mergedTypeConfig.fields) {
157
- const fieldConfig = mergedTypeConfig.fields[fieldName];
158
- if (!fieldConfig.selectionSet)
159
- continue;
160
- const selectionSet = parseSelectionSet(fieldConfig.selectionSet, { noLocation: true });
161
- if (selectionSet) {
162
- if (computedFieldSelectionSets[typeName]?.[fieldName]) {
163
- computedFieldSelectionSets[typeName][fieldName] = mergeSelectionSets(computedFieldSelectionSets[typeName][fieldName], selectionSet);
164
- }
165
- else {
166
- if (computedFieldSelectionSets[typeName] == null) {
167
- computedFieldSelectionSets[typeName] = Object.create(null);
168
- }
169
- computedFieldSelectionSets[typeName][fieldName] = selectionSet;
170
- }
171
- }
172
- }
173
- }
174
- }
175
- }
176
- const allSelectionSetsByType = Object.create(null);
177
- for (const typeName in selectionSetsByType) {
178
- allSelectionSetsByType[typeName] = allSelectionSetsByType[typeName] || [];
179
- const selectionSet = selectionSetsByType[typeName];
180
- allSelectionSetsByType[typeName].push(selectionSet);
181
- }
182
- for (const typeName in computedFieldSelectionSets) {
183
- const selectionSets = computedFieldSelectionSets[typeName];
184
- for (const i in selectionSets) {
185
- allSelectionSetsByType[typeName] = allSelectionSetsByType[typeName] || [];
186
- const selectionSet = selectionSets[i];
187
- allSelectionSetsByType[typeName].push(selectionSet);
188
- }
189
- }
190
- mapSchema(schema, {
191
- [MapperKind.OBJECT_FIELD]: function objectFieldMapper(fieldConfig, fieldName) {
192
- const mergeDirective = getDirective(schema, fieldConfig, mergeDirectiveName, pathToDirectivesInExtensions)?.[0];
193
- if (mergeDirective != null) {
194
- const returnType = getNullableType(fieldConfig.type);
195
- const returnsList = isListType(returnType);
196
- const namedType = getNamedType(returnType);
197
- let mergeArgsExpr = mergeDirective['argsExpr'];
198
- if (mergeArgsExpr == null) {
199
- const key = mergeDirective['key'];
200
- const keyField = mergeDirective['keyField'];
201
- const keyExpr = key != null ? buildKeyExpr(key) : keyField != null ? `$key.${keyField}` : '$key';
202
- const keyArg = mergeDirective['keyArg'];
203
- const argNames = keyArg == null ? [Object.keys(fieldConfig.args ?? {})[0]] : keyArg.split('.');
204
- const lastArgName = argNames.pop();
205
- mergeArgsExpr = returnsList
206
- ? `${lastArgName}: [[${keyExpr}]]`
207
- : `${lastArgName}: ${keyExpr}`;
208
- for (const argName of argNames.reverse()) {
209
- mergeArgsExpr = `${argName}: { ${mergeArgsExpr} }`;
210
- }
211
- }
212
- const typeNames = mergeDirective['types'];
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
- }
221
- const parsedMergeArgsExpr = parseMergeArgsExpr(mergeArgsExpr, allSelectionSetsByType[typeName] == null
222
- ? undefined
223
- : mergeSelectionSets(...mergedSelectionSets));
224
- const additionalArgs = mergeDirective['additionalArgs'];
225
- if (additionalArgs != null) {
226
- parsedMergeArgsExpr.args = mergeDeep([
227
- parsedMergeArgsExpr.args,
228
- valueFromASTUntyped(parseValue(`{ ${additionalArgs} }`, { noLocation: true })),
229
- ]);
230
- }
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
- }
247
- });
248
- }
249
- return undefined;
250
- },
251
- });
252
- for (const typeName in selectionSetsByType) {
253
- const selectionSet = selectionSetsByType[typeName];
254
- const mergeConfig = newSubschemaConfig.merge ?? Object.create(null);
255
- newSubschemaConfig.merge = mergeConfig;
256
- if (mergeConfig[typeName] == null) {
257
- newSubschemaConfig.merge[typeName] = Object.create(null);
258
- }
259
- const mergeTypeConfig = mergeConfig[typeName];
260
- mergeTypeConfig.selectionSet = print(selectionSet);
261
- }
262
- for (const typeName in computedFieldSelectionSets) {
263
- const selectionSets = computedFieldSelectionSets[typeName];
264
- const mergeConfig = newSubschemaConfig.merge ?? Object.create(null);
265
- newSubschemaConfig.merge = mergeConfig;
266
- if (mergeConfig[typeName] == null) {
267
- mergeConfig[typeName] = Object.create(null);
268
- }
269
- const mergeTypeConfig = newSubschemaConfig.merge[typeName];
270
- const mergeTypeConfigFields = mergeTypeConfig.fields ?? Object.create(null);
271
- mergeTypeConfig.fields = mergeTypeConfigFields;
272
- for (const fieldName in selectionSets) {
273
- const selectionSet = selectionSets[fieldName];
274
- const fieldConfig = mergeTypeConfigFields[fieldName] ?? Object.create(null);
275
- mergeTypeConfigFields[fieldName] = fieldConfig;
276
- fieldConfig.selectionSet = print(selectionSet);
277
- fieldConfig.computed = true;
278
- }
279
- }
280
- for (const typeName in mergedTypesResolversInfo) {
281
- const mergedTypeResolverInfo = mergedTypesResolversInfo[typeName];
282
- const mergeConfig = newSubschemaConfig.merge ?? Object.create(null);
283
- newSubschemaConfig.merge = mergeConfig;
284
- if (newSubschemaConfig.merge[typeName] == null) {
285
- newSubschemaConfig.merge[typeName] = Object.create(null);
286
- }
287
- const mergeTypeConfig = newSubschemaConfig.merge[typeName];
288
- mergeTypeConfig.fieldName = mergedTypeResolverInfo.fieldName;
289
- if (mergedTypeResolverInfo.returnsList) {
290
- mergeTypeConfig.key = generateKeyFn(mergedTypeResolverInfo);
291
- mergeTypeConfig.argsFromKeys = generateArgsFromKeysFn(mergedTypeResolverInfo);
292
- }
293
- else {
294
- mergeTypeConfig.args = generateArgsFn(mergedTypeResolverInfo);
295
- }
296
- }
297
- for (const typeName in canonicalTypesInfo) {
298
- const canonicalTypeInfo = canonicalTypesInfo[typeName];
299
- const mergeConfig = newSubschemaConfig.merge ?? Object.create(null);
300
- newSubschemaConfig.merge = mergeConfig;
301
- if (newSubschemaConfig.merge[typeName] == null) {
302
- newSubschemaConfig.merge[typeName] = Object.create(null);
303
- }
304
- const mergeTypeConfig = newSubschemaConfig.merge[typeName];
305
- if (canonicalTypeInfo.canonical) {
306
- mergeTypeConfig.canonical = true;
307
- }
308
- if (canonicalTypeInfo.fields) {
309
- const mergeTypeConfigFields = mergeTypeConfig.fields ?? Object.create(null);
310
- mergeTypeConfig.fields = mergeTypeConfigFields;
311
- for (const fieldName in canonicalTypeInfo.fields) {
312
- if (mergeTypeConfigFields[fieldName] == null) {
313
- mergeTypeConfigFields[fieldName] = Object.create(null);
314
- }
315
- mergeTypeConfigFields[fieldName].canonical = true;
316
- }
317
- }
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
- if (entryPoints.length === 1) {
353
- const [entryPoint] = entryPoints;
354
- const { fields, canonical } = newMergeConfig[typeName];
355
- newMergeConfig[typeName] = {
356
- ...entryPoint,
357
- fields,
358
- canonical,
359
- };
360
- }
361
- }
362
- return newSubschemaConfig;
363
- };
364
- }
365
- function forEachConcreteType(schema, type, typeNames, fn) {
366
- if (isInterfaceType(type)) {
367
- for (const typeName of getImplementingTypes(type.name, schema)) {
368
- if (typeNames == null || typeNames.includes(typeName)) {
369
- fn(typeName);
370
- }
371
- }
372
- }
373
- else if (isUnionType(type)) {
374
- for (const { name: typeName } of type.getTypes()) {
375
- if (typeNames == null || typeNames.includes(typeName)) {
376
- fn(typeName);
377
- }
378
- }
379
- }
380
- else if (isObjectType(type)) {
381
- fn(type.name);
382
- }
383
- }
384
- function generateKeyFn(mergedTypeResolverInfo) {
385
- return function keyFn(originalResult) {
386
- return getProperties(originalResult, mergedTypeResolverInfo.usedProperties);
387
- };
388
- }
389
- function generateArgsFromKeysFn(mergedTypeResolverInfo) {
390
- const { expansions, args } = mergedTypeResolverInfo;
391
- return function generateArgsFromKeys(keys) {
392
- const newArgs = mergeDeep([{}, args]);
393
- if (expansions) {
394
- for (const expansion of expansions) {
395
- const mappingInstructions = expansion.mappingInstructions;
396
- const expanded = [];
397
- for (const key of keys) {
398
- let newValue = mergeDeep([{}, expansion.valuePath]);
399
- for (const { destinationPath, sourcePath } of mappingInstructions) {
400
- if (destinationPath.length) {
401
- addProperty(newValue, destinationPath, getProperty(key, sourcePath));
402
- }
403
- else {
404
- newValue = getProperty(key, sourcePath);
405
- }
406
- }
407
- expanded.push(newValue);
408
- }
409
- addProperty(newArgs, expansion.valuePath, expanded);
410
- }
411
- }
412
- return newArgs;
413
- };
414
- }
415
- function generateArgsFn(mergedTypeResolverInfo) {
416
- const { mappingInstructions, args, usedProperties } = mergedTypeResolverInfo;
417
- return function generateArgs(originalResult) {
418
- const newArgs = mergeDeep([{}, args]);
419
- const filteredResult = getProperties(originalResult, usedProperties);
420
- if (mappingInstructions) {
421
- for (const mappingInstruction of mappingInstructions) {
422
- const { destinationPath, sourcePath } = mappingInstruction;
423
- addProperty(newArgs, destinationPath, getProperty(filteredResult, sourcePath));
424
- }
425
- }
426
- return newArgs;
427
- };
428
- }
429
- function buildKeyExpr(key) {
430
- let mergedObject = {};
431
- for (const keyDef of key) {
432
- let [aliasOrKeyPath, keyPath] = keyDef.split(':');
433
- let aliasPath;
434
- if (keyPath == null) {
435
- keyPath = aliasPath = aliasOrKeyPath;
436
- }
437
- else {
438
- aliasPath = aliasOrKeyPath;
439
- }
440
- const aliasParts = aliasPath.split('.');
441
- const lastAliasPart = aliasParts.pop();
442
- if (lastAliasPart == null) {
443
- throw new Error(`Key "${key}" is invalid, no path provided.`);
444
- }
445
- let object = { [lastAliasPart]: `$key.${keyPath}` };
446
- for (const aliasPart of aliasParts.reverse()) {
447
- object = { [aliasPart]: object };
448
- }
449
- mergedObject = mergeDeep([mergedObject, object]);
450
- }
451
- return JSON.stringify(mergedObject).replace(/"/g, '');
452
- }
453
- function mergeSelectionSets(...selectionSets) {
454
- const normalizedSelections = Object.create(null);
455
- for (const selectionSet of selectionSets) {
456
- for (const selection of selectionSet.selections) {
457
- const normalizedSelection = print(selection);
458
- normalizedSelections[normalizedSelection] = selection;
459
- }
460
- }
461
- const newSelectionSet = {
462
- kind: Kind.SELECTION_SET,
463
- selections: Object.values(normalizedSelections),
464
- };
465
- return newSelectionSet;
466
- }
467
- function forEachConcreteTypeName(returnType, schema, typeNames, fn) {
468
- if (isInterfaceType(returnType)) {
469
- for (const typeName of getImplementingTypes(returnType.name, schema)) {
470
- if (typeNames == null || typeNames.includes(typeName)) {
471
- fn(typeName);
472
- }
473
- }
474
- }
475
- else if (isUnionType(returnType)) {
476
- for (const type of returnType.getTypes()) {
477
- if (typeNames == null || typeNames.includes(type.name)) {
478
- fn(type.name);
479
- }
480
- }
481
- }
482
- else if (isObjectType(returnType) &&
483
- (typeNames == null || typeNames.includes(returnType.name))) {
484
- fn(returnType.name);
485
- }
486
- }
@@ -1,115 +0,0 @@
1
- import { getNullableType, isAbstractType, isInterfaceType, isListType, isNamedType, isObjectType, isUnionType, parseValue, } from 'graphql';
2
- import { getDirective, getImplementingTypes, isSome, MapperKind, mapSchema, parseSelectionSet, } from '@graphql-tools/utils';
3
- import { defaultStitchingDirectiveOptions } from './defaultStitchingDirectiveOptions.js';
4
- import { parseMergeArgsExpr } from './parseMergeArgsExpr.js';
5
- const dottedNameRegEx = /^[_A-Za-z][_0-9A-Za-z]*(.[_A-Za-z][_0-9A-Za-z]*)*$/;
6
- export function stitchingDirectivesValidator(options = {}) {
7
- const { keyDirectiveName, computedDirectiveName, mergeDirectiveName, pathToDirectivesInExtensions, } = {
8
- ...defaultStitchingDirectiveOptions,
9
- ...options,
10
- };
11
- return (schema) => {
12
- const queryTypeName = schema.getQueryType()?.name;
13
- mapSchema(schema, {
14
- [MapperKind.OBJECT_TYPE]: type => {
15
- const keyDirective = getDirective(schema, type, keyDirectiveName, pathToDirectivesInExtensions)?.[0];
16
- if (keyDirective != null) {
17
- parseSelectionSet(keyDirective['selectionSet']);
18
- }
19
- return undefined;
20
- },
21
- [MapperKind.OBJECT_FIELD]: (fieldConfig, _fieldName, typeName) => {
22
- const computedDirective = getDirective(schema, fieldConfig, computedDirectiveName, pathToDirectivesInExtensions)?.[0];
23
- if (computedDirective != null) {
24
- parseSelectionSet(computedDirective['selectionSet']);
25
- }
26
- const mergeDirective = getDirective(schema, fieldConfig, mergeDirectiveName, pathToDirectivesInExtensions)?.[0];
27
- if (mergeDirective != null) {
28
- if (typeName !== queryTypeName) {
29
- throw new Error('@merge directive may be used only for root fields of the root Query type.');
30
- }
31
- let returnType = getNullableType(fieldConfig.type);
32
- if (isListType(returnType)) {
33
- returnType = getNullableType(returnType.ofType);
34
- }
35
- if (!isNamedType(returnType)) {
36
- throw new Error('@merge directive must be used on a field that returns an object or a list of objects.');
37
- }
38
- const mergeArgsExpr = mergeDirective['argsExpr'];
39
- if (mergeArgsExpr != null) {
40
- parseMergeArgsExpr(mergeArgsExpr);
41
- }
42
- const args = Object.keys(fieldConfig.args ?? {});
43
- const keyArg = mergeDirective['keyArg'];
44
- if (keyArg == null) {
45
- if (!mergeArgsExpr && args.length !== 1) {
46
- throw new Error('Cannot use @merge directive without `keyArg` argument if resolver takes more than one argument.');
47
- }
48
- }
49
- else if (!keyArg.match(dottedNameRegEx)) {
50
- throw new Error('`keyArg` argument for @merge directive must be a set of valid GraphQL SDL names separated by periods.');
51
- // TODO: ideally we should check that the arg exists for the resolver
52
- }
53
- const keyField = mergeDirective['keyField'];
54
- if (keyField != null && !keyField.match(dottedNameRegEx)) {
55
- throw new Error('`keyField` argument for @merge directive must be a set of valid GraphQL SDL names separated by periods.');
56
- // TODO: ideally we should check that it is part of the key
57
- }
58
- const key = mergeDirective['key'];
59
- if (key != null) {
60
- if (keyField != null) {
61
- throw new Error('Cannot use @merge directive with both `keyField` and `key` arguments.');
62
- }
63
- for (const keyDef of key) {
64
- let [aliasOrKeyPath, keyPath] = keyDef.split(':');
65
- let aliasPath;
66
- if (keyPath == null) {
67
- keyPath = aliasPath = aliasOrKeyPath;
68
- }
69
- else {
70
- aliasPath = aliasOrKeyPath;
71
- }
72
- if (keyPath != null && !keyPath.match(dottedNameRegEx)) {
73
- throw new Error('Each partial key within the `key` argument for @merge directive must be a set of valid GraphQL SDL names separated by periods.');
74
- // TODO: ideally we should check that it is part of the key
75
- }
76
- if (aliasPath != null && !aliasOrKeyPath.match(dottedNameRegEx)) {
77
- throw new Error('Each alias within the `key` argument for @merge directive must be a set of valid GraphQL SDL names separated by periods.');
78
- // TODO: ideally we should check that the arg exists within the resolver
79
- }
80
- }
81
- }
82
- const additionalArgs = mergeDirective['additionalArgs'];
83
- if (additionalArgs != null) {
84
- parseValue(`{ ${additionalArgs} }`, { noLocation: true });
85
- }
86
- if (mergeArgsExpr != null && (keyArg != null || additionalArgs != null)) {
87
- throw new Error('Cannot use @merge directive with both `argsExpr` argument and any additional argument.');
88
- }
89
- if (!isInterfaceType(returnType) &&
90
- !isUnionType(returnType) &&
91
- !isObjectType(returnType)) {
92
- throw new Error('@merge directive may be used only with resolver that return an object, interface, or union.');
93
- }
94
- const typeNames = mergeDirective['types'];
95
- if (typeNames != null) {
96
- if (!isAbstractType(returnType)) {
97
- throw new Error('Types argument can only be used with a field that returns an abstract type.');
98
- }
99
- const implementingTypes = isInterfaceType(returnType)
100
- ? getImplementingTypes(returnType.name, schema).map(typeName => schema.getType(typeName))
101
- : returnType.getTypes();
102
- const implementingTypeNames = implementingTypes.map(type => type?.name).filter(isSome);
103
- for (const typeName of typeNames) {
104
- if (!implementingTypeNames.includes(typeName)) {
105
- throw new Error(`Types argument can only include only type names that implement the field return type's abstract type.`);
106
- }
107
- }
108
- }
109
- }
110
- return undefined;
111
- },
112
- });
113
- return schema;
114
- };
115
- }
package/esm/types.js DELETED
File without changes
@@ -1,2 +0,0 @@
1
- import { StitchingDirectivesFinalOptions } from './types.cjs';
2
- export declare const defaultStitchingDirectiveOptions: StitchingDirectivesFinalOptions;
@@ -1,2 +0,0 @@
1
- import { StitchingDirectivesFinalOptions } from './types.js';
2
- export declare const defaultStitchingDirectiveOptions: StitchingDirectivesFinalOptions;
@@ -1,7 +0,0 @@
1
- import { ValueNode } from 'graphql';
2
- type VariablePaths = Record<string, Array<string | number>>;
3
- export declare function extractVariables(inputValue: ValueNode): {
4
- inputValue: ValueNode;
5
- variablePaths: VariablePaths;
6
- };
7
- export {};
@@ -1,7 +0,0 @@
1
- import { ValueNode } from 'graphql';
2
- type VariablePaths = Record<string, Array<string | number>>;
3
- export declare function extractVariables(inputValue: ValueNode): {
4
- inputValue: ValueNode;
5
- variablePaths: VariablePaths;
6
- };
7
- export {};
@@ -1,2 +0,0 @@
1
- import { StitchingDirectivesResult } from './stitchingDirectives.cjs';
2
- export declare function federationToStitchingSDL(federationSDL: string, stitchingConfig?: StitchingDirectivesResult): string;
@@ -1,2 +0,0 @@
1
- import { StitchingDirectivesResult } from './stitchingDirectives.js';
2
- export declare function federationToStitchingSDL(federationSDL: string, stitchingConfig?: StitchingDirectivesResult): string;
@@ -1,3 +0,0 @@
1
- import { SelectionSetNode } from 'graphql';
2
- import { MappingInstruction } from './types.cjs';
3
- export declare function getSourcePaths(mappingInstructions: Array<MappingInstruction>, selectionSet?: SelectionSetNode): Array<Array<string>>;
@@ -1,3 +0,0 @@
1
- import { SelectionSetNode } from 'graphql';
2
- import { MappingInstruction } from './types.js';
3
- export declare function getSourcePaths(mappingInstructions: Array<MappingInstruction>, selectionSet?: SelectionSetNode): Array<Array<string>>;
@@ -1,3 +0,0 @@
1
- export * from './stitchingDirectives.cjs';
2
- export * from './types.cjs';
3
- export * from './federationToStitchingSDL.cjs';
@@ -1,3 +0,0 @@
1
- export * from './stitchingDirectives.js';
2
- export * from './types.js';
3
- export * from './federationToStitchingSDL.js';
@@ -1,3 +0,0 @@
1
- import { SelectionSetNode } from 'graphql';
2
- import { ParsedMergeArgsExpr } from './types.cjs';
3
- export declare function parseMergeArgsExpr(mergeArgsExpr: string, selectionSet?: SelectionSetNode): ParsedMergeArgsExpr;
@@ -1,3 +0,0 @@
1
- import { SelectionSetNode } from 'graphql';
2
- import { ParsedMergeArgsExpr } from './types.js';
3
- export declare function parseMergeArgsExpr(mergeArgsExpr: string, selectionSet?: SelectionSetNode): ParsedMergeArgsExpr;