@graphql-tools/utils 8.7.0 → 8.8.0-alpha-6c480b2d.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/AggregateError.js +25 -0
- package/cjs/Interfaces.js +31 -0
- package/cjs/addTypes.js +62 -0
- package/cjs/astFromType.js +31 -0
- package/cjs/astFromValueUntyped.js +78 -0
- package/cjs/build-operation-for-field.js +351 -0
- package/cjs/collectFields.js +98 -0
- package/cjs/comments.js +380 -0
- package/cjs/errors.js +22 -0
- package/cjs/executor.js +2 -0
- package/cjs/fields.js +115 -0
- package/cjs/filterSchema.js +66 -0
- package/cjs/fixSchemaAst.js +26 -0
- package/cjs/forEachDefaultValue.js +29 -0
- package/cjs/forEachField.js +19 -0
- package/cjs/get-directives.js +103 -0
- package/cjs/get-fields-with-directives.js +52 -0
- package/cjs/get-implementing-types.js +19 -0
- package/cjs/getArgumentValues.js +76 -0
- package/cjs/getObjectTypeFromTypeMap.js +13 -0
- package/cjs/getOperationASTFromRequest.js +16 -0
- package/cjs/getResolversFromSchema.js +73 -0
- package/cjs/getResponseKeyFromInfo.js +12 -0
- package/cjs/heal.js +177 -0
- package/cjs/helpers.js +76 -0
- package/cjs/implementsAbstractType.js +17 -0
- package/cjs/index.js +53 -0
- package/cjs/inspect.js +107 -0
- package/cjs/isAsyncIterable.js +10 -0
- package/cjs/isDocumentNode.js +8 -0
- package/cjs/loaders.js +2 -0
- package/cjs/mapAsyncIterator.js +53 -0
- package/cjs/mapSchema.js +470 -0
- package/cjs/memoize.js +189 -0
- package/cjs/mergeDeep.js +45 -0
- package/cjs/observableToAsyncIterable.js +85 -0
- package/cjs/package.json +1 -0
- package/cjs/parse-graphql-json.js +44 -0
- package/cjs/parse-graphql-sdl.js +84 -0
- package/cjs/print-schema-with-directives.js +494 -0
- package/cjs/prune.js +133 -0
- package/cjs/renameType.js +152 -0
- package/cjs/rewire.js +159 -0
- package/cjs/rootTypes.js +37 -0
- package/cjs/selectionSets.js +9 -0
- package/cjs/stub.js +68 -0
- package/cjs/transformInputValue.js +55 -0
- package/cjs/types.js +27 -0
- package/cjs/updateArgument.js +54 -0
- package/cjs/validate-documents.js +76 -0
- package/cjs/valueMatchesCriteria.js +21 -0
- package/cjs/visitResult.js +229 -0
- package/cjs/withCancel.js +56 -0
- package/esm/AggregateError.js +21 -0
- package/esm/Interfaces.js +28 -0
- package/esm/addTypes.js +58 -0
- package/esm/astFromType.js +27 -0
- package/esm/astFromValueUntyped.js +74 -0
- package/esm/build-operation-for-field.js +347 -0
- package/esm/collectFields.js +94 -0
- package/esm/comments.js +367 -0
- package/esm/errors.js +17 -0
- package/esm/executor.js +1 -0
- package/esm/fields.js +108 -0
- package/esm/filterSchema.js +62 -0
- package/esm/fixSchemaAst.js +22 -0
- package/esm/forEachDefaultValue.js +25 -0
- package/esm/forEachField.js +15 -0
- package/esm/get-directives.js +96 -0
- package/esm/get-fields-with-directives.js +48 -0
- package/esm/get-implementing-types.js +15 -0
- package/esm/getArgumentValues.js +72 -0
- package/esm/getObjectTypeFromTypeMap.js +9 -0
- package/esm/getOperationASTFromRequest.js +12 -0
- package/esm/getResolversFromSchema.js +69 -0
- package/esm/getResponseKeyFromInfo.js +8 -0
- package/esm/heal.js +172 -0
- package/esm/helpers.js +65 -0
- package/esm/implementsAbstractType.js +13 -0
- package/esm/index.js +50 -0
- package/esm/inspect.js +103 -0
- package/esm/isAsyncIterable.js +6 -0
- package/esm/isDocumentNode.js +4 -0
- package/esm/loaders.js +1 -0
- package/esm/mapAsyncIterator.js +49 -0
- package/esm/mapSchema.js +465 -0
- package/esm/memoize.js +180 -0
- package/esm/mergeDeep.js +41 -0
- package/esm/observableToAsyncIterable.js +81 -0
- package/esm/parse-graphql-json.js +40 -0
- package/esm/parse-graphql-sdl.js +78 -0
- package/esm/print-schema-with-directives.js +472 -0
- package/esm/prune.js +129 -0
- package/esm/renameType.js +148 -0
- package/esm/rewire.js +155 -0
- package/esm/rootTypes.js +33 -0
- package/esm/selectionSets.js +5 -0
- package/esm/stub.js +61 -0
- package/esm/transformInputValue.js +48 -0
- package/esm/types.js +24 -0
- package/esm/updateArgument.js +49 -0
- package/esm/validate-documents.js +70 -0
- package/esm/valueMatchesCriteria.js +17 -0
- package/esm/visitResult.js +223 -0
- package/esm/withCancel.js +51 -0
- package/package.json +31 -10
- package/{AggregateError.d.ts → typings/AggregateError.d.ts} +0 -0
- package/{Interfaces.d.ts → typings/Interfaces.d.ts} +0 -0
- package/{addTypes.d.ts → typings/addTypes.d.ts} +0 -0
- package/{astFromType.d.ts → typings/astFromType.d.ts} +0 -0
- package/{astFromValueUntyped.d.ts → typings/astFromValueUntyped.d.ts} +0 -0
- package/{build-operation-for-field.d.ts → typings/build-operation-for-field.d.ts} +0 -0
- package/{collectFields.d.ts → typings/collectFields.d.ts} +0 -0
- package/{comments.d.ts → typings/comments.d.ts} +0 -0
- package/{errors.d.ts → typings/errors.d.ts} +1 -1
- package/{executor.d.ts → typings/executor.d.ts} +1 -1
- package/{fields.d.ts → typings/fields.d.ts} +0 -0
- package/{filterSchema.d.ts → typings/filterSchema.d.ts} +1 -1
- package/{fixSchemaAst.d.ts → typings/fixSchemaAst.d.ts} +1 -1
- package/{forEachDefaultValue.d.ts → typings/forEachDefaultValue.d.ts} +1 -1
- package/{forEachField.d.ts → typings/forEachField.d.ts} +1 -1
- package/{get-directives.d.ts → typings/get-directives.d.ts} +0 -0
- package/{get-fields-with-directives.d.ts → typings/get-fields-with-directives.d.ts} +0 -0
- package/{get-implementing-types.d.ts → typings/get-implementing-types.d.ts} +0 -0
- package/{getArgumentValues.d.ts → typings/getArgumentValues.d.ts} +0 -0
- package/{getObjectTypeFromTypeMap.d.ts → typings/getObjectTypeFromTypeMap.d.ts} +1 -1
- package/{getOperationASTFromRequest.d.ts → typings/getOperationASTFromRequest.d.ts} +1 -1
- package/{getResolversFromSchema.d.ts → typings/getResolversFromSchema.d.ts} +1 -1
- package/{getResponseKeyFromInfo.d.ts → typings/getResponseKeyFromInfo.d.ts} +0 -0
- package/{heal.d.ts → typings/heal.d.ts} +0 -0
- package/{helpers.d.ts → typings/helpers.d.ts} +0 -0
- package/{implementsAbstractType.d.ts → typings/implementsAbstractType.d.ts} +1 -1
- package/typings/index.d.ts +50 -0
- package/{inspect.d.ts → typings/inspect.d.ts} +0 -0
- package/{isAsyncIterable.d.ts → typings/isAsyncIterable.d.ts} +0 -0
- package/{isDocumentNode.d.ts → typings/isDocumentNode.d.ts} +0 -0
- package/{loaders.d.ts → typings/loaders.d.ts} +1 -1
- package/{mapAsyncIterator.d.ts → typings/mapAsyncIterator.d.ts} +0 -0
- package/{mapSchema.d.ts → typings/mapSchema.d.ts} +1 -1
- package/{memoize.d.ts → typings/memoize.d.ts} +0 -0
- package/{mergeDeep.d.ts → typings/mergeDeep.d.ts} +0 -0
- package/{observableToAsyncIterable.d.ts → typings/observableToAsyncIterable.d.ts} +0 -0
- package/{parse-graphql-json.d.ts → typings/parse-graphql-json.d.ts} +2 -2
- package/{parse-graphql-sdl.d.ts → typings/parse-graphql-sdl.d.ts} +1 -1
- package/{print-schema-with-directives.d.ts → typings/print-schema-with-directives.d.ts} +1 -1
- package/{prune.d.ts → typings/prune.d.ts} +1 -1
- package/{renameType.d.ts → typings/renameType.d.ts} +0 -0
- package/{rewire.d.ts → typings/rewire.d.ts} +0 -0
- package/{rootTypes.d.ts → typings/rootTypes.d.ts} +0 -0
- package/{selectionSets.d.ts → typings/selectionSets.d.ts} +1 -1
- package/{stub.d.ts → typings/stub.d.ts} +0 -0
- package/{transformInputValue.d.ts → typings/transformInputValue.d.ts} +1 -1
- package/{types.d.ts → typings/types.d.ts} +0 -0
- package/{updateArgument.d.ts → typings/updateArgument.d.ts} +0 -0
- package/{validate-documents.d.ts → typings/validate-documents.d.ts} +1 -1
- package/{valueMatchesCriteria.d.ts → typings/valueMatchesCriteria.d.ts} +0 -0
- package/{visitResult.d.ts → typings/visitResult.d.ts} +1 -1
- package/{withCancel.d.ts → typings/withCancel.d.ts} +0 -0
- package/index.d.ts +0 -50
- package/index.js +0 -4428
- package/index.mjs +0 -4315
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { getArgumentValues } from './getArgumentValues.js';
|
|
2
|
+
export function getDirectivesInExtensions(node, pathToDirectivesInExtensions = ['directives']) {
|
|
3
|
+
return pathToDirectivesInExtensions.reduce((acc, pathSegment) => (acc == null ? acc : acc[pathSegment]), node === null || node === void 0 ? void 0 : node.extensions);
|
|
4
|
+
}
|
|
5
|
+
function _getDirectiveInExtensions(directivesInExtensions, directiveName) {
|
|
6
|
+
const directiveInExtensions = directivesInExtensions.filter(directiveAnnotation => directiveAnnotation.name === directiveName);
|
|
7
|
+
if (!directiveInExtensions.length) {
|
|
8
|
+
return undefined;
|
|
9
|
+
}
|
|
10
|
+
return directiveInExtensions.map(directive => { var _a; return (_a = directive.args) !== null && _a !== void 0 ? _a : {}; });
|
|
11
|
+
}
|
|
12
|
+
export function getDirectiveInExtensions(node, directiveName, pathToDirectivesInExtensions = ['directives']) {
|
|
13
|
+
const directivesInExtensions = pathToDirectivesInExtensions.reduce((acc, pathSegment) => (acc == null ? acc : acc[pathSegment]), node === null || node === void 0 ? void 0 : node.extensions);
|
|
14
|
+
if (directivesInExtensions === undefined) {
|
|
15
|
+
return undefined;
|
|
16
|
+
}
|
|
17
|
+
if (Array.isArray(directivesInExtensions)) {
|
|
18
|
+
return _getDirectiveInExtensions(directivesInExtensions, directiveName);
|
|
19
|
+
}
|
|
20
|
+
// Support condensed format by converting to longer format
|
|
21
|
+
// The condensed format does not preserve ordering of directives when repeatable directives are used.
|
|
22
|
+
// See https://github.com/ardatan/graphql-tools/issues/2534
|
|
23
|
+
const reformattedDirectivesInExtensions = [];
|
|
24
|
+
for (const [name, argsOrArrayOfArgs] of Object.entries(directivesInExtensions)) {
|
|
25
|
+
if (Array.isArray(argsOrArrayOfArgs)) {
|
|
26
|
+
for (const args of argsOrArrayOfArgs) {
|
|
27
|
+
reformattedDirectivesInExtensions.push({ name, args });
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
else {
|
|
31
|
+
reformattedDirectivesInExtensions.push({ name, args: argsOrArrayOfArgs });
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
return _getDirectiveInExtensions(reformattedDirectivesInExtensions, directiveName);
|
|
35
|
+
}
|
|
36
|
+
export function getDirectives(schema, node, pathToDirectivesInExtensions = ['directives']) {
|
|
37
|
+
const directivesInExtensions = getDirectivesInExtensions(node, pathToDirectivesInExtensions);
|
|
38
|
+
if (directivesInExtensions != null && directivesInExtensions.length > 0) {
|
|
39
|
+
return directivesInExtensions;
|
|
40
|
+
}
|
|
41
|
+
const schemaDirectives = schema && schema.getDirectives ? schema.getDirectives() : [];
|
|
42
|
+
const schemaDirectiveMap = schemaDirectives.reduce((schemaDirectiveMap, schemaDirective) => {
|
|
43
|
+
schemaDirectiveMap[schemaDirective.name] = schemaDirective;
|
|
44
|
+
return schemaDirectiveMap;
|
|
45
|
+
}, {});
|
|
46
|
+
let astNodes = [];
|
|
47
|
+
if (node.astNode) {
|
|
48
|
+
astNodes.push(node.astNode);
|
|
49
|
+
}
|
|
50
|
+
if ('extensionASTNodes' in node && node.extensionASTNodes) {
|
|
51
|
+
astNodes = [...astNodes, ...node.extensionASTNodes];
|
|
52
|
+
}
|
|
53
|
+
const result = [];
|
|
54
|
+
for (const astNode of astNodes) {
|
|
55
|
+
if (astNode.directives) {
|
|
56
|
+
for (const directiveNode of astNode.directives) {
|
|
57
|
+
const schemaDirective = schemaDirectiveMap[directiveNode.name.value];
|
|
58
|
+
if (schemaDirective) {
|
|
59
|
+
result.push({ name: directiveNode.name.value, args: getArgumentValues(schemaDirective, directiveNode) });
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
return result;
|
|
65
|
+
}
|
|
66
|
+
export function getDirective(schema, node, directiveName, pathToDirectivesInExtensions = ['directives']) {
|
|
67
|
+
const directiveInExtensions = getDirectiveInExtensions(node, directiveName, pathToDirectivesInExtensions);
|
|
68
|
+
if (directiveInExtensions != null) {
|
|
69
|
+
return directiveInExtensions;
|
|
70
|
+
}
|
|
71
|
+
const schemaDirective = schema && schema.getDirective ? schema.getDirective(directiveName) : undefined;
|
|
72
|
+
if (schemaDirective == null) {
|
|
73
|
+
return undefined;
|
|
74
|
+
}
|
|
75
|
+
let astNodes = [];
|
|
76
|
+
if (node.astNode) {
|
|
77
|
+
astNodes.push(node.astNode);
|
|
78
|
+
}
|
|
79
|
+
if ('extensionASTNodes' in node && node.extensionASTNodes) {
|
|
80
|
+
astNodes = [...astNodes, ...node.extensionASTNodes];
|
|
81
|
+
}
|
|
82
|
+
const result = [];
|
|
83
|
+
for (const astNode of astNodes) {
|
|
84
|
+
if (astNode.directives) {
|
|
85
|
+
for (const directiveNode of astNode.directives) {
|
|
86
|
+
if (directiveNode.name.value === directiveName) {
|
|
87
|
+
result.push(getArgumentValues(schemaDirective, directiveNode));
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
if (!result.length) {
|
|
93
|
+
return undefined;
|
|
94
|
+
}
|
|
95
|
+
return result;
|
|
96
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { Kind, } from 'graphql';
|
|
2
|
+
function parseDirectiveValue(value) {
|
|
3
|
+
switch (value.kind) {
|
|
4
|
+
case Kind.INT:
|
|
5
|
+
return parseInt(value.value);
|
|
6
|
+
case Kind.FLOAT:
|
|
7
|
+
return parseFloat(value.value);
|
|
8
|
+
case Kind.BOOLEAN:
|
|
9
|
+
return Boolean(value.value);
|
|
10
|
+
case Kind.STRING:
|
|
11
|
+
case Kind.ENUM:
|
|
12
|
+
return value.value;
|
|
13
|
+
case Kind.LIST:
|
|
14
|
+
return value.values.map(v => parseDirectiveValue(v));
|
|
15
|
+
case Kind.OBJECT:
|
|
16
|
+
return value.fields.reduce((prev, v) => ({ ...prev, [v.name.value]: parseDirectiveValue(v.value) }), {});
|
|
17
|
+
case Kind.NULL:
|
|
18
|
+
return null;
|
|
19
|
+
default:
|
|
20
|
+
return null;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
export function getFieldsWithDirectives(documentNode, options = {}) {
|
|
24
|
+
const result = {};
|
|
25
|
+
let selected = ['ObjectTypeDefinition', 'ObjectTypeExtension'];
|
|
26
|
+
if (options.includeInputTypes) {
|
|
27
|
+
selected = [...selected, 'InputObjectTypeDefinition', 'InputObjectTypeExtension'];
|
|
28
|
+
}
|
|
29
|
+
const allTypes = documentNode.definitions.filter(obj => selected.includes(obj.kind));
|
|
30
|
+
for (const type of allTypes) {
|
|
31
|
+
const typeName = type.name.value;
|
|
32
|
+
if (type.fields == null) {
|
|
33
|
+
continue;
|
|
34
|
+
}
|
|
35
|
+
for (const field of type.fields) {
|
|
36
|
+
if (field.directives && field.directives.length > 0) {
|
|
37
|
+
const fieldName = field.name.value;
|
|
38
|
+
const key = `${typeName}.${fieldName}`;
|
|
39
|
+
const directives = field.directives.map(d => ({
|
|
40
|
+
name: d.name.value,
|
|
41
|
+
args: (d.arguments || []).reduce((prev, arg) => ({ ...prev, [arg.name.value]: parseDirectiveValue(arg.value) }), {}),
|
|
42
|
+
}));
|
|
43
|
+
result[key] = directives;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
return result;
|
|
48
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { isObjectType } from 'graphql';
|
|
2
|
+
export function getImplementingTypes(interfaceName, schema) {
|
|
3
|
+
const allTypesMap = schema.getTypeMap();
|
|
4
|
+
const result = [];
|
|
5
|
+
for (const graphqlTypeName in allTypesMap) {
|
|
6
|
+
const graphqlType = allTypesMap[graphqlTypeName];
|
|
7
|
+
if (isObjectType(graphqlType)) {
|
|
8
|
+
const allInterfaces = graphqlType.getInterfaces();
|
|
9
|
+
if (allInterfaces.find(int => int.name === interfaceName)) {
|
|
10
|
+
result.push(graphqlType.name);
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
return result;
|
|
15
|
+
}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { valueFromAST, isNonNullType, Kind, print, } from 'graphql';
|
|
2
|
+
import { createGraphQLError } from './errors.js';
|
|
3
|
+
import { inspect } from './inspect.js';
|
|
4
|
+
/**
|
|
5
|
+
* Prepares an object map of argument values given a list of argument
|
|
6
|
+
* definitions and list of argument AST nodes.
|
|
7
|
+
*
|
|
8
|
+
* Note: The returned value is a plain Object with a prototype, since it is
|
|
9
|
+
* exposed to user code. Care should be taken to not pull values from the
|
|
10
|
+
* Object prototype.
|
|
11
|
+
*/
|
|
12
|
+
export function getArgumentValues(def, node, variableValues = {}) {
|
|
13
|
+
var _a;
|
|
14
|
+
const variableMap = Object.entries(variableValues).reduce((prev, [key, value]) => ({
|
|
15
|
+
...prev,
|
|
16
|
+
[key]: value,
|
|
17
|
+
}), {});
|
|
18
|
+
const coercedValues = {};
|
|
19
|
+
const argumentNodes = (_a = node.arguments) !== null && _a !== void 0 ? _a : [];
|
|
20
|
+
const argNodeMap = argumentNodes.reduce((prev, arg) => ({
|
|
21
|
+
...prev,
|
|
22
|
+
[arg.name.value]: arg,
|
|
23
|
+
}), {});
|
|
24
|
+
for (const { name, type: argType, defaultValue } of def.args) {
|
|
25
|
+
const argumentNode = argNodeMap[name];
|
|
26
|
+
if (!argumentNode) {
|
|
27
|
+
if (defaultValue !== undefined) {
|
|
28
|
+
coercedValues[name] = defaultValue;
|
|
29
|
+
}
|
|
30
|
+
else if (isNonNullType(argType)) {
|
|
31
|
+
throw createGraphQLError(`Argument "${name}" of required type "${inspect(argType)}" ` + 'was not provided.', {
|
|
32
|
+
nodes: [node],
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
continue;
|
|
36
|
+
}
|
|
37
|
+
const valueNode = argumentNode.value;
|
|
38
|
+
let isNull = valueNode.kind === Kind.NULL;
|
|
39
|
+
if (valueNode.kind === Kind.VARIABLE) {
|
|
40
|
+
const variableName = valueNode.name.value;
|
|
41
|
+
if (variableValues == null || variableMap[variableName] == null) {
|
|
42
|
+
if (defaultValue !== undefined) {
|
|
43
|
+
coercedValues[name] = defaultValue;
|
|
44
|
+
}
|
|
45
|
+
else if (isNonNullType(argType)) {
|
|
46
|
+
throw createGraphQLError(`Argument "${name}" of required type "${inspect(argType)}" ` +
|
|
47
|
+
`was provided the variable "$${variableName}" which was not provided a runtime value.`, {
|
|
48
|
+
nodes: [valueNode],
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
continue;
|
|
52
|
+
}
|
|
53
|
+
isNull = variableValues[variableName] == null;
|
|
54
|
+
}
|
|
55
|
+
if (isNull && isNonNullType(argType)) {
|
|
56
|
+
throw createGraphQLError(`Argument "${name}" of non-null type "${inspect(argType)}" ` + 'must not be null.', {
|
|
57
|
+
nodes: [valueNode],
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
const coercedValue = valueFromAST(valueNode, argType, variableValues);
|
|
61
|
+
if (coercedValue === undefined) {
|
|
62
|
+
// Note: ValuesOfCorrectTypeRule validation should catch this before
|
|
63
|
+
// execution. This is a runtime check to ensure execution does not
|
|
64
|
+
// continue with an invalid argument value.
|
|
65
|
+
throw createGraphQLError(`Argument "${name}" has invalid value ${print(valueNode)}.`, {
|
|
66
|
+
nodes: [valueNode],
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
coercedValues[name] = coercedValue;
|
|
70
|
+
}
|
|
71
|
+
return coercedValues;
|
|
72
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { getOperationAST } from 'graphql';
|
|
2
|
+
import { memoize1 } from './memoize.js';
|
|
3
|
+
export function getOperationASTFromDocument(documentNode, operationName) {
|
|
4
|
+
const doc = getOperationAST(documentNode, operationName);
|
|
5
|
+
if (!doc) {
|
|
6
|
+
throw new Error(`Cannot infer operation ${operationName || ''}`);
|
|
7
|
+
}
|
|
8
|
+
return doc;
|
|
9
|
+
}
|
|
10
|
+
export const getOperationASTFromRequest = memoize1(function getOperationASTFromRequest(request) {
|
|
11
|
+
return getOperationASTFromDocument(request.document, request.operationName);
|
|
12
|
+
});
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { GraphQLScalarType, isScalarType, isEnumType, isInterfaceType, isUnionType, isObjectType, isSpecifiedScalarType, } from 'graphql';
|
|
2
|
+
export function getResolversFromSchema(schema,
|
|
3
|
+
// Include default merged resolvers
|
|
4
|
+
includeDefaultMergedResolver) {
|
|
5
|
+
var _a, _b;
|
|
6
|
+
const resolvers = Object.create(null);
|
|
7
|
+
const typeMap = schema.getTypeMap();
|
|
8
|
+
for (const typeName in typeMap) {
|
|
9
|
+
if (!typeName.startsWith('__')) {
|
|
10
|
+
const type = typeMap[typeName];
|
|
11
|
+
if (isScalarType(type)) {
|
|
12
|
+
if (!isSpecifiedScalarType(type)) {
|
|
13
|
+
const config = type.toConfig();
|
|
14
|
+
delete config.astNode; // avoid AST duplication elsewhere
|
|
15
|
+
resolvers[typeName] = new GraphQLScalarType(config);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
else if (isEnumType(type)) {
|
|
19
|
+
resolvers[typeName] = {};
|
|
20
|
+
const values = type.getValues();
|
|
21
|
+
for (const value of values) {
|
|
22
|
+
resolvers[typeName][value.name] = value.value;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
else if (isInterfaceType(type)) {
|
|
26
|
+
if (type.resolveType != null) {
|
|
27
|
+
resolvers[typeName] = {
|
|
28
|
+
__resolveType: type.resolveType,
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
else if (isUnionType(type)) {
|
|
33
|
+
if (type.resolveType != null) {
|
|
34
|
+
resolvers[typeName] = {
|
|
35
|
+
__resolveType: type.resolveType,
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
else if (isObjectType(type)) {
|
|
40
|
+
resolvers[typeName] = {};
|
|
41
|
+
if (type.isTypeOf != null) {
|
|
42
|
+
resolvers[typeName].__isTypeOf = type.isTypeOf;
|
|
43
|
+
}
|
|
44
|
+
const fields = type.getFields();
|
|
45
|
+
for (const fieldName in fields) {
|
|
46
|
+
const field = fields[fieldName];
|
|
47
|
+
if (field.subscribe != null) {
|
|
48
|
+
resolvers[typeName][fieldName] = resolvers[typeName][fieldName] || {};
|
|
49
|
+
resolvers[typeName][fieldName].subscribe = field.subscribe;
|
|
50
|
+
}
|
|
51
|
+
if (field.resolve != null && ((_a = field.resolve) === null || _a === void 0 ? void 0 : _a.name) !== 'defaultFieldResolver') {
|
|
52
|
+
switch ((_b = field.resolve) === null || _b === void 0 ? void 0 : _b.name) {
|
|
53
|
+
case 'defaultMergedResolver':
|
|
54
|
+
if (!includeDefaultMergedResolver) {
|
|
55
|
+
continue;
|
|
56
|
+
}
|
|
57
|
+
break;
|
|
58
|
+
case 'defaultFieldResolver':
|
|
59
|
+
continue;
|
|
60
|
+
}
|
|
61
|
+
resolvers[typeName][fieldName] = resolvers[typeName][fieldName] || {};
|
|
62
|
+
resolvers[typeName][fieldName].resolve = field.resolve;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
return resolvers;
|
|
69
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Get the key under which the result of this resolver will be placed in the response JSON. Basically, just
|
|
3
|
+
* resolves aliases.
|
|
4
|
+
* @param info The info argument to the resolver.
|
|
5
|
+
*/
|
|
6
|
+
export function getResponseKeyFromInfo(info) {
|
|
7
|
+
return info.fieldNodes[0].alias != null ? info.fieldNodes[0].alias.value : info.fieldName;
|
|
8
|
+
}
|
package/esm/heal.js
ADDED
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
import { GraphQLList, GraphQLNonNull, isNamedType, isObjectType, isInterfaceType, isUnionType, isInputObjectType, isLeafType, isListType, isNonNullType, } from 'graphql';
|
|
2
|
+
// Update any references to named schema types that disagree with the named
|
|
3
|
+
// types found in schema.getTypeMap().
|
|
4
|
+
//
|
|
5
|
+
// healSchema and its callers (visitSchema/visitSchemaDirectives) all modify the schema in place.
|
|
6
|
+
// Therefore, private variables (such as the stored implementation map and the proper root types)
|
|
7
|
+
// are not updated.
|
|
8
|
+
//
|
|
9
|
+
// If this causes issues, the schema could be more aggressively healed as follows:
|
|
10
|
+
//
|
|
11
|
+
// healSchema(schema);
|
|
12
|
+
// const config = schema.toConfig()
|
|
13
|
+
// const healedSchema = new GraphQLSchema({
|
|
14
|
+
// ...config,
|
|
15
|
+
// query: schema.getType('<desired new root query type name>'),
|
|
16
|
+
// mutation: schema.getType('<desired new root mutation type name>'),
|
|
17
|
+
// subscription: schema.getType('<desired new root subscription type name>'),
|
|
18
|
+
// });
|
|
19
|
+
//
|
|
20
|
+
// One can then also -- if necessary -- assign the correct private variables to the initial schema
|
|
21
|
+
// as follows:
|
|
22
|
+
// Object.assign(schema, healedSchema);
|
|
23
|
+
//
|
|
24
|
+
// These steps are not taken automatically to preserve backwards compatibility with graphql-tools v4.
|
|
25
|
+
// See https://github.com/ardatan/graphql-tools/issues/1462
|
|
26
|
+
//
|
|
27
|
+
// They were briefly taken in v5, but can now be phased out as they were only required when other
|
|
28
|
+
// areas of the codebase were using healSchema and visitSchema more extensively.
|
|
29
|
+
//
|
|
30
|
+
export function healSchema(schema) {
|
|
31
|
+
healTypes(schema.getTypeMap(), schema.getDirectives());
|
|
32
|
+
return schema;
|
|
33
|
+
}
|
|
34
|
+
export function healTypes(originalTypeMap, directives) {
|
|
35
|
+
const actualNamedTypeMap = Object.create(null);
|
|
36
|
+
// If any of the .name properties of the GraphQLNamedType objects in
|
|
37
|
+
// schema.getTypeMap() have changed, the keys of the type map need to
|
|
38
|
+
// be updated accordingly.
|
|
39
|
+
for (const typeName in originalTypeMap) {
|
|
40
|
+
const namedType = originalTypeMap[typeName];
|
|
41
|
+
if (namedType == null || typeName.startsWith('__')) {
|
|
42
|
+
continue;
|
|
43
|
+
}
|
|
44
|
+
const actualName = namedType.name;
|
|
45
|
+
if (actualName.startsWith('__')) {
|
|
46
|
+
continue;
|
|
47
|
+
}
|
|
48
|
+
if (actualName in actualNamedTypeMap) {
|
|
49
|
+
throw new Error(`Duplicate schema type name ${actualName}`);
|
|
50
|
+
}
|
|
51
|
+
actualNamedTypeMap[actualName] = namedType;
|
|
52
|
+
// Note: we are deliberately leaving namedType in the schema by its
|
|
53
|
+
// original name (which might be different from actualName), so that
|
|
54
|
+
// references by that name can be healed.
|
|
55
|
+
}
|
|
56
|
+
// Now add back every named type by its actual name.
|
|
57
|
+
for (const typeName in actualNamedTypeMap) {
|
|
58
|
+
const namedType = actualNamedTypeMap[typeName];
|
|
59
|
+
originalTypeMap[typeName] = namedType;
|
|
60
|
+
}
|
|
61
|
+
// Directive declaration argument types can refer to named types.
|
|
62
|
+
for (const decl of directives) {
|
|
63
|
+
decl.args = decl.args.filter(arg => {
|
|
64
|
+
arg.type = healType(arg.type);
|
|
65
|
+
return arg.type !== null;
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
for (const typeName in originalTypeMap) {
|
|
69
|
+
const namedType = originalTypeMap[typeName];
|
|
70
|
+
// Heal all named types, except for dangling references, kept only to redirect.
|
|
71
|
+
if (!typeName.startsWith('__') && typeName in actualNamedTypeMap) {
|
|
72
|
+
if (namedType != null) {
|
|
73
|
+
healNamedType(namedType);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
for (const typeName in originalTypeMap) {
|
|
78
|
+
if (!typeName.startsWith('__') && !(typeName in actualNamedTypeMap)) {
|
|
79
|
+
delete originalTypeMap[typeName];
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
function healNamedType(type) {
|
|
83
|
+
if (isObjectType(type)) {
|
|
84
|
+
healFields(type);
|
|
85
|
+
healInterfaces(type);
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
else if (isInterfaceType(type)) {
|
|
89
|
+
healFields(type);
|
|
90
|
+
if ('getInterfaces' in type) {
|
|
91
|
+
healInterfaces(type);
|
|
92
|
+
}
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
else if (isUnionType(type)) {
|
|
96
|
+
healUnderlyingTypes(type);
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
else if (isInputObjectType(type)) {
|
|
100
|
+
healInputFields(type);
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
else if (isLeafType(type)) {
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
throw new Error(`Unexpected schema type: ${type}`);
|
|
107
|
+
}
|
|
108
|
+
function healFields(type) {
|
|
109
|
+
const fieldMap = type.getFields();
|
|
110
|
+
for (const [key, field] of Object.entries(fieldMap)) {
|
|
111
|
+
field.args
|
|
112
|
+
.map(arg => {
|
|
113
|
+
arg.type = healType(arg.type);
|
|
114
|
+
return arg.type === null ? null : arg;
|
|
115
|
+
})
|
|
116
|
+
.filter(Boolean);
|
|
117
|
+
field.type = healType(field.type);
|
|
118
|
+
if (field.type === null) {
|
|
119
|
+
delete fieldMap[key];
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
function healInterfaces(type) {
|
|
124
|
+
if ('getInterfaces' in type) {
|
|
125
|
+
const interfaces = type.getInterfaces();
|
|
126
|
+
interfaces.push(...interfaces
|
|
127
|
+
.splice(0)
|
|
128
|
+
.map(iface => healType(iface))
|
|
129
|
+
.filter(Boolean));
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
function healInputFields(type) {
|
|
133
|
+
const fieldMap = type.getFields();
|
|
134
|
+
for (const [key, field] of Object.entries(fieldMap)) {
|
|
135
|
+
field.type = healType(field.type);
|
|
136
|
+
if (field.type === null) {
|
|
137
|
+
delete fieldMap[key];
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
function healUnderlyingTypes(type) {
|
|
142
|
+
const types = type.getTypes();
|
|
143
|
+
types.push(...types
|
|
144
|
+
.splice(0)
|
|
145
|
+
.map(t => healType(t))
|
|
146
|
+
.filter(Boolean));
|
|
147
|
+
}
|
|
148
|
+
function healType(type) {
|
|
149
|
+
// Unwrap the two known wrapper types
|
|
150
|
+
if (isListType(type)) {
|
|
151
|
+
const healedType = healType(type.ofType);
|
|
152
|
+
return healedType != null ? new GraphQLList(healedType) : null;
|
|
153
|
+
}
|
|
154
|
+
else if (isNonNullType(type)) {
|
|
155
|
+
const healedType = healType(type.ofType);
|
|
156
|
+
return healedType != null ? new GraphQLNonNull(healedType) : null;
|
|
157
|
+
}
|
|
158
|
+
else if (isNamedType(type)) {
|
|
159
|
+
// If a type annotation on a field or an argument or a union member is
|
|
160
|
+
// any `GraphQLNamedType` with a `name`, then it must end up identical
|
|
161
|
+
// to `schema.getType(name)`, since `schema.getTypeMap()` is the source
|
|
162
|
+
// of truth for all named schema types.
|
|
163
|
+
// Note that new types can still be simply added by adding a field, as
|
|
164
|
+
// the official type will be undefined, not null.
|
|
165
|
+
const officialType = originalTypeMap[type.name];
|
|
166
|
+
if (officialType && type !== officialType) {
|
|
167
|
+
return officialType;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
return type;
|
|
171
|
+
}
|
|
172
|
+
}
|
package/esm/helpers.js
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { parse } from 'graphql';
|
|
2
|
+
export const asArray = (fns) => (Array.isArray(fns) ? fns : fns ? [fns] : []);
|
|
3
|
+
const invalidDocRegex = /\.[a-z0-9]+$/i;
|
|
4
|
+
export function isDocumentString(str) {
|
|
5
|
+
if (typeof str !== 'string') {
|
|
6
|
+
return false;
|
|
7
|
+
}
|
|
8
|
+
// XXX: is-valid-path or is-glob treat SDL as a valid path
|
|
9
|
+
// (`scalar Date` for example)
|
|
10
|
+
// this why checking the extension is fast enough
|
|
11
|
+
// and prevent from parsing the string in order to find out
|
|
12
|
+
// if the string is a SDL
|
|
13
|
+
if (invalidDocRegex.test(str)) {
|
|
14
|
+
return false;
|
|
15
|
+
}
|
|
16
|
+
try {
|
|
17
|
+
parse(str);
|
|
18
|
+
return true;
|
|
19
|
+
}
|
|
20
|
+
catch (e) { }
|
|
21
|
+
return false;
|
|
22
|
+
}
|
|
23
|
+
const invalidPathRegex = /[‘“!%&^<=>`]/;
|
|
24
|
+
export function isValidPath(str) {
|
|
25
|
+
return typeof str === 'string' && !invalidPathRegex.test(str);
|
|
26
|
+
}
|
|
27
|
+
export function compareStrings(a, b) {
|
|
28
|
+
if (String(a) < String(b)) {
|
|
29
|
+
return -1;
|
|
30
|
+
}
|
|
31
|
+
if (String(a) > String(b)) {
|
|
32
|
+
return 1;
|
|
33
|
+
}
|
|
34
|
+
return 0;
|
|
35
|
+
}
|
|
36
|
+
export function nodeToString(a) {
|
|
37
|
+
var _a, _b;
|
|
38
|
+
let name;
|
|
39
|
+
if ('alias' in a) {
|
|
40
|
+
name = (_a = a.alias) === null || _a === void 0 ? void 0 : _a.value;
|
|
41
|
+
}
|
|
42
|
+
if (name == null && 'name' in a) {
|
|
43
|
+
name = (_b = a.name) === null || _b === void 0 ? void 0 : _b.value;
|
|
44
|
+
}
|
|
45
|
+
if (name == null) {
|
|
46
|
+
name = a.kind;
|
|
47
|
+
}
|
|
48
|
+
return name;
|
|
49
|
+
}
|
|
50
|
+
export function compareNodes(a, b, customFn) {
|
|
51
|
+
const aStr = nodeToString(a);
|
|
52
|
+
const bStr = nodeToString(b);
|
|
53
|
+
if (typeof customFn === 'function') {
|
|
54
|
+
return customFn(aStr, bStr);
|
|
55
|
+
}
|
|
56
|
+
return compareStrings(aStr, bStr);
|
|
57
|
+
}
|
|
58
|
+
export function isSome(input) {
|
|
59
|
+
return input != null;
|
|
60
|
+
}
|
|
61
|
+
export function assertSome(input, message = 'Value should be something') {
|
|
62
|
+
if (input == null) {
|
|
63
|
+
throw new Error(message);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { doTypesOverlap, isCompositeType } from 'graphql';
|
|
2
|
+
export function implementsAbstractType(schema, typeA, typeB) {
|
|
3
|
+
if (typeB == null || typeA == null) {
|
|
4
|
+
return false;
|
|
5
|
+
}
|
|
6
|
+
else if (typeA === typeB) {
|
|
7
|
+
return true;
|
|
8
|
+
}
|
|
9
|
+
else if (isCompositeType(typeA) && isCompositeType(typeB)) {
|
|
10
|
+
return doTypesOverlap(schema, typeA, typeB);
|
|
11
|
+
}
|
|
12
|
+
return false;
|
|
13
|
+
}
|
package/esm/index.js
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
export * from './loaders.js';
|
|
2
|
+
export * from './helpers.js';
|
|
3
|
+
export * from './get-directives.js';
|
|
4
|
+
export * from './get-fields-with-directives.js';
|
|
5
|
+
export * from './get-implementing-types.js';
|
|
6
|
+
export * from './print-schema-with-directives.js';
|
|
7
|
+
export * from './get-fields-with-directives.js';
|
|
8
|
+
export * from './validate-documents.js';
|
|
9
|
+
export * from './parse-graphql-json.js';
|
|
10
|
+
export * from './parse-graphql-sdl.js';
|
|
11
|
+
export * from './build-operation-for-field.js';
|
|
12
|
+
export * from './types.js';
|
|
13
|
+
export * from './filterSchema.js';
|
|
14
|
+
export * from './heal.js';
|
|
15
|
+
export * from './getResolversFromSchema.js';
|
|
16
|
+
export * from './forEachField.js';
|
|
17
|
+
export * from './forEachDefaultValue.js';
|
|
18
|
+
export * from './mapSchema.js';
|
|
19
|
+
export * from './addTypes.js';
|
|
20
|
+
export * from './rewire.js';
|
|
21
|
+
export * from './prune.js';
|
|
22
|
+
export * from './mergeDeep.js';
|
|
23
|
+
export * from './Interfaces.js';
|
|
24
|
+
export * from './stub.js';
|
|
25
|
+
export * from './selectionSets.js';
|
|
26
|
+
export * from './getResponseKeyFromInfo.js';
|
|
27
|
+
export * from './fields.js';
|
|
28
|
+
export * from './renameType.js';
|
|
29
|
+
export * from './transformInputValue.js';
|
|
30
|
+
export * from './mapAsyncIterator.js';
|
|
31
|
+
export * from './updateArgument.js';
|
|
32
|
+
export * from './implementsAbstractType.js';
|
|
33
|
+
export * from './errors.js';
|
|
34
|
+
export * from './observableToAsyncIterable.js';
|
|
35
|
+
export * from './visitResult.js';
|
|
36
|
+
export * from './getArgumentValues.js';
|
|
37
|
+
export * from './valueMatchesCriteria.js';
|
|
38
|
+
export * from './isAsyncIterable.js';
|
|
39
|
+
export * from './isDocumentNode.js';
|
|
40
|
+
export * from './astFromValueUntyped.js';
|
|
41
|
+
export * from './executor.js';
|
|
42
|
+
export * from './withCancel.js';
|
|
43
|
+
export * from './AggregateError.js';
|
|
44
|
+
export * from './rootTypes.js';
|
|
45
|
+
export * from './comments.js';
|
|
46
|
+
export * from './collectFields.js';
|
|
47
|
+
export * from './inspect.js';
|
|
48
|
+
export * from './memoize.js';
|
|
49
|
+
export * from './fixSchemaAst.js';
|
|
50
|
+
export * from './getOperationASTFromRequest.js';
|