graphql 16.8.2 → 16.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.
Files changed (45) hide show
  1. package/index.d.ts +3 -0
  2. package/index.js +18 -0
  3. package/index.mjs +6 -3
  4. package/package.json +1 -1
  5. package/type/definition.d.ts +4 -1
  6. package/type/definition.js +29 -6
  7. package/type/definition.mjs +26 -6
  8. package/type/directives.d.ts +4 -0
  9. package/type/directives.js +15 -1
  10. package/type/directives.mjs +12 -0
  11. package/type/index.d.ts +1 -0
  12. package/type/index.js +6 -0
  13. package/type/index.mjs +2 -1
  14. package/type/introspection.js +8 -0
  15. package/type/introspection.mjs +8 -0
  16. package/type/validate.js +24 -0
  17. package/type/validate.mjs +24 -0
  18. package/utilities/buildClientSchema.js +1 -0
  19. package/utilities/buildClientSchema.mjs +1 -0
  20. package/utilities/coerceInputValue.js +25 -0
  21. package/utilities/coerceInputValue.mjs +25 -0
  22. package/utilities/extendSchema.js +10 -0
  23. package/utilities/extendSchema.mjs +9 -0
  24. package/utilities/getIntrospectionQuery.d.ts +6 -0
  25. package/utilities/getIntrospectionQuery.js +3 -0
  26. package/utilities/getIntrospectionQuery.mjs +3 -0
  27. package/utilities/introspectionFromSchema.js +1 -0
  28. package/utilities/introspectionFromSchema.mjs +1 -0
  29. package/utilities/printSchema.js +6 -1
  30. package/utilities/printSchema.mjs +6 -1
  31. package/utilities/valueFromAST.js +12 -0
  32. package/utilities/valueFromAST.mjs +12 -0
  33. package/validation/index.d.ts +2 -1
  34. package/validation/index.js +14 -0
  35. package/validation/index.mjs +3 -2
  36. package/validation/rules/MaxIntrospectionDepthRule.d.ts +5 -0
  37. package/validation/rules/MaxIntrospectionDepthRule.js +90 -0
  38. package/validation/rules/MaxIntrospectionDepthRule.mjs +77 -0
  39. package/validation/rules/ValuesOfCorrectTypeRule.js +88 -0
  40. package/validation/rules/ValuesOfCorrectTypeRule.mjs +83 -0
  41. package/validation/specifiedRules.d.ts +6 -0
  42. package/validation/specifiedRules.js +17 -1
  43. package/validation/specifiedRules.mjs +10 -1
  44. package/version.js +3 -3
  45. package/version.mjs +3 -3
@@ -9,6 +9,7 @@ export function getIntrospectionQuery(options) {
9
9
  directiveIsRepeatable: false,
10
10
  schemaDescription: false,
11
11
  inputValueDeprecation: false,
12
+ oneOf: false,
12
13
  ...options,
13
14
  };
14
15
  const descriptions = optionsWithDefault.descriptions ? 'description' : '';
@@ -26,6 +27,7 @@ export function getIntrospectionQuery(options) {
26
27
  return optionsWithDefault.inputValueDeprecation ? str : '';
27
28
  }
28
29
 
30
+ const oneOf = optionsWithDefault.oneOf ? 'isOneOf' : '';
29
31
  return `
30
32
  query IntrospectionQuery {
31
33
  __schema {
@@ -53,6 +55,7 @@ export function getIntrospectionQuery(options) {
53
55
  name
54
56
  ${descriptions}
55
57
  ${specifiedByUrl}
58
+ ${oneOf}
56
59
  fields(includeDeprecated: true) {
57
60
  name
58
61
  ${descriptions}
@@ -28,6 +28,7 @@ function introspectionFromSchema(schema, options) {
28
28
  directiveIsRepeatable: true,
29
29
  schemaDescription: true,
30
30
  inputValueDeprecation: true,
31
+ oneOf: true,
31
32
  ...options,
32
33
  };
33
34
  const document = (0, _parser.parse)(
@@ -18,6 +18,7 @@ export function introspectionFromSchema(schema, options) {
18
18
  directiveIsRepeatable: true,
19
19
  schemaDescription: true,
20
20
  inputValueDeprecation: true,
21
+ oneOf: true,
21
22
  ...options,
22
23
  };
23
24
  const document = parse(getIntrospectionQuery(optionsWithDefaults));
@@ -214,7 +214,12 @@ function printInputObject(type) {
214
214
  const fields = Object.values(type.getFields()).map(
215
215
  (f, i) => printDescription(f, ' ', !i) + ' ' + printInputValue(f),
216
216
  );
217
- return printDescription(type) + `input ${type.name}` + printBlock(fields);
217
+ return (
218
+ printDescription(type) +
219
+ `input ${type.name}` +
220
+ (type.isOneOf ? ' @oneOf' : '') +
221
+ printBlock(fields)
222
+ );
218
223
  }
219
224
 
220
225
  function printFields(type) {
@@ -193,7 +193,12 @@ function printInputObject(type) {
193
193
  const fields = Object.values(type.getFields()).map(
194
194
  (f, i) => printDescription(f, ' ', !i) + ' ' + printInputValue(f),
195
195
  );
196
- return printDescription(type) + `input ${type.name}` + printBlock(fields);
196
+ return (
197
+ printDescription(type) +
198
+ `input ${type.name}` +
199
+ (type.isOneOf ? ' @oneOf' : '') +
200
+ printBlock(fields)
201
+ );
197
202
  }
198
203
 
199
204
  function printFields(type) {
@@ -145,6 +145,18 @@ function valueFromAST(valueNode, type, variables) {
145
145
  coercedObj[field.name] = fieldValue;
146
146
  }
147
147
 
148
+ if (type.isOneOf) {
149
+ const keys = Object.keys(coercedObj);
150
+
151
+ if (keys.length !== 1) {
152
+ return; // Invalid: not exactly one key, intentionally return no value.
153
+ }
154
+
155
+ if (coercedObj[keys[0]] === null) {
156
+ return; // Invalid: value not non-null, intentionally return no value.
157
+ }
158
+ }
159
+
148
160
  return coercedObj;
149
161
  }
150
162
 
@@ -136,6 +136,18 @@ export function valueFromAST(valueNode, type, variables) {
136
136
  coercedObj[field.name] = fieldValue;
137
137
  }
138
138
 
139
+ if (type.isOneOf) {
140
+ const keys = Object.keys(coercedObj);
141
+
142
+ if (keys.length !== 1) {
143
+ return; // Invalid: not exactly one key, intentionally return no value.
144
+ }
145
+
146
+ if (coercedObj[keys[0]] === null) {
147
+ return; // Invalid: value not non-null, intentionally return no value.
148
+ }
149
+ }
150
+
139
151
  return coercedObj;
140
152
  }
141
153
 
@@ -1,7 +1,7 @@
1
1
  export { validate } from './validate';
2
2
  export { ValidationContext } from './ValidationContext';
3
3
  export type { ValidationRule } from './ValidationContext';
4
- export { specifiedRules } from './specifiedRules';
4
+ export { specifiedRules, recommendedRules } from './specifiedRules';
5
5
  export { ExecutableDefinitionsRule } from './rules/ExecutableDefinitionsRule';
6
6
  export { FieldsOnCorrectTypeRule } from './rules/FieldsOnCorrectTypeRule';
7
7
  export { FragmentsOnCompositeTypesRule } from './rules/FragmentsOnCompositeTypesRule';
@@ -28,6 +28,7 @@ export { UniqueVariableNamesRule } from './rules/UniqueVariableNamesRule';
28
28
  export { ValuesOfCorrectTypeRule } from './rules/ValuesOfCorrectTypeRule';
29
29
  export { VariablesAreInputTypesRule } from './rules/VariablesAreInputTypesRule';
30
30
  export { VariablesInAllowedPositionRule } from './rules/VariablesInAllowedPositionRule';
31
+ export { MaxIntrospectionDepthRule } from './rules/MaxIntrospectionDepthRule';
31
32
  export { LoneSchemaDefinitionRule } from './rules/LoneSchemaDefinitionRule';
32
33
  export { UniqueOperationTypesRule } from './rules/UniqueOperationTypesRule';
33
34
  export { UniqueTypeNamesRule } from './rules/UniqueTypeNamesRule';
@@ -57,6 +57,12 @@ Object.defineProperty(exports, 'LoneSchemaDefinitionRule', {
57
57
  return _LoneSchemaDefinitionRule.LoneSchemaDefinitionRule;
58
58
  },
59
59
  });
60
+ Object.defineProperty(exports, 'MaxIntrospectionDepthRule', {
61
+ enumerable: true,
62
+ get: function () {
63
+ return _MaxIntrospectionDepthRule.MaxIntrospectionDepthRule;
64
+ },
65
+ });
60
66
  Object.defineProperty(exports, 'NoDeprecatedCustomRule', {
61
67
  enumerable: true,
62
68
  get: function () {
@@ -225,6 +231,12 @@ Object.defineProperty(exports, 'VariablesInAllowedPositionRule', {
225
231
  return _VariablesInAllowedPositionRule.VariablesInAllowedPositionRule;
226
232
  },
227
233
  });
234
+ Object.defineProperty(exports, 'recommendedRules', {
235
+ enumerable: true,
236
+ get: function () {
237
+ return _specifiedRules.recommendedRules;
238
+ },
239
+ });
228
240
  Object.defineProperty(exports, 'specifiedRules', {
229
241
  enumerable: true,
230
242
  get: function () {
@@ -296,6 +308,8 @@ var _VariablesAreInputTypesRule = require('./rules/VariablesAreInputTypesRule.js
296
308
 
297
309
  var _VariablesInAllowedPositionRule = require('./rules/VariablesInAllowedPositionRule.js');
298
310
 
311
+ var _MaxIntrospectionDepthRule = require('./rules/MaxIntrospectionDepthRule.js');
312
+
299
313
  var _LoneSchemaDefinitionRule = require('./rules/LoneSchemaDefinitionRule.js');
300
314
 
301
315
  var _UniqueOperationTypesRule = require('./rules/UniqueOperationTypesRule.js');
@@ -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'; // SDL-specific validation rules
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,5 @@
1
+ import type { ASTVisitor } from '../../language/visitor';
2
+ import type { ASTValidationContext } from '../ValidationContext';
3
+ export declare function MaxIntrospectionDepthRule(
4
+ context: ASTValidationContext,
5
+ ): ASTVisitor;
@@ -0,0 +1,90 @@
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
+ const 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, visitedFragments = Object.create(null), depth = 0) {
20
+ if (node.kind === _kinds.Kind.FRAGMENT_SPREAD) {
21
+ const fragmentName = node.name.value;
22
+
23
+ if (visitedFragments[fragmentName] === true) {
24
+ // Fragment cycles are handled by `NoFragmentCyclesRule`.
25
+ return false;
26
+ }
27
+
28
+ const fragment = context.getFragment(fragmentName);
29
+
30
+ if (!fragment) {
31
+ // Missing fragments checks are handled by `KnownFragmentNamesRule`.
32
+ return false;
33
+ } // Rather than following an immutable programming pattern which has
34
+ // significant memory and garbage collection overhead, we've opted to
35
+ // take a mutable approach for efficiency's sake. Importantly visiting a
36
+ // fragment twice is fine, so long as you don't do one visit inside the
37
+ // other.
38
+
39
+ try {
40
+ visitedFragments[fragmentName] = true;
41
+ return checkDepth(fragment, visitedFragments, depth);
42
+ } finally {
43
+ visitedFragments[fragmentName] = undefined;
44
+ }
45
+ }
46
+
47
+ if (
48
+ node.kind === _kinds.Kind.FIELD && // check all introspection lists
49
+ (node.name.value === 'fields' ||
50
+ node.name.value === 'interfaces' ||
51
+ node.name.value === 'possibleTypes' ||
52
+ node.name.value === 'inputFields')
53
+ ) {
54
+ // eslint-disable-next-line no-param-reassign
55
+ depth++;
56
+
57
+ if (depth >= MAX_LISTS_DEPTH) {
58
+ return true;
59
+ }
60
+ } // handles fields and inline fragments
61
+
62
+ if ('selectionSet' in node && node.selectionSet) {
63
+ for (const child of node.selectionSet.selections) {
64
+ if (checkDepth(child, visitedFragments, depth)) {
65
+ return true;
66
+ }
67
+ }
68
+ }
69
+
70
+ return false;
71
+ }
72
+
73
+ return {
74
+ Field(node) {
75
+ if (node.name.value === '__schema' || node.name.value === '__type') {
76
+ if (checkDepth(node)) {
77
+ context.reportError(
78
+ new _GraphQLError.GraphQLError(
79
+ 'Maximum introspection depth exceeded',
80
+ {
81
+ nodes: [node],
82
+ },
83
+ ),
84
+ );
85
+ return false;
86
+ }
87
+ }
88
+ },
89
+ };
90
+ }
@@ -0,0 +1,77 @@
1
+ import { GraphQLError } from '../../error/GraphQLError.mjs';
2
+ import { Kind } from '../../language/kinds.mjs';
3
+ const 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, visitedFragments = Object.create(null), depth = 0) {
10
+ if (node.kind === Kind.FRAGMENT_SPREAD) {
11
+ const fragmentName = node.name.value;
12
+
13
+ if (visitedFragments[fragmentName] === true) {
14
+ // Fragment cycles are handled by `NoFragmentCyclesRule`.
15
+ return false;
16
+ }
17
+
18
+ const fragment = context.getFragment(fragmentName);
19
+
20
+ if (!fragment) {
21
+ // Missing fragments checks are handled by `KnownFragmentNamesRule`.
22
+ return false;
23
+ } // Rather than following an immutable programming pattern which has
24
+ // significant memory and garbage collection overhead, we've opted to
25
+ // take a mutable approach for efficiency's sake. Importantly visiting a
26
+ // fragment twice is fine, so long as you don't do one visit inside the
27
+ // other.
28
+
29
+ try {
30
+ visitedFragments[fragmentName] = true;
31
+ return checkDepth(fragment, visitedFragments, depth);
32
+ } finally {
33
+ visitedFragments[fragmentName] = undefined;
34
+ }
35
+ }
36
+
37
+ if (
38
+ node.kind === Kind.FIELD && // check all introspection lists
39
+ (node.name.value === 'fields' ||
40
+ node.name.value === 'interfaces' ||
41
+ node.name.value === 'possibleTypes' ||
42
+ node.name.value === 'inputFields')
43
+ ) {
44
+ // eslint-disable-next-line no-param-reassign
45
+ depth++;
46
+
47
+ if (depth >= MAX_LISTS_DEPTH) {
48
+ return true;
49
+ }
50
+ } // handles fields and inline fragments
51
+
52
+ if ('selectionSet' in node && node.selectionSet) {
53
+ for (const child of node.selectionSet.selections) {
54
+ if (checkDepth(child, visitedFragments, depth)) {
55
+ return true;
56
+ }
57
+ }
58
+ }
59
+
60
+ return false;
61
+ }
62
+
63
+ return {
64
+ Field(node) {
65
+ if (node.name.value === '__schema' || node.name.value === '__type') {
66
+ if (checkDepth(node)) {
67
+ context.reportError(
68
+ new GraphQLError('Maximum introspection depth exceeded', {
69
+ nodes: [node],
70
+ }),
71
+ );
72
+ return false;
73
+ }
74
+ }
75
+ },
76
+ };
77
+ }
@@ -15,6 +15,8 @@ var _suggestionList = require('../../jsutils/suggestionList.js');
15
15
 
16
16
  var _GraphQLError = require('../../error/GraphQLError.js');
17
17
 
18
+ var _kinds = require('../../language/kinds.js');
19
+
18
20
  var _printer = require('../../language/printer.js');
19
21
 
20
22
  var _definition = require('../../type/definition.js');
@@ -28,7 +30,18 @@ var _definition = require('../../type/definition.js');
28
30
  * See https://spec.graphql.org/draft/#sec-Values-of-Correct-Type
29
31
  */
30
32
  function ValuesOfCorrectTypeRule(context) {
33
+ let variableDefinitions = {};
31
34
  return {
35
+ OperationDefinition: {
36
+ enter() {
37
+ variableDefinitions = {};
38
+ },
39
+ },
40
+
41
+ VariableDefinition(definition) {
42
+ variableDefinitions[definition.variable.name.value] = definition;
43
+ },
44
+
32
45
  ListValue(node) {
33
46
  // Note: TypeInfo will traverse into a list's item type, so look to the
34
47
  // parent input type to check if it is a list.
@@ -70,6 +83,16 @@ function ValuesOfCorrectTypeRule(context) {
70
83
  );
71
84
  }
72
85
  }
86
+
87
+ if (type.isOneOf) {
88
+ validateOneOfInputObject(
89
+ context,
90
+ node,
91
+ type,
92
+ fieldNodeMap,
93
+ variableDefinitions,
94
+ );
95
+ }
73
96
  },
74
97
 
75
98
  ObjectField(node) {
@@ -190,3 +213,68 @@ function isValidValueNode(context, node) {
190
213
  }
191
214
  }
192
215
  }
216
+
217
+ function validateOneOfInputObject(
218
+ context,
219
+ node,
220
+ type,
221
+ fieldNodeMap,
222
+ variableDefinitions,
223
+ ) {
224
+ var _fieldNodeMap$keys$;
225
+
226
+ const keys = Object.keys(fieldNodeMap);
227
+ const isNotExactlyOneField = keys.length !== 1;
228
+
229
+ if (isNotExactlyOneField) {
230
+ context.reportError(
231
+ new _GraphQLError.GraphQLError(
232
+ `OneOf Input Object "${type.name}" must specify exactly one key.`,
233
+ {
234
+ nodes: [node],
235
+ },
236
+ ),
237
+ );
238
+ return;
239
+ }
240
+
241
+ const value =
242
+ (_fieldNodeMap$keys$ = fieldNodeMap[keys[0]]) === null ||
243
+ _fieldNodeMap$keys$ === void 0
244
+ ? void 0
245
+ : _fieldNodeMap$keys$.value;
246
+ const isNullLiteral = !value || value.kind === _kinds.Kind.NULL;
247
+ const isVariable =
248
+ (value === null || value === void 0 ? void 0 : value.kind) ===
249
+ _kinds.Kind.VARIABLE;
250
+
251
+ if (isNullLiteral) {
252
+ context.reportError(
253
+ new _GraphQLError.GraphQLError(
254
+ `Field "${type.name}.${keys[0]}" must be non-null.`,
255
+ {
256
+ nodes: [node],
257
+ },
258
+ ),
259
+ );
260
+ return;
261
+ }
262
+
263
+ if (isVariable) {
264
+ const variableName = value.name.value;
265
+ const definition = variableDefinitions[variableName];
266
+ const isNullableVariable =
267
+ definition.type.kind !== _kinds.Kind.NON_NULL_TYPE;
268
+
269
+ if (isNullableVariable) {
270
+ context.reportError(
271
+ new _GraphQLError.GraphQLError(
272
+ `Variable "${variableName}" must be non-nullable to be used for OneOf Input Object "${type.name}".`,
273
+ {
274
+ nodes: [node],
275
+ },
276
+ ),
277
+ );
278
+ }
279
+ }
280
+ }
@@ -3,6 +3,7 @@ import { inspect } from '../../jsutils/inspect.mjs';
3
3
  import { keyMap } from '../../jsutils/keyMap.mjs';
4
4
  import { suggestionList } from '../../jsutils/suggestionList.mjs';
5
5
  import { GraphQLError } from '../../error/GraphQLError.mjs';
6
+ import { Kind } from '../../language/kinds.mjs';
6
7
  import { print } from '../../language/printer.mjs';
7
8
  import {
8
9
  getNamedType,
@@ -23,7 +24,18 @@ import {
23
24
  * See https://spec.graphql.org/draft/#sec-Values-of-Correct-Type
24
25
  */
25
26
  export function ValuesOfCorrectTypeRule(context) {
27
+ let variableDefinitions = {};
26
28
  return {
29
+ OperationDefinition: {
30
+ enter() {
31
+ variableDefinitions = {};
32
+ },
33
+ },
34
+
35
+ VariableDefinition(definition) {
36
+ variableDefinitions[definition.variable.name.value] = definition;
37
+ },
38
+
27
39
  ListValue(node) {
28
40
  // Note: TypeInfo will traverse into a list's item type, so look to the
29
41
  // parent input type to check if it is a list.
@@ -60,6 +72,16 @@ export function ValuesOfCorrectTypeRule(context) {
60
72
  );
61
73
  }
62
74
  }
75
+
76
+ if (type.isOneOf) {
77
+ validateOneOfInputObject(
78
+ context,
79
+ node,
80
+ type,
81
+ fieldNodeMap,
82
+ variableDefinitions,
83
+ );
84
+ }
63
85
  },
64
86
 
65
87
  ObjectField(node) {
@@ -171,3 +193,64 @@ function isValidValueNode(context, node) {
171
193
  }
172
194
  }
173
195
  }
196
+
197
+ function validateOneOfInputObject(
198
+ context,
199
+ node,
200
+ type,
201
+ fieldNodeMap,
202
+ variableDefinitions,
203
+ ) {
204
+ var _fieldNodeMap$keys$;
205
+
206
+ const keys = Object.keys(fieldNodeMap);
207
+ const isNotExactlyOneField = keys.length !== 1;
208
+
209
+ if (isNotExactlyOneField) {
210
+ context.reportError(
211
+ new GraphQLError(
212
+ `OneOf Input Object "${type.name}" must specify exactly one key.`,
213
+ {
214
+ nodes: [node],
215
+ },
216
+ ),
217
+ );
218
+ return;
219
+ }
220
+
221
+ const value =
222
+ (_fieldNodeMap$keys$ = fieldNodeMap[keys[0]]) === null ||
223
+ _fieldNodeMap$keys$ === void 0
224
+ ? void 0
225
+ : _fieldNodeMap$keys$.value;
226
+ const isNullLiteral = !value || value.kind === Kind.NULL;
227
+ const isVariable =
228
+ (value === null || value === void 0 ? void 0 : value.kind) ===
229
+ Kind.VARIABLE;
230
+
231
+ if (isNullLiteral) {
232
+ context.reportError(
233
+ new GraphQLError(`Field "${type.name}.${keys[0]}" must be non-null.`, {
234
+ nodes: [node],
235
+ }),
236
+ );
237
+ return;
238
+ }
239
+
240
+ if (isVariable) {
241
+ const variableName = value.name.value;
242
+ const definition = variableDefinitions[variableName];
243
+ const isNullableVariable = definition.type.kind !== Kind.NON_NULL_TYPE;
244
+
245
+ if (isNullableVariable) {
246
+ context.reportError(
247
+ new GraphQLError(
248
+ `Variable "${variableName}" must be non-nullable to be used for OneOf Input Object "${type.name}".`,
249
+ {
250
+ nodes: [node],
251
+ },
252
+ ),
253
+ );
254
+ }
255
+ }
256
+ }
@@ -1,4 +1,10 @@
1
+ import { MaxIntrospectionDepthRule } from './rules/MaxIntrospectionDepthRule';
1
2
  import type { SDLValidationRule, ValidationRule } from './ValidationContext';
3
+ /**
4
+ * Technically these aren't part of the spec but they are strongly encouraged
5
+ * validation rules.
6
+ */
7
+ export declare const recommendedRules: readonly typeof MaxIntrospectionDepthRule[];
2
8
  /**
3
9
  * This set includes all validation rules defined by the GraphQL spec.
4
10
  *
@@ -3,7 +3,10 @@
3
3
  Object.defineProperty(exports, '__esModule', {
4
4
  value: true,
5
5
  });
6
- exports.specifiedSDLRules = exports.specifiedRules = void 0;
6
+ exports.specifiedSDLRules =
7
+ exports.specifiedRules =
8
+ exports.recommendedRules =
9
+ void 0;
7
10
 
8
11
  var _ExecutableDefinitionsRule = require('./rules/ExecutableDefinitionsRule.js');
9
12
 
@@ -23,6 +26,8 @@ var _LoneAnonymousOperationRule = require('./rules/LoneAnonymousOperationRule.js
23
26
 
24
27
  var _LoneSchemaDefinitionRule = require('./rules/LoneSchemaDefinitionRule.js');
25
28
 
29
+ var _MaxIntrospectionDepthRule = require('./rules/MaxIntrospectionDepthRule.js');
30
+
26
31
  var _NoFragmentCyclesRule = require('./rules/NoFragmentCyclesRule.js');
27
32
 
28
33
  var _NoUndefinedVariablesRule = require('./rules/NoUndefinedVariablesRule.js');
@@ -82,6 +87,7 @@ var _VariablesInAllowedPositionRule = require('./rules/VariablesInAllowedPositio
82
87
  // Spec Section: "Fragment Spread Type Existence"
83
88
  // Spec Section: "Lone Anonymous Operation"
84
89
  // SDL-specific validation rules
90
+ // TODO: Spec Section
85
91
  // Spec Section: "Fragments must not form cycles"
86
92
  // Spec Section: "All Variable Used Defined"
87
93
  // Spec Section: "Fragments must be used"
@@ -101,12 +107,21 @@ var _VariablesInAllowedPositionRule = require('./rules/VariablesInAllowedPositio
101
107
  // Spec Section: "Variables are Input Types"
102
108
  // Spec Section: "All Variable Usages Are Allowed"
103
109
 
110
+ /**
111
+ * Technically these aren't part of the spec but they are strongly encouraged
112
+ * validation rules.
113
+ */
114
+ const recommendedRules = Object.freeze([
115
+ _MaxIntrospectionDepthRule.MaxIntrospectionDepthRule,
116
+ ]);
104
117
  /**
105
118
  * This set includes all validation rules defined by the GraphQL spec.
106
119
  *
107
120
  * The order of the rules in this list has been adjusted to lead to the
108
121
  * most clear output when encountering multiple validation errors.
109
122
  */
123
+
124
+ exports.recommendedRules = recommendedRules;
110
125
  const specifiedRules = Object.freeze([
111
126
  _ExecutableDefinitionsRule.ExecutableDefinitionsRule,
112
127
  _UniqueOperationNamesRule.UniqueOperationNamesRule,
@@ -134,6 +149,7 @@ const specifiedRules = Object.freeze([
134
149
  _VariablesInAllowedPositionRule.VariablesInAllowedPositionRule,
135
150
  _OverlappingFieldsCanBeMergedRule.OverlappingFieldsCanBeMergedRule,
136
151
  _UniqueInputFieldNamesRule.UniqueInputFieldNamesRule,
152
+ ...recommendedRules,
137
153
  ]);
138
154
  /**
139
155
  * @internal
@@ -18,7 +18,9 @@ import { KnownTypeNamesRule } from './rules/KnownTypeNamesRule.mjs'; // Spec Sec
18
18
 
19
19
  import { LoneAnonymousOperationRule } from './rules/LoneAnonymousOperationRule.mjs'; // SDL-specific validation rules
20
20
 
21
- import { LoneSchemaDefinitionRule } from './rules/LoneSchemaDefinitionRule.mjs'; // Spec Section: "Fragments must not form cycles"
21
+ import { LoneSchemaDefinitionRule } from './rules/LoneSchemaDefinitionRule.mjs'; // TODO: Spec Section
22
+
23
+ import { MaxIntrospectionDepthRule } from './rules/MaxIntrospectionDepthRule.mjs'; // Spec Section: "Fragments must not form cycles"
22
24
 
23
25
  import { NoFragmentCyclesRule } from './rules/NoFragmentCyclesRule.mjs'; // Spec Section: "All Variable Used Defined"
24
26
 
@@ -66,12 +68,18 @@ import { VariablesAreInputTypesRule } from './rules/VariablesAreInputTypesRule.m
66
68
 
67
69
  import { VariablesInAllowedPositionRule } from './rules/VariablesInAllowedPositionRule.mjs';
68
70
 
71
+ /**
72
+ * Technically these aren't part of the spec but they are strongly encouraged
73
+ * validation rules.
74
+ */
75
+ export const recommendedRules = Object.freeze([MaxIntrospectionDepthRule]);
69
76
  /**
70
77
  * This set includes all validation rules defined by the GraphQL spec.
71
78
  *
72
79
  * The order of the rules in this list has been adjusted to lead to the
73
80
  * most clear output when encountering multiple validation errors.
74
81
  */
82
+
75
83
  export const specifiedRules = Object.freeze([
76
84
  ExecutableDefinitionsRule,
77
85
  UniqueOperationNamesRule,
@@ -99,6 +107,7 @@ export const specifiedRules = Object.freeze([
99
107
  VariablesInAllowedPositionRule,
100
108
  OverlappingFieldsCanBeMergedRule,
101
109
  UniqueInputFieldNamesRule,
110
+ ...recommendedRules,
102
111
  ]);
103
112
  /**
104
113
  * @internal