@graphql-tools/stitching-directives 3.1.13-alpha-20241113142246-527bbf8c4e20af3d172439ab4746fe676b3a61c5 → 3.1.14-alpha-c1f969d9556b274c8e1313a3d2a4742f231bc03a
Sign up to get free protection for your applications and to get access to all the features.
- package/CHANGELOG.md +929 -0
- package/dist/index.cjs +1196 -0
- package/dist/index.d.cts +58 -0
- package/dist/index.d.ts +58 -0
- package/dist/index.js +1193 -0
- package/package.json +32 -42
- package/cjs/defaultStitchingDirectiveOptions.js +0 -10
- package/cjs/extractVariables.js +0 -52
- package/cjs/federationToStitchingSDL.js +0 -116
- package/cjs/getSourcePaths.js +0 -25
- package/cjs/index.js +0 -6
- package/cjs/package.json +0 -1
- package/cjs/parseMergeArgsExpr.js +0 -77
- package/cjs/pathsFromSelectionSet.js +0 -29
- package/cjs/preparseMergeArgsExpr.js +0 -31
- package/cjs/properties.js +0 -70
- package/cjs/stitchingDirectives.js +0 -78
- package/cjs/stitchingDirectivesTransformer.js +0 -490
- package/cjs/stitchingDirectivesValidator.js +0 -119
- package/cjs/types.js +0 -0
- package/esm/defaultStitchingDirectiveOptions.js +0 -7
- package/esm/extractVariables.js +0 -48
- package/esm/federationToStitchingSDL.js +0 -112
- package/esm/getSourcePaths.js +0 -21
- package/esm/index.js +0 -3
- package/esm/parseMergeArgsExpr.js +0 -73
- package/esm/pathsFromSelectionSet.js +0 -25
- package/esm/preparseMergeArgsExpr.js +0 -27
- package/esm/properties.js +0 -63
- package/esm/stitchingDirectives.js +0 -74
- package/esm/stitchingDirectivesTransformer.js +0 -486
- package/esm/stitchingDirectivesValidator.js +0 -115
- package/esm/types.js +0 -0
- package/typings/defaultStitchingDirectiveOptions.d.cts +0 -2
- package/typings/defaultStitchingDirectiveOptions.d.ts +0 -2
- package/typings/extractVariables.d.cts +0 -7
- package/typings/extractVariables.d.ts +0 -7
- package/typings/federationToStitchingSDL.d.cts +0 -2
- package/typings/federationToStitchingSDL.d.ts +0 -2
- package/typings/getSourcePaths.d.cts +0 -3
- package/typings/getSourcePaths.d.ts +0 -3
- package/typings/index.d.cts +0 -3
- package/typings/index.d.ts +0 -3
- package/typings/parseMergeArgsExpr.d.cts +0 -3
- package/typings/parseMergeArgsExpr.d.ts +0 -3
- package/typings/pathsFromSelectionSet.d.cts +0 -2
- package/typings/pathsFromSelectionSet.d.ts +0 -2
- package/typings/preparseMergeArgsExpr.d.cts +0 -6
- package/typings/preparseMergeArgsExpr.d.ts +0 -6
- package/typings/properties.d.cts +0 -5
- package/typings/properties.d.ts +0 -5
- package/typings/stitchingDirectives.d.cts +0 -19
- package/typings/stitchingDirectives.d.ts +0 -19
- package/typings/stitchingDirectivesTransformer.d.cts +0 -3
- package/typings/stitchingDirectivesTransformer.d.ts +0 -3
- package/typings/stitchingDirectivesValidator.d.cts +0 -3
- package/typings/stitchingDirectivesValidator.d.ts +0 -3
- package/typings/types.d.cts +0 -35
- package/typings/types.d.ts +0 -35
@@ -1,112 +0,0 @@
|
|
1
|
-
// Taken from https://github.com/gmac/federation-to-stitching-sdl/blob/main/index.js
|
2
|
-
import { Kind, parse, print, } from 'graphql';
|
3
|
-
import { stitchingDirectives } from './stitchingDirectives.js';
|
4
|
-
const extensionKind = /Extension$/;
|
5
|
-
const entityKinds = [
|
6
|
-
Kind.OBJECT_TYPE_DEFINITION,
|
7
|
-
Kind.OBJECT_TYPE_EXTENSION,
|
8
|
-
Kind.INTERFACE_TYPE_DEFINITION,
|
9
|
-
Kind.INTERFACE_TYPE_EXTENSION,
|
10
|
-
];
|
11
|
-
function isEntityKind(def) {
|
12
|
-
return entityKinds.includes(def.kind);
|
13
|
-
}
|
14
|
-
function getQueryTypeDef(definitions) {
|
15
|
-
const schemaDef = definitions.find(def => def.kind === Kind.SCHEMA_DEFINITION);
|
16
|
-
const typeName = schemaDef
|
17
|
-
? schemaDef.operationTypes.find(({ operation }) => operation === 'query')?.type.name.value
|
18
|
-
: 'Query';
|
19
|
-
return definitions.find(def => def.kind === Kind.OBJECT_TYPE_DEFINITION && def.name.value === typeName);
|
20
|
-
}
|
21
|
-
// Federation services are actually fairly complex,
|
22
|
-
// as the `buildFederatedSchema` helper does a fair amount
|
23
|
-
// of hidden work to setup the Federation schema specification:
|
24
|
-
// https://www.apollographql.com/docs/federation/federation-spec/#federation-schema-specification
|
25
|
-
export function federationToStitchingSDL(federationSDL, stitchingConfig = stitchingDirectives()) {
|
26
|
-
const doc = parse(federationSDL);
|
27
|
-
const entityTypes = [];
|
28
|
-
const baseTypeNames = doc.definitions.reduce((memo, typeDef) => {
|
29
|
-
if (!extensionKind.test(typeDef.kind) && 'name' in typeDef && typeDef.name) {
|
30
|
-
memo[typeDef.name.value] = true;
|
31
|
-
}
|
32
|
-
return memo;
|
33
|
-
}, {});
|
34
|
-
doc.definitions.forEach(typeDef => {
|
35
|
-
// Un-extend all types (remove "extends" keywords)...
|
36
|
-
// extended types are invalid GraphQL without a local base type to extend from.
|
37
|
-
// Stitching merges flat types in lieu of hierarchical extensions.
|
38
|
-
if (extensionKind.test(typeDef.kind) &&
|
39
|
-
'name' in typeDef &&
|
40
|
-
typeDef.name &&
|
41
|
-
!baseTypeNames[typeDef.name.value]) {
|
42
|
-
typeDef.kind = typeDef.kind.replace(extensionKind, 'Definition');
|
43
|
-
}
|
44
|
-
if (!isEntityKind(typeDef))
|
45
|
-
return;
|
46
|
-
// Find object definitions with "@key" directives;
|
47
|
-
// these are federated entities that get turned into merged types.
|
48
|
-
const keyDirs = [];
|
49
|
-
const otherDirs = [];
|
50
|
-
typeDef.directives?.forEach(dir => {
|
51
|
-
if (dir.name.value === 'key') {
|
52
|
-
keyDirs.push(dir);
|
53
|
-
}
|
54
|
-
else {
|
55
|
-
otherDirs.push(dir);
|
56
|
-
}
|
57
|
-
});
|
58
|
-
if (!keyDirs.length)
|
59
|
-
return;
|
60
|
-
// Setup stitching MergedTypeConfig for all federated entities:
|
61
|
-
const selectionSet = `{ ${keyDirs.map((dir) => dir.arguments[0].value.value).join(' ')} }`;
|
62
|
-
const keyFields = parse(selectionSet).definitions[0].selectionSet.selections.map((sel) => sel.name.value);
|
63
|
-
const keyDir = keyDirs[0];
|
64
|
-
keyDir.name.value = stitchingConfig.keyDirective.name;
|
65
|
-
keyDir.arguments[0].name.value = 'selectionSet';
|
66
|
-
keyDir.arguments[0].value.value = selectionSet;
|
67
|
-
typeDef.directives = [keyDir, ...otherDirs];
|
68
|
-
// Remove non-key "@external" fields from the type...
|
69
|
-
// the stitching query planner expects services to only publish their own fields.
|
70
|
-
// This makes "@provides" moot because the query planner can automate the logic.
|
71
|
-
typeDef.fields = typeDef.fields?.filter(fieldDef => {
|
72
|
-
return (keyFields.includes(fieldDef.name.value) ||
|
73
|
-
!fieldDef.directives?.find(dir => dir.name.value === 'external'));
|
74
|
-
});
|
75
|
-
// Discard remaining "@external" directives and any "@provides" directives
|
76
|
-
typeDef.fields?.forEach((fieldDef) => {
|
77
|
-
fieldDef.directives = fieldDef.directives.filter((dir) => !/^(external|provides)$/.test(dir.name.value));
|
78
|
-
fieldDef.directives.forEach((dir) => {
|
79
|
-
if (dir.name.value === 'requires') {
|
80
|
-
dir.name.value = stitchingConfig.computedDirective.name;
|
81
|
-
dir.arguments[0].name.value = 'selectionSet';
|
82
|
-
dir.arguments[0].value.value = `{ ${dir.arguments[0].value.value} }`;
|
83
|
-
}
|
84
|
-
});
|
85
|
-
});
|
86
|
-
if (typeDef.kind === Kind.OBJECT_TYPE_DEFINITION ||
|
87
|
-
typeDef.kind === Kind.OBJECT_TYPE_EXTENSION) {
|
88
|
-
entityTypes.push(typeDef.name.value);
|
89
|
-
}
|
90
|
-
});
|
91
|
-
// Federation service SDLs are incomplete because they omit the federation spec itself...
|
92
|
-
// (https://www.apollographql.com/docs/federation/federation-spec/#federation-schema-specification)
|
93
|
-
// To make federation SDLs into valid and parsable GraphQL schemas,
|
94
|
-
// we must fill in the missing details from the specification.
|
95
|
-
if (entityTypes.length) {
|
96
|
-
const queryDef = getQueryTypeDef(doc.definitions);
|
97
|
-
const entitiesSchema = parse(/* GraphQL */ `
|
98
|
-
scalar _Any
|
99
|
-
union _Entity = ${entityTypes.filter((v, i, a) => a.indexOf(v) === i).join(' | ')}
|
100
|
-
type Query { _entities(representations: [_Any!]!): [_Entity]! @${stitchingConfig.mergeDirective.name} }
|
101
|
-
`).definitions;
|
102
|
-
doc.definitions.push(entitiesSchema[0]);
|
103
|
-
doc.definitions.push(entitiesSchema[1]);
|
104
|
-
if (queryDef) {
|
105
|
-
queryDef.fields.push(entitiesSchema[2].fields[0]);
|
106
|
-
}
|
107
|
-
else {
|
108
|
-
doc.definitions.push(entitiesSchema[2]);
|
109
|
-
}
|
110
|
-
}
|
111
|
-
return [stitchingConfig.stitchingDirectivesTypeDefs, print(doc)].join('\n');
|
112
|
-
}
|
package/esm/getSourcePaths.js
DELETED
@@ -1,21 +0,0 @@
|
|
1
|
-
import { TypeNameMetaFieldDef } from 'graphql';
|
2
|
-
import { pathsFromSelectionSet } from './pathsFromSelectionSet.js';
|
3
|
-
export function getSourcePaths(mappingInstructions, selectionSet) {
|
4
|
-
const sourcePaths = [];
|
5
|
-
for (const mappingInstruction of mappingInstructions) {
|
6
|
-
const { sourcePath } = mappingInstruction;
|
7
|
-
if (sourcePath.length) {
|
8
|
-
sourcePaths.push(sourcePath);
|
9
|
-
continue;
|
10
|
-
}
|
11
|
-
if (selectionSet == null) {
|
12
|
-
continue;
|
13
|
-
}
|
14
|
-
const paths = pathsFromSelectionSet(selectionSet);
|
15
|
-
for (const path of paths) {
|
16
|
-
sourcePaths.push(path);
|
17
|
-
}
|
18
|
-
sourcePaths.push([TypeNameMetaFieldDef.name]);
|
19
|
-
}
|
20
|
-
return sourcePaths;
|
21
|
-
}
|
package/esm/index.js
DELETED
@@ -1,73 +0,0 @@
|
|
1
|
-
import { parseValue, valueFromASTUntyped } from 'graphql';
|
2
|
-
import { extractVariables } from './extractVariables.js';
|
3
|
-
import { getSourcePaths } from './getSourcePaths.js';
|
4
|
-
import { EXPANSION_PREFIX, KEY_DELIMITER, preparseMergeArgsExpr } from './preparseMergeArgsExpr.js';
|
5
|
-
import { propertyTreeFromPaths } from './properties.js';
|
6
|
-
export function parseMergeArgsExpr(mergeArgsExpr, selectionSet) {
|
7
|
-
const { mergeArgsExpr: newMergeArgsExpr, expansionExpressions } = preparseMergeArgsExpr(mergeArgsExpr);
|
8
|
-
const inputValue = parseValue(`{ ${newMergeArgsExpr} }`, { noLocation: true });
|
9
|
-
const { inputValue: newInputValue, variablePaths } = extractVariables(inputValue);
|
10
|
-
if (!Object.keys(expansionExpressions).length) {
|
11
|
-
if (!Object.keys(variablePaths).length) {
|
12
|
-
throw new Error('Merge arguments must declare a key.');
|
13
|
-
}
|
14
|
-
const mappingInstructions = getMappingInstructions(variablePaths);
|
15
|
-
const usedProperties = propertyTreeFromPaths(getSourcePaths(mappingInstructions, selectionSet));
|
16
|
-
return {
|
17
|
-
args: valueFromASTUntyped(newInputValue),
|
18
|
-
usedProperties,
|
19
|
-
mappingInstructions,
|
20
|
-
};
|
21
|
-
}
|
22
|
-
const expansionRegEx = new RegExp(`^${EXPANSION_PREFIX}[0-9]+$`);
|
23
|
-
for (const variableName in variablePaths) {
|
24
|
-
if (!variableName.match(expansionRegEx)) {
|
25
|
-
throw new Error('Expansions cannot be mixed with single key declarations.');
|
26
|
-
}
|
27
|
-
}
|
28
|
-
const expansions = [];
|
29
|
-
const sourcePaths = [];
|
30
|
-
for (const variableName in expansionExpressions) {
|
31
|
-
const str = expansionExpressions[variableName];
|
32
|
-
const valuePath = variablePaths[variableName];
|
33
|
-
const { inputValue: expansionInputValue, variablePaths: expansionVariablePaths } = extractVariables(parseValue(`${str}`, { noLocation: true }));
|
34
|
-
if (!Object.keys(expansionVariablePaths).length) {
|
35
|
-
throw new Error('Merge arguments must declare a key.');
|
36
|
-
}
|
37
|
-
const mappingInstructions = getMappingInstructions(expansionVariablePaths);
|
38
|
-
const value = valueFromASTUntyped(expansionInputValue);
|
39
|
-
sourcePaths.push(...getSourcePaths(mappingInstructions, selectionSet));
|
40
|
-
assertNotWithinList(valuePath);
|
41
|
-
expansions.push({
|
42
|
-
valuePath,
|
43
|
-
value,
|
44
|
-
mappingInstructions,
|
45
|
-
});
|
46
|
-
}
|
47
|
-
const usedProperties = propertyTreeFromPaths(sourcePaths);
|
48
|
-
return {
|
49
|
-
args: valueFromASTUntyped(newInputValue),
|
50
|
-
usedProperties,
|
51
|
-
expansions,
|
52
|
-
};
|
53
|
-
}
|
54
|
-
function getMappingInstructions(variablePaths) {
|
55
|
-
const mappingInstructions = [];
|
56
|
-
for (const keyPath in variablePaths) {
|
57
|
-
const valuePath = variablePaths[keyPath];
|
58
|
-
const splitKeyPath = keyPath.split(KEY_DELIMITER).slice(1);
|
59
|
-
assertNotWithinList(valuePath);
|
60
|
-
mappingInstructions.push({
|
61
|
-
destinationPath: valuePath,
|
62
|
-
sourcePath: splitKeyPath,
|
63
|
-
});
|
64
|
-
}
|
65
|
-
return mappingInstructions;
|
66
|
-
}
|
67
|
-
function assertNotWithinList(path) {
|
68
|
-
for (const pathSegment of path) {
|
69
|
-
if (typeof pathSegment === 'number') {
|
70
|
-
throw new Error('Insertions cannot be made into a list.');
|
71
|
-
}
|
72
|
-
}
|
73
|
-
}
|
@@ -1,25 +0,0 @@
|
|
1
|
-
import { Kind } from 'graphql';
|
2
|
-
export function pathsFromSelectionSet(selectionSet, path = []) {
|
3
|
-
const paths = [];
|
4
|
-
for (const selection of selectionSet.selections) {
|
5
|
-
const additions = pathsFromSelection(selection, path) ?? [];
|
6
|
-
for (const addition of additions) {
|
7
|
-
paths.push(addition);
|
8
|
-
}
|
9
|
-
}
|
10
|
-
return paths;
|
11
|
-
}
|
12
|
-
function pathsFromSelection(selection, path) {
|
13
|
-
if (selection.kind === Kind.FIELD) {
|
14
|
-
const responseKey = selection.alias?.value ?? selection.name.value;
|
15
|
-
if (selection.selectionSet) {
|
16
|
-
return pathsFromSelectionSet(selection.selectionSet, path.concat([responseKey]));
|
17
|
-
}
|
18
|
-
else {
|
19
|
-
return [path.concat([responseKey])];
|
20
|
-
}
|
21
|
-
}
|
22
|
-
else if (selection.kind === Kind.INLINE_FRAGMENT) {
|
23
|
-
return pathsFromSelectionSet(selection.selectionSet, path);
|
24
|
-
}
|
25
|
-
}
|
@@ -1,27 +0,0 @@
|
|
1
|
-
export const KEY_DELIMITER = '__dot__';
|
2
|
-
export const EXPANSION_PREFIX = '__exp';
|
3
|
-
export function preparseMergeArgsExpr(mergeArgsExpr) {
|
4
|
-
const variableRegex = /\$[_A-Za-z][_A-Za-z0-9.]*/g;
|
5
|
-
const dotRegex = /\./g;
|
6
|
-
mergeArgsExpr = mergeArgsExpr.replace(variableRegex, variable => variable.replace(dotRegex, KEY_DELIMITER));
|
7
|
-
const segments = mergeArgsExpr.split('[[');
|
8
|
-
const expansionExpressions = Object.create(null);
|
9
|
-
if (segments.length === 1) {
|
10
|
-
return { mergeArgsExpr, expansionExpressions };
|
11
|
-
}
|
12
|
-
let finalSegments = [segments[0]];
|
13
|
-
for (let i = 1; i < segments.length; i++) {
|
14
|
-
const additionalSegments = segments[i].split(']]');
|
15
|
-
if (additionalSegments.length !== 2) {
|
16
|
-
throw new Error(`Each opening "[[" must be matched by a closing "]]" without nesting.`);
|
17
|
-
}
|
18
|
-
finalSegments = finalSegments.concat(additionalSegments);
|
19
|
-
}
|
20
|
-
let finalMergeArgsExpr = finalSegments[0];
|
21
|
-
for (let i = 1; i < finalSegments.length - 1; i += 2) {
|
22
|
-
const variableName = `${EXPANSION_PREFIX}${(i - 1) / 2 + 1}`;
|
23
|
-
expansionExpressions[variableName] = finalSegments[i];
|
24
|
-
finalMergeArgsExpr += `\$${variableName}${finalSegments[i + 1]}`;
|
25
|
-
}
|
26
|
-
return { mergeArgsExpr: finalMergeArgsExpr, expansionExpressions };
|
27
|
-
}
|
package/esm/properties.js
DELETED
@@ -1,63 +0,0 @@
|
|
1
|
-
export function addProperty(object, path, value) {
|
2
|
-
const initialSegment = path[0];
|
3
|
-
if (path.length === 1) {
|
4
|
-
object[initialSegment] = value;
|
5
|
-
return;
|
6
|
-
}
|
7
|
-
let field = object[initialSegment];
|
8
|
-
if (field != null) {
|
9
|
-
addProperty(field, path.slice(1), value);
|
10
|
-
return;
|
11
|
-
}
|
12
|
-
if (typeof path[1] === 'string') {
|
13
|
-
field = Object.create(null);
|
14
|
-
}
|
15
|
-
else {
|
16
|
-
field = [];
|
17
|
-
}
|
18
|
-
addProperty(field, path.slice(1), value);
|
19
|
-
object[initialSegment] = field;
|
20
|
-
}
|
21
|
-
export function getProperty(object, path) {
|
22
|
-
if (!path.length || object == null) {
|
23
|
-
return object;
|
24
|
-
}
|
25
|
-
const newPath = path.slice();
|
26
|
-
const key = newPath.shift();
|
27
|
-
if (key == null) {
|
28
|
-
return;
|
29
|
-
}
|
30
|
-
const prop = object[key];
|
31
|
-
return getProperty(prop, newPath);
|
32
|
-
}
|
33
|
-
export function getProperties(object, propertyTree) {
|
34
|
-
if (object == null) {
|
35
|
-
return object;
|
36
|
-
}
|
37
|
-
const newObject = Object.create(null);
|
38
|
-
for (const key in propertyTree) {
|
39
|
-
const subKey = propertyTree[key];
|
40
|
-
if (subKey == null) {
|
41
|
-
newObject[key] = object[key];
|
42
|
-
continue;
|
43
|
-
}
|
44
|
-
const prop = object[key];
|
45
|
-
newObject[key] = deepMap(prop, function deepMapFn(item) {
|
46
|
-
return getProperties(item, subKey);
|
47
|
-
});
|
48
|
-
}
|
49
|
-
return newObject;
|
50
|
-
}
|
51
|
-
export function propertyTreeFromPaths(paths) {
|
52
|
-
const propertyTree = Object.create(null);
|
53
|
-
for (const path of paths) {
|
54
|
-
addProperty(propertyTree, path, null);
|
55
|
-
}
|
56
|
-
return propertyTree;
|
57
|
-
}
|
58
|
-
function deepMap(arrayOrItem, fn) {
|
59
|
-
if (Array.isArray(arrayOrItem)) {
|
60
|
-
return arrayOrItem.map(nestedArrayOrItem => deepMap(nestedArrayOrItem, fn));
|
61
|
-
}
|
62
|
-
return fn(arrayOrItem);
|
63
|
-
}
|
@@ -1,74 +0,0 @@
|
|
1
|
-
import { GraphQLDirective, GraphQLList, GraphQLNonNull, GraphQLString, } from 'graphql';
|
2
|
-
import { defaultStitchingDirectiveOptions } from './defaultStitchingDirectiveOptions.js';
|
3
|
-
import { stitchingDirectivesTransformer } from './stitchingDirectivesTransformer.js';
|
4
|
-
import { stitchingDirectivesValidator } from './stitchingDirectivesValidator.js';
|
5
|
-
export function stitchingDirectives(options = {}) {
|
6
|
-
const finalOptions = {
|
7
|
-
...defaultStitchingDirectiveOptions,
|
8
|
-
...options,
|
9
|
-
};
|
10
|
-
const { keyDirectiveName, computedDirectiveName, mergeDirectiveName, canonicalDirectiveName } = finalOptions;
|
11
|
-
const keyDirectiveTypeDefs = /* GraphQL */ `directive @${keyDirectiveName}(selectionSet: String!) on OBJECT`;
|
12
|
-
const computedDirectiveTypeDefs = /* GraphQL */ `directive @${computedDirectiveName}(selectionSet: String!) on FIELD_DEFINITION`;
|
13
|
-
const mergeDirectiveTypeDefs = /* GraphQL */ `directive @${mergeDirectiveName}(argsExpr: String, keyArg: String, keyField: String, key: [String!], additionalArgs: String) on FIELD_DEFINITION`;
|
14
|
-
const canonicalDirectiveTypeDefs = /* GraphQL */ `directive @${canonicalDirectiveName} on OBJECT | INTERFACE | INPUT_OBJECT | UNION | ENUM | SCALAR | FIELD_DEFINITION | INPUT_FIELD_DEFINITION`;
|
15
|
-
const keyDirective = new GraphQLDirective({
|
16
|
-
name: keyDirectiveName,
|
17
|
-
locations: ['OBJECT'],
|
18
|
-
args: {
|
19
|
-
selectionSet: { type: new GraphQLNonNull(GraphQLString) },
|
20
|
-
},
|
21
|
-
});
|
22
|
-
const computedDirective = new GraphQLDirective({
|
23
|
-
name: computedDirectiveName,
|
24
|
-
locations: ['FIELD_DEFINITION'],
|
25
|
-
args: {
|
26
|
-
selectionSet: { type: new GraphQLNonNull(GraphQLString) },
|
27
|
-
},
|
28
|
-
});
|
29
|
-
const mergeDirective = new GraphQLDirective({
|
30
|
-
name: mergeDirectiveName,
|
31
|
-
locations: ['FIELD_DEFINITION'],
|
32
|
-
args: {
|
33
|
-
argsExpr: { type: GraphQLString },
|
34
|
-
keyArg: { type: GraphQLString },
|
35
|
-
keyField: { type: GraphQLString },
|
36
|
-
key: { type: new GraphQLList(new GraphQLNonNull(GraphQLString)) },
|
37
|
-
additionalArgs: { type: GraphQLString },
|
38
|
-
},
|
39
|
-
});
|
40
|
-
const canonicalDirective = new GraphQLDirective({
|
41
|
-
name: canonicalDirectiveName,
|
42
|
-
locations: [
|
43
|
-
'OBJECT',
|
44
|
-
'INTERFACE',
|
45
|
-
'INPUT_OBJECT',
|
46
|
-
'UNION',
|
47
|
-
'ENUM',
|
48
|
-
'SCALAR',
|
49
|
-
'FIELD_DEFINITION',
|
50
|
-
'INPUT_FIELD_DEFINITION',
|
51
|
-
],
|
52
|
-
});
|
53
|
-
const allStitchingDirectivesTypeDefs = [
|
54
|
-
keyDirectiveTypeDefs,
|
55
|
-
computedDirectiveTypeDefs,
|
56
|
-
mergeDirectiveTypeDefs,
|
57
|
-
canonicalDirectiveTypeDefs,
|
58
|
-
].join('\n');
|
59
|
-
return {
|
60
|
-
keyDirectiveTypeDefs,
|
61
|
-
computedDirectiveTypeDefs,
|
62
|
-
mergeDirectiveTypeDefs,
|
63
|
-
canonicalDirectiveTypeDefs,
|
64
|
-
stitchingDirectivesTypeDefs: allStitchingDirectivesTypeDefs, // for backwards compatibility
|
65
|
-
allStitchingDirectivesTypeDefs,
|
66
|
-
keyDirective,
|
67
|
-
computedDirective,
|
68
|
-
mergeDirective,
|
69
|
-
canonicalDirective,
|
70
|
-
allStitchingDirectives: [keyDirective, computedDirective, mergeDirective, canonicalDirective],
|
71
|
-
stitchingDirectivesValidator: stitchingDirectivesValidator(finalOptions),
|
72
|
-
stitchingDirectivesTransformer: stitchingDirectivesTransformer(finalOptions),
|
73
|
-
};
|
74
|
-
}
|