@graphql-tools/merge 8.2.15 → 8.3.0-alpha-b76ec274.0
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.
- package/cjs/extensions.js +132 -0
- package/cjs/index.js +6 -0
- package/cjs/merge-resolvers.js +67 -0
- package/cjs/package.json +1 -0
- package/cjs/typedefs-mergers/arguments.js +21 -0
- package/cjs/typedefs-mergers/directives.js +100 -0
- package/cjs/typedefs-mergers/enum-values.js +40 -0
- package/cjs/typedefs-mergers/enum.js +27 -0
- package/cjs/typedefs-mergers/fields.js +85 -0
- package/cjs/typedefs-mergers/index.js +17 -0
- package/cjs/typedefs-mergers/input-type.js +34 -0
- package/cjs/typedefs-mergers/interface.js +38 -0
- package/cjs/typedefs-mergers/merge-named-type-array.js +15 -0
- package/cjs/typedefs-mergers/merge-nodes.js +72 -0
- package/cjs/typedefs-mergers/merge-typedefs.js +121 -0
- package/cjs/typedefs-mergers/scalar.js +27 -0
- package/cjs/typedefs-mergers/schema-def.js +39 -0
- package/cjs/typedefs-mergers/type.js +36 -0
- package/cjs/typedefs-mergers/union.js +28 -0
- package/cjs/typedefs-mergers/utils.js +65 -0
- package/esm/extensions.js +125 -0
- package/esm/index.js +3 -0
- package/esm/merge-resolvers.js +63 -0
- package/esm/typedefs-mergers/arguments.js +17 -0
- package/esm/typedefs-mergers/directives.js +95 -0
- package/esm/typedefs-mergers/enum-values.js +36 -0
- package/esm/typedefs-mergers/enum.js +23 -0
- package/esm/typedefs-mergers/fields.js +81 -0
- package/esm/typedefs-mergers/index.js +14 -0
- package/esm/typedefs-mergers/input-type.js +30 -0
- package/esm/typedefs-mergers/interface.js +34 -0
- package/esm/typedefs-mergers/merge-named-type-array.js +11 -0
- package/esm/typedefs-mergers/merge-nodes.js +67 -0
- package/esm/typedefs-mergers/merge-typedefs.js +116 -0
- package/esm/typedefs-mergers/scalar.js +23 -0
- package/esm/typedefs-mergers/schema-def.js +35 -0
- package/esm/typedefs-mergers/type.js +32 -0
- package/esm/typedefs-mergers/union.js +24 -0
- package/esm/typedefs-mergers/utils.js +54 -0
- package/package.json +32 -11
- package/{extensions.d.ts → typings/extensions.d.ts} +0 -0
- package/typings/index.d.ts +3 -0
- package/{merge-resolvers.d.ts → typings/merge-resolvers.d.ts} +0 -0
- package/{typedefs-mergers → typings/typedefs-mergers}/arguments.d.ts +1 -1
- package/{typedefs-mergers → typings/typedefs-mergers}/directives.d.ts +1 -1
- package/{typedefs-mergers → typings/typedefs-mergers}/enum-values.d.ts +1 -1
- package/{typedefs-mergers → typings/typedefs-mergers}/enum.d.ts +1 -1
- package/{typedefs-mergers → typings/typedefs-mergers}/fields.d.ts +1 -1
- package/typings/typedefs-mergers/index.d.ts +14 -0
- package/{typedefs-mergers → typings/typedefs-mergers}/input-type.d.ts +1 -1
- package/{typedefs-mergers → typings/typedefs-mergers}/interface.d.ts +1 -1
- package/{typedefs-mergers → typings/typedefs-mergers}/merge-named-type-array.d.ts +1 -1
- package/{typedefs-mergers → typings/typedefs-mergers}/merge-nodes.d.ts +1 -1
- package/{typedefs-mergers → typings/typedefs-mergers}/merge-typedefs.d.ts +1 -1
- package/{typedefs-mergers → typings/typedefs-mergers}/scalar.d.ts +1 -1
- package/{typedefs-mergers → typings/typedefs-mergers}/schema-def.d.ts +1 -1
- package/{typedefs-mergers → typings/typedefs-mergers}/type.d.ts +1 -1
- package/{typedefs-mergers → typings/typedefs-mergers}/union.d.ts +1 -1
- package/{typedefs-mergers → typings/typedefs-mergers}/utils.d.ts +0 -0
- package/README.md +0 -5
- package/index.d.ts +0 -3
- package/index.js +0 -869
- package/index.mjs +0 -837
- package/typedefs-mergers/index.d.ts +0 -14
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.mergeGraphQLTypes = exports.mergeTypeDefs = void 0;
|
|
4
|
+
const graphql_1 = require("graphql");
|
|
5
|
+
const utils_js_1 = require("./utils.js");
|
|
6
|
+
const merge_nodes_js_1 = require("./merge-nodes.js");
|
|
7
|
+
const utils_1 = require("@graphql-tools/utils");
|
|
8
|
+
const schema_def_js_1 = require("./schema-def.js");
|
|
9
|
+
function mergeTypeDefs(typeSource, config) {
|
|
10
|
+
(0, utils_1.resetComments)();
|
|
11
|
+
const doc = {
|
|
12
|
+
kind: graphql_1.Kind.DOCUMENT,
|
|
13
|
+
definitions: mergeGraphQLTypes(typeSource, {
|
|
14
|
+
useSchemaDefinition: true,
|
|
15
|
+
forceSchemaDefinition: false,
|
|
16
|
+
throwOnConflict: false,
|
|
17
|
+
commentDescriptions: false,
|
|
18
|
+
...config,
|
|
19
|
+
}),
|
|
20
|
+
};
|
|
21
|
+
let result;
|
|
22
|
+
if (config === null || config === void 0 ? void 0 : config.commentDescriptions) {
|
|
23
|
+
result = (0, utils_1.printWithComments)(doc);
|
|
24
|
+
}
|
|
25
|
+
else {
|
|
26
|
+
result = doc;
|
|
27
|
+
}
|
|
28
|
+
(0, utils_1.resetComments)();
|
|
29
|
+
return result;
|
|
30
|
+
}
|
|
31
|
+
exports.mergeTypeDefs = mergeTypeDefs;
|
|
32
|
+
function visitTypeSources(typeSource, options, allNodes = [], visitedTypeSources = new Set()) {
|
|
33
|
+
if (typeSource && !visitedTypeSources.has(typeSource)) {
|
|
34
|
+
visitedTypeSources.add(typeSource);
|
|
35
|
+
if (typeof typeSource === 'function') {
|
|
36
|
+
visitTypeSources(typeSource(), options, allNodes, visitedTypeSources);
|
|
37
|
+
}
|
|
38
|
+
else if (Array.isArray(typeSource)) {
|
|
39
|
+
for (const type of typeSource) {
|
|
40
|
+
visitTypeSources(type, options, allNodes, visitedTypeSources);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
else if ((0, graphql_1.isSchema)(typeSource)) {
|
|
44
|
+
const documentNode = (0, utils_1.getDocumentNodeFromSchema)(typeSource, options);
|
|
45
|
+
visitTypeSources(documentNode.definitions, options, allNodes, visitedTypeSources);
|
|
46
|
+
}
|
|
47
|
+
else if ((0, utils_js_1.isStringTypes)(typeSource) || (0, utils_js_1.isSourceTypes)(typeSource)) {
|
|
48
|
+
const documentNode = (0, graphql_1.parse)(typeSource, options);
|
|
49
|
+
visitTypeSources(documentNode.definitions, options, allNodes, visitedTypeSources);
|
|
50
|
+
}
|
|
51
|
+
else if (typeof typeSource === 'object' && (0, graphql_1.isDefinitionNode)(typeSource)) {
|
|
52
|
+
allNodes.push(typeSource);
|
|
53
|
+
}
|
|
54
|
+
else if ((0, utils_1.isDocumentNode)(typeSource)) {
|
|
55
|
+
visitTypeSources(typeSource.definitions, options, allNodes, visitedTypeSources);
|
|
56
|
+
}
|
|
57
|
+
else {
|
|
58
|
+
throw new Error(`typeDefs must contain only strings, documents, schemas, or functions, got ${typeof typeSource}`);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
return allNodes;
|
|
62
|
+
}
|
|
63
|
+
function mergeGraphQLTypes(typeSource, config) {
|
|
64
|
+
var _a, _b, _c;
|
|
65
|
+
(0, utils_1.resetComments)();
|
|
66
|
+
const allNodes = visitTypeSources(typeSource, config);
|
|
67
|
+
const mergedNodes = (0, merge_nodes_js_1.mergeGraphQLNodes)(allNodes, config);
|
|
68
|
+
if (config === null || config === void 0 ? void 0 : config.useSchemaDefinition) {
|
|
69
|
+
// XXX: right now we don't handle multiple schema definitions
|
|
70
|
+
const schemaDef = mergedNodes[merge_nodes_js_1.schemaDefSymbol] || {
|
|
71
|
+
kind: graphql_1.Kind.SCHEMA_DEFINITION,
|
|
72
|
+
operationTypes: [],
|
|
73
|
+
};
|
|
74
|
+
const operationTypes = schemaDef.operationTypes;
|
|
75
|
+
for (const opTypeDefNodeType in schema_def_js_1.DEFAULT_OPERATION_TYPE_NAME_MAP) {
|
|
76
|
+
const opTypeDefNode = operationTypes.find(operationType => operationType.operation === opTypeDefNodeType);
|
|
77
|
+
if (!opTypeDefNode) {
|
|
78
|
+
const possibleRootTypeName = schema_def_js_1.DEFAULT_OPERATION_TYPE_NAME_MAP[opTypeDefNodeType];
|
|
79
|
+
const existingPossibleRootType = mergedNodes[possibleRootTypeName];
|
|
80
|
+
if (existingPossibleRootType != null && existingPossibleRootType.name != null) {
|
|
81
|
+
operationTypes.push({
|
|
82
|
+
kind: graphql_1.Kind.OPERATION_TYPE_DEFINITION,
|
|
83
|
+
type: {
|
|
84
|
+
kind: graphql_1.Kind.NAMED_TYPE,
|
|
85
|
+
name: existingPossibleRootType.name,
|
|
86
|
+
},
|
|
87
|
+
operation: opTypeDefNodeType,
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
if (((_a = schemaDef === null || schemaDef === void 0 ? void 0 : schemaDef.operationTypes) === null || _a === void 0 ? void 0 : _a.length) != null && schemaDef.operationTypes.length > 0) {
|
|
93
|
+
mergedNodes[merge_nodes_js_1.schemaDefSymbol] = schemaDef;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
if ((config === null || config === void 0 ? void 0 : config.forceSchemaDefinition) && !((_c = (_b = mergedNodes[merge_nodes_js_1.schemaDefSymbol]) === null || _b === void 0 ? void 0 : _b.operationTypes) === null || _c === void 0 ? void 0 : _c.length)) {
|
|
97
|
+
mergedNodes[merge_nodes_js_1.schemaDefSymbol] = {
|
|
98
|
+
kind: graphql_1.Kind.SCHEMA_DEFINITION,
|
|
99
|
+
operationTypes: [
|
|
100
|
+
{
|
|
101
|
+
kind: graphql_1.Kind.OPERATION_TYPE_DEFINITION,
|
|
102
|
+
operation: 'query',
|
|
103
|
+
type: {
|
|
104
|
+
kind: graphql_1.Kind.NAMED_TYPE,
|
|
105
|
+
name: {
|
|
106
|
+
kind: graphql_1.Kind.NAME,
|
|
107
|
+
value: 'Query',
|
|
108
|
+
},
|
|
109
|
+
},
|
|
110
|
+
},
|
|
111
|
+
],
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
const mergedNodeDefinitions = Object.values(mergedNodes);
|
|
115
|
+
if (config === null || config === void 0 ? void 0 : config.sort) {
|
|
116
|
+
const sortFn = typeof config.sort === 'function' ? config.sort : utils_js_1.defaultStringComparator;
|
|
117
|
+
mergedNodeDefinitions.sort((a, b) => { var _a, _b; return sortFn((_a = a.name) === null || _a === void 0 ? void 0 : _a.value, (_b = b.name) === null || _b === void 0 ? void 0 : _b.value); });
|
|
118
|
+
}
|
|
119
|
+
return mergedNodeDefinitions;
|
|
120
|
+
}
|
|
121
|
+
exports.mergeGraphQLTypes = mergeGraphQLTypes;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.mergeScalar = void 0;
|
|
4
|
+
const graphql_1 = require("graphql");
|
|
5
|
+
const directives_js_1 = require("./directives.js");
|
|
6
|
+
function mergeScalar(node, existingNode, config) {
|
|
7
|
+
if (existingNode) {
|
|
8
|
+
return {
|
|
9
|
+
name: node.name,
|
|
10
|
+
description: node['description'] || existingNode['description'],
|
|
11
|
+
kind: (config === null || config === void 0 ? void 0 : config.convertExtensions) ||
|
|
12
|
+
node.kind === 'ScalarTypeDefinition' ||
|
|
13
|
+
existingNode.kind === 'ScalarTypeDefinition'
|
|
14
|
+
? 'ScalarTypeDefinition'
|
|
15
|
+
: 'ScalarTypeExtension',
|
|
16
|
+
loc: node.loc,
|
|
17
|
+
directives: (0, directives_js_1.mergeDirectives)(node.directives, existingNode.directives, config),
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
return (config === null || config === void 0 ? void 0 : config.convertExtensions)
|
|
21
|
+
? {
|
|
22
|
+
...node,
|
|
23
|
+
kind: graphql_1.Kind.SCALAR_TYPE_DEFINITION,
|
|
24
|
+
}
|
|
25
|
+
: node;
|
|
26
|
+
}
|
|
27
|
+
exports.mergeScalar = mergeScalar;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.mergeSchemaDefs = exports.DEFAULT_OPERATION_TYPE_NAME_MAP = void 0;
|
|
4
|
+
const graphql_1 = require("graphql");
|
|
5
|
+
const directives_js_1 = require("./directives.js");
|
|
6
|
+
exports.DEFAULT_OPERATION_TYPE_NAME_MAP = {
|
|
7
|
+
query: 'Query',
|
|
8
|
+
mutation: 'Mutation',
|
|
9
|
+
subscription: 'Subscription',
|
|
10
|
+
};
|
|
11
|
+
function mergeOperationTypes(opNodeList = [], existingOpNodeList = []) {
|
|
12
|
+
const finalOpNodeList = [];
|
|
13
|
+
for (const opNodeType in exports.DEFAULT_OPERATION_TYPE_NAME_MAP) {
|
|
14
|
+
const opNode = opNodeList.find(n => n.operation === opNodeType) || existingOpNodeList.find(n => n.operation === opNodeType);
|
|
15
|
+
if (opNode) {
|
|
16
|
+
finalOpNodeList.push(opNode);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
return finalOpNodeList;
|
|
20
|
+
}
|
|
21
|
+
function mergeSchemaDefs(node, existingNode, config) {
|
|
22
|
+
if (existingNode) {
|
|
23
|
+
return {
|
|
24
|
+
kind: node.kind === graphql_1.Kind.SCHEMA_DEFINITION || existingNode.kind === graphql_1.Kind.SCHEMA_DEFINITION
|
|
25
|
+
? graphql_1.Kind.SCHEMA_DEFINITION
|
|
26
|
+
: graphql_1.Kind.SCHEMA_EXTENSION,
|
|
27
|
+
description: node['description'] || existingNode['description'],
|
|
28
|
+
directives: (0, directives_js_1.mergeDirectives)(node.directives, existingNode.directives, config),
|
|
29
|
+
operationTypes: mergeOperationTypes(node.operationTypes, existingNode.operationTypes),
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
return ((config === null || config === void 0 ? void 0 : config.convertExtensions)
|
|
33
|
+
? {
|
|
34
|
+
...node,
|
|
35
|
+
kind: graphql_1.Kind.SCHEMA_DEFINITION,
|
|
36
|
+
}
|
|
37
|
+
: node);
|
|
38
|
+
}
|
|
39
|
+
exports.mergeSchemaDefs = mergeSchemaDefs;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.mergeType = void 0;
|
|
4
|
+
const graphql_1 = require("graphql");
|
|
5
|
+
const fields_js_1 = require("./fields.js");
|
|
6
|
+
const directives_js_1 = require("./directives.js");
|
|
7
|
+
const merge_named_type_array_js_1 = require("./merge-named-type-array.js");
|
|
8
|
+
function mergeType(node, existingNode, config) {
|
|
9
|
+
if (existingNode) {
|
|
10
|
+
try {
|
|
11
|
+
return {
|
|
12
|
+
name: node.name,
|
|
13
|
+
description: node['description'] || existingNode['description'],
|
|
14
|
+
kind: (config === null || config === void 0 ? void 0 : config.convertExtensions) ||
|
|
15
|
+
node.kind === 'ObjectTypeDefinition' ||
|
|
16
|
+
existingNode.kind === 'ObjectTypeDefinition'
|
|
17
|
+
? 'ObjectTypeDefinition'
|
|
18
|
+
: 'ObjectTypeExtension',
|
|
19
|
+
loc: node.loc,
|
|
20
|
+
fields: (0, fields_js_1.mergeFields)(node, node.fields, existingNode.fields, config),
|
|
21
|
+
directives: (0, directives_js_1.mergeDirectives)(node.directives, existingNode.directives, config),
|
|
22
|
+
interfaces: (0, merge_named_type_array_js_1.mergeNamedTypeArray)(node.interfaces, existingNode.interfaces, config),
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
catch (e) {
|
|
26
|
+
throw new Error(`Unable to merge GraphQL type "${node.name.value}": ${e.message}`);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
return (config === null || config === void 0 ? void 0 : config.convertExtensions)
|
|
30
|
+
? {
|
|
31
|
+
...node,
|
|
32
|
+
kind: graphql_1.Kind.OBJECT_TYPE_DEFINITION,
|
|
33
|
+
}
|
|
34
|
+
: node;
|
|
35
|
+
}
|
|
36
|
+
exports.mergeType = mergeType;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.mergeUnion = void 0;
|
|
4
|
+
const graphql_1 = require("graphql");
|
|
5
|
+
const directives_js_1 = require("./directives.js");
|
|
6
|
+
const merge_named_type_array_js_1 = require("./merge-named-type-array.js");
|
|
7
|
+
function mergeUnion(first, second, config) {
|
|
8
|
+
if (second) {
|
|
9
|
+
return {
|
|
10
|
+
name: first.name,
|
|
11
|
+
description: first['description'] || second['description'],
|
|
12
|
+
// ConstXNode has been introduced in v16 but it is not compatible with XNode so we do `as any` for backwards compatibility
|
|
13
|
+
directives: (0, directives_js_1.mergeDirectives)(first.directives, second.directives, config),
|
|
14
|
+
kind: (config === null || config === void 0 ? void 0 : config.convertExtensions) || first.kind === 'UnionTypeDefinition' || second.kind === 'UnionTypeDefinition'
|
|
15
|
+
? graphql_1.Kind.UNION_TYPE_DEFINITION
|
|
16
|
+
: graphql_1.Kind.UNION_TYPE_EXTENSION,
|
|
17
|
+
loc: first.loc,
|
|
18
|
+
types: (0, merge_named_type_array_js_1.mergeNamedTypeArray)(first.types, second.types, config),
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
return (config === null || config === void 0 ? void 0 : config.convertExtensions)
|
|
22
|
+
? {
|
|
23
|
+
...first,
|
|
24
|
+
kind: graphql_1.Kind.UNION_TYPE_DEFINITION,
|
|
25
|
+
}
|
|
26
|
+
: first;
|
|
27
|
+
}
|
|
28
|
+
exports.mergeUnion = mergeUnion;
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.defaultStringComparator = exports.CompareVal = exports.printTypeNode = exports.isNonNullTypeNode = exports.isListTypeNode = exports.isWrappingTypeNode = exports.extractType = exports.isSourceTypes = exports.isStringTypes = void 0;
|
|
4
|
+
const graphql_1 = require("graphql");
|
|
5
|
+
function isStringTypes(types) {
|
|
6
|
+
return typeof types === 'string';
|
|
7
|
+
}
|
|
8
|
+
exports.isStringTypes = isStringTypes;
|
|
9
|
+
function isSourceTypes(types) {
|
|
10
|
+
return types instanceof graphql_1.Source;
|
|
11
|
+
}
|
|
12
|
+
exports.isSourceTypes = isSourceTypes;
|
|
13
|
+
function extractType(type) {
|
|
14
|
+
let visitedType = type;
|
|
15
|
+
while (visitedType.kind === graphql_1.Kind.LIST_TYPE || visitedType.kind === 'NonNullType') {
|
|
16
|
+
visitedType = visitedType.type;
|
|
17
|
+
}
|
|
18
|
+
return visitedType;
|
|
19
|
+
}
|
|
20
|
+
exports.extractType = extractType;
|
|
21
|
+
function isWrappingTypeNode(type) {
|
|
22
|
+
return type.kind !== graphql_1.Kind.NAMED_TYPE;
|
|
23
|
+
}
|
|
24
|
+
exports.isWrappingTypeNode = isWrappingTypeNode;
|
|
25
|
+
function isListTypeNode(type) {
|
|
26
|
+
return type.kind === graphql_1.Kind.LIST_TYPE;
|
|
27
|
+
}
|
|
28
|
+
exports.isListTypeNode = isListTypeNode;
|
|
29
|
+
function isNonNullTypeNode(type) {
|
|
30
|
+
return type.kind === graphql_1.Kind.NON_NULL_TYPE;
|
|
31
|
+
}
|
|
32
|
+
exports.isNonNullTypeNode = isNonNullTypeNode;
|
|
33
|
+
function printTypeNode(type) {
|
|
34
|
+
if (isListTypeNode(type)) {
|
|
35
|
+
return `[${printTypeNode(type.type)}]`;
|
|
36
|
+
}
|
|
37
|
+
if (isNonNullTypeNode(type)) {
|
|
38
|
+
return `${printTypeNode(type.type)}!`;
|
|
39
|
+
}
|
|
40
|
+
return type.name.value;
|
|
41
|
+
}
|
|
42
|
+
exports.printTypeNode = printTypeNode;
|
|
43
|
+
var CompareVal;
|
|
44
|
+
(function (CompareVal) {
|
|
45
|
+
CompareVal[CompareVal["A_SMALLER_THAN_B"] = -1] = "A_SMALLER_THAN_B";
|
|
46
|
+
CompareVal[CompareVal["A_EQUALS_B"] = 0] = "A_EQUALS_B";
|
|
47
|
+
CompareVal[CompareVal["A_GREATER_THAN_B"] = 1] = "A_GREATER_THAN_B";
|
|
48
|
+
})(CompareVal = exports.CompareVal || (exports.CompareVal = {}));
|
|
49
|
+
function defaultStringComparator(a, b) {
|
|
50
|
+
if (a == null && b == null) {
|
|
51
|
+
return CompareVal.A_EQUALS_B;
|
|
52
|
+
}
|
|
53
|
+
if (a == null) {
|
|
54
|
+
return CompareVal.A_SMALLER_THAN_B;
|
|
55
|
+
}
|
|
56
|
+
if (b == null) {
|
|
57
|
+
return CompareVal.A_GREATER_THAN_B;
|
|
58
|
+
}
|
|
59
|
+
if (a < b)
|
|
60
|
+
return CompareVal.A_SMALLER_THAN_B;
|
|
61
|
+
if (a > b)
|
|
62
|
+
return CompareVal.A_GREATER_THAN_B;
|
|
63
|
+
return CompareVal.A_EQUALS_B;
|
|
64
|
+
}
|
|
65
|
+
exports.defaultStringComparator = defaultStringComparator;
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import { isObjectType, isInterfaceType, isInputObjectType, isUnionType, isScalarType, isEnumType, isSpecifiedScalarType, isIntrospectionType, } from 'graphql';
|
|
2
|
+
import { mergeDeep } from '@graphql-tools/utils';
|
|
3
|
+
export function travelSchemaPossibleExtensions(schema, hooks) {
|
|
4
|
+
hooks.onSchema(schema);
|
|
5
|
+
const typesMap = schema.getTypeMap();
|
|
6
|
+
for (const [, type] of Object.entries(typesMap)) {
|
|
7
|
+
const isPredefinedScalar = isScalarType(type) && isSpecifiedScalarType(type);
|
|
8
|
+
const isIntrospection = isIntrospectionType(type);
|
|
9
|
+
if (isPredefinedScalar || isIntrospection) {
|
|
10
|
+
continue;
|
|
11
|
+
}
|
|
12
|
+
if (isObjectType(type)) {
|
|
13
|
+
hooks.onObjectType(type);
|
|
14
|
+
const fields = type.getFields();
|
|
15
|
+
for (const [, field] of Object.entries(fields)) {
|
|
16
|
+
hooks.onObjectField(type, field);
|
|
17
|
+
const args = field.args || [];
|
|
18
|
+
for (const arg of args) {
|
|
19
|
+
hooks.onObjectFieldArg(type, field, arg);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
else if (isInterfaceType(type)) {
|
|
24
|
+
hooks.onInterface(type);
|
|
25
|
+
const fields = type.getFields();
|
|
26
|
+
for (const [, field] of Object.entries(fields)) {
|
|
27
|
+
hooks.onInterfaceField(type, field);
|
|
28
|
+
const args = field.args || [];
|
|
29
|
+
for (const arg of args) {
|
|
30
|
+
hooks.onInterfaceFieldArg(type, field, arg);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
else if (isInputObjectType(type)) {
|
|
35
|
+
hooks.onInputType(type);
|
|
36
|
+
const fields = type.getFields();
|
|
37
|
+
for (const [, field] of Object.entries(fields)) {
|
|
38
|
+
hooks.onInputFieldType(type, field);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
else if (isUnionType(type)) {
|
|
42
|
+
hooks.onUnion(type);
|
|
43
|
+
}
|
|
44
|
+
else if (isScalarType(type)) {
|
|
45
|
+
hooks.onScalar(type);
|
|
46
|
+
}
|
|
47
|
+
else if (isEnumType(type)) {
|
|
48
|
+
hooks.onEnum(type);
|
|
49
|
+
for (const value of type.getValues()) {
|
|
50
|
+
hooks.onEnumValue(type, value);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
export function mergeExtensions(extensions) {
|
|
56
|
+
return mergeDeep(extensions);
|
|
57
|
+
}
|
|
58
|
+
function applyExtensionObject(obj, extensions) {
|
|
59
|
+
if (!obj) {
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
obj.extensions = mergeDeep([obj.extensions || {}, extensions || {}]);
|
|
63
|
+
}
|
|
64
|
+
export function applyExtensions(schema, extensions) {
|
|
65
|
+
applyExtensionObject(schema, extensions.schemaExtensions);
|
|
66
|
+
for (const [typeName, data] of Object.entries(extensions.types || {})) {
|
|
67
|
+
const type = schema.getType(typeName);
|
|
68
|
+
if (type) {
|
|
69
|
+
applyExtensionObject(type, data.extensions);
|
|
70
|
+
if (data.type === 'object' || data.type === 'interface') {
|
|
71
|
+
for (const [fieldName, fieldData] of Object.entries(data.fields)) {
|
|
72
|
+
const field = type.getFields()[fieldName];
|
|
73
|
+
if (field) {
|
|
74
|
+
applyExtensionObject(field, fieldData.extensions);
|
|
75
|
+
for (const [arg, argData] of Object.entries(fieldData.arguments)) {
|
|
76
|
+
applyExtensionObject(field.args.find(a => a.name === arg), argData);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
else if (data.type === 'input') {
|
|
82
|
+
for (const [fieldName, fieldData] of Object.entries(data.fields)) {
|
|
83
|
+
const field = type.getFields()[fieldName];
|
|
84
|
+
applyExtensionObject(field, fieldData.extensions);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
else if (data.type === 'enum') {
|
|
88
|
+
for (const [valueName, valueData] of Object.entries(data.values)) {
|
|
89
|
+
const value = type.getValue(valueName);
|
|
90
|
+
applyExtensionObject(value, valueData);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
return schema;
|
|
96
|
+
}
|
|
97
|
+
export function extractExtensionsFromSchema(schema) {
|
|
98
|
+
const result = {
|
|
99
|
+
schemaExtensions: {},
|
|
100
|
+
types: {},
|
|
101
|
+
};
|
|
102
|
+
travelSchemaPossibleExtensions(schema, {
|
|
103
|
+
onSchema: schema => (result.schemaExtensions = schema.extensions || {}),
|
|
104
|
+
onObjectType: type => (result.types[type.name] = { fields: {}, type: 'object', extensions: type.extensions || {} }),
|
|
105
|
+
onObjectField: (type, field) => (result.types[type.name].fields[field.name] = {
|
|
106
|
+
arguments: {},
|
|
107
|
+
extensions: field.extensions || {},
|
|
108
|
+
}),
|
|
109
|
+
onObjectFieldArg: (type, field, arg) => (result.types[type.name].fields[field.name].arguments[arg.name] = arg.extensions || {}),
|
|
110
|
+
onInterface: type => (result.types[type.name] = { fields: {}, type: 'interface', extensions: type.extensions || {} }),
|
|
111
|
+
onInterfaceField: (type, field) => (result.types[type.name].fields[field.name] = {
|
|
112
|
+
arguments: {},
|
|
113
|
+
extensions: field.extensions || {},
|
|
114
|
+
}),
|
|
115
|
+
onInterfaceFieldArg: (type, field, arg) => (result.types[type.name].fields[field.name].arguments[arg.name] =
|
|
116
|
+
arg.extensions || {}),
|
|
117
|
+
onEnum: type => (result.types[type.name] = { values: {}, type: 'enum', extensions: type.extensions || {} }),
|
|
118
|
+
onEnumValue: (type, value) => (result.types[type.name].values[value.name] = value.extensions || {}),
|
|
119
|
+
onScalar: type => (result.types[type.name] = { type: 'scalar', extensions: type.extensions || {} }),
|
|
120
|
+
onUnion: type => (result.types[type.name] = { type: 'union', extensions: type.extensions || {} }),
|
|
121
|
+
onInputType: type => (result.types[type.name] = { fields: {}, type: 'input', extensions: type.extensions || {} }),
|
|
122
|
+
onInputFieldType: (type, field) => (result.types[type.name].fields[field.name] = { extensions: field.extensions || {} }),
|
|
123
|
+
});
|
|
124
|
+
return result;
|
|
125
|
+
}
|
package/esm/index.js
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { mergeDeep } from '@graphql-tools/utils';
|
|
2
|
+
/**
|
|
3
|
+
* Deep merges multiple resolver definition objects into a single definition.
|
|
4
|
+
* @param resolversDefinitions Resolver definitions to be merged
|
|
5
|
+
* @param options Additional options
|
|
6
|
+
*
|
|
7
|
+
* ```js
|
|
8
|
+
* const { mergeResolvers } = require('@graphql-tools/merge');
|
|
9
|
+
* const clientResolver = require('./clientResolver');
|
|
10
|
+
* const productResolver = require('./productResolver');
|
|
11
|
+
*
|
|
12
|
+
* const resolvers = mergeResolvers([
|
|
13
|
+
* clientResolver,
|
|
14
|
+
* productResolver,
|
|
15
|
+
* ]);
|
|
16
|
+
* ```
|
|
17
|
+
*
|
|
18
|
+
* If you don't want to manually create the array of resolver objects, you can
|
|
19
|
+
* also use this function along with loadFiles:
|
|
20
|
+
*
|
|
21
|
+
* ```js
|
|
22
|
+
* const path = require('path');
|
|
23
|
+
* const { mergeResolvers } = require('@graphql-tools/merge');
|
|
24
|
+
* const { loadFilesSync } = require('@graphql-tools/load-files');
|
|
25
|
+
*
|
|
26
|
+
* const resolversArray = loadFilesSync(path.join(__dirname, './resolvers'));
|
|
27
|
+
*
|
|
28
|
+
* const resolvers = mergeResolvers(resolversArray)
|
|
29
|
+
* ```
|
|
30
|
+
*/
|
|
31
|
+
export function mergeResolvers(resolversDefinitions, options) {
|
|
32
|
+
if (!resolversDefinitions || (Array.isArray(resolversDefinitions) && resolversDefinitions.length === 0)) {
|
|
33
|
+
return {};
|
|
34
|
+
}
|
|
35
|
+
if (!Array.isArray(resolversDefinitions)) {
|
|
36
|
+
return resolversDefinitions;
|
|
37
|
+
}
|
|
38
|
+
if (resolversDefinitions.length === 1) {
|
|
39
|
+
return resolversDefinitions[0] || {};
|
|
40
|
+
}
|
|
41
|
+
const resolvers = new Array();
|
|
42
|
+
for (let resolversDefinition of resolversDefinitions) {
|
|
43
|
+
if (Array.isArray(resolversDefinition)) {
|
|
44
|
+
resolversDefinition = mergeResolvers(resolversDefinition);
|
|
45
|
+
}
|
|
46
|
+
if (typeof resolversDefinition === 'object' && resolversDefinition) {
|
|
47
|
+
resolvers.push(resolversDefinition);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
const result = mergeDeep(resolvers, true);
|
|
51
|
+
if (options === null || options === void 0 ? void 0 : options.exclusions) {
|
|
52
|
+
for (const exclusion of options.exclusions) {
|
|
53
|
+
const [typeName, fieldName] = exclusion.split('.');
|
|
54
|
+
if (!fieldName || fieldName === '*') {
|
|
55
|
+
delete result[typeName];
|
|
56
|
+
}
|
|
57
|
+
else if (result[typeName]) {
|
|
58
|
+
delete result[typeName][fieldName];
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
return result;
|
|
63
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { compareNodes, isSome } from '@graphql-tools/utils';
|
|
2
|
+
export function mergeArguments(args1, args2, config) {
|
|
3
|
+
const result = deduplicateArguments([...args2, ...args1].filter(isSome));
|
|
4
|
+
if (config && config.sort) {
|
|
5
|
+
result.sort(compareNodes);
|
|
6
|
+
}
|
|
7
|
+
return result;
|
|
8
|
+
}
|
|
9
|
+
function deduplicateArguments(args) {
|
|
10
|
+
return args.reduce((acc, current) => {
|
|
11
|
+
const dup = acc.find(arg => arg.name.value === current.name.value);
|
|
12
|
+
if (!dup) {
|
|
13
|
+
return acc.concat([current]);
|
|
14
|
+
}
|
|
15
|
+
return acc;
|
|
16
|
+
}, []);
|
|
17
|
+
}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { print } from 'graphql';
|
|
2
|
+
import { isSome } from '@graphql-tools/utils';
|
|
3
|
+
function directiveAlreadyExists(directivesArr, otherDirective) {
|
|
4
|
+
return !!directivesArr.find(directive => directive.name.value === otherDirective.name.value);
|
|
5
|
+
}
|
|
6
|
+
function nameAlreadyExists(name, namesArr) {
|
|
7
|
+
return namesArr.some(({ value }) => value === name.value);
|
|
8
|
+
}
|
|
9
|
+
function mergeArguments(a1, a2) {
|
|
10
|
+
const result = [...a2];
|
|
11
|
+
for (const argument of a1) {
|
|
12
|
+
const existingIndex = result.findIndex(a => a.name.value === argument.name.value);
|
|
13
|
+
if (existingIndex > -1) {
|
|
14
|
+
const existingArg = result[existingIndex];
|
|
15
|
+
if (existingArg.value.kind === 'ListValue') {
|
|
16
|
+
const source = existingArg.value.values;
|
|
17
|
+
const target = argument.value.values;
|
|
18
|
+
// merge values of two lists
|
|
19
|
+
existingArg.value.values = deduplicateLists(source, target, (targetVal, source) => {
|
|
20
|
+
const value = targetVal.value;
|
|
21
|
+
return !value || !source.some((sourceVal) => sourceVal.value === value);
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
else {
|
|
25
|
+
existingArg.value = argument.value;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
else {
|
|
29
|
+
result.push(argument);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
return result;
|
|
33
|
+
}
|
|
34
|
+
function deduplicateDirectives(directives) {
|
|
35
|
+
return directives
|
|
36
|
+
.map((directive, i, all) => {
|
|
37
|
+
const firstAt = all.findIndex(d => d.name.value === directive.name.value);
|
|
38
|
+
if (firstAt !== i) {
|
|
39
|
+
const dup = all[firstAt];
|
|
40
|
+
directive.arguments = mergeArguments(directive.arguments, dup.arguments);
|
|
41
|
+
return null;
|
|
42
|
+
}
|
|
43
|
+
return directive;
|
|
44
|
+
})
|
|
45
|
+
.filter(isSome);
|
|
46
|
+
}
|
|
47
|
+
export function mergeDirectives(d1 = [], d2 = [], config) {
|
|
48
|
+
const reverseOrder = config && config.reverseDirectives;
|
|
49
|
+
const asNext = reverseOrder ? d1 : d2;
|
|
50
|
+
const asFirst = reverseOrder ? d2 : d1;
|
|
51
|
+
const result = deduplicateDirectives([...asNext]);
|
|
52
|
+
for (const directive of asFirst) {
|
|
53
|
+
if (directiveAlreadyExists(result, directive)) {
|
|
54
|
+
const existingDirectiveIndex = result.findIndex(d => d.name.value === directive.name.value);
|
|
55
|
+
const existingDirective = result[existingDirectiveIndex];
|
|
56
|
+
result[existingDirectiveIndex].arguments = mergeArguments(directive.arguments || [], existingDirective.arguments || []);
|
|
57
|
+
}
|
|
58
|
+
else {
|
|
59
|
+
result.push(directive);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
return result;
|
|
63
|
+
}
|
|
64
|
+
function validateInputs(node, existingNode) {
|
|
65
|
+
const printedNode = print({
|
|
66
|
+
...node,
|
|
67
|
+
description: undefined,
|
|
68
|
+
});
|
|
69
|
+
const printedExistingNode = print({
|
|
70
|
+
...existingNode,
|
|
71
|
+
description: undefined,
|
|
72
|
+
});
|
|
73
|
+
// eslint-disable-next-line
|
|
74
|
+
const leaveInputs = new RegExp('(directive @w*d*)|( on .*$)', 'g');
|
|
75
|
+
const sameArguments = printedNode.replace(leaveInputs, '') === printedExistingNode.replace(leaveInputs, '');
|
|
76
|
+
if (!sameArguments) {
|
|
77
|
+
throw new Error(`Unable to merge GraphQL directive "${node.name.value}". \nExisting directive: \n\t${printedExistingNode} \nReceived directive: \n\t${printedNode}`);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
export function mergeDirective(node, existingNode) {
|
|
81
|
+
if (existingNode) {
|
|
82
|
+
validateInputs(node, existingNode);
|
|
83
|
+
return {
|
|
84
|
+
...node,
|
|
85
|
+
locations: [
|
|
86
|
+
...existingNode.locations,
|
|
87
|
+
...node.locations.filter(name => !nameAlreadyExists(name, existingNode.locations)),
|
|
88
|
+
],
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
return node;
|
|
92
|
+
}
|
|
93
|
+
function deduplicateLists(source, target, filterFn) {
|
|
94
|
+
return source.concat(target.filter(val => filterFn(val, source)));
|
|
95
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { mergeDirectives } from './directives.js';
|
|
2
|
+
import { compareNodes } from '@graphql-tools/utils';
|
|
3
|
+
export function mergeEnumValues(first, second, config) {
|
|
4
|
+
if (config === null || config === void 0 ? void 0 : config.consistentEnumMerge) {
|
|
5
|
+
const reversed = [];
|
|
6
|
+
if (first) {
|
|
7
|
+
reversed.push(...first);
|
|
8
|
+
}
|
|
9
|
+
first = second;
|
|
10
|
+
second = reversed;
|
|
11
|
+
}
|
|
12
|
+
const enumValueMap = new Map();
|
|
13
|
+
if (first) {
|
|
14
|
+
for (const firstValue of first) {
|
|
15
|
+
enumValueMap.set(firstValue.name.value, firstValue);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
if (second) {
|
|
19
|
+
for (const secondValue of second) {
|
|
20
|
+
const enumValue = secondValue.name.value;
|
|
21
|
+
if (enumValueMap.has(enumValue)) {
|
|
22
|
+
const firstValue = enumValueMap.get(enumValue);
|
|
23
|
+
firstValue.description = secondValue.description || firstValue.description;
|
|
24
|
+
firstValue.directives = mergeDirectives(secondValue.directives, firstValue.directives);
|
|
25
|
+
}
|
|
26
|
+
else {
|
|
27
|
+
enumValueMap.set(enumValue, secondValue);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
const result = [...enumValueMap.values()];
|
|
32
|
+
if (config && config.sort) {
|
|
33
|
+
result.sort(compareNodes);
|
|
34
|
+
}
|
|
35
|
+
return result;
|
|
36
|
+
}
|