@graphql-tools/stitching-directives 3.0.0-rc-20230519104627-f6fea064 → 3.0.1-alpha-20240219120727-4ddb37add3a5ff00293680e2dd1cfc9757253ec3
Sign up to get free protection for your applications and to get access to all the features.
- package/cjs/federationToStitchingSDL.js +8 -3
- package/cjs/parseMergeArgsExpr.js +11 -3
- package/cjs/stitchingDirectives.js +2 -2
- package/cjs/stitchingDirectivesTransformer.js +21 -14
- package/cjs/stitchingDirectivesValidator.js +4 -2
- package/esm/federationToStitchingSDL.js +9 -4
- package/esm/parseMergeArgsExpr.js +11 -3
- package/esm/stitchingDirectives.js +3 -3
- package/esm/stitchingDirectivesTransformer.js +23 -16
- package/esm/stitchingDirectivesValidator.js +4 -2
- package/package.json +3 -3
@@ -38,7 +38,10 @@ function federationToStitchingSDL(federationSDL, stitchingConfig = (0, stitching
|
|
38
38
|
// Un-extend all types (remove "extends" keywords)...
|
39
39
|
// extended types are invalid GraphQL without a local base type to extend from.
|
40
40
|
// Stitching merges flat types in lieu of hierarchical extensions.
|
41
|
-
if (extensionKind.test(typeDef.kind) &&
|
41
|
+
if (extensionKind.test(typeDef.kind) &&
|
42
|
+
'name' in typeDef &&
|
43
|
+
typeDef.name &&
|
44
|
+
!baseTypeNames[typeDef.name.value]) {
|
42
45
|
typeDef.kind = typeDef.kind.replace(extensionKind, 'Definition');
|
43
46
|
}
|
44
47
|
if (!isEntityKind(typeDef))
|
@@ -69,7 +72,8 @@ function federationToStitchingSDL(federationSDL, stitchingConfig = (0, stitching
|
|
69
72
|
// the stitching query planner expects services to only publish their own fields.
|
70
73
|
// This makes "@provides" moot because the query planner can automate the logic.
|
71
74
|
typeDef.fields = typeDef.fields?.filter(fieldDef => {
|
72
|
-
return (keyFields.includes(fieldDef.name.value) ||
|
75
|
+
return (keyFields.includes(fieldDef.name.value) ||
|
76
|
+
!fieldDef.directives?.find(dir => dir.name.value === 'external'));
|
73
77
|
});
|
74
78
|
// Discard remaining "@external" directives and any "@provides" directives
|
75
79
|
typeDef.fields?.forEach((fieldDef) => {
|
@@ -82,7 +86,8 @@ function federationToStitchingSDL(federationSDL, stitchingConfig = (0, stitching
|
|
82
86
|
}
|
83
87
|
});
|
84
88
|
});
|
85
|
-
if (typeDef.kind === graphql_1.Kind.OBJECT_TYPE_DEFINITION ||
|
89
|
+
if (typeDef.kind === graphql_1.Kind.OBJECT_TYPE_DEFINITION ||
|
90
|
+
typeDef.kind === graphql_1.Kind.OBJECT_TYPE_EXTENSION) {
|
86
91
|
entityTypes.push(typeDef.name.value);
|
87
92
|
}
|
88
93
|
});
|
@@ -3,9 +3,9 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.parseMergeArgsExpr = void 0;
|
4
4
|
const graphql_1 = require("graphql");
|
5
5
|
const extractVariables_js_1 = require("./extractVariables.js");
|
6
|
+
const getSourcePaths_js_1 = require("./getSourcePaths.js");
|
6
7
|
const preparseMergeArgsExpr_js_1 = require("./preparseMergeArgsExpr.js");
|
7
8
|
const properties_js_1 = require("./properties.js");
|
8
|
-
const getSourcePaths_js_1 = require("./getSourcePaths.js");
|
9
9
|
function parseMergeArgsExpr(mergeArgsExpr, selectionSet) {
|
10
10
|
const { mergeArgsExpr: newMergeArgsExpr, expansionExpressions } = (0, preparseMergeArgsExpr_js_1.preparseMergeArgsExpr)(mergeArgsExpr);
|
11
11
|
const inputValue = (0, graphql_1.parseValue)(`{ ${newMergeArgsExpr} }`, { noLocation: true });
|
@@ -16,7 +16,11 @@ function parseMergeArgsExpr(mergeArgsExpr, selectionSet) {
|
|
16
16
|
}
|
17
17
|
const mappingInstructions = getMappingInstructions(variablePaths);
|
18
18
|
const usedProperties = (0, properties_js_1.propertyTreeFromPaths)((0, getSourcePaths_js_1.getSourcePaths)(mappingInstructions, selectionSet));
|
19
|
-
return {
|
19
|
+
return {
|
20
|
+
args: (0, graphql_1.valueFromASTUntyped)(newInputValue),
|
21
|
+
usedProperties,
|
22
|
+
mappingInstructions,
|
23
|
+
};
|
20
24
|
}
|
21
25
|
const expansionRegEx = new RegExp(`^${preparseMergeArgsExpr_js_1.EXPANSION_PREFIX}[0-9]+$`);
|
22
26
|
for (const variableName in variablePaths) {
|
@@ -44,7 +48,11 @@ function parseMergeArgsExpr(mergeArgsExpr, selectionSet) {
|
|
44
48
|
});
|
45
49
|
}
|
46
50
|
const usedProperties = (0, properties_js_1.propertyTreeFromPaths)(sourcePaths);
|
47
|
-
return {
|
51
|
+
return {
|
52
|
+
args: (0, graphql_1.valueFromASTUntyped)(newInputValue),
|
53
|
+
usedProperties,
|
54
|
+
expansions,
|
55
|
+
};
|
48
56
|
}
|
49
57
|
exports.parseMergeArgsExpr = parseMergeArgsExpr;
|
50
58
|
function getMappingInstructions(variablePaths) {
|
@@ -3,8 +3,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.stitchingDirectives = void 0;
|
4
4
|
const graphql_1 = require("graphql");
|
5
5
|
const defaultStitchingDirectiveOptions_js_1 = require("./defaultStitchingDirectiveOptions.js");
|
6
|
-
const stitchingDirectivesValidator_js_1 = require("./stitchingDirectivesValidator.js");
|
7
6
|
const stitchingDirectivesTransformer_js_1 = require("./stitchingDirectivesTransformer.js");
|
7
|
+
const stitchingDirectivesValidator_js_1 = require("./stitchingDirectivesValidator.js");
|
8
8
|
function stitchingDirectives(options = {}) {
|
9
9
|
const finalOptions = {
|
10
10
|
...defaultStitchingDirectiveOptions_js_1.defaultStitchingDirectiveOptions,
|
@@ -64,7 +64,7 @@ function stitchingDirectives(options = {}) {
|
|
64
64
|
computedDirectiveTypeDefs,
|
65
65
|
mergeDirectiveTypeDefs,
|
66
66
|
canonicalDirectiveTypeDefs,
|
67
|
-
stitchingDirectivesTypeDefs: allStitchingDirectivesTypeDefs,
|
67
|
+
stitchingDirectivesTypeDefs: allStitchingDirectivesTypeDefs, // for backwards compatibility
|
68
68
|
allStitchingDirectivesTypeDefs,
|
69
69
|
keyDirective,
|
70
70
|
computedDirective,
|
@@ -37,7 +37,9 @@ function stitchingDirectivesTransformer(options = {}) {
|
|
37
37
|
[utils_1.MapperKind.OBJECT_TYPE]: type => {
|
38
38
|
const keyDirective = (0, utils_1.getDirective)(schema, type, keyDirectiveName, pathToDirectivesInExtensions)?.[0];
|
39
39
|
if (keyDirective != null) {
|
40
|
-
const selectionSet = (0, utils_1.parseSelectionSet)(keyDirective['selectionSet'], {
|
40
|
+
const selectionSet = (0, utils_1.parseSelectionSet)(keyDirective['selectionSet'], {
|
41
|
+
noLocation: true,
|
42
|
+
});
|
41
43
|
selectionSetsByType[type.name] = selectionSet;
|
42
44
|
}
|
43
45
|
const canonicalDirective = (0, utils_1.getDirective)(schema, type, canonicalDirectiveName, pathToDirectivesInExtensions)?.[0];
|
@@ -49,7 +51,9 @@ function stitchingDirectivesTransformer(options = {}) {
|
|
49
51
|
[utils_1.MapperKind.OBJECT_FIELD]: (fieldConfig, fieldName, typeName) => {
|
50
52
|
const computedDirective = (0, utils_1.getDirective)(schema, fieldConfig, computedDirectiveName, pathToDirectivesInExtensions)?.[0];
|
51
53
|
if (computedDirective != null) {
|
52
|
-
const selectionSet = (0, utils_1.parseSelectionSet)(computedDirective['selectionSet'], {
|
54
|
+
const selectionSet = (0, utils_1.parseSelectionSet)(computedDirective['selectionSet'], {
|
55
|
+
noLocation: true,
|
56
|
+
});
|
53
57
|
if (!computedFieldSelectionSets[typeName]) {
|
54
58
|
computedFieldSelectionSets[typeName] = Object.create(null);
|
55
59
|
}
|
@@ -58,7 +62,9 @@ function stitchingDirectivesTransformer(options = {}) {
|
|
58
62
|
const mergeDirective = (0, utils_1.getDirective)(schema, fieldConfig, mergeDirectiveName, pathToDirectivesInExtensions)?.[0];
|
59
63
|
if (mergeDirective?.['keyField'] != null) {
|
60
64
|
const mergeDirectiveKeyField = mergeDirective['keyField'];
|
61
|
-
const selectionSet = (0, utils_1.parseSelectionSet)(`{ ${mergeDirectiveKeyField}}`, {
|
65
|
+
const selectionSet = (0, utils_1.parseSelectionSet)(`{ ${mergeDirectiveKeyField}}`, {
|
66
|
+
noLocation: true,
|
67
|
+
});
|
62
68
|
const typeNames = mergeDirective['types'];
|
63
69
|
const returnType = (0, graphql_1.getNamedType)(fieldConfig.type);
|
64
70
|
forEachConcreteType(schema, returnType, typeNames, typeName => {
|
@@ -130,7 +136,9 @@ function stitchingDirectivesTransformer(options = {}) {
|
|
130
136
|
for (const typeName in subschemaConfig.merge) {
|
131
137
|
const mergedTypeConfig = subschemaConfig.merge[typeName];
|
132
138
|
if (mergedTypeConfig.selectionSet) {
|
133
|
-
const selectionSet = (0, utils_1.parseSelectionSet)(mergedTypeConfig.selectionSet, {
|
139
|
+
const selectionSet = (0, utils_1.parseSelectionSet)(mergedTypeConfig.selectionSet, {
|
140
|
+
noLocation: true,
|
141
|
+
});
|
134
142
|
if (selectionSet) {
|
135
143
|
if (selectionSetsByType[typeName]) {
|
136
144
|
selectionSetsByType[typeName] = mergeSelectionSets(selectionSetsByType[typeName], selectionSet);
|
@@ -190,7 +198,9 @@ function stitchingDirectivesTransformer(options = {}) {
|
|
190
198
|
const keyArg = mergeDirective['keyArg'];
|
191
199
|
const argNames = keyArg == null ? [Object.keys(fieldConfig.args ?? {})[0]] : keyArg.split('.');
|
192
200
|
const lastArgName = argNames.pop();
|
193
|
-
mergeArgsExpr = returnsList
|
201
|
+
mergeArgsExpr = returnsList
|
202
|
+
? `${lastArgName}: [[${keyExpr}]]`
|
203
|
+
: `${lastArgName}: ${keyExpr}`;
|
194
204
|
for (const argName of argNames.reverse()) {
|
195
205
|
mergeArgsExpr = `${argName}: { ${mergeArgsExpr} }`;
|
196
206
|
}
|
@@ -219,8 +229,7 @@ function stitchingDirectivesTransformer(options = {}) {
|
|
219
229
|
});
|
220
230
|
for (const typeName in selectionSetsByType) {
|
221
231
|
const selectionSet = selectionSetsByType[typeName];
|
222
|
-
const mergeConfig = newSubschemaConfig.merge ??
|
223
|
-
Object.create(null);
|
232
|
+
const mergeConfig = newSubschemaConfig.merge ?? Object.create(null);
|
224
233
|
newSubschemaConfig.merge = mergeConfig;
|
225
234
|
if (mergeConfig[typeName] == null) {
|
226
235
|
newSubschemaConfig.merge[typeName] = Object.create(null);
|
@@ -230,8 +239,7 @@ function stitchingDirectivesTransformer(options = {}) {
|
|
230
239
|
}
|
231
240
|
for (const typeName in computedFieldSelectionSets) {
|
232
241
|
const selectionSets = computedFieldSelectionSets[typeName];
|
233
|
-
const mergeConfig = newSubschemaConfig.merge ??
|
234
|
-
Object.create(null);
|
242
|
+
const mergeConfig = newSubschemaConfig.merge ?? Object.create(null);
|
235
243
|
newSubschemaConfig.merge = mergeConfig;
|
236
244
|
if (mergeConfig[typeName] == null) {
|
237
245
|
mergeConfig[typeName] = Object.create(null);
|
@@ -249,8 +257,7 @@ function stitchingDirectivesTransformer(options = {}) {
|
|
249
257
|
}
|
250
258
|
for (const typeName in mergedTypesResolversInfo) {
|
251
259
|
const mergedTypeResolverInfo = mergedTypesResolversInfo[typeName];
|
252
|
-
const mergeConfig = newSubschemaConfig.merge ??
|
253
|
-
Object.create(null);
|
260
|
+
const mergeConfig = newSubschemaConfig.merge ?? Object.create(null);
|
254
261
|
newSubschemaConfig.merge = mergeConfig;
|
255
262
|
if (newSubschemaConfig.merge[typeName] == null) {
|
256
263
|
newSubschemaConfig.merge[typeName] = Object.create(null);
|
@@ -267,8 +274,7 @@ function stitchingDirectivesTransformer(options = {}) {
|
|
267
274
|
}
|
268
275
|
for (const typeName in canonicalTypesInfo) {
|
269
276
|
const canonicalTypeInfo = canonicalTypesInfo[typeName];
|
270
|
-
const mergeConfig = newSubschemaConfig.merge ??
|
271
|
-
Object.create(null);
|
277
|
+
const mergeConfig = newSubschemaConfig.merge ?? Object.create(null);
|
272
278
|
newSubschemaConfig.merge = mergeConfig;
|
273
279
|
if (newSubschemaConfig.merge[typeName] == null) {
|
274
280
|
newSubschemaConfig.merge[typeName] = Object.create(null);
|
@@ -409,7 +415,8 @@ function forEachConcreteTypeName(returnType, schema, typeNames, fn) {
|
|
409
415
|
}
|
410
416
|
}
|
411
417
|
}
|
412
|
-
else if ((0, graphql_1.isObjectType)(returnType) &&
|
418
|
+
else if ((0, graphql_1.isObjectType)(returnType) &&
|
419
|
+
(typeNames == null || typeNames.includes(returnType.name))) {
|
413
420
|
fn(returnType.name);
|
414
421
|
}
|
415
422
|
}
|
@@ -7,7 +7,7 @@ const defaultStitchingDirectiveOptions_js_1 = require("./defaultStitchingDirecti
|
|
7
7
|
const parseMergeArgsExpr_js_1 = require("./parseMergeArgsExpr.js");
|
8
8
|
const dottedNameRegEx = /^[_A-Za-z][_0-9A-Za-z]*(.[_A-Za-z][_0-9A-Za-z]*)*$/;
|
9
9
|
function stitchingDirectivesValidator(options = {}) {
|
10
|
-
const { keyDirectiveName, computedDirectiveName, mergeDirectiveName, pathToDirectivesInExtensions } = {
|
10
|
+
const { keyDirectiveName, computedDirectiveName, mergeDirectiveName, pathToDirectivesInExtensions, } = {
|
11
11
|
...defaultStitchingDirectiveOptions_js_1.defaultStitchingDirectiveOptions,
|
12
12
|
...options,
|
13
13
|
};
|
@@ -89,7 +89,9 @@ function stitchingDirectivesValidator(options = {}) {
|
|
89
89
|
if (mergeArgsExpr != null && (keyArg != null || additionalArgs != null)) {
|
90
90
|
throw new Error('Cannot use @merge directive with both `argsExpr` argument and any additional argument.');
|
91
91
|
}
|
92
|
-
if (!(0, graphql_1.isInterfaceType)(returnType) &&
|
92
|
+
if (!(0, graphql_1.isInterfaceType)(returnType) &&
|
93
|
+
!(0, graphql_1.isUnionType)(returnType) &&
|
94
|
+
!(0, graphql_1.isObjectType)(returnType)) {
|
93
95
|
throw new Error('@merge directive may be used only with resolver that return an object, interface, or union.');
|
94
96
|
}
|
95
97
|
const typeNames = mergeDirective['types'];
|
@@ -1,5 +1,5 @@
|
|
1
1
|
// Taken from https://github.com/gmac/federation-to-stitching-sdl/blob/main/index.js
|
2
|
-
import {
|
2
|
+
import { Kind, parse, print, } from 'graphql';
|
3
3
|
import { stitchingDirectives } from './stitchingDirectives.js';
|
4
4
|
const extensionKind = /Extension$/;
|
5
5
|
const entityKinds = [
|
@@ -35,7 +35,10 @@ export function federationToStitchingSDL(federationSDL, stitchingConfig = stitch
|
|
35
35
|
// Un-extend all types (remove "extends" keywords)...
|
36
36
|
// extended types are invalid GraphQL without a local base type to extend from.
|
37
37
|
// Stitching merges flat types in lieu of hierarchical extensions.
|
38
|
-
if (extensionKind.test(typeDef.kind) &&
|
38
|
+
if (extensionKind.test(typeDef.kind) &&
|
39
|
+
'name' in typeDef &&
|
40
|
+
typeDef.name &&
|
41
|
+
!baseTypeNames[typeDef.name.value]) {
|
39
42
|
typeDef.kind = typeDef.kind.replace(extensionKind, 'Definition');
|
40
43
|
}
|
41
44
|
if (!isEntityKind(typeDef))
|
@@ -66,7 +69,8 @@ export function federationToStitchingSDL(federationSDL, stitchingConfig = stitch
|
|
66
69
|
// the stitching query planner expects services to only publish their own fields.
|
67
70
|
// This makes "@provides" moot because the query planner can automate the logic.
|
68
71
|
typeDef.fields = typeDef.fields?.filter(fieldDef => {
|
69
|
-
return (keyFields.includes(fieldDef.name.value) ||
|
72
|
+
return (keyFields.includes(fieldDef.name.value) ||
|
73
|
+
!fieldDef.directives?.find(dir => dir.name.value === 'external'));
|
70
74
|
});
|
71
75
|
// Discard remaining "@external" directives and any "@provides" directives
|
72
76
|
typeDef.fields?.forEach((fieldDef) => {
|
@@ -79,7 +83,8 @@ export function federationToStitchingSDL(federationSDL, stitchingConfig = stitch
|
|
79
83
|
}
|
80
84
|
});
|
81
85
|
});
|
82
|
-
if (typeDef.kind === Kind.OBJECT_TYPE_DEFINITION ||
|
86
|
+
if (typeDef.kind === Kind.OBJECT_TYPE_DEFINITION ||
|
87
|
+
typeDef.kind === Kind.OBJECT_TYPE_EXTENSION) {
|
83
88
|
entityTypes.push(typeDef.name.value);
|
84
89
|
}
|
85
90
|
});
|
@@ -1,8 +1,8 @@
|
|
1
1
|
import { parseValue, valueFromASTUntyped } from 'graphql';
|
2
2
|
import { extractVariables } from './extractVariables.js';
|
3
|
+
import { getSourcePaths } from './getSourcePaths.js';
|
3
4
|
import { EXPANSION_PREFIX, KEY_DELIMITER, preparseMergeArgsExpr } from './preparseMergeArgsExpr.js';
|
4
5
|
import { propertyTreeFromPaths } from './properties.js';
|
5
|
-
import { getSourcePaths } from './getSourcePaths.js';
|
6
6
|
export function parseMergeArgsExpr(mergeArgsExpr, selectionSet) {
|
7
7
|
const { mergeArgsExpr: newMergeArgsExpr, expansionExpressions } = preparseMergeArgsExpr(mergeArgsExpr);
|
8
8
|
const inputValue = parseValue(`{ ${newMergeArgsExpr} }`, { noLocation: true });
|
@@ -13,7 +13,11 @@ export function parseMergeArgsExpr(mergeArgsExpr, selectionSet) {
|
|
13
13
|
}
|
14
14
|
const mappingInstructions = getMappingInstructions(variablePaths);
|
15
15
|
const usedProperties = propertyTreeFromPaths(getSourcePaths(mappingInstructions, selectionSet));
|
16
|
-
return {
|
16
|
+
return {
|
17
|
+
args: valueFromASTUntyped(newInputValue),
|
18
|
+
usedProperties,
|
19
|
+
mappingInstructions,
|
20
|
+
};
|
17
21
|
}
|
18
22
|
const expansionRegEx = new RegExp(`^${EXPANSION_PREFIX}[0-9]+$`);
|
19
23
|
for (const variableName in variablePaths) {
|
@@ -41,7 +45,11 @@ export function parseMergeArgsExpr(mergeArgsExpr, selectionSet) {
|
|
41
45
|
});
|
42
46
|
}
|
43
47
|
const usedProperties = propertyTreeFromPaths(sourcePaths);
|
44
|
-
return {
|
48
|
+
return {
|
49
|
+
args: valueFromASTUntyped(newInputValue),
|
50
|
+
usedProperties,
|
51
|
+
expansions,
|
52
|
+
};
|
45
53
|
}
|
46
54
|
function getMappingInstructions(variablePaths) {
|
47
55
|
const mappingInstructions = [];
|
@@ -1,7 +1,7 @@
|
|
1
|
-
import { GraphQLDirective, GraphQLList, GraphQLNonNull, GraphQLString } from 'graphql';
|
1
|
+
import { GraphQLDirective, GraphQLList, GraphQLNonNull, GraphQLString, } from 'graphql';
|
2
2
|
import { defaultStitchingDirectiveOptions } from './defaultStitchingDirectiveOptions.js';
|
3
|
-
import { stitchingDirectivesValidator } from './stitchingDirectivesValidator.js';
|
4
3
|
import { stitchingDirectivesTransformer } from './stitchingDirectivesTransformer.js';
|
4
|
+
import { stitchingDirectivesValidator } from './stitchingDirectivesValidator.js';
|
5
5
|
export function stitchingDirectives(options = {}) {
|
6
6
|
const finalOptions = {
|
7
7
|
...defaultStitchingDirectiveOptions,
|
@@ -61,7 +61,7 @@ export function stitchingDirectives(options = {}) {
|
|
61
61
|
computedDirectiveTypeDefs,
|
62
62
|
mergeDirectiveTypeDefs,
|
63
63
|
canonicalDirectiveTypeDefs,
|
64
|
-
stitchingDirectivesTypeDefs: allStitchingDirectivesTypeDefs,
|
64
|
+
stitchingDirectivesTypeDefs: allStitchingDirectivesTypeDefs, // for backwards compatibility
|
65
65
|
allStitchingDirectivesTypeDefs,
|
66
66
|
keyDirective,
|
67
67
|
computedDirective,
|
@@ -1,9 +1,9 @@
|
|
1
1
|
import { getNamedType, getNullableType, isInterfaceType, isListType, isObjectType, isUnionType, Kind, parseValue, print, valueFromASTUntyped, } from 'graphql';
|
2
|
-
import { cloneSubschemaConfig } from '@graphql-tools/delegate';
|
2
|
+
import { cloneSubschemaConfig, } from '@graphql-tools/delegate';
|
3
3
|
import { getDirective, getImplementingTypes, MapperKind, mapSchema, mergeDeep, parseSelectionSet, } from '@graphql-tools/utils';
|
4
4
|
import { defaultStitchingDirectiveOptions } from './defaultStitchingDirectiveOptions.js';
|
5
5
|
import { parseMergeArgsExpr } from './parseMergeArgsExpr.js';
|
6
|
-
import { addProperty,
|
6
|
+
import { addProperty, getProperties, getProperty } from './properties.js';
|
7
7
|
import { stitchingDirectivesValidator } from './stitchingDirectivesValidator.js';
|
8
8
|
export function stitchingDirectivesTransformer(options = {}) {
|
9
9
|
const { keyDirectiveName, computedDirectiveName, mergeDirectiveName, canonicalDirectiveName, pathToDirectivesInExtensions, } = {
|
@@ -34,7 +34,9 @@ export function stitchingDirectivesTransformer(options = {}) {
|
|
34
34
|
[MapperKind.OBJECT_TYPE]: type => {
|
35
35
|
const keyDirective = getDirective(schema, type, keyDirectiveName, pathToDirectivesInExtensions)?.[0];
|
36
36
|
if (keyDirective != null) {
|
37
|
-
const selectionSet = parseSelectionSet(keyDirective['selectionSet'], {
|
37
|
+
const selectionSet = parseSelectionSet(keyDirective['selectionSet'], {
|
38
|
+
noLocation: true,
|
39
|
+
});
|
38
40
|
selectionSetsByType[type.name] = selectionSet;
|
39
41
|
}
|
40
42
|
const canonicalDirective = getDirective(schema, type, canonicalDirectiveName, pathToDirectivesInExtensions)?.[0];
|
@@ -46,7 +48,9 @@ export function stitchingDirectivesTransformer(options = {}) {
|
|
46
48
|
[MapperKind.OBJECT_FIELD]: (fieldConfig, fieldName, typeName) => {
|
47
49
|
const computedDirective = getDirective(schema, fieldConfig, computedDirectiveName, pathToDirectivesInExtensions)?.[0];
|
48
50
|
if (computedDirective != null) {
|
49
|
-
const selectionSet = parseSelectionSet(computedDirective['selectionSet'], {
|
51
|
+
const selectionSet = parseSelectionSet(computedDirective['selectionSet'], {
|
52
|
+
noLocation: true,
|
53
|
+
});
|
50
54
|
if (!computedFieldSelectionSets[typeName]) {
|
51
55
|
computedFieldSelectionSets[typeName] = Object.create(null);
|
52
56
|
}
|
@@ -55,7 +59,9 @@ export function stitchingDirectivesTransformer(options = {}) {
|
|
55
59
|
const mergeDirective = getDirective(schema, fieldConfig, mergeDirectiveName, pathToDirectivesInExtensions)?.[0];
|
56
60
|
if (mergeDirective?.['keyField'] != null) {
|
57
61
|
const mergeDirectiveKeyField = mergeDirective['keyField'];
|
58
|
-
const selectionSet = parseSelectionSet(`{ ${mergeDirectiveKeyField}}`, {
|
62
|
+
const selectionSet = parseSelectionSet(`{ ${mergeDirectiveKeyField}}`, {
|
63
|
+
noLocation: true,
|
64
|
+
});
|
59
65
|
const typeNames = mergeDirective['types'];
|
60
66
|
const returnType = getNamedType(fieldConfig.type);
|
61
67
|
forEachConcreteType(schema, returnType, typeNames, typeName => {
|
@@ -127,7 +133,9 @@ export function stitchingDirectivesTransformer(options = {}) {
|
|
127
133
|
for (const typeName in subschemaConfig.merge) {
|
128
134
|
const mergedTypeConfig = subschemaConfig.merge[typeName];
|
129
135
|
if (mergedTypeConfig.selectionSet) {
|
130
|
-
const selectionSet = parseSelectionSet(mergedTypeConfig.selectionSet, {
|
136
|
+
const selectionSet = parseSelectionSet(mergedTypeConfig.selectionSet, {
|
137
|
+
noLocation: true,
|
138
|
+
});
|
131
139
|
if (selectionSet) {
|
132
140
|
if (selectionSetsByType[typeName]) {
|
133
141
|
selectionSetsByType[typeName] = mergeSelectionSets(selectionSetsByType[typeName], selectionSet);
|
@@ -187,7 +195,9 @@ export function stitchingDirectivesTransformer(options = {}) {
|
|
187
195
|
const keyArg = mergeDirective['keyArg'];
|
188
196
|
const argNames = keyArg == null ? [Object.keys(fieldConfig.args ?? {})[0]] : keyArg.split('.');
|
189
197
|
const lastArgName = argNames.pop();
|
190
|
-
mergeArgsExpr = returnsList
|
198
|
+
mergeArgsExpr = returnsList
|
199
|
+
? `${lastArgName}: [[${keyExpr}]]`
|
200
|
+
: `${lastArgName}: ${keyExpr}`;
|
191
201
|
for (const argName of argNames.reverse()) {
|
192
202
|
mergeArgsExpr = `${argName}: { ${mergeArgsExpr} }`;
|
193
203
|
}
|
@@ -216,8 +226,7 @@ export function stitchingDirectivesTransformer(options = {}) {
|
|
216
226
|
});
|
217
227
|
for (const typeName in selectionSetsByType) {
|
218
228
|
const selectionSet = selectionSetsByType[typeName];
|
219
|
-
const mergeConfig = newSubschemaConfig.merge ??
|
220
|
-
Object.create(null);
|
229
|
+
const mergeConfig = newSubschemaConfig.merge ?? Object.create(null);
|
221
230
|
newSubschemaConfig.merge = mergeConfig;
|
222
231
|
if (mergeConfig[typeName] == null) {
|
223
232
|
newSubschemaConfig.merge[typeName] = Object.create(null);
|
@@ -227,8 +236,7 @@ export function stitchingDirectivesTransformer(options = {}) {
|
|
227
236
|
}
|
228
237
|
for (const typeName in computedFieldSelectionSets) {
|
229
238
|
const selectionSets = computedFieldSelectionSets[typeName];
|
230
|
-
const mergeConfig = newSubschemaConfig.merge ??
|
231
|
-
Object.create(null);
|
239
|
+
const mergeConfig = newSubschemaConfig.merge ?? Object.create(null);
|
232
240
|
newSubschemaConfig.merge = mergeConfig;
|
233
241
|
if (mergeConfig[typeName] == null) {
|
234
242
|
mergeConfig[typeName] = Object.create(null);
|
@@ -246,8 +254,7 @@ export function stitchingDirectivesTransformer(options = {}) {
|
|
246
254
|
}
|
247
255
|
for (const typeName in mergedTypesResolversInfo) {
|
248
256
|
const mergedTypeResolverInfo = mergedTypesResolversInfo[typeName];
|
249
|
-
const mergeConfig = newSubschemaConfig.merge ??
|
250
|
-
Object.create(null);
|
257
|
+
const mergeConfig = newSubschemaConfig.merge ?? Object.create(null);
|
251
258
|
newSubschemaConfig.merge = mergeConfig;
|
252
259
|
if (newSubschemaConfig.merge[typeName] == null) {
|
253
260
|
newSubschemaConfig.merge[typeName] = Object.create(null);
|
@@ -264,8 +271,7 @@ export function stitchingDirectivesTransformer(options = {}) {
|
|
264
271
|
}
|
265
272
|
for (const typeName in canonicalTypesInfo) {
|
266
273
|
const canonicalTypeInfo = canonicalTypesInfo[typeName];
|
267
|
-
const mergeConfig = newSubschemaConfig.merge ??
|
268
|
-
Object.create(null);
|
274
|
+
const mergeConfig = newSubschemaConfig.merge ?? Object.create(null);
|
269
275
|
newSubschemaConfig.merge = mergeConfig;
|
270
276
|
if (newSubschemaConfig.merge[typeName] == null) {
|
271
277
|
newSubschemaConfig.merge[typeName] = Object.create(null);
|
@@ -405,7 +411,8 @@ function forEachConcreteTypeName(returnType, schema, typeNames, fn) {
|
|
405
411
|
}
|
406
412
|
}
|
407
413
|
}
|
408
|
-
else if (isObjectType(returnType) &&
|
414
|
+
else if (isObjectType(returnType) &&
|
415
|
+
(typeNames == null || typeNames.includes(returnType.name))) {
|
409
416
|
fn(returnType.name);
|
410
417
|
}
|
411
418
|
}
|
@@ -4,7 +4,7 @@ import { defaultStitchingDirectiveOptions } from './defaultStitchingDirectiveOpt
|
|
4
4
|
import { parseMergeArgsExpr } from './parseMergeArgsExpr.js';
|
5
5
|
const dottedNameRegEx = /^[_A-Za-z][_0-9A-Za-z]*(.[_A-Za-z][_0-9A-Za-z]*)*$/;
|
6
6
|
export function stitchingDirectivesValidator(options = {}) {
|
7
|
-
const { keyDirectiveName, computedDirectiveName, mergeDirectiveName, pathToDirectivesInExtensions } = {
|
7
|
+
const { keyDirectiveName, computedDirectiveName, mergeDirectiveName, pathToDirectivesInExtensions, } = {
|
8
8
|
...defaultStitchingDirectiveOptions,
|
9
9
|
...options,
|
10
10
|
};
|
@@ -86,7 +86,9 @@ export function stitchingDirectivesValidator(options = {}) {
|
|
86
86
|
if (mergeArgsExpr != null && (keyArg != null || additionalArgs != null)) {
|
87
87
|
throw new Error('Cannot use @merge directive with both `argsExpr` argument and any additional argument.');
|
88
88
|
}
|
89
|
-
if (!isInterfaceType(returnType) &&
|
89
|
+
if (!isInterfaceType(returnType) &&
|
90
|
+
!isUnionType(returnType) &&
|
91
|
+
!isObjectType(returnType)) {
|
90
92
|
throw new Error('@merge directive may be used only with resolver that return an object, interface, or union.');
|
91
93
|
}
|
92
94
|
const typeNames = mergeDirective['types'];
|
package/package.json
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
{
|
2
2
|
"name": "@graphql-tools/stitching-directives",
|
3
|
-
"version": "3.0.
|
3
|
+
"version": "3.0.1-alpha-20240219120727-4ddb37add3a5ff00293680e2dd1cfc9757253ec3",
|
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 || ^17.0.0"
|
8
8
|
},
|
9
9
|
"dependencies": {
|
10
|
-
"@graphql-tools/delegate": "10.0.
|
11
|
-
"@graphql-tools/utils": "10.0.0
|
10
|
+
"@graphql-tools/delegate": "10.0.4-alpha-20240219120727-4ddb37add3a5ff00293680e2dd1cfc9757253ec3",
|
11
|
+
"@graphql-tools/utils": "^10.0.0",
|
12
12
|
"tslib": "^2.4.0"
|
13
13
|
},
|
14
14
|
"repository": {
|