graphql 15.8.0 → 15.9.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/execution/execute.js +20 -9
- package/execution/execute.js.flow +24 -14
- package/execution/execute.mjs +20 -9
- package/index.d.ts +1 -0
- package/index.js +12 -0
- package/index.js.flow +2 -0
- package/index.mjs +2 -2
- package/package.json +1 -1
- package/validation/index.d.ts +1 -1
- package/validation/index.js +14 -0
- package/validation/index.js.flow +3 -1
- package/validation/index.mjs +3 -2
- package/validation/rules/MaxIntrospectionDepthRule.d.ts +6 -0
- package/validation/rules/MaxIntrospectionDepthRule.js +85 -0
- package/validation/rules/MaxIntrospectionDepthRule.js.flow +91 -0
- package/validation/rules/MaxIntrospectionDepthRule.mjs +75 -0
- package/validation/rules/OverlappingFieldsCanBeMergedRule.js +7 -0
- package/validation/rules/OverlappingFieldsCanBeMergedRule.js.flow +18 -0
- package/validation/rules/OverlappingFieldsCanBeMergedRule.mjs +7 -0
- package/validation/specifiedRules.d.ts +6 -0
- package/validation/specifiedRules.js +12 -2
- package/validation/specifiedRules.js.flow +10 -0
- package/validation/specifiedRules.mjs +10 -2
- package/version.js +2 -2
- package/version.js.flow +2 -2
- package/version.mjs +2 -2
package/execution/execute.js
CHANGED
|
@@ -285,19 +285,30 @@ function executeFields(exeContext, parentType, sourceValue, path, fields) {
|
|
|
285
285
|
var results = Object.create(null);
|
|
286
286
|
var containsPromise = false;
|
|
287
287
|
|
|
288
|
-
|
|
289
|
-
var
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
288
|
+
try {
|
|
289
|
+
for (var _i4 = 0, _Object$keys2 = Object.keys(fields); _i4 < _Object$keys2.length; _i4++) {
|
|
290
|
+
var responseName = _Object$keys2[_i4];
|
|
291
|
+
var fieldNodes = fields[responseName];
|
|
292
|
+
var fieldPath = (0, _Path.addPath)(path, responseName, parentType.name);
|
|
293
|
+
var result = resolveField(exeContext, parentType, sourceValue, fieldNodes, fieldPath);
|
|
293
294
|
|
|
294
|
-
|
|
295
|
-
|
|
295
|
+
if (result !== undefined) {
|
|
296
|
+
results[responseName] = result;
|
|
296
297
|
|
|
297
|
-
|
|
298
|
-
|
|
298
|
+
if ((0, _isPromise.default)(result)) {
|
|
299
|
+
containsPromise = true;
|
|
300
|
+
}
|
|
299
301
|
}
|
|
300
302
|
}
|
|
303
|
+
} catch (error) {
|
|
304
|
+
if (containsPromise) {
|
|
305
|
+
// Ensure that any promises returned by other fields are handled, as they may also reject.
|
|
306
|
+
return (0, _promiseForObject.default)(results).finally(function () {
|
|
307
|
+
throw error;
|
|
308
|
+
});
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
throw error;
|
|
301
312
|
} // If there are no promises, we can just return the object
|
|
302
313
|
|
|
303
314
|
|
|
@@ -457,23 +457,33 @@ function executeFields(
|
|
|
457
457
|
const results = Object.create(null);
|
|
458
458
|
let containsPromise = false;
|
|
459
459
|
|
|
460
|
-
|
|
461
|
-
const
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
460
|
+
try {
|
|
461
|
+
for (const responseName of Object.keys(fields)) {
|
|
462
|
+
const fieldNodes = fields[responseName];
|
|
463
|
+
const fieldPath = addPath(path, responseName, parentType.name);
|
|
464
|
+
const result = resolveField(
|
|
465
|
+
exeContext,
|
|
466
|
+
parentType,
|
|
467
|
+
sourceValue,
|
|
468
|
+
fieldNodes,
|
|
469
|
+
fieldPath,
|
|
470
|
+
);
|
|
470
471
|
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
472
|
+
if (result !== undefined) {
|
|
473
|
+
results[responseName] = result;
|
|
474
|
+
if (isPromise(result)) {
|
|
475
|
+
containsPromise = true;
|
|
476
|
+
}
|
|
475
477
|
}
|
|
476
478
|
}
|
|
479
|
+
} catch (error) {
|
|
480
|
+
if (containsPromise) {
|
|
481
|
+
// Ensure that any promises returned by other fields are handled, as they may also reject.
|
|
482
|
+
return promiseForObject(results).finally(() => {
|
|
483
|
+
throw error;
|
|
484
|
+
});
|
|
485
|
+
}
|
|
486
|
+
throw error;
|
|
477
487
|
}
|
|
478
488
|
|
|
479
489
|
// If there are no promises, we can just return the object
|
package/execution/execute.mjs
CHANGED
|
@@ -273,19 +273,30 @@ function executeFields(exeContext, parentType, sourceValue, path, fields) {
|
|
|
273
273
|
var results = Object.create(null);
|
|
274
274
|
var containsPromise = false;
|
|
275
275
|
|
|
276
|
-
|
|
277
|
-
var
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
276
|
+
try {
|
|
277
|
+
for (var _i4 = 0, _Object$keys2 = Object.keys(fields); _i4 < _Object$keys2.length; _i4++) {
|
|
278
|
+
var responseName = _Object$keys2[_i4];
|
|
279
|
+
var fieldNodes = fields[responseName];
|
|
280
|
+
var fieldPath = addPath(path, responseName, parentType.name);
|
|
281
|
+
var result = resolveField(exeContext, parentType, sourceValue, fieldNodes, fieldPath);
|
|
281
282
|
|
|
282
|
-
|
|
283
|
-
|
|
283
|
+
if (result !== undefined) {
|
|
284
|
+
results[responseName] = result;
|
|
284
285
|
|
|
285
|
-
|
|
286
|
-
|
|
286
|
+
if (isPromise(result)) {
|
|
287
|
+
containsPromise = true;
|
|
288
|
+
}
|
|
287
289
|
}
|
|
288
290
|
}
|
|
291
|
+
} catch (error) {
|
|
292
|
+
if (containsPromise) {
|
|
293
|
+
// Ensure that any promises returned by other fields are handled, as they may also reject.
|
|
294
|
+
return promiseForObject(results).finally(function () {
|
|
295
|
+
throw error;
|
|
296
|
+
});
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
throw error;
|
|
289
300
|
} // If there are no promises, we can just return the object
|
|
290
301
|
|
|
291
302
|
|
package/index.d.ts
CHANGED
package/index.js
CHANGED
|
@@ -747,6 +747,12 @@ Object.defineProperty(exports, "specifiedRules", {
|
|
|
747
747
|
return _index5.specifiedRules;
|
|
748
748
|
}
|
|
749
749
|
});
|
|
750
|
+
Object.defineProperty(exports, "recommendedRules", {
|
|
751
|
+
enumerable: true,
|
|
752
|
+
get: function get() {
|
|
753
|
+
return _index5.recommendedRules;
|
|
754
|
+
}
|
|
755
|
+
});
|
|
750
756
|
Object.defineProperty(exports, "ExecutableDefinitionsRule", {
|
|
751
757
|
enumerable: true,
|
|
752
758
|
get: function get() {
|
|
@@ -903,6 +909,12 @@ Object.defineProperty(exports, "VariablesInAllowedPositionRule", {
|
|
|
903
909
|
return _index5.VariablesInAllowedPositionRule;
|
|
904
910
|
}
|
|
905
911
|
});
|
|
912
|
+
Object.defineProperty(exports, "MaxIntrospectionDepthRule", {
|
|
913
|
+
enumerable: true,
|
|
914
|
+
get: function get() {
|
|
915
|
+
return _index5.MaxIntrospectionDepthRule;
|
|
916
|
+
}
|
|
917
|
+
});
|
|
906
918
|
Object.defineProperty(exports, "LoneSchemaDefinitionRule", {
|
|
907
919
|
enumerable: true,
|
|
908
920
|
get: function get() {
|
package/index.js.flow
CHANGED
|
@@ -304,6 +304,7 @@ export {
|
|
|
304
304
|
ValidationContext,
|
|
305
305
|
// All validation rules in the GraphQL Specification.
|
|
306
306
|
specifiedRules,
|
|
307
|
+
recommendedRules,
|
|
307
308
|
// Individual validation rules.
|
|
308
309
|
ExecutableDefinitionsRule,
|
|
309
310
|
FieldsOnCorrectTypeRule,
|
|
@@ -331,6 +332,7 @@ export {
|
|
|
331
332
|
ValuesOfCorrectTypeRule,
|
|
332
333
|
VariablesAreInputTypesRule,
|
|
333
334
|
VariablesInAllowedPositionRule,
|
|
335
|
+
MaxIntrospectionDepthRule,
|
|
334
336
|
// SDL-specific validation rules
|
|
335
337
|
LoneSchemaDefinitionRule,
|
|
336
338
|
UniqueOperationTypesRule,
|
package/index.mjs
CHANGED
|
@@ -51,8 +51,8 @@ export { execute, executeSync, defaultFieldResolver, defaultTypeResolver, respon
|
|
|
51
51
|
export { subscribe, createSourceEventStream } from "./subscription/index.mjs";
|
|
52
52
|
// Validate GraphQL documents.
|
|
53
53
|
export { validate, ValidationContext // All validation rules in the GraphQL Specification.
|
|
54
|
-
, specifiedRules // Individual validation rules.
|
|
55
|
-
, ExecutableDefinitionsRule, FieldsOnCorrectTypeRule, FragmentsOnCompositeTypesRule, KnownArgumentNamesRule, KnownDirectivesRule, KnownFragmentNamesRule, KnownTypeNamesRule, LoneAnonymousOperationRule, NoFragmentCyclesRule, NoUndefinedVariablesRule, NoUnusedFragmentsRule, NoUnusedVariablesRule, OverlappingFieldsCanBeMergedRule, PossibleFragmentSpreadsRule, ProvidedRequiredArgumentsRule, ScalarLeafsRule, SingleFieldSubscriptionsRule, UniqueArgumentNamesRule, UniqueDirectivesPerLocationRule, UniqueFragmentNamesRule, UniqueInputFieldNamesRule, UniqueOperationNamesRule, UniqueVariableNamesRule, ValuesOfCorrectTypeRule, VariablesAreInputTypesRule, VariablesInAllowedPositionRule // SDL-specific validation rules
|
|
54
|
+
, specifiedRules, recommendedRules // Individual validation rules.
|
|
55
|
+
, ExecutableDefinitionsRule, FieldsOnCorrectTypeRule, FragmentsOnCompositeTypesRule, KnownArgumentNamesRule, KnownDirectivesRule, KnownFragmentNamesRule, KnownTypeNamesRule, LoneAnonymousOperationRule, NoFragmentCyclesRule, NoUndefinedVariablesRule, NoUnusedFragmentsRule, NoUnusedVariablesRule, OverlappingFieldsCanBeMergedRule, PossibleFragmentSpreadsRule, ProvidedRequiredArgumentsRule, ScalarLeafsRule, SingleFieldSubscriptionsRule, UniqueArgumentNamesRule, UniqueDirectivesPerLocationRule, UniqueFragmentNamesRule, UniqueInputFieldNamesRule, UniqueOperationNamesRule, UniqueVariableNamesRule, ValuesOfCorrectTypeRule, VariablesAreInputTypesRule, VariablesInAllowedPositionRule, MaxIntrospectionDepthRule // SDL-specific validation rules
|
|
56
56
|
, LoneSchemaDefinitionRule, UniqueOperationTypesRule, UniqueTypeNamesRule, UniqueEnumValueNamesRule, UniqueFieldDefinitionNamesRule, UniqueDirectiveNamesRule, PossibleTypeExtensionsRule // Custom validation rules
|
|
57
57
|
, NoDeprecatedCustomRule, NoSchemaIntrospectionCustomRule } from "./validation/index.mjs";
|
|
58
58
|
// Create, format, and print GraphQL errors.
|
package/package.json
CHANGED
package/validation/index.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ export { validate } from './validate';
|
|
|
2
2
|
|
|
3
3
|
export { ValidationContext, ValidationRule } from './ValidationContext';
|
|
4
4
|
|
|
5
|
-
export { specifiedRules } from './specifiedRules';
|
|
5
|
+
export { specifiedRules, recommendedRules } from './specifiedRules';
|
|
6
6
|
|
|
7
7
|
// Spec Section: "Executable Definitions"
|
|
8
8
|
export { ExecutableDefinitionsRule } from './rules/ExecutableDefinitionsRule';
|
package/validation/index.js
CHANGED
|
@@ -21,6 +21,12 @@ Object.defineProperty(exports, "specifiedRules", {
|
|
|
21
21
|
return _specifiedRules.specifiedRules;
|
|
22
22
|
}
|
|
23
23
|
});
|
|
24
|
+
Object.defineProperty(exports, "recommendedRules", {
|
|
25
|
+
enumerable: true,
|
|
26
|
+
get: function get() {
|
|
27
|
+
return _specifiedRules.recommendedRules;
|
|
28
|
+
}
|
|
29
|
+
});
|
|
24
30
|
Object.defineProperty(exports, "ExecutableDefinitionsRule", {
|
|
25
31
|
enumerable: true,
|
|
26
32
|
get: function get() {
|
|
@@ -177,6 +183,12 @@ Object.defineProperty(exports, "VariablesInAllowedPositionRule", {
|
|
|
177
183
|
return _VariablesInAllowedPositionRule.VariablesInAllowedPositionRule;
|
|
178
184
|
}
|
|
179
185
|
});
|
|
186
|
+
Object.defineProperty(exports, "MaxIntrospectionDepthRule", {
|
|
187
|
+
enumerable: true,
|
|
188
|
+
get: function get() {
|
|
189
|
+
return _MaxIntrospectionDepthRule.MaxIntrospectionDepthRule;
|
|
190
|
+
}
|
|
191
|
+
});
|
|
180
192
|
Object.defineProperty(exports, "LoneSchemaDefinitionRule", {
|
|
181
193
|
enumerable: true,
|
|
182
194
|
get: function get() {
|
|
@@ -290,6 +302,8 @@ var _VariablesAreInputTypesRule = require("./rules/VariablesAreInputTypesRule.js
|
|
|
290
302
|
|
|
291
303
|
var _VariablesInAllowedPositionRule = require("./rules/VariablesInAllowedPositionRule.js");
|
|
292
304
|
|
|
305
|
+
var _MaxIntrospectionDepthRule = require("./rules/MaxIntrospectionDepthRule.js");
|
|
306
|
+
|
|
293
307
|
var _LoneSchemaDefinitionRule = require("./rules/LoneSchemaDefinitionRule.js");
|
|
294
308
|
|
|
295
309
|
var _UniqueOperationTypesRule = require("./rules/UniqueOperationTypesRule.js");
|
package/validation/index.js.flow
CHANGED
|
@@ -5,7 +5,7 @@ export { ValidationContext } from './ValidationContext';
|
|
|
5
5
|
export type { ValidationRule } from './ValidationContext';
|
|
6
6
|
|
|
7
7
|
// All validation rules in the GraphQL Specification.
|
|
8
|
-
export { specifiedRules } from './specifiedRules';
|
|
8
|
+
export { specifiedRules, recommendedRules } from './specifiedRules';
|
|
9
9
|
|
|
10
10
|
// Spec Section: "Executable Definitions"
|
|
11
11
|
export { ExecutableDefinitionsRule } from './rules/ExecutableDefinitionsRule';
|
|
@@ -85,6 +85,8 @@ export { VariablesAreInputTypesRule } from './rules/VariablesAreInputTypesRule';
|
|
|
85
85
|
// Spec Section: "All Variable Usages Are Allowed"
|
|
86
86
|
export { VariablesInAllowedPositionRule } from './rules/VariablesInAllowedPositionRule';
|
|
87
87
|
|
|
88
|
+
export { MaxIntrospectionDepthRule } from './rules/MaxIntrospectionDepthRule';
|
|
89
|
+
|
|
88
90
|
// SDL-specific validation rules
|
|
89
91
|
export { LoneSchemaDefinitionRule } from './rules/LoneSchemaDefinitionRule';
|
|
90
92
|
export { UniqueOperationTypesRule } from './rules/UniqueOperationTypesRule';
|
package/validation/index.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export { validate } from "./validate.mjs";
|
|
2
2
|
export { ValidationContext } from "./ValidationContext.mjs";
|
|
3
3
|
// All validation rules in the GraphQL Specification.
|
|
4
|
-
export { specifiedRules } from "./specifiedRules.mjs"; // Spec Section: "Executable Definitions"
|
|
4
|
+
export { specifiedRules, recommendedRules } from "./specifiedRules.mjs"; // Spec Section: "Executable Definitions"
|
|
5
5
|
|
|
6
6
|
export { ExecutableDefinitionsRule } from "./rules/ExecutableDefinitionsRule.mjs"; // Spec Section: "Field Selections on Objects, Interfaces, and Unions Types"
|
|
7
7
|
|
|
@@ -53,7 +53,8 @@ export { ValuesOfCorrectTypeRule } from "./rules/ValuesOfCorrectTypeRule.mjs"; /
|
|
|
53
53
|
|
|
54
54
|
export { VariablesAreInputTypesRule } from "./rules/VariablesAreInputTypesRule.mjs"; // Spec Section: "All Variable Usages Are Allowed"
|
|
55
55
|
|
|
56
|
-
export { VariablesInAllowedPositionRule } from "./rules/VariablesInAllowedPositionRule.mjs";
|
|
56
|
+
export { VariablesInAllowedPositionRule } from "./rules/VariablesInAllowedPositionRule.mjs";
|
|
57
|
+
export { MaxIntrospectionDepthRule } from "./rules/MaxIntrospectionDepthRule.mjs"; // SDL-specific validation rules
|
|
57
58
|
|
|
58
59
|
export { LoneSchemaDefinitionRule } from "./rules/LoneSchemaDefinitionRule.mjs";
|
|
59
60
|
export { UniqueOperationTypesRule } from "./rules/UniqueOperationTypesRule.mjs";
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.MaxIntrospectionDepthRule = MaxIntrospectionDepthRule;
|
|
7
|
+
|
|
8
|
+
var _GraphQLError = require("../../error/GraphQLError.js");
|
|
9
|
+
|
|
10
|
+
var _kinds = require("../../language/kinds.js");
|
|
11
|
+
|
|
12
|
+
var MAX_LISTS_DEPTH = 3;
|
|
13
|
+
|
|
14
|
+
function MaxIntrospectionDepthRule(context) {
|
|
15
|
+
/**
|
|
16
|
+
* Counts the depth of list fields in "__Type" recursively and
|
|
17
|
+
* returns `true` if the limit has been reached.
|
|
18
|
+
*/
|
|
19
|
+
function checkDepth(node) {
|
|
20
|
+
var visitedFragments = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : Object.create(null);
|
|
21
|
+
var depth = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0;
|
|
22
|
+
|
|
23
|
+
if (node.kind === _kinds.Kind.FRAGMENT_SPREAD) {
|
|
24
|
+
var _fragmentName = node.name.value;
|
|
25
|
+
|
|
26
|
+
if (visitedFragments[_fragmentName] === true) {
|
|
27
|
+
// Fragment cycles are handled by `NoFragmentCyclesRule`.
|
|
28
|
+
return false;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
var fragment = context.getFragment(_fragmentName);
|
|
32
|
+
|
|
33
|
+
if (!fragment) {
|
|
34
|
+
// Missing fragments checks are handled by `KnownFragmentNamesRule`.
|
|
35
|
+
return false;
|
|
36
|
+
} // Rather than following an immutable programming pattern which has
|
|
37
|
+
// significant memory and garbage collection overhead, we've opted to
|
|
38
|
+
// take a mutable approach for efficiency's sake. Importantly visiting a
|
|
39
|
+
// fragment twice is fine, so long as you don't do one visit inside the
|
|
40
|
+
// other.
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
try {
|
|
44
|
+
visitedFragments[_fragmentName] = true;
|
|
45
|
+
return checkDepth(fragment, visitedFragments, depth);
|
|
46
|
+
} finally {
|
|
47
|
+
visitedFragments[_fragmentName] = null;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
if (node.kind === _kinds.Kind.FIELD && ( // check all introspection lists
|
|
52
|
+
node.name.value === 'fields' || node.name.value === 'interfaces' || node.name.value === 'possibleTypes' || node.name.value === 'inputFields')) {
|
|
53
|
+
// $FlowFixMe[reassign-const] why are argument parameters treated as const in flow?
|
|
54
|
+
depth++; // eslint-disable-line no-param-reassign
|
|
55
|
+
|
|
56
|
+
if (depth >= MAX_LISTS_DEPTH) {
|
|
57
|
+
return true;
|
|
58
|
+
}
|
|
59
|
+
} // handles fields and inline fragments
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
if ('selectionSet' in node && node.selectionSet) {
|
|
63
|
+
for (var _i2 = 0, _node$selectionSet$se2 = node.selectionSet.selections; _i2 < _node$selectionSet$se2.length; _i2++) {
|
|
64
|
+
var child = _node$selectionSet$se2[_i2];
|
|
65
|
+
|
|
66
|
+
if (checkDepth(child, visitedFragments, depth)) {
|
|
67
|
+
return true;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
return false;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
return {
|
|
76
|
+
Field: function Field(node) {
|
|
77
|
+
if (node.name.value === '__schema' || node.name.value === '__type') {
|
|
78
|
+
if (checkDepth(node)) {
|
|
79
|
+
context.reportError(new _GraphQLError.GraphQLError('Maximum introspection depth exceeded', [node]));
|
|
80
|
+
return false;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
};
|
|
85
|
+
}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
// @flow strict
|
|
2
|
+
import { GraphQLError } from '../../error/GraphQLError';
|
|
3
|
+
|
|
4
|
+
import type { ASTNode } from '../../language/ast';
|
|
5
|
+
import { Kind } from '../../language/kinds';
|
|
6
|
+
import type { ASTVisitor } from '../../language/visitor';
|
|
7
|
+
|
|
8
|
+
import type { ASTValidationContext } from '../ValidationContext';
|
|
9
|
+
|
|
10
|
+
const MAX_LISTS_DEPTH = 3;
|
|
11
|
+
|
|
12
|
+
export function MaxIntrospectionDepthRule(
|
|
13
|
+
context: ASTValidationContext,
|
|
14
|
+
): ASTVisitor {
|
|
15
|
+
/**
|
|
16
|
+
* Counts the depth of list fields in "__Type" recursively and
|
|
17
|
+
* returns `true` if the limit has been reached.
|
|
18
|
+
*/
|
|
19
|
+
function checkDepth(
|
|
20
|
+
node: ASTNode,
|
|
21
|
+
visitedFragments: {
|
|
22
|
+
[fragmentName: string]: true | null,
|
|
23
|
+
__proto__: null,
|
|
24
|
+
} = Object.create(null),
|
|
25
|
+
depth: number = 0,
|
|
26
|
+
): boolean {
|
|
27
|
+
if (node.kind === Kind.FRAGMENT_SPREAD) {
|
|
28
|
+
const fragmentName = node.name.value;
|
|
29
|
+
if (visitedFragments[fragmentName] === true) {
|
|
30
|
+
// Fragment cycles are handled by `NoFragmentCyclesRule`.
|
|
31
|
+
return false;
|
|
32
|
+
}
|
|
33
|
+
const fragment = context.getFragment(fragmentName);
|
|
34
|
+
if (!fragment) {
|
|
35
|
+
// Missing fragments checks are handled by `KnownFragmentNamesRule`.
|
|
36
|
+
return false;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// Rather than following an immutable programming pattern which has
|
|
40
|
+
// significant memory and garbage collection overhead, we've opted to
|
|
41
|
+
// take a mutable approach for efficiency's sake. Importantly visiting a
|
|
42
|
+
// fragment twice is fine, so long as you don't do one visit inside the
|
|
43
|
+
// other.
|
|
44
|
+
try {
|
|
45
|
+
visitedFragments[fragmentName] = true;
|
|
46
|
+
return checkDepth(fragment, visitedFragments, depth);
|
|
47
|
+
} finally {
|
|
48
|
+
visitedFragments[fragmentName] = null;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
if (
|
|
53
|
+
node.kind === Kind.FIELD &&
|
|
54
|
+
// check all introspection lists
|
|
55
|
+
(node.name.value === 'fields' ||
|
|
56
|
+
node.name.value === 'interfaces' ||
|
|
57
|
+
node.name.value === 'possibleTypes' ||
|
|
58
|
+
node.name.value === 'inputFields')
|
|
59
|
+
) {
|
|
60
|
+
// $FlowFixMe[reassign-const] why are argument parameters treated as const in flow?
|
|
61
|
+
depth++; // eslint-disable-line no-param-reassign
|
|
62
|
+
if (depth >= MAX_LISTS_DEPTH) {
|
|
63
|
+
return true;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// handles fields and inline fragments
|
|
68
|
+
if ('selectionSet' in node && node.selectionSet) {
|
|
69
|
+
for (const child of node.selectionSet.selections) {
|
|
70
|
+
if (checkDepth(child, visitedFragments, depth)) {
|
|
71
|
+
return true;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
return false;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
return {
|
|
80
|
+
Field(node) {
|
|
81
|
+
if (node.name.value === '__schema' || node.name.value === '__type') {
|
|
82
|
+
if (checkDepth(node)) {
|
|
83
|
+
context.reportError(
|
|
84
|
+
new GraphQLError('Maximum introspection depth exceeded', [node]),
|
|
85
|
+
);
|
|
86
|
+
return false;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
},
|
|
90
|
+
};
|
|
91
|
+
}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { GraphQLError } from "../../error/GraphQLError.mjs";
|
|
2
|
+
import { Kind } from "../../language/kinds.mjs";
|
|
3
|
+
var MAX_LISTS_DEPTH = 3;
|
|
4
|
+
export function MaxIntrospectionDepthRule(context) {
|
|
5
|
+
/**
|
|
6
|
+
* Counts the depth of list fields in "__Type" recursively and
|
|
7
|
+
* returns `true` if the limit has been reached.
|
|
8
|
+
*/
|
|
9
|
+
function checkDepth(node) {
|
|
10
|
+
var visitedFragments = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : Object.create(null);
|
|
11
|
+
var depth = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0;
|
|
12
|
+
|
|
13
|
+
if (node.kind === Kind.FRAGMENT_SPREAD) {
|
|
14
|
+
var _fragmentName = node.name.value;
|
|
15
|
+
|
|
16
|
+
if (visitedFragments[_fragmentName] === true) {
|
|
17
|
+
// Fragment cycles are handled by `NoFragmentCyclesRule`.
|
|
18
|
+
return false;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
var fragment = context.getFragment(_fragmentName);
|
|
22
|
+
|
|
23
|
+
if (!fragment) {
|
|
24
|
+
// Missing fragments checks are handled by `KnownFragmentNamesRule`.
|
|
25
|
+
return false;
|
|
26
|
+
} // Rather than following an immutable programming pattern which has
|
|
27
|
+
// significant memory and garbage collection overhead, we've opted to
|
|
28
|
+
// take a mutable approach for efficiency's sake. Importantly visiting a
|
|
29
|
+
// fragment twice is fine, so long as you don't do one visit inside the
|
|
30
|
+
// other.
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
try {
|
|
34
|
+
visitedFragments[_fragmentName] = true;
|
|
35
|
+
return checkDepth(fragment, visitedFragments, depth);
|
|
36
|
+
} finally {
|
|
37
|
+
visitedFragments[_fragmentName] = null;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
if (node.kind === Kind.FIELD && ( // check all introspection lists
|
|
42
|
+
node.name.value === 'fields' || node.name.value === 'interfaces' || node.name.value === 'possibleTypes' || node.name.value === 'inputFields')) {
|
|
43
|
+
// $FlowFixMe[reassign-const] why are argument parameters treated as const in flow?
|
|
44
|
+
depth++; // eslint-disable-line no-param-reassign
|
|
45
|
+
|
|
46
|
+
if (depth >= MAX_LISTS_DEPTH) {
|
|
47
|
+
return true;
|
|
48
|
+
}
|
|
49
|
+
} // handles fields and inline fragments
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
if ('selectionSet' in node && node.selectionSet) {
|
|
53
|
+
for (var _i2 = 0, _node$selectionSet$se2 = node.selectionSet.selections; _i2 < _node$selectionSet$se2.length; _i2++) {
|
|
54
|
+
var child = _node$selectionSet$se2[_i2];
|
|
55
|
+
|
|
56
|
+
if (checkDepth(child, visitedFragments, depth)) {
|
|
57
|
+
return true;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
return false;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
return {
|
|
66
|
+
Field: function Field(node) {
|
|
67
|
+
if (node.name.value === '__schema' || node.name.value === '__type') {
|
|
68
|
+
if (checkDepth(node)) {
|
|
69
|
+
context.reportError(new GraphQLError('Maximum introspection depth exceeded', [node]));
|
|
70
|
+
return false;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
};
|
|
75
|
+
}
|
|
@@ -180,6 +180,13 @@ function collectConflictsBetweenFieldsAndFragment(context, conflicts, cachedFiel
|
|
|
180
180
|
// and any fragment names found in the given fragment.
|
|
181
181
|
|
|
182
182
|
for (var i = 0; i < fragmentNames2.length; i++) {
|
|
183
|
+
var referencedFragmentName = fragmentNames2[i]; // Memoize so two fragments are not compared for conflicts more than once.
|
|
184
|
+
|
|
185
|
+
if (comparedFragmentPairs.has(referencedFragmentName, fragmentName, areMutuallyExclusive)) {
|
|
186
|
+
continue;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
comparedFragmentPairs.add(referencedFragmentName, fragmentName, areMutuallyExclusive);
|
|
183
190
|
collectConflictsBetweenFieldsAndFragment(context, conflicts, cachedFieldsAndFragmentNames, comparedFragmentPairs, areMutuallyExclusive, fieldMap, fragmentNames2[i]);
|
|
184
191
|
}
|
|
185
192
|
} // Collect all conflicts found between two fragments, including via spreading in
|
|
@@ -265,6 +265,24 @@ function collectConflictsBetweenFieldsAndFragment(
|
|
|
265
265
|
// (E) Then collect any conflicts between the provided collection of fields
|
|
266
266
|
// and any fragment names found in the given fragment.
|
|
267
267
|
for (let i = 0; i < fragmentNames2.length; i++) {
|
|
268
|
+
const referencedFragmentName = fragmentNames2[i];
|
|
269
|
+
|
|
270
|
+
// Memoize so two fragments are not compared for conflicts more than once.
|
|
271
|
+
if (
|
|
272
|
+
comparedFragmentPairs.has(
|
|
273
|
+
referencedFragmentName,
|
|
274
|
+
fragmentName,
|
|
275
|
+
areMutuallyExclusive,
|
|
276
|
+
)
|
|
277
|
+
) {
|
|
278
|
+
continue;
|
|
279
|
+
}
|
|
280
|
+
comparedFragmentPairs.add(
|
|
281
|
+
referencedFragmentName,
|
|
282
|
+
fragmentName,
|
|
283
|
+
areMutuallyExclusive,
|
|
284
|
+
);
|
|
285
|
+
|
|
268
286
|
collectConflictsBetweenFieldsAndFragment(
|
|
269
287
|
context,
|
|
270
288
|
conflicts,
|
|
@@ -164,6 +164,13 @@ function collectConflictsBetweenFieldsAndFragment(context, conflicts, cachedFiel
|
|
|
164
164
|
// and any fragment names found in the given fragment.
|
|
165
165
|
|
|
166
166
|
for (var i = 0; i < fragmentNames2.length; i++) {
|
|
167
|
+
var referencedFragmentName = fragmentNames2[i]; // Memoize so two fragments are not compared for conflicts more than once.
|
|
168
|
+
|
|
169
|
+
if (comparedFragmentPairs.has(referencedFragmentName, fragmentName, areMutuallyExclusive)) {
|
|
170
|
+
continue;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
comparedFragmentPairs.add(referencedFragmentName, fragmentName, areMutuallyExclusive);
|
|
167
174
|
collectConflictsBetweenFieldsAndFragment(context, conflicts, cachedFieldsAndFragmentNames, comparedFragmentPairs, areMutuallyExclusive, fieldMap, fragmentNames2[i]);
|
|
168
175
|
}
|
|
169
176
|
} // Collect all conflicts found between two fragments, including via spreading in
|
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
import { ValidationRule, SDLValidationRule } from './ValidationContext';
|
|
2
2
|
|
|
3
|
+
/**
|
|
4
|
+
* Technically these aren't part of the spec but they are strongly encouraged
|
|
5
|
+
* validation rules.
|
|
6
|
+
*/
|
|
7
|
+
export const recommendedRules: ReadonlyArray<ValidationRule>;
|
|
8
|
+
|
|
3
9
|
/**
|
|
4
10
|
* This set includes all validation rules defined by the GraphQL spec.
|
|
5
11
|
*
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
exports.specifiedSDLRules = exports.specifiedRules = void 0;
|
|
6
|
+
exports.specifiedSDLRules = exports.specifiedRules = exports.recommendedRules = void 0;
|
|
7
7
|
|
|
8
8
|
var _ExecutableDefinitionsRule = require("./rules/ExecutableDefinitionsRule.js");
|
|
9
9
|
|
|
@@ -57,6 +57,8 @@ var _OverlappingFieldsCanBeMergedRule = require("./rules/OverlappingFieldsCanBeM
|
|
|
57
57
|
|
|
58
58
|
var _UniqueInputFieldNamesRule = require("./rules/UniqueInputFieldNamesRule.js");
|
|
59
59
|
|
|
60
|
+
var _MaxIntrospectionDepthRule = require("./rules/MaxIntrospectionDepthRule.js");
|
|
61
|
+
|
|
60
62
|
var _LoneSchemaDefinitionRule = require("./rules/LoneSchemaDefinitionRule.js");
|
|
61
63
|
|
|
62
64
|
var _UniqueOperationTypesRule = require("./rules/UniqueOperationTypesRule.js");
|
|
@@ -97,15 +99,23 @@ var _PossibleTypeExtensionsRule = require("./rules/PossibleTypeExtensionsRule.js
|
|
|
97
99
|
// Spec Section: "All Variable Usages Are Allowed"
|
|
98
100
|
// Spec Section: "Field Selection Merging"
|
|
99
101
|
// Spec Section: "Input Object Field Uniqueness"
|
|
102
|
+
// TODO: Spec Section
|
|
100
103
|
// SDL-specific validation rules
|
|
101
104
|
|
|
105
|
+
/**
|
|
106
|
+
* Technically these aren't part of the spec but they are strongly encouraged
|
|
107
|
+
* validation rules.
|
|
108
|
+
*/
|
|
109
|
+
var recommendedRules = Object.freeze([_MaxIntrospectionDepthRule.MaxIntrospectionDepthRule]);
|
|
102
110
|
/**
|
|
103
111
|
* This set includes all validation rules defined by the GraphQL spec.
|
|
104
112
|
*
|
|
105
113
|
* The order of the rules in this list has been adjusted to lead to the
|
|
106
114
|
* most clear output when encountering multiple validation errors.
|
|
107
115
|
*/
|
|
108
|
-
|
|
116
|
+
|
|
117
|
+
exports.recommendedRules = recommendedRules;
|
|
118
|
+
var specifiedRules = Object.freeze([_ExecutableDefinitionsRule.ExecutableDefinitionsRule, _UniqueOperationNamesRule.UniqueOperationNamesRule, _LoneAnonymousOperationRule.LoneAnonymousOperationRule, _SingleFieldSubscriptionsRule.SingleFieldSubscriptionsRule, _KnownTypeNamesRule.KnownTypeNamesRule, _FragmentsOnCompositeTypesRule.FragmentsOnCompositeTypesRule, _VariablesAreInputTypesRule.VariablesAreInputTypesRule, _ScalarLeafsRule.ScalarLeafsRule, _FieldsOnCorrectTypeRule.FieldsOnCorrectTypeRule, _UniqueFragmentNamesRule.UniqueFragmentNamesRule, _KnownFragmentNamesRule.KnownFragmentNamesRule, _NoUnusedFragmentsRule.NoUnusedFragmentsRule, _PossibleFragmentSpreadsRule.PossibleFragmentSpreadsRule, _NoFragmentCyclesRule.NoFragmentCyclesRule, _UniqueVariableNamesRule.UniqueVariableNamesRule, _NoUndefinedVariablesRule.NoUndefinedVariablesRule, _NoUnusedVariablesRule.NoUnusedVariablesRule, _KnownDirectivesRule.KnownDirectivesRule, _UniqueDirectivesPerLocationRule.UniqueDirectivesPerLocationRule, _KnownArgumentNamesRule.KnownArgumentNamesRule, _UniqueArgumentNamesRule.UniqueArgumentNamesRule, _ValuesOfCorrectTypeRule.ValuesOfCorrectTypeRule, _ProvidedRequiredArgumentsRule.ProvidedRequiredArgumentsRule, _VariablesInAllowedPositionRule.VariablesInAllowedPositionRule, _OverlappingFieldsCanBeMergedRule.OverlappingFieldsCanBeMergedRule, _UniqueInputFieldNamesRule.UniqueInputFieldNamesRule].concat(recommendedRules));
|
|
109
119
|
/**
|
|
110
120
|
* @internal
|
|
111
121
|
*/
|
|
@@ -83,6 +83,9 @@ import { OverlappingFieldsCanBeMergedRule } from './rules/OverlappingFieldsCanBe
|
|
|
83
83
|
// Spec Section: "Input Object Field Uniqueness"
|
|
84
84
|
import { UniqueInputFieldNamesRule } from './rules/UniqueInputFieldNamesRule';
|
|
85
85
|
|
|
86
|
+
// TODO: Spec Section
|
|
87
|
+
import { MaxIntrospectionDepthRule } from './rules/MaxIntrospectionDepthRule';
|
|
88
|
+
|
|
86
89
|
// SDL-specific validation rules
|
|
87
90
|
import { LoneSchemaDefinitionRule } from './rules/LoneSchemaDefinitionRule';
|
|
88
91
|
import { UniqueOperationTypesRule } from './rules/UniqueOperationTypesRule';
|
|
@@ -92,6 +95,12 @@ import { UniqueFieldDefinitionNamesRule } from './rules/UniqueFieldDefinitionNam
|
|
|
92
95
|
import { UniqueDirectiveNamesRule } from './rules/UniqueDirectiveNamesRule';
|
|
93
96
|
import { PossibleTypeExtensionsRule } from './rules/PossibleTypeExtensionsRule';
|
|
94
97
|
|
|
98
|
+
/**
|
|
99
|
+
* Technically these aren't part of the spec but they are strongly encouraged
|
|
100
|
+
* validation rules.
|
|
101
|
+
*/
|
|
102
|
+
export const recommendedRules = Object.freeze([MaxIntrospectionDepthRule]);
|
|
103
|
+
|
|
95
104
|
/**
|
|
96
105
|
* This set includes all validation rules defined by the GraphQL spec.
|
|
97
106
|
*
|
|
@@ -125,6 +134,7 @@ export const specifiedRules = Object.freeze([
|
|
|
125
134
|
VariablesInAllowedPositionRule,
|
|
126
135
|
OverlappingFieldsCanBeMergedRule,
|
|
127
136
|
UniqueInputFieldNamesRule,
|
|
137
|
+
...recommendedRules,
|
|
128
138
|
]);
|
|
129
139
|
|
|
130
140
|
/**
|
|
@@ -49,7 +49,9 @@ import { VariablesInAllowedPositionRule } from "./rules/VariablesInAllowedPositi
|
|
|
49
49
|
|
|
50
50
|
import { OverlappingFieldsCanBeMergedRule } from "./rules/OverlappingFieldsCanBeMergedRule.mjs"; // Spec Section: "Input Object Field Uniqueness"
|
|
51
51
|
|
|
52
|
-
import { UniqueInputFieldNamesRule } from "./rules/UniqueInputFieldNamesRule.mjs"; //
|
|
52
|
+
import { UniqueInputFieldNamesRule } from "./rules/UniqueInputFieldNamesRule.mjs"; // TODO: Spec Section
|
|
53
|
+
|
|
54
|
+
import { MaxIntrospectionDepthRule } from "./rules/MaxIntrospectionDepthRule.mjs"; // SDL-specific validation rules
|
|
53
55
|
|
|
54
56
|
import { LoneSchemaDefinitionRule } from "./rules/LoneSchemaDefinitionRule.mjs";
|
|
55
57
|
import { UniqueOperationTypesRule } from "./rules/UniqueOperationTypesRule.mjs";
|
|
@@ -58,6 +60,12 @@ import { UniqueEnumValueNamesRule } from "./rules/UniqueEnumValueNamesRule.mjs";
|
|
|
58
60
|
import { UniqueFieldDefinitionNamesRule } from "./rules/UniqueFieldDefinitionNamesRule.mjs";
|
|
59
61
|
import { UniqueDirectiveNamesRule } from "./rules/UniqueDirectiveNamesRule.mjs";
|
|
60
62
|
import { PossibleTypeExtensionsRule } from "./rules/PossibleTypeExtensionsRule.mjs";
|
|
63
|
+
/**
|
|
64
|
+
* Technically these aren't part of the spec but they are strongly encouraged
|
|
65
|
+
* validation rules.
|
|
66
|
+
*/
|
|
67
|
+
|
|
68
|
+
export var recommendedRules = Object.freeze([MaxIntrospectionDepthRule]);
|
|
61
69
|
/**
|
|
62
70
|
* This set includes all validation rules defined by the GraphQL spec.
|
|
63
71
|
*
|
|
@@ -65,7 +73,7 @@ import { PossibleTypeExtensionsRule } from "./rules/PossibleTypeExtensionsRule.m
|
|
|
65
73
|
* most clear output when encountering multiple validation errors.
|
|
66
74
|
*/
|
|
67
75
|
|
|
68
|
-
export var specifiedRules = Object.freeze([ExecutableDefinitionsRule, UniqueOperationNamesRule, LoneAnonymousOperationRule, SingleFieldSubscriptionsRule, KnownTypeNamesRule, FragmentsOnCompositeTypesRule, VariablesAreInputTypesRule, ScalarLeafsRule, FieldsOnCorrectTypeRule, UniqueFragmentNamesRule, KnownFragmentNamesRule, NoUnusedFragmentsRule, PossibleFragmentSpreadsRule, NoFragmentCyclesRule, UniqueVariableNamesRule, NoUndefinedVariablesRule, NoUnusedVariablesRule, KnownDirectivesRule, UniqueDirectivesPerLocationRule, KnownArgumentNamesRule, UniqueArgumentNamesRule, ValuesOfCorrectTypeRule, ProvidedRequiredArgumentsRule, VariablesInAllowedPositionRule, OverlappingFieldsCanBeMergedRule, UniqueInputFieldNamesRule]);
|
|
76
|
+
export var specifiedRules = Object.freeze([ExecutableDefinitionsRule, UniqueOperationNamesRule, LoneAnonymousOperationRule, SingleFieldSubscriptionsRule, KnownTypeNamesRule, FragmentsOnCompositeTypesRule, VariablesAreInputTypesRule, ScalarLeafsRule, FieldsOnCorrectTypeRule, UniqueFragmentNamesRule, KnownFragmentNamesRule, NoUnusedFragmentsRule, PossibleFragmentSpreadsRule, NoFragmentCyclesRule, UniqueVariableNamesRule, NoUndefinedVariablesRule, NoUnusedVariablesRule, KnownDirectivesRule, UniqueDirectivesPerLocationRule, KnownArgumentNamesRule, UniqueArgumentNamesRule, ValuesOfCorrectTypeRule, ProvidedRequiredArgumentsRule, VariablesInAllowedPositionRule, OverlappingFieldsCanBeMergedRule, UniqueInputFieldNamesRule].concat(recommendedRules));
|
|
69
77
|
/**
|
|
70
78
|
* @internal
|
|
71
79
|
*/
|
package/version.js
CHANGED
|
@@ -13,7 +13,7 @@ exports.versionInfo = exports.version = void 0;
|
|
|
13
13
|
/**
|
|
14
14
|
* A string containing the version of the GraphQL.js library
|
|
15
15
|
*/
|
|
16
|
-
var version = '15.
|
|
16
|
+
var version = '15.9.0';
|
|
17
17
|
/**
|
|
18
18
|
* An object containing the components of the GraphQL.js version string
|
|
19
19
|
*/
|
|
@@ -21,7 +21,7 @@ var version = '15.8.0';
|
|
|
21
21
|
exports.version = version;
|
|
22
22
|
var versionInfo = Object.freeze({
|
|
23
23
|
major: 15,
|
|
24
|
-
minor:
|
|
24
|
+
minor: 9,
|
|
25
25
|
patch: 0,
|
|
26
26
|
preReleaseTag: null
|
|
27
27
|
});
|
package/version.js.flow
CHANGED
|
@@ -7,14 +7,14 @@
|
|
|
7
7
|
/**
|
|
8
8
|
* A string containing the version of the GraphQL.js library
|
|
9
9
|
*/
|
|
10
|
-
export const version = '15.
|
|
10
|
+
export const version = '15.9.0';
|
|
11
11
|
|
|
12
12
|
/**
|
|
13
13
|
* An object containing the components of the GraphQL.js version string
|
|
14
14
|
*/
|
|
15
15
|
export const versionInfo = Object.freeze({
|
|
16
16
|
major: 15,
|
|
17
|
-
minor:
|
|
17
|
+
minor: 9,
|
|
18
18
|
patch: 0,
|
|
19
19
|
preReleaseTag: null,
|
|
20
20
|
});
|
package/version.mjs
CHANGED
|
@@ -6,14 +6,14 @@
|
|
|
6
6
|
/**
|
|
7
7
|
* A string containing the version of the GraphQL.js library
|
|
8
8
|
*/
|
|
9
|
-
export var version = '15.
|
|
9
|
+
export var version = '15.9.0';
|
|
10
10
|
/**
|
|
11
11
|
* An object containing the components of the GraphQL.js version string
|
|
12
12
|
*/
|
|
13
13
|
|
|
14
14
|
export var versionInfo = Object.freeze({
|
|
15
15
|
major: 15,
|
|
16
|
-
minor:
|
|
16
|
+
minor: 9,
|
|
17
17
|
patch: 0,
|
|
18
18
|
preReleaseTag: null
|
|
19
19
|
});
|