@graphql-inspector/core 4.0.2 → 4.0.3
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/ast/document.js +40 -0
- package/cjs/coverage/index.js +128 -0
- package/cjs/coverage/output/json.js +7 -0
- package/cjs/diff/argument.js +25 -0
- package/cjs/diff/changes/argument.js +48 -0
- package/cjs/diff/changes/change.js +75 -0
- package/cjs/diff/changes/directive.js +124 -0
- package/cjs/diff/changes/enum.js +75 -0
- package/cjs/diff/changes/field.js +166 -0
- package/cjs/diff/changes/input.js +98 -0
- package/cjs/diff/changes/object.js +28 -0
- package/cjs/diff/changes/schema.js +40 -0
- package/cjs/diff/changes/type.js +72 -0
- package/cjs/diff/changes/union.js +28 -0
- package/cjs/diff/directive.js +41 -0
- package/cjs/diff/enum.js +34 -0
- package/cjs/diff/field.js +54 -0
- package/cjs/diff/index.js +22 -0
- package/cjs/diff/input.js +47 -0
- package/cjs/diff/interface.js +20 -0
- package/cjs/diff/object.js +33 -0
- package/cjs/diff/onComplete/types.js +0 -0
- package/cjs/diff/rules/config.js +0 -0
- package/cjs/diff/rules/consider-usage.js +39 -0
- package/cjs/diff/rules/dangerous-breaking.js +13 -0
- package/cjs/diff/rules/ignore-description-changes.js +21 -0
- package/cjs/diff/rules/index.js +8 -0
- package/cjs/diff/rules/safe-unreachable.js +19 -0
- package/cjs/diff/rules/suppress-removal-of-deprecated-field.js +58 -0
- package/cjs/diff/rules/types.js +0 -0
- package/cjs/diff/schema.js +107 -0
- package/cjs/diff/union.js +18 -0
- package/cjs/index.js +27 -0
- package/cjs/package.json +1 -0
- package/cjs/similar/index.js +57 -0
- package/cjs/utils/apollo.js +21 -0
- package/cjs/utils/compare.js +91 -0
- package/cjs/utils/graphql.js +194 -0
- package/cjs/utils/is-deprecated.js +17 -0
- package/cjs/utils/path.js +7 -0
- package/cjs/utils/string.js +70 -0
- package/cjs/validate/alias-count.js +37 -0
- package/cjs/validate/complexity.js +39 -0
- package/cjs/validate/directive-count.js +37 -0
- package/cjs/validate/index.js +143 -0
- package/cjs/validate/query-depth.js +103 -0
- package/cjs/validate/token-count.js +55 -0
- package/esm/ast/document.js +36 -0
- package/esm/coverage/index.js +124 -0
- package/esm/coverage/output/json.js +3 -0
- package/esm/diff/argument.js +21 -0
- package/esm/diff/changes/argument.js +42 -0
- package/esm/diff/changes/change.js +72 -0
- package/esm/diff/changes/directive.js +111 -0
- package/esm/diff/changes/enum.js +66 -0
- package/esm/diff/changes/field.js +150 -0
- package/esm/diff/changes/input.js +88 -0
- package/esm/diff/changes/object.js +23 -0
- package/esm/diff/changes/schema.js +34 -0
- package/esm/diff/changes/type.js +63 -0
- package/esm/diff/changes/union.js +23 -0
- package/esm/diff/directive.js +37 -0
- package/esm/diff/enum.js +30 -0
- package/esm/diff/field.js +50 -0
- package/esm/diff/index.js +18 -0
- package/esm/diff/input.js +43 -0
- package/esm/diff/interface.js +16 -0
- package/esm/diff/object.js +29 -0
- package/esm/diff/onComplete/types.js +0 -0
- package/esm/diff/rules/config.js +0 -0
- package/esm/diff/rules/consider-usage.js +35 -0
- package/esm/diff/rules/dangerous-breaking.js +9 -0
- package/esm/diff/rules/ignore-description-changes.js +17 -0
- package/esm/diff/rules/index.js +5 -0
- package/esm/diff/rules/safe-unreachable.js +15 -0
- package/esm/diff/rules/suppress-removal-of-deprecated-field.js +54 -0
- package/esm/diff/rules/types.js +0 -0
- package/esm/diff/schema.js +103 -0
- package/esm/diff/union.js +14 -0
- package/esm/index.js +11 -0
- package/esm/similar/index.js +53 -0
- package/esm/utils/apollo.js +16 -0
- package/esm/utils/compare.js +82 -0
- package/esm/utils/graphql.js +181 -0
- package/esm/utils/is-deprecated.js +13 -0
- package/esm/utils/path.js +3 -0
- package/esm/utils/string.js +64 -0
- package/esm/validate/alias-count.js +32 -0
- package/esm/validate/complexity.js +34 -0
- package/esm/validate/directive-count.js +32 -0
- package/esm/validate/index.js +139 -0
- package/esm/validate/query-depth.js +97 -0
- package/esm/validate/token-count.js +50 -0
- package/package.json +30 -9
- package/typings/ast/document.d.ts +15 -0
- package/typings/coverage/index.d.ts +51 -0
- package/typings/coverage/output/json.d.cts +2 -0
- package/{coverage → typings/coverage}/output/json.d.ts +1 -1
- package/typings/diff/argument.d.cts +3 -0
- package/{diff → typings/diff}/argument.d.ts +1 -1
- package/typings/diff/changes/argument.d.cts +5 -0
- package/{diff → typings/diff}/changes/argument.d.ts +1 -1
- package/typings/diff/changes/change.d.ts +69 -0
- package/typings/diff/changes/directive.d.cts +12 -0
- package/{diff → typings/diff}/changes/directive.d.ts +1 -1
- package/typings/diff/changes/enum.d.cts +8 -0
- package/{diff → typings/diff}/changes/enum.d.ts +1 -1
- package/typings/diff/changes/field.d.cts +15 -0
- package/{diff → typings/diff}/changes/field.d.ts +1 -1
- package/typings/diff/changes/input.d.cts +9 -0
- package/{diff → typings/diff}/changes/input.d.ts +1 -1
- package/typings/diff/changes/object.d.cts +4 -0
- package/{diff → typings/diff}/changes/object.d.ts +1 -1
- package/typings/diff/changes/schema.d.cts +5 -0
- package/{diff → typings/diff}/changes/schema.d.ts +1 -1
- package/typings/diff/changes/type.d.cts +8 -0
- package/{diff → typings/diff}/changes/type.d.ts +1 -1
- package/typings/diff/changes/union.d.cts +4 -0
- package/{diff → typings/diff}/changes/union.d.ts +1 -1
- package/typings/diff/directive.d.cts +3 -0
- package/{diff → typings/diff}/directive.d.ts +1 -1
- package/typings/diff/enum.d.cts +3 -0
- package/{diff → typings/diff}/enum.d.ts +1 -1
- package/typings/diff/field.d.cts +3 -0
- package/{diff → typings/diff}/field.d.ts +1 -1
- package/typings/diff/index.d.cts +9 -0
- package/typings/diff/index.d.ts +9 -0
- package/typings/diff/input.d.cts +3 -0
- package/{diff → typings/diff}/input.d.ts +1 -1
- package/typings/diff/interface.d.cts +3 -0
- package/{diff → typings/diff}/interface.d.ts +1 -1
- package/typings/diff/object.d.cts +3 -0
- package/{diff → typings/diff}/object.d.ts +1 -1
- package/typings/diff/onComplete/types.d.cts +7 -0
- package/typings/diff/onComplete/types.d.ts +7 -0
- package/typings/diff/rules/config.d.cts +2 -0
- package/typings/diff/rules/config.d.ts +2 -0
- package/typings/diff/rules/consider-usage.d.cts +29 -0
- package/{diff → typings/diff}/rules/consider-usage.d.ts +2 -2
- package/typings/diff/rules/dangerous-breaking.d.cts +2 -0
- package/{diff → typings/diff}/rules/dangerous-breaking.d.ts +1 -1
- package/typings/diff/rules/ignore-description-changes.d.cts +2 -0
- package/{diff → typings/diff}/rules/ignore-description-changes.d.ts +1 -1
- package/typings/diff/rules/index.d.cts +5 -0
- package/typings/diff/rules/index.d.ts +5 -0
- package/typings/diff/rules/safe-unreachable.d.cts +2 -0
- package/{diff → typings/diff}/rules/safe-unreachable.d.ts +1 -1
- package/typings/diff/rules/suppress-removal-of-deprecated-field.d.cts +2 -0
- package/{diff → typings/diff}/rules/suppress-removal-of-deprecated-field.d.ts +1 -1
- package/typings/diff/rules/types.d.cts +8 -0
- package/{diff → typings/diff}/rules/types.d.ts +2 -2
- package/typings/diff/schema.d.cts +4 -0
- package/{diff → typings/diff}/schema.d.ts +2 -2
- package/typings/diff/union.d.cts +3 -0
- package/{diff → typings/diff}/union.d.ts +1 -1
- package/typings/index.d.cts +12 -0
- package/typings/index.d.ts +12 -0
- package/typings/similar/index.d.cts +6 -0
- package/{similar → typings/similar}/index.d.ts +1 -1
- package/typings/utils/apollo.d.ts +5 -0
- package/typings/utils/compare.d.ts +22 -0
- package/typings/utils/graphql.d.ts +11 -0
- package/typings/utils/is-deprecated.d.cts +2 -0
- package/{utils → typings/utils}/is-deprecated.d.ts +1 -1
- package/typings/utils/path.d.ts +1 -0
- package/typings/utils/string.d.ts +14 -0
- package/typings/validate/alias-count.d.ts +10 -0
- package/typings/validate/complexity.d.cts +16 -0
- package/{validate → typings/validate}/complexity.d.ts +1 -1
- package/typings/validate/directive-count.d.ts +10 -0
- package/typings/validate/index.d.ts +49 -0
- package/typings/validate/query-depth.d.ts +15 -0
- package/typings/validate/token-count.d.ts +12 -0
- package/diff/index.d.ts +0 -9
- package/diff/onComplete/types.d.ts +0 -7
- package/diff/rules/config.d.ts +0 -2
- package/diff/rules/index.d.ts +0 -5
- package/index.d.ts +0 -12
- package/index.js +0 -2075
- package/index.mjs +0 -2061
- /package/{ast/document.d.ts → typings/ast/document.d.cts} +0 -0
- /package/{coverage/index.d.ts → typings/coverage/index.d.cts} +0 -0
- /package/{diff/changes/change.d.ts → typings/diff/changes/change.d.cts} +0 -0
- /package/{utils/apollo.d.ts → typings/utils/apollo.d.cts} +0 -0
- /package/{utils/compare.d.ts → typings/utils/compare.d.cts} +0 -0
- /package/{utils/graphql.d.ts → typings/utils/graphql.d.cts} +0 -0
- /package/{utils/path.d.ts → typings/utils/path.d.cts} +0 -0
- /package/{utils/string.d.ts → typings/utils/string.d.cts} +0 -0
- /package/{validate/alias-count.d.ts → typings/validate/alias-count.d.cts} +0 -0
- /package/{validate/directive-count.d.ts → typings/validate/directive-count.d.cts} +0 -0
- /package/{validate/index.d.ts → typings/validate/index.d.cts} +0 -0
- /package/{validate/query-depth.d.ts → typings/validate/query-depth.d.cts} +0 -0
- /package/{validate/token-count.d.ts → typings/validate/token-count.d.cts} +0 -0
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getReachableTypes = exports.removeDirectives = exports.removeFieldIfDirectives = exports.findDeprecatedUsages = exports.isForIntrospection = exports.isPrimitive = exports.getTypePrefix = exports.getKind = exports.safeChangeForInputValue = exports.safeChangeForField = void 0;
|
|
4
|
+
const graphql_1 = require("graphql");
|
|
5
|
+
const is_deprecated_js_1 = require("./is-deprecated.js");
|
|
6
|
+
function safeChangeForField(oldType, newType) {
|
|
7
|
+
if (!(0, graphql_1.isWrappingType)(oldType) && !(0, graphql_1.isWrappingType)(newType)) {
|
|
8
|
+
return oldType.toString() === newType.toString();
|
|
9
|
+
}
|
|
10
|
+
if ((0, graphql_1.isNonNullType)(newType)) {
|
|
11
|
+
const ofType = (0, graphql_1.isNonNullType)(oldType) ? oldType.ofType : oldType;
|
|
12
|
+
return safeChangeForField(ofType, newType.ofType);
|
|
13
|
+
}
|
|
14
|
+
if ((0, graphql_1.isListType)(oldType)) {
|
|
15
|
+
return (((0, graphql_1.isListType)(newType) && safeChangeForField(oldType.ofType, newType.ofType)) ||
|
|
16
|
+
((0, graphql_1.isNonNullType)(newType) && safeChangeForField(oldType, newType.ofType)));
|
|
17
|
+
}
|
|
18
|
+
return false;
|
|
19
|
+
}
|
|
20
|
+
exports.safeChangeForField = safeChangeForField;
|
|
21
|
+
function safeChangeForInputValue(oldType, newType) {
|
|
22
|
+
if (!(0, graphql_1.isWrappingType)(oldType) && !(0, graphql_1.isWrappingType)(newType)) {
|
|
23
|
+
return oldType.toString() === newType.toString();
|
|
24
|
+
}
|
|
25
|
+
if ((0, graphql_1.isListType)(oldType) && (0, graphql_1.isListType)(newType)) {
|
|
26
|
+
return safeChangeForInputValue(oldType.ofType, newType.ofType);
|
|
27
|
+
}
|
|
28
|
+
if ((0, graphql_1.isNonNullType)(oldType)) {
|
|
29
|
+
const ofType = (0, graphql_1.isNonNullType)(newType) ? newType.ofType : newType;
|
|
30
|
+
return safeChangeForInputValue(oldType.ofType, ofType);
|
|
31
|
+
}
|
|
32
|
+
return false;
|
|
33
|
+
}
|
|
34
|
+
exports.safeChangeForInputValue = safeChangeForInputValue;
|
|
35
|
+
function getKind(type) {
|
|
36
|
+
const node = type.astNode;
|
|
37
|
+
return (node === null || node === void 0 ? void 0 : node.kind) || '';
|
|
38
|
+
}
|
|
39
|
+
exports.getKind = getKind;
|
|
40
|
+
function getTypePrefix(type) {
|
|
41
|
+
const kind = getKind(type);
|
|
42
|
+
const kindsMap = {
|
|
43
|
+
[graphql_1.Kind.SCALAR_TYPE_DEFINITION]: 'scalar',
|
|
44
|
+
[graphql_1.Kind.OBJECT_TYPE_DEFINITION]: 'type',
|
|
45
|
+
[graphql_1.Kind.INTERFACE_TYPE_DEFINITION]: 'interface',
|
|
46
|
+
[graphql_1.Kind.UNION_TYPE_DEFINITION]: 'union',
|
|
47
|
+
[graphql_1.Kind.ENUM_TYPE_DEFINITION]: 'enum',
|
|
48
|
+
[graphql_1.Kind.INPUT_OBJECT_TYPE_DEFINITION]: 'input',
|
|
49
|
+
};
|
|
50
|
+
return kindsMap[kind.toString()];
|
|
51
|
+
}
|
|
52
|
+
exports.getTypePrefix = getTypePrefix;
|
|
53
|
+
function isPrimitive(type) {
|
|
54
|
+
return ['String', 'Int', 'Float', 'Boolean', 'ID'].includes(typeof type === 'string' ? type : type.name);
|
|
55
|
+
}
|
|
56
|
+
exports.isPrimitive = isPrimitive;
|
|
57
|
+
function isForIntrospection(type) {
|
|
58
|
+
return [
|
|
59
|
+
'__Schema',
|
|
60
|
+
'__Type',
|
|
61
|
+
'__TypeKind',
|
|
62
|
+
'__Field',
|
|
63
|
+
'__InputValue',
|
|
64
|
+
'__EnumValue',
|
|
65
|
+
'__Directive',
|
|
66
|
+
'__DirectiveLocation',
|
|
67
|
+
].includes(typeof type === 'string' ? type : type.name);
|
|
68
|
+
}
|
|
69
|
+
exports.isForIntrospection = isForIntrospection;
|
|
70
|
+
function findDeprecatedUsages(schema, ast) {
|
|
71
|
+
const errors = [];
|
|
72
|
+
const typeInfo = new graphql_1.TypeInfo(schema);
|
|
73
|
+
(0, graphql_1.visit)(ast, (0, graphql_1.visitWithTypeInfo)(typeInfo, {
|
|
74
|
+
Argument(node) {
|
|
75
|
+
const argument = typeInfo.getArgument();
|
|
76
|
+
if (argument) {
|
|
77
|
+
const reason = argument.deprecationReason;
|
|
78
|
+
if (reason) {
|
|
79
|
+
const fieldDef = typeInfo.getFieldDef();
|
|
80
|
+
if (fieldDef) {
|
|
81
|
+
errors.push(new graphql_1.GraphQLError(`The argument '${argument === null || argument === void 0 ? void 0 : argument.name}' of '${fieldDef.name}' is deprecated. ${reason}`, [node]));
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
},
|
|
86
|
+
Field(node) {
|
|
87
|
+
const fieldDef = typeInfo.getFieldDef();
|
|
88
|
+
if (fieldDef && (0, is_deprecated_js_1.isDeprecated)(fieldDef)) {
|
|
89
|
+
const parentType = typeInfo.getParentType();
|
|
90
|
+
if (parentType) {
|
|
91
|
+
const reason = fieldDef.deprecationReason;
|
|
92
|
+
errors.push(new graphql_1.GraphQLError(`The field '${parentType.name}.${fieldDef.name}' is deprecated.${reason ? ' ' + reason : ''}`, [node]));
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
},
|
|
96
|
+
EnumValue(node) {
|
|
97
|
+
const enumVal = typeInfo.getEnumValue();
|
|
98
|
+
if (enumVal && (0, is_deprecated_js_1.isDeprecated)(enumVal)) {
|
|
99
|
+
const type = (0, graphql_1.getNamedType)(typeInfo.getInputType());
|
|
100
|
+
if (type) {
|
|
101
|
+
const reason = enumVal.deprecationReason;
|
|
102
|
+
errors.push(new graphql_1.GraphQLError(`The enum value '${type.name}.${enumVal.name}' is deprecated.${reason ? ' ' + reason : ''}`, [node]));
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
},
|
|
106
|
+
}));
|
|
107
|
+
return errors;
|
|
108
|
+
}
|
|
109
|
+
exports.findDeprecatedUsages = findDeprecatedUsages;
|
|
110
|
+
function removeFieldIfDirectives(node, directiveNames) {
|
|
111
|
+
var _a;
|
|
112
|
+
if ((_a = node.directives) === null || _a === void 0 ? void 0 : _a.some(d => directiveNames.includes(d.name.value))) {
|
|
113
|
+
return null;
|
|
114
|
+
}
|
|
115
|
+
return node;
|
|
116
|
+
}
|
|
117
|
+
exports.removeFieldIfDirectives = removeFieldIfDirectives;
|
|
118
|
+
function removeDirectives(node, directiveNames) {
|
|
119
|
+
if (node.directives) {
|
|
120
|
+
return Object.assign(Object.assign({}, node), { directives: node.directives.filter(d => !directiveNames.includes(d.name.value)) });
|
|
121
|
+
}
|
|
122
|
+
return node;
|
|
123
|
+
}
|
|
124
|
+
exports.removeDirectives = removeDirectives;
|
|
125
|
+
function getReachableTypes(schema) {
|
|
126
|
+
const reachableTypes = new Set();
|
|
127
|
+
const collect = (type) => {
|
|
128
|
+
const typeName = type.name;
|
|
129
|
+
if (reachableTypes.has(typeName)) {
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
132
|
+
reachableTypes.add(typeName);
|
|
133
|
+
if ((0, graphql_1.isScalarType)(type)) {
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
if ((0, graphql_1.isInterfaceType)(type) || (0, graphql_1.isObjectType)(type)) {
|
|
137
|
+
if ((0, graphql_1.isInterfaceType)(type)) {
|
|
138
|
+
const { objects, interfaces } = schema.getImplementations(type);
|
|
139
|
+
for (const child of objects) {
|
|
140
|
+
collect(child);
|
|
141
|
+
}
|
|
142
|
+
for (const child of interfaces) {
|
|
143
|
+
collect(child);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
const fields = type.getFields();
|
|
147
|
+
for (const fieldName in fields) {
|
|
148
|
+
const field = fields[fieldName];
|
|
149
|
+
collect(resolveOutputType(field.type));
|
|
150
|
+
const args = field.args;
|
|
151
|
+
for (const argName in args) {
|
|
152
|
+
const arg = args[argName];
|
|
153
|
+
collect(resolveInputType(arg.type));
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
else if ((0, graphql_1.isUnionType)(type)) {
|
|
158
|
+
const types = type.getTypes();
|
|
159
|
+
for (const child of types) {
|
|
160
|
+
collect(child);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
else if ((0, graphql_1.isInputObjectType)(type)) {
|
|
164
|
+
const fields = type.getFields();
|
|
165
|
+
for (const fieldName in fields) {
|
|
166
|
+
const field = fields[fieldName];
|
|
167
|
+
collect(resolveInputType(field.type));
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
};
|
|
171
|
+
for (const type of [
|
|
172
|
+
schema.getQueryType(),
|
|
173
|
+
schema.getMutationType(),
|
|
174
|
+
schema.getSubscriptionType(),
|
|
175
|
+
]) {
|
|
176
|
+
if (type) {
|
|
177
|
+
collect(type);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
return reachableTypes;
|
|
181
|
+
}
|
|
182
|
+
exports.getReachableTypes = getReachableTypes;
|
|
183
|
+
function resolveOutputType(output) {
|
|
184
|
+
if ((0, graphql_1.isListType)(output) || (0, graphql_1.isNonNullType)(output)) {
|
|
185
|
+
return resolveOutputType(output.ofType);
|
|
186
|
+
}
|
|
187
|
+
return output;
|
|
188
|
+
}
|
|
189
|
+
function resolveInputType(input) {
|
|
190
|
+
if ((0, graphql_1.isListType)(input) || (0, graphql_1.isNonNullType)(input)) {
|
|
191
|
+
return resolveInputType(input.ofType);
|
|
192
|
+
}
|
|
193
|
+
return input;
|
|
194
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.isDeprecated = void 0;
|
|
4
|
+
function isDeprecated(fieldOrEnumValue) {
|
|
5
|
+
var _a, _b;
|
|
6
|
+
if ('isDeprecated' in fieldOrEnumValue) {
|
|
7
|
+
return fieldOrEnumValue['isDeprecated'];
|
|
8
|
+
}
|
|
9
|
+
if (fieldOrEnumValue.deprecationReason != null) {
|
|
10
|
+
return true;
|
|
11
|
+
}
|
|
12
|
+
if ((_b = (_a = fieldOrEnumValue.astNode) === null || _a === void 0 ? void 0 : _a.directives) === null || _b === void 0 ? void 0 : _b.some(directive => directive.name.value === 'deprecated')) {
|
|
13
|
+
return true;
|
|
14
|
+
}
|
|
15
|
+
return false;
|
|
16
|
+
}
|
|
17
|
+
exports.isDeprecated = isDeprecated;
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.safeString = exports.findBestMatch = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const object_inspect_1 = tslib_1.__importDefault(require("object-inspect"));
|
|
6
|
+
function compareTwoStrings(str1, str2) {
|
|
7
|
+
if (!str1.length && !str2.length)
|
|
8
|
+
return 1;
|
|
9
|
+
if (!str1.length || !str2.length)
|
|
10
|
+
return 0;
|
|
11
|
+
if (str1.toUpperCase() === str2.toUpperCase())
|
|
12
|
+
return 1;
|
|
13
|
+
if (str1.length === 1 && str2.length === 1)
|
|
14
|
+
return 0;
|
|
15
|
+
const pairs1 = wordLetterPairs(str1);
|
|
16
|
+
const pairs2 = wordLetterPairs(str2);
|
|
17
|
+
const union = pairs1.length + pairs2.length;
|
|
18
|
+
let intersection = 0;
|
|
19
|
+
pairs1.forEach(pair1 => {
|
|
20
|
+
for (let i = 0, pair2; (pair2 = pairs2[i]); i++) {
|
|
21
|
+
if (pair1 !== pair2)
|
|
22
|
+
continue;
|
|
23
|
+
intersection++;
|
|
24
|
+
pairs2.splice(i, 1);
|
|
25
|
+
break;
|
|
26
|
+
}
|
|
27
|
+
});
|
|
28
|
+
return (intersection * 2) / union;
|
|
29
|
+
}
|
|
30
|
+
function findBestMatch(mainString, targetStrings) {
|
|
31
|
+
if (!areArgsValid(mainString, targetStrings))
|
|
32
|
+
throw new Error('Bad arguments: First argument should be a string, second should be an array of strings');
|
|
33
|
+
const ratings = targetStrings.map(target => ({
|
|
34
|
+
target,
|
|
35
|
+
rating: compareTwoStrings(mainString, target.value),
|
|
36
|
+
}));
|
|
37
|
+
const bestMatch = Array.from(ratings).sort((a, b) => b.rating - a.rating)[0];
|
|
38
|
+
return { ratings, bestMatch };
|
|
39
|
+
}
|
|
40
|
+
exports.findBestMatch = findBestMatch;
|
|
41
|
+
function flattenDeep(arr) {
|
|
42
|
+
return Array.isArray(arr) ? arr.reduce((a, b) => a.concat(flattenDeep(b)), []) : [arr];
|
|
43
|
+
}
|
|
44
|
+
function areArgsValid(mainString, targetStrings) {
|
|
45
|
+
if (typeof mainString !== 'string')
|
|
46
|
+
return false;
|
|
47
|
+
if (!Array.isArray(targetStrings))
|
|
48
|
+
return false;
|
|
49
|
+
if (!targetStrings.length)
|
|
50
|
+
return false;
|
|
51
|
+
if (targetStrings.find(s => typeof s.value !== 'string'))
|
|
52
|
+
return false;
|
|
53
|
+
return true;
|
|
54
|
+
}
|
|
55
|
+
function letterPairs(str) {
|
|
56
|
+
const pairs = [];
|
|
57
|
+
for (let i = 0, max = str.length - 1; i < max; i++)
|
|
58
|
+
pairs[i] = str.substring(i, i + 2);
|
|
59
|
+
return pairs;
|
|
60
|
+
}
|
|
61
|
+
function wordLetterPairs(str) {
|
|
62
|
+
const pairs = str.toUpperCase().split(' ').map(letterPairs);
|
|
63
|
+
return flattenDeep(pairs);
|
|
64
|
+
}
|
|
65
|
+
function safeString(obj) {
|
|
66
|
+
return (0, object_inspect_1.default)(obj)
|
|
67
|
+
.replace(/\[Object: null prototype\] /g, '')
|
|
68
|
+
.replace(/(^')|('$)/g, '');
|
|
69
|
+
}
|
|
70
|
+
exports.safeString = safeString;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.countAliases = exports.validateAliasCount = void 0;
|
|
4
|
+
const graphql_1 = require("graphql");
|
|
5
|
+
function validateAliasCount({ source, doc, maxAliasCount, fragmentGraph, }) {
|
|
6
|
+
var _a;
|
|
7
|
+
const getFragmentByFragmentName = (fragmentName) => fragmentGraph.getNodeData(fragmentName);
|
|
8
|
+
for (const definition of doc.definitions) {
|
|
9
|
+
if (definition.kind !== graphql_1.Kind.OPERATION_DEFINITION) {
|
|
10
|
+
continue;
|
|
11
|
+
}
|
|
12
|
+
const aliasCount = countAliases(definition, getFragmentByFragmentName);
|
|
13
|
+
if (aliasCount > maxAliasCount) {
|
|
14
|
+
return new graphql_1.GraphQLError(`Too many aliases (${aliasCount}). Maximum allowed is ${maxAliasCount}`, [definition], source, ((_a = definition.loc) === null || _a === void 0 ? void 0 : _a.start) ? [definition.loc.start] : undefined);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
exports.validateAliasCount = validateAliasCount;
|
|
19
|
+
function countAliases(node, getFragmentByName) {
|
|
20
|
+
let aliases = 0;
|
|
21
|
+
if ('alias' in node && node.alias) {
|
|
22
|
+
++aliases;
|
|
23
|
+
}
|
|
24
|
+
if ('selectionSet' in node && node.selectionSet) {
|
|
25
|
+
for (const child of node.selectionSet.selections) {
|
|
26
|
+
aliases += countAliases(child, getFragmentByName);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
else if (node.kind === graphql_1.Kind.FRAGMENT_SPREAD) {
|
|
30
|
+
const fragmentNode = getFragmentByName(node.name.value);
|
|
31
|
+
if (fragmentNode) {
|
|
32
|
+
aliases += countAliases(fragmentNode, getFragmentByName);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
return aliases;
|
|
36
|
+
}
|
|
37
|
+
exports.countAliases = countAliases;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.calculateOperationComplexity = exports.validateComplexity = void 0;
|
|
4
|
+
const graphql_1 = require("graphql");
|
|
5
|
+
function validateComplexity({ source, doc, maxComplexityScore, config, fragmentGraph, }) {
|
|
6
|
+
var _a;
|
|
7
|
+
const getFragmentByFragmentName = (fragmentName) => fragmentGraph.getNodeData(fragmentName);
|
|
8
|
+
for (const definition of doc.definitions) {
|
|
9
|
+
if (definition.kind !== graphql_1.Kind.OPERATION_DEFINITION) {
|
|
10
|
+
continue;
|
|
11
|
+
}
|
|
12
|
+
const complexityScore = calculateOperationComplexity(definition, config, getFragmentByFragmentName);
|
|
13
|
+
if (complexityScore > maxComplexityScore) {
|
|
14
|
+
return new graphql_1.GraphQLError(`Too high complexity score (${complexityScore}). Maximum allowed is ${maxComplexityScore}`, [definition], source, ((_a = definition.loc) === null || _a === void 0 ? void 0 : _a.start) ? [definition.loc.start] : undefined);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
exports.validateComplexity = validateComplexity;
|
|
19
|
+
function calculateOperationComplexity(node, config, getFragmentByName, depth = 0) {
|
|
20
|
+
let cost = config.scalarCost;
|
|
21
|
+
if ('selectionSet' in node && node.selectionSet) {
|
|
22
|
+
cost = config.objectCost;
|
|
23
|
+
for (const child of node.selectionSet.selections) {
|
|
24
|
+
cost +=
|
|
25
|
+
config.depthCostFactor *
|
|
26
|
+
calculateOperationComplexity(child, config, getFragmentByName, depth + 1);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
if (node.kind == graphql_1.Kind.FRAGMENT_SPREAD) {
|
|
30
|
+
const fragment = getFragmentByName(node.name.value);
|
|
31
|
+
if (fragment) {
|
|
32
|
+
cost +=
|
|
33
|
+
config.depthCostFactor *
|
|
34
|
+
calculateOperationComplexity(fragment, config, getFragmentByName, depth + 1);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
return cost;
|
|
38
|
+
}
|
|
39
|
+
exports.calculateOperationComplexity = calculateOperationComplexity;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.countDirectives = exports.validateDirectiveCount = void 0;
|
|
4
|
+
const graphql_1 = require("graphql");
|
|
5
|
+
function validateDirectiveCount({ source, doc, maxDirectiveCount, fragmentGraph, }) {
|
|
6
|
+
var _a;
|
|
7
|
+
const getFragmentByFragmentName = (fragmentName) => fragmentGraph.getNodeData(fragmentName);
|
|
8
|
+
for (const definition of doc.definitions) {
|
|
9
|
+
if (definition.kind !== graphql_1.Kind.OPERATION_DEFINITION) {
|
|
10
|
+
continue;
|
|
11
|
+
}
|
|
12
|
+
const directiveCount = countDirectives(definition, getFragmentByFragmentName);
|
|
13
|
+
if (directiveCount > maxDirectiveCount) {
|
|
14
|
+
return new graphql_1.GraphQLError(`Too many directives (${directiveCount}). Maximum allowed is ${maxDirectiveCount}`, [definition], source, ((_a = definition.loc) === null || _a === void 0 ? void 0 : _a.start) ? [definition.loc.start] : undefined);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
exports.validateDirectiveCount = validateDirectiveCount;
|
|
19
|
+
function countDirectives(node, getFragmentByName) {
|
|
20
|
+
let directives = 0;
|
|
21
|
+
if (node.directives) {
|
|
22
|
+
directives += node.directives.length;
|
|
23
|
+
}
|
|
24
|
+
if ('selectionSet' in node && node.selectionSet) {
|
|
25
|
+
for (const child of node.selectionSet.selections) {
|
|
26
|
+
directives += countDirectives(child, getFragmentByName);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
if (node.kind == graphql_1.Kind.FRAGMENT_SPREAD) {
|
|
30
|
+
const fragment = getFragmentByName(node.name.value);
|
|
31
|
+
if (fragment) {
|
|
32
|
+
directives += countDirectives(fragment, getFragmentByName);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
return directives;
|
|
36
|
+
}
|
|
37
|
+
exports.countDirectives = countDirectives;
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.validate = void 0;
|
|
4
|
+
const dependency_graph_1 = require("dependency-graph");
|
|
5
|
+
const graphql_1 = require("graphql");
|
|
6
|
+
const document_js_1 = require("../ast/document.js");
|
|
7
|
+
const apollo_js_1 = require("../utils/apollo.js");
|
|
8
|
+
const graphql_js_1 = require("../utils/graphql.js");
|
|
9
|
+
const alias_count_js_1 = require("./alias-count.js");
|
|
10
|
+
const directive_count_js_1 = require("./directive-count.js");
|
|
11
|
+
const query_depth_js_1 = require("./query-depth.js");
|
|
12
|
+
const token_count_js_1 = require("./token-count.js");
|
|
13
|
+
function validate(schema, sources, options) {
|
|
14
|
+
const config = Object.assign({ strictDeprecated: true, strictFragments: true, keepClientFields: false, apollo: false }, options);
|
|
15
|
+
const invalidDocuments = [];
|
|
16
|
+
// read documents
|
|
17
|
+
const documents = sources.map(document_js_1.readDocument);
|
|
18
|
+
// keep all named fragments
|
|
19
|
+
const fragments = [];
|
|
20
|
+
const fragmentNames = [];
|
|
21
|
+
const graph = new dependency_graph_1.DepGraph({ circular: true });
|
|
22
|
+
documents.forEach(doc => {
|
|
23
|
+
doc.fragments.forEach(fragment => {
|
|
24
|
+
fragmentNames.push(fragment.node.name.value);
|
|
25
|
+
fragments.push(fragment);
|
|
26
|
+
graph.addNode(fragment.node.name.value, fragment.node);
|
|
27
|
+
});
|
|
28
|
+
});
|
|
29
|
+
fragments.forEach(fragment => {
|
|
30
|
+
const depends = extractFragments((0, graphql_1.print)(fragment.node));
|
|
31
|
+
if (depends) {
|
|
32
|
+
depends.forEach(name => {
|
|
33
|
+
graph.addDependency(fragment.node.name.value, name);
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
documents
|
|
38
|
+
// since we include fragments, validate only operations
|
|
39
|
+
.filter(doc => doc.hasOperations)
|
|
40
|
+
.forEach(doc => {
|
|
41
|
+
const docWithOperations = {
|
|
42
|
+
kind: graphql_1.Kind.DOCUMENT,
|
|
43
|
+
definitions: doc.operations.map(d => d.node),
|
|
44
|
+
};
|
|
45
|
+
const extractedFragments = (extractFragments((0, graphql_1.print)(docWithOperations)) || [])
|
|
46
|
+
// resolve all nested fragments
|
|
47
|
+
.map(fragmentName => resolveFragment(graph.getNodeData(fragmentName), graph))
|
|
48
|
+
// flatten arrays
|
|
49
|
+
.reduce((list, current) => list.concat(current), [])
|
|
50
|
+
// remove duplicates
|
|
51
|
+
.filter((def, i, all) => all.findIndex(item => item.name.value === def.name.value) === i);
|
|
52
|
+
const merged = {
|
|
53
|
+
kind: graphql_1.Kind.DOCUMENT,
|
|
54
|
+
definitions: [...docWithOperations.definitions, ...extractedFragments],
|
|
55
|
+
};
|
|
56
|
+
const transformedSchema = config.apollo ? (0, apollo_js_1.transformSchemaWithApollo)(schema) : schema;
|
|
57
|
+
const transformedDoc = config.apollo
|
|
58
|
+
? (0, apollo_js_1.transformDocumentWithApollo)(merged, {
|
|
59
|
+
keepClientFields: config.keepClientFields,
|
|
60
|
+
})
|
|
61
|
+
: merged;
|
|
62
|
+
const errors = (0, graphql_1.validate)(transformedSchema, transformedDoc) || [];
|
|
63
|
+
if (config.maxDepth) {
|
|
64
|
+
const depthError = (0, query_depth_js_1.validateQueryDepth)({
|
|
65
|
+
source: doc.source,
|
|
66
|
+
doc: transformedDoc,
|
|
67
|
+
maxDepth: config.maxDepth,
|
|
68
|
+
fragmentGraph: graph,
|
|
69
|
+
});
|
|
70
|
+
if (depthError) {
|
|
71
|
+
errors.push(depthError);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
if (config.maxAliasCount) {
|
|
75
|
+
const aliasError = (0, alias_count_js_1.validateAliasCount)({
|
|
76
|
+
source: doc.source,
|
|
77
|
+
doc: transformedDoc,
|
|
78
|
+
maxAliasCount: config.maxAliasCount,
|
|
79
|
+
fragmentGraph: graph,
|
|
80
|
+
});
|
|
81
|
+
if (aliasError) {
|
|
82
|
+
errors.push(aliasError);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
if (config.maxDirectiveCount) {
|
|
86
|
+
const directiveError = (0, directive_count_js_1.validateDirectiveCount)({
|
|
87
|
+
source: doc.source,
|
|
88
|
+
doc: transformedDoc,
|
|
89
|
+
maxDirectiveCount: config.maxDirectiveCount,
|
|
90
|
+
fragmentGraph: graph,
|
|
91
|
+
});
|
|
92
|
+
if (directiveError) {
|
|
93
|
+
errors.push(directiveError);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
if (config.maxTokenCount) {
|
|
97
|
+
const tokenCountError = (0, token_count_js_1.validateTokenCount)({
|
|
98
|
+
source: doc.source,
|
|
99
|
+
document: transformedDoc,
|
|
100
|
+
maxTokenCount: config.maxTokenCount,
|
|
101
|
+
getReferencedFragmentSource: fragmentName => (0, graphql_1.print)(graph.getNodeData(fragmentName)),
|
|
102
|
+
});
|
|
103
|
+
if (tokenCountError) {
|
|
104
|
+
errors.push(tokenCountError);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
const deprecated = config.strictDeprecated
|
|
108
|
+
? (0, graphql_js_1.findDeprecatedUsages)(transformedSchema, transformedDoc)
|
|
109
|
+
: [];
|
|
110
|
+
const duplicatedFragments = config.strictFragments
|
|
111
|
+
? findDuplicatedFragments(fragmentNames)
|
|
112
|
+
: [];
|
|
113
|
+
if (sumLengths(errors, duplicatedFragments, deprecated) > 0) {
|
|
114
|
+
invalidDocuments.push({
|
|
115
|
+
source: doc.source,
|
|
116
|
+
errors: [...errors, ...duplicatedFragments],
|
|
117
|
+
deprecated,
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
});
|
|
121
|
+
return invalidDocuments;
|
|
122
|
+
}
|
|
123
|
+
exports.validate = validate;
|
|
124
|
+
function findDuplicatedFragments(fragmentNames) {
|
|
125
|
+
return fragmentNames
|
|
126
|
+
.filter((name, i, all) => all.indexOf(name) !== i)
|
|
127
|
+
.map(name => new graphql_1.GraphQLError(`Name of '${name}' fragment is not unique`));
|
|
128
|
+
}
|
|
129
|
+
//
|
|
130
|
+
// PostInfo -> AuthorInfo
|
|
131
|
+
// AuthorInfo -> None
|
|
132
|
+
//
|
|
133
|
+
function resolveFragment(fragment, graph) {
|
|
134
|
+
return graph
|
|
135
|
+
.dependenciesOf(fragment.name.value)
|
|
136
|
+
.reduce((list, current) => [...list, ...resolveFragment(graph.getNodeData(current), graph)], [fragment]);
|
|
137
|
+
}
|
|
138
|
+
function extractFragments(document) {
|
|
139
|
+
return (document.match(/[.]{3}[a-z0-9_]+\b/gi) || []).map(name => name.replace('...', ''));
|
|
140
|
+
}
|
|
141
|
+
function sumLengths(...arrays) {
|
|
142
|
+
return arrays.reduce((sum, { length }) => sum + length, 0);
|
|
143
|
+
}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.countDepth = exports.calculateDepth = exports.validateQueryDepth = void 0;
|
|
4
|
+
const graphql_1 = require("graphql");
|
|
5
|
+
function validateQueryDepth({ source, doc, maxDepth, fragmentGraph, }) {
|
|
6
|
+
var _a;
|
|
7
|
+
try {
|
|
8
|
+
calculateDepth({
|
|
9
|
+
node: doc,
|
|
10
|
+
currentDepth: 0,
|
|
11
|
+
maxDepth,
|
|
12
|
+
getFragment(name) {
|
|
13
|
+
return fragmentGraph.getNodeData(name);
|
|
14
|
+
},
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
catch (errorOrNode) {
|
|
18
|
+
if (errorOrNode instanceof Error) {
|
|
19
|
+
throw errorOrNode;
|
|
20
|
+
}
|
|
21
|
+
const node = errorOrNode;
|
|
22
|
+
return new graphql_1.GraphQLError(`Query exceeds maximum depth of ${maxDepth}`, node, source, ((_a = node.loc) === null || _a === void 0 ? void 0 : _a.start) ? [node.loc.start] : undefined);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
exports.validateQueryDepth = validateQueryDepth;
|
|
26
|
+
function calculateDepth({ node, currentDepth, maxDepth, getFragment, }) {
|
|
27
|
+
if (maxDepth && currentDepth > maxDepth) {
|
|
28
|
+
throw node;
|
|
29
|
+
}
|
|
30
|
+
switch (node.kind) {
|
|
31
|
+
case graphql_1.Kind.FIELD: {
|
|
32
|
+
if (node.name.value.startsWith('__') || !node.selectionSet) {
|
|
33
|
+
return 0;
|
|
34
|
+
}
|
|
35
|
+
const maxInnerDepth = calculateDepth({
|
|
36
|
+
node: node.selectionSet,
|
|
37
|
+
currentDepth: currentDepth + 1,
|
|
38
|
+
maxDepth,
|
|
39
|
+
getFragment,
|
|
40
|
+
});
|
|
41
|
+
return 1 + maxInnerDepth;
|
|
42
|
+
}
|
|
43
|
+
case graphql_1.Kind.SELECTION_SET: {
|
|
44
|
+
return Math.max(...node.selections.map(selection => {
|
|
45
|
+
return calculateDepth({
|
|
46
|
+
node: selection,
|
|
47
|
+
currentDepth,
|
|
48
|
+
maxDepth,
|
|
49
|
+
getFragment,
|
|
50
|
+
});
|
|
51
|
+
}));
|
|
52
|
+
}
|
|
53
|
+
case graphql_1.Kind.DOCUMENT: {
|
|
54
|
+
return Math.max(...node.definitions.map(def => {
|
|
55
|
+
return calculateDepth({
|
|
56
|
+
node: def,
|
|
57
|
+
currentDepth,
|
|
58
|
+
maxDepth,
|
|
59
|
+
getFragment,
|
|
60
|
+
});
|
|
61
|
+
}));
|
|
62
|
+
}
|
|
63
|
+
case graphql_1.Kind.OPERATION_DEFINITION:
|
|
64
|
+
case graphql_1.Kind.INLINE_FRAGMENT:
|
|
65
|
+
case graphql_1.Kind.FRAGMENT_DEFINITION: {
|
|
66
|
+
return Math.max(...node.selectionSet.selections.map(selection => {
|
|
67
|
+
return calculateDepth({
|
|
68
|
+
node: selection,
|
|
69
|
+
currentDepth,
|
|
70
|
+
maxDepth,
|
|
71
|
+
getFragment,
|
|
72
|
+
});
|
|
73
|
+
}));
|
|
74
|
+
}
|
|
75
|
+
case graphql_1.Kind.FRAGMENT_SPREAD:
|
|
76
|
+
return calculateDepth({
|
|
77
|
+
node: getFragment(node.name.value),
|
|
78
|
+
currentDepth,
|
|
79
|
+
maxDepth,
|
|
80
|
+
getFragment,
|
|
81
|
+
});
|
|
82
|
+
default: {
|
|
83
|
+
throw new Error(`Couldn't handle ${node.kind}`);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
exports.calculateDepth = calculateDepth;
|
|
88
|
+
function countDepth(node, parentDepth, getFragmentReference) {
|
|
89
|
+
let depth = parentDepth;
|
|
90
|
+
if ('selectionSet' in node && node.selectionSet) {
|
|
91
|
+
for (const child of node.selectionSet.selections) {
|
|
92
|
+
depth = Math.max(depth, countDepth(child, parentDepth + 1, getFragmentReference));
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
if (node.kind == graphql_1.Kind.FRAGMENT_SPREAD) {
|
|
96
|
+
const fragment = getFragmentReference(node.name.value);
|
|
97
|
+
if (fragment) {
|
|
98
|
+
depth = Math.max(depth, countDepth(fragment, parentDepth + 1, getFragmentReference));
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
return depth;
|
|
102
|
+
}
|
|
103
|
+
exports.countDepth = countDepth;
|