@graphql-eslint/eslint-plugin 3.0.0-alpha-7462f3d.0 → 3.0.0-alpha-636cc2a.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 (80) hide show
  1. package/README.md +19 -8
  2. package/configs/base.d.ts +5 -0
  3. package/configs/index.d.ts +76 -117
  4. package/configs/operations-all.d.ts +19 -0
  5. package/configs/operations-recommended.d.ts +50 -0
  6. package/configs/schema-all.d.ts +17 -0
  7. package/configs/schema-recommended.d.ts +46 -0
  8. package/docs/README.md +9 -15
  9. package/docs/rules/alphabetize.md +1 -1
  10. package/docs/rules/description-style.md +5 -3
  11. package/docs/rules/executable-definitions.md +2 -2
  12. package/docs/rules/fields-on-correct-type.md +2 -2
  13. package/docs/rules/fragments-on-composite-type.md +2 -2
  14. package/docs/rules/input-name.md +1 -1
  15. package/docs/rules/known-argument-names.md +2 -2
  16. package/docs/rules/known-directives.md +2 -2
  17. package/docs/rules/known-fragment-names.md +2 -2
  18. package/docs/rules/known-type-names.md +2 -2
  19. package/docs/rules/lone-anonymous-operation.md +2 -2
  20. package/docs/rules/lone-schema-definition.md +2 -2
  21. package/docs/rules/match-document-filename.md +6 -4
  22. package/docs/rules/naming-convention.md +180 -41
  23. package/docs/rules/no-anonymous-operations.md +2 -2
  24. package/docs/rules/no-case-insensitive-enum-values-duplicates.md +2 -2
  25. package/docs/rules/no-deprecated.md +3 -1
  26. package/docs/rules/no-duplicate-fields.md +3 -1
  27. package/docs/rules/no-fragment-cycles.md +2 -2
  28. package/docs/rules/no-hashtag-description.md +3 -1
  29. package/docs/rules/no-root-type.md +4 -15
  30. package/docs/rules/no-scalar-result-type-on-mutation.md +1 -1
  31. package/docs/rules/no-typename-prefix.md +2 -2
  32. package/docs/rules/no-undefined-variables.md +2 -2
  33. package/docs/rules/no-unreachable-types.md +3 -1
  34. package/docs/rules/no-unused-fields.md +1 -1
  35. package/docs/rules/no-unused-fragments.md +2 -2
  36. package/docs/rules/no-unused-variables.md +2 -2
  37. package/docs/rules/one-field-subscriptions.md +2 -2
  38. package/docs/rules/overlapping-fields-can-be-merged.md +2 -2
  39. package/docs/rules/possible-fragment-spread.md +2 -2
  40. package/docs/rules/possible-type-extension.md +2 -2
  41. package/docs/rules/provided-required-arguments.md +2 -2
  42. package/docs/rules/require-deprecation-date.md +1 -1
  43. package/docs/rules/require-deprecation-reason.md +2 -2
  44. package/docs/rules/require-description.md +38 -22
  45. package/docs/rules/require-field-of-type-query-in-mutation-result.md +1 -1
  46. package/docs/rules/require-id-when-available.md +3 -1
  47. package/docs/rules/scalar-leafs.md +2 -2
  48. package/docs/rules/selection-set-depth.md +9 -2
  49. package/docs/rules/strict-id-in-types.md +16 -10
  50. package/docs/rules/unique-argument-names.md +2 -2
  51. package/docs/rules/unique-directive-names-per-location.md +2 -2
  52. package/docs/rules/unique-directive-names.md +2 -2
  53. package/docs/rules/unique-enum-value-names.md +2 -2
  54. package/docs/rules/unique-field-definition-names.md +2 -2
  55. package/docs/rules/unique-fragment-name.md +1 -1
  56. package/docs/rules/unique-input-field-names.md +2 -2
  57. package/docs/rules/unique-operation-name.md +1 -1
  58. package/docs/rules/unique-operation-types.md +2 -2
  59. package/docs/rules/unique-type-names.md +2 -2
  60. package/docs/rules/unique-variable-names.md +2 -2
  61. package/docs/rules/value-literals-of-correct-type.md +2 -2
  62. package/docs/rules/variables-are-input-types.md +2 -2
  63. package/docs/rules/variables-in-allowed-position.md +2 -2
  64. package/index.js +329 -208
  65. package/index.mjs +329 -208
  66. package/package.json +1 -1
  67. package/rules/alphabetize.d.ts +8 -10
  68. package/rules/description-style.d.ts +4 -6
  69. package/rules/index.d.ts +112 -114
  70. package/rules/input-name.d.ts +1 -1
  71. package/rules/match-document-filename.d.ts +8 -10
  72. package/rules/naming-convention.d.ts +3 -4
  73. package/rules/no-root-type.d.ts +1 -1
  74. package/rules/require-description.d.ts +2 -3
  75. package/rules/require-id-when-available.d.ts +3 -3
  76. package/rules/selection-set-depth.d.ts +3 -3
  77. package/rules/strict-id-in-types.d.ts +6 -8
  78. package/types.d.ts +9 -5
  79. package/configs/all.d.ts +0 -102
  80. package/configs/recommended.d.ts +0 -71
package/index.js CHANGED
@@ -18,12 +18,88 @@ const codeFileLoader = require('@graphql-tools/code-file-loader');
18
18
  const eslint = require('eslint');
19
19
  const codeFrame = require('@babel/code-frame');
20
20
 
21
+ const base = {
22
+ parser: '@graphql-eslint/eslint-plugin',
23
+ plugins: ['@graphql-eslint'],
24
+ };
25
+
21
26
  /*
22
27
  * 🚨 IMPORTANT! Do not manually modify this file. Run: `yarn generate-configs`
23
28
  */
24
- const recommendedConfig = {
25
- parser: '@graphql-eslint/eslint-plugin',
26
- plugins: ['@graphql-eslint'],
29
+ const schemaRecommendedConfig = {
30
+ extends: ['plugin:@graphql-eslint/base'],
31
+ rules: {
32
+ '@graphql-eslint/description-style': 'error',
33
+ '@graphql-eslint/known-argument-names': 'error',
34
+ '@graphql-eslint/known-directives': 'error',
35
+ '@graphql-eslint/known-type-names': 'error',
36
+ '@graphql-eslint/lone-schema-definition': 'error',
37
+ '@graphql-eslint/naming-convention': [
38
+ 'error',
39
+ {
40
+ types: 'PascalCase',
41
+ fields: 'camelCase',
42
+ EnumValueDefinition: 'UPPER_CASE',
43
+ 'FieldDefinition[parent.name.value=Query]': {
44
+ forbiddenPrefixes: ['query', 'get'],
45
+ forbiddenSuffixes: ['Query'],
46
+ },
47
+ 'FieldDefinition[parent.name.value=Mutation]': {
48
+ forbiddenPrefixes: ['mutation'],
49
+ forbiddenSuffixes: ['Mutation'],
50
+ },
51
+ 'FieldDefinition[parent.name.value=Subscription]': {
52
+ forbiddenPrefixes: ['subscription'],
53
+ forbiddenSuffixes: ['Subscription'],
54
+ },
55
+ },
56
+ ],
57
+ '@graphql-eslint/no-case-insensitive-enum-values-duplicates': 'error',
58
+ '@graphql-eslint/no-hashtag-description': 'error',
59
+ '@graphql-eslint/no-typename-prefix': 'error',
60
+ '@graphql-eslint/no-unreachable-types': 'error',
61
+ '@graphql-eslint/possible-type-extension': 'error',
62
+ '@graphql-eslint/provided-required-arguments': 'error',
63
+ '@graphql-eslint/require-deprecation-reason': 'error',
64
+ '@graphql-eslint/require-description': ['error', { types: true, DirectiveDefinition: true }],
65
+ '@graphql-eslint/strict-id-in-types': 'error',
66
+ '@graphql-eslint/unique-directive-names': 'error',
67
+ '@graphql-eslint/unique-directive-names-per-location': 'error',
68
+ '@graphql-eslint/unique-enum-value-names': 'error',
69
+ '@graphql-eslint/unique-field-definition-names': 'error',
70
+ '@graphql-eslint/unique-operation-types': 'error',
71
+ '@graphql-eslint/unique-type-names': 'error',
72
+ },
73
+ };
74
+
75
+ /*
76
+ * 🚨 IMPORTANT! Do not manually modify this file. Run: `yarn generate-configs`
77
+ */
78
+ const schemaAllConfig = {
79
+ extends: ['plugin:@graphql-eslint/base', 'plugin:@graphql-eslint/schema-recommended'],
80
+ rules: {
81
+ '@graphql-eslint/alphabetize': [
82
+ 'error',
83
+ {
84
+ fields: ['ObjectTypeDefinition', 'InterfaceTypeDefinition', 'InputObjectTypeDefinition'],
85
+ values: ['EnumTypeDefinition'],
86
+ arguments: ['FieldDefinition', 'Field', 'DirectiveDefinition', 'Directive'],
87
+ },
88
+ ],
89
+ '@graphql-eslint/input-name': 'error',
90
+ '@graphql-eslint/no-root-type': 'off',
91
+ '@graphql-eslint/no-scalar-result-type-on-mutation': 'error',
92
+ '@graphql-eslint/no-unused-fields': 'off',
93
+ '@graphql-eslint/require-deprecation-date': 'error',
94
+ '@graphql-eslint/require-field-of-type-query-in-mutation-result': 'error',
95
+ },
96
+ };
97
+
98
+ /*
99
+ * 🚨 IMPORTANT! Do not manually modify this file. Run: `yarn generate-configs`
100
+ */
101
+ const operationsRecommendedConfig = {
102
+ extends: ['plugin:@graphql-eslint/base'],
27
103
  rules: {
28
104
  '@graphql-eslint/executable-definitions': 'error',
29
105
  '@graphql-eslint/fields-on-correct-type': 'error',
@@ -33,58 +109,35 @@ const recommendedConfig = {
33
109
  '@graphql-eslint/known-fragment-names': 'error',
34
110
  '@graphql-eslint/known-type-names': 'error',
35
111
  '@graphql-eslint/lone-anonymous-operation': 'error',
36
- '@graphql-eslint/lone-schema-definition': 'error',
37
112
  '@graphql-eslint/naming-convention': [
38
113
  'error',
39
114
  {
40
- types: 'PascalCase',
41
- fields: 'camelCase',
42
- overrides: {
43
- EnumValueDefinition: 'UPPER_CASE',
44
- OperationDefinition: {
45
- style: 'PascalCase',
46
- forbiddenPrefixes: ['Query', 'Mutation', 'Subscription', 'Get'],
47
- forbiddenSuffixes: ['Query', 'Mutation', 'Subscription'],
48
- },
49
- FragmentDefinition: { style: 'PascalCase', forbiddenPrefixes: ['Fragment'], forbiddenSuffixes: ['Fragment'] },
50
- 'FieldDefinition[parent.name.value=Query]': {
51
- forbiddenPrefixes: ['query', 'get'],
52
- forbiddenSuffixes: ['Query'],
53
- },
54
- 'FieldDefinition[parent.name.value=Mutation]': {
55
- forbiddenPrefixes: ['mutation'],
56
- forbiddenSuffixes: ['Mutation'],
57
- },
58
- 'FieldDefinition[parent.name.value=Subscription]': {
59
- forbiddenPrefixes: ['subscription'],
60
- forbiddenSuffixes: ['Subscription'],
61
- },
115
+ VariableDefinition: 'camelCase',
116
+ OperationDefinition: {
117
+ style: 'PascalCase',
118
+ forbiddenPrefixes: ['Query', 'Mutation', 'Subscription', 'Get'],
119
+ forbiddenSuffixes: ['Query', 'Mutation', 'Subscription'],
62
120
  },
121
+ FragmentDefinition: { style: 'PascalCase', forbiddenPrefixes: ['Fragment'], forbiddenSuffixes: ['Fragment'] },
63
122
  },
64
123
  ],
65
124
  '@graphql-eslint/no-anonymous-operations': 'error',
66
- '@graphql-eslint/no-case-insensitive-enum-values-duplicates': 'error',
125
+ '@graphql-eslint/no-deprecated': 'error',
126
+ '@graphql-eslint/no-duplicate-fields': 'error',
67
127
  '@graphql-eslint/no-fragment-cycles': 'error',
68
- '@graphql-eslint/no-typename-prefix': 'error',
69
128
  '@graphql-eslint/no-undefined-variables': 'error',
70
129
  '@graphql-eslint/no-unused-fragments': 'error',
71
130
  '@graphql-eslint/no-unused-variables': 'error',
72
131
  '@graphql-eslint/one-field-subscriptions': 'error',
73
132
  '@graphql-eslint/overlapping-fields-can-be-merged': 'error',
74
133
  '@graphql-eslint/possible-fragment-spread': 'error',
75
- '@graphql-eslint/possible-type-extension': 'error',
76
134
  '@graphql-eslint/provided-required-arguments': 'error',
77
- '@graphql-eslint/require-deprecation-reason': 'error',
135
+ '@graphql-eslint/require-id-when-available': 'error',
78
136
  '@graphql-eslint/scalar-leafs': 'error',
79
- '@graphql-eslint/strict-id-in-types': 'error',
137
+ '@graphql-eslint/selection-set-depth': ['error', { maxDepth: 7 }],
80
138
  '@graphql-eslint/unique-argument-names': 'error',
81
- '@graphql-eslint/unique-directive-names': 'error',
82
139
  '@graphql-eslint/unique-directive-names-per-location': 'error',
83
- '@graphql-eslint/unique-enum-value-names': 'error',
84
- '@graphql-eslint/unique-field-definition-names': 'error',
85
140
  '@graphql-eslint/unique-input-field-names': 'error',
86
- '@graphql-eslint/unique-operation-types': 'error',
87
- '@graphql-eslint/unique-type-names': 'error',
88
141
  '@graphql-eslint/unique-variable-names': 'error',
89
142
  '@graphql-eslint/value-literals-of-correct-type': 'error',
90
143
  '@graphql-eslint/variables-are-input-types': 'error',
@@ -95,43 +148,32 @@ const recommendedConfig = {
95
148
  /*
96
149
  * 🚨 IMPORTANT! Do not manually modify this file. Run: `yarn generate-configs`
97
150
  */
98
- const allConfig = {
99
- ...recommendedConfig,
151
+ const operationsAllConfig = {
152
+ extends: ['plugin:@graphql-eslint/base', 'plugin:@graphql-eslint/operations-recommended'],
100
153
  rules: {
101
- ...recommendedConfig.rules,
102
154
  '@graphql-eslint/alphabetize': [
103
155
  'error',
104
156
  {
105
- fields: ['ObjectTypeDefinition', 'InterfaceTypeDefinition', 'InputObjectTypeDefinition'],
106
- values: ['EnumTypeDefinition'],
107
157
  selections: ['OperationDefinition', 'FragmentDefinition'],
108
158
  variables: ['OperationDefinition'],
109
- arguments: ['FieldDefinition', 'Field', 'DirectiveDefinition', 'Directive'],
159
+ arguments: ['Field', 'Directive'],
110
160
  },
111
161
  ],
112
- '@graphql-eslint/description-style': 'error',
113
- '@graphql-eslint/input-name': 'error',
114
- '@graphql-eslint/match-document-filename': 'error',
115
- '@graphql-eslint/no-deprecated': 'error',
116
- '@graphql-eslint/no-duplicate-fields': 'error',
117
- '@graphql-eslint/no-hashtag-description': 'error',
118
- '@graphql-eslint/no-root-type': ['error', { disallow: ['subscription'] }],
119
- '@graphql-eslint/no-scalar-result-type-on-mutation': 'error',
120
- '@graphql-eslint/no-unreachable-types': 'error',
121
- '@graphql-eslint/no-unused-fields': 'error',
122
- '@graphql-eslint/require-deprecation-date': 'error',
123
- '@graphql-eslint/require-description': ['error', { types: true, overrides: { DirectiveDefinition: true } }],
124
- '@graphql-eslint/require-field-of-type-query-in-mutation-result': 'error',
125
- '@graphql-eslint/require-id-when-available': 'error',
126
- '@graphql-eslint/selection-set-depth': 'error',
162
+ '@graphql-eslint/match-document-filename': [
163
+ 'error',
164
+ { query: 'kebab-case', mutation: 'kebab-case', subscription: 'kebab-case', fragment: 'kebab-case' },
165
+ ],
127
166
  '@graphql-eslint/unique-fragment-name': 'error',
128
167
  '@graphql-eslint/unique-operation-name': 'error',
129
168
  },
130
169
  };
131
170
 
132
171
  const configs = {
133
- all: allConfig,
134
- recommended: recommendedConfig,
172
+ base,
173
+ 'schema-recommended': schemaRecommendedConfig,
174
+ 'schema-all': schemaAllConfig,
175
+ 'operations-recommended': operationsRecommendedConfig,
176
+ 'operations-all': operationsAllConfig,
135
177
  };
136
178
 
137
179
  function requireSiblingsOperations(ruleName, context) {
@@ -344,7 +386,6 @@ const validationToRule = (name, ruleName, docs, getDocumentNode) => {
344
386
  docs: {
345
387
  ...docs,
346
388
  graphQLJSRuleName: ruleName,
347
- category: 'Validation',
348
389
  recommended: true,
349
390
  requiresSchema,
350
391
  url: `https://github.com/dotansimha/graphql-eslint/blob/master/docs/rules/${name}.md`,
@@ -381,16 +422,22 @@ const importFiles = (context) => {
381
422
  return _import.processImport(context.getFilename());
382
423
  };
383
424
  const GRAPHQL_JS_VALIDATIONS = Object.assign({}, validationToRule('executable-definitions', 'ExecutableDefinitions', {
425
+ category: 'Operations',
384
426
  description: `A GraphQL document is only valid for execution if all definitions are either operation or fragment definitions.`,
385
427
  }), validationToRule('fields-on-correct-type', 'FieldsOnCorrectType', {
428
+ category: 'Operations',
386
429
  description: 'A GraphQL document is only valid if all fields selected are defined by the parent type, or are an allowed meta field such as `__typename`.',
387
430
  }), validationToRule('fragments-on-composite-type', 'FragmentsOnCompositeTypes', {
431
+ category: 'Operations',
388
432
  description: `Fragments use a type condition to determine if they apply, since fragments can only be spread into a composite type (object, interface, or union), the type condition must also be a composite type.`,
389
433
  }), validationToRule('known-argument-names', 'KnownArgumentNames', {
434
+ category: ['Schema', 'Operations'],
390
435
  description: `A GraphQL field is only valid if all supplied arguments are defined by that field.`,
391
436
  }), validationToRule('known-directives', 'KnownDirectives', {
437
+ category: ['Schema', 'Operations'],
392
438
  description: `A GraphQL document is only valid if all \`@directives\` are known by the schema and legally positioned.`,
393
439
  }), validationToRule('known-fragment-names', 'KnownFragmentNames', {
440
+ category: 'Operations',
394
441
  description: `A GraphQL document is only valid if all \`...Fragment\` fragment spreads refer to fragments defined in the same document.`,
395
442
  examples: [
396
443
  {
@@ -457,17 +504,23 @@ const GRAPHQL_JS_VALIDATIONS = Object.assign({}, validationToRule('executable-de
457
504
  },
458
505
  ],
459
506
  }, importFiles), validationToRule('known-type-names', 'KnownTypeNames', {
507
+ category: ['Schema', 'Operations'],
460
508
  description: `A GraphQL document is only valid if referenced types (specifically variable definitions and fragment conditions) are defined by the type schema.`,
461
509
  }), validationToRule('lone-anonymous-operation', 'LoneAnonymousOperation', {
510
+ category: 'Operations',
462
511
  description: `A GraphQL document is only valid if when it contains an anonymous operation (the query short-hand) that it contains only that one operation definition.`,
463
512
  }), validationToRule('lone-schema-definition', 'LoneSchemaDefinition', {
513
+ category: 'Schema',
464
514
  description: `A GraphQL document is only valid if it contains only one schema definition.`,
465
515
  requiresSchema: false,
466
516
  }), validationToRule('no-fragment-cycles', 'NoFragmentCycles', {
517
+ category: 'Operations',
467
518
  description: `A GraphQL fragment is only valid when it does not have cycles in fragments usage.`,
468
519
  }), validationToRule('no-undefined-variables', 'NoUndefinedVariables', {
520
+ category: 'Operations',
469
521
  description: `A GraphQL operation is only valid if all variables encountered, both directly and via fragment spreads, are defined by that operation.`,
470
522
  }, importFiles), validationToRule('no-unused-fragments', 'NoUnusedFragments', {
523
+ category: 'Operations',
471
524
  description: `A GraphQL document is only valid if all fragment definitions are spread within operations, or spread within other fragments spread within operations.`,
472
525
  requiresSiblings: true,
473
526
  }, context => {
@@ -497,49 +550,68 @@ const GRAPHQL_JS_VALIDATIONS = Object.assign({}, validationToRule('executable-de
497
550
  };
498
551
  return getParentNode(context.getFilename());
499
552
  }), validationToRule('no-unused-variables', 'NoUnusedVariables', {
553
+ category: 'Operations',
500
554
  description: `A GraphQL operation is only valid if all variables defined by an operation are used, either directly or within a spread fragment.`,
501
555
  }, importFiles), validationToRule('overlapping-fields-can-be-merged', 'OverlappingFieldsCanBeMerged', {
556
+ category: 'Operations',
502
557
  description: `A selection set is only valid if all fields (including spreading any fragments) either correspond to distinct response names or can be merged without ambiguity.`,
503
558
  }), validationToRule('possible-fragment-spread', 'PossibleFragmentSpreads', {
559
+ category: 'Operations',
504
560
  description: `A fragment spread is only valid if the type condition could ever possibly be true: if there is a non-empty intersection of the possible parent types, and possible types which pass the type condition.`,
505
561
  }), validationToRule('possible-type-extension', 'PossibleTypeExtensions', {
562
+ category: 'Schema',
506
563
  description: `A type extension is only valid if the type is defined and has the same kind.`,
507
564
  requiresSchema: false,
508
565
  }), validationToRule('provided-required-arguments', 'ProvidedRequiredArguments', {
566
+ category: ['Schema', 'Operations'],
509
567
  description: `A field or directive is only valid if all required (non-null without a default value) field arguments have been provided.`,
510
568
  }), validationToRule('scalar-leafs', 'ScalarLeafs', {
569
+ category: 'Operations',
511
570
  description: `A GraphQL document is valid only if all leaf fields (fields without sub selections) are of scalar or enum types.`,
512
571
  }), validationToRule('one-field-subscriptions', 'SingleFieldSubscriptions', {
572
+ category: 'Operations',
513
573
  description: `A GraphQL subscription is valid only if it contains a single root field.`,
514
574
  }), validationToRule('unique-argument-names', 'UniqueArgumentNames', {
575
+ category: 'Operations',
515
576
  description: `A GraphQL field or directive is only valid if all supplied arguments are uniquely named.`,
516
577
  }), validationToRule('unique-directive-names', 'UniqueDirectiveNames', {
578
+ category: 'Schema',
517
579
  description: `A GraphQL document is only valid if all defined directives have unique names.`,
518
580
  requiresSchema: false,
519
581
  }), validationToRule('unique-directive-names-per-location', 'UniqueDirectivesPerLocation', {
582
+ category: ['Schema', 'Operations'],
520
583
  description: `A GraphQL document is only valid if all non-repeatable directives at a given location are uniquely named.`,
521
584
  }), validationToRule('unique-enum-value-names', 'UniqueEnumValueNames', {
585
+ category: 'Schema',
522
586
  description: `A GraphQL enum type is only valid if all its values are uniquely named.`,
523
587
  requiresSchema: false,
524
588
  }), validationToRule('unique-field-definition-names', 'UniqueFieldDefinitionNames', {
589
+ category: 'Schema',
525
590
  description: `A GraphQL complex type is only valid if all its fields are uniquely named.`,
526
591
  requiresSchema: false,
527
592
  }), validationToRule('unique-input-field-names', 'UniqueInputFieldNames', {
593
+ category: 'Operations',
528
594
  description: `A GraphQL input object value is only valid if all supplied fields are uniquely named.`,
529
595
  requiresSchema: false,
530
596
  }), validationToRule('unique-operation-types', 'UniqueOperationTypes', {
597
+ category: 'Schema',
531
598
  description: `A GraphQL document is only valid if it has only one type per operation.`,
532
599
  requiresSchema: false,
533
600
  }), validationToRule('unique-type-names', 'UniqueTypeNames', {
601
+ category: 'Schema',
534
602
  description: `A GraphQL document is only valid if all defined types have unique names.`,
535
603
  requiresSchema: false,
536
604
  }), validationToRule('unique-variable-names', 'UniqueVariableNames', {
605
+ category: 'Operations',
537
606
  description: `A GraphQL operation is only valid if all its variables are uniquely named.`,
538
607
  }), validationToRule('value-literals-of-correct-type', 'ValuesOfCorrectType', {
608
+ category: 'Operations',
539
609
  description: `A GraphQL document is only valid if all value literals are of the type expected at their position.`,
540
610
  }), validationToRule('variables-are-input-types', 'VariablesAreInputTypes', {
611
+ category: 'Operations',
541
612
  description: `A GraphQL operation is only valid if all the variables it defines are of input types (scalar, enum, or input object).`,
542
613
  }), validationToRule('variables-in-allowed-position', 'VariablesInAllowedPosition', {
614
+ category: 'Operations',
543
615
  description: `Variables passed to field arguments conform to type.`,
544
616
  }));
545
617
 
@@ -565,7 +637,7 @@ const rule = {
565
637
  meta: {
566
638
  type: 'suggestion',
567
639
  docs: {
568
- category: 'Best Practices',
640
+ category: ['Schema', 'Operations'],
569
641
  description: 'Enforce arrange in alphabetical order for type fields, enum values, input object fields, operation selections and more.',
570
642
  url: 'https://github.com/dotansimha/graphql-eslint/blob/master/docs/rules/alphabetize.md',
571
643
  examples: [
@@ -644,15 +716,22 @@ const rule = {
644
716
  `,
645
717
  },
646
718
  ],
647
- optionsForConfig: [
648
- {
649
- fields: fieldsEnum,
650
- values: valuesEnum,
651
- selections: selectionsEnum,
652
- variables: variablesEnum,
653
- arguments: argumentsEnum,
654
- },
655
- ],
719
+ configOptions: {
720
+ schema: [
721
+ {
722
+ fields: fieldsEnum,
723
+ values: valuesEnum,
724
+ arguments: argumentsEnum,
725
+ },
726
+ ],
727
+ operations: [
728
+ {
729
+ selections: selectionsEnum,
730
+ variables: variablesEnum,
731
+ arguments: [graphql.Kind.FIELD, graphql.Kind.DIRECTIVE],
732
+ },
733
+ ],
734
+ },
656
735
  },
657
736
  messages: {
658
737
  [ALPHABETIZE]: '"{{ currName }}" should be before "{{ prevName }}"',
@@ -817,34 +896,32 @@ const rule$1 = {
817
896
  },
818
897
  ],
819
898
  description: 'Require all comments to follow the same style (either block or inline).',
820
- category: 'Stylistic Issues',
899
+ category: 'Schema',
821
900
  url: 'https://github.com/dotansimha/graphql-eslint/blob/master/docs/rules/description-style.md',
901
+ recommended: true,
822
902
  },
823
903
  schema: [
824
904
  {
825
905
  type: 'object',
906
+ additionalProperties: false,
826
907
  properties: {
827
908
  style: {
828
- type: 'string',
829
909
  enum: ['block', 'inline'],
830
- default: 'inline',
910
+ default: 'block',
831
911
  },
832
912
  },
833
- additionalProperties: false,
834
913
  },
835
914
  ],
836
915
  },
837
916
  create(context) {
838
- const { style } = context.options[0] || { style: 'inline' };
839
- const wrongDescriptionType = style === 'block' ? 'inline' : 'block';
917
+ const { style = 'block' } = context.options[0] || {};
918
+ const isBlock = style === 'block';
840
919
  return {
841
- '[description.type="StringValue"]': node => {
842
- if (node.description.block !== (style === 'block')) {
843
- context.report({
844
- loc: getLocation(node.description.loc),
845
- message: `Unexpected ${wrongDescriptionType} description`,
846
- });
847
- }
920
+ [`.description[type=StringValue][block!=${isBlock}]`](node) {
921
+ context.report({
922
+ loc: getLocation(node.loc),
923
+ message: `Unexpected ${isBlock ? 'inline' : 'block'} description`,
924
+ });
848
925
  },
849
926
  };
850
927
  },
@@ -858,7 +935,7 @@ const rule$2 = {
858
935
  type: 'suggestion',
859
936
  docs: {
860
937
  description: 'Require mutation argument to be always called "input" and input type to be called Mutation name + "Input".\nUsing the same name for all input parameters will make your schemas easier to consume and more predictable. Using the same name as mutation for InputType will make it easier to find mutations that InputType belongs to.',
861
- category: 'Stylistic Issues',
938
+ category: 'Schema',
862
939
  url: 'https://github.com/dotansimha/graphql-eslint/blob/master/docs/rules/input-name.md',
863
940
  examples: [
864
941
  {
@@ -983,7 +1060,7 @@ const rule$3 = {
983
1060
  meta: {
984
1061
  type: 'suggestion',
985
1062
  docs: {
986
- category: 'Best Practices',
1063
+ category: 'Operations',
987
1064
  description: 'This rule allows you to enforce that the file name should match the operation name.',
988
1065
  url: `https://github.com/dotansimha/graphql-eslint/blob/master/docs/rules/match-document-filename.md`,
989
1066
  examples: [
@@ -1057,6 +1134,14 @@ const rule$3 = {
1057
1134
  `,
1058
1135
  },
1059
1136
  ],
1137
+ configOptions: [
1138
+ {
1139
+ query: CaseStyle.kebabCase,
1140
+ mutation: CaseStyle.kebabCase,
1141
+ subscription: CaseStyle.kebabCase,
1142
+ fragment: CaseStyle.kebabCase,
1143
+ },
1144
+ ],
1060
1145
  },
1061
1146
  messages: {
1062
1147
  [MATCH_EXTENSION]: `File extension "{{ fileExtension }}" don't match extension "{{ expectedFileExtension }}"`,
@@ -1065,27 +1150,29 @@ const rule$3 = {
1065
1150
  schema: {
1066
1151
  definitions: {
1067
1152
  asString: {
1068
- type: 'string',
1069
- description: `One of: ${CASE_STYLES.map(t => `\`${t}\``).join(', ')}`,
1070
1153
  enum: CASE_STYLES,
1154
+ description: `One of: ${CASE_STYLES.map(t => `\`${t}\``).join(', ')}`,
1071
1155
  },
1072
1156
  asObject: {
1073
1157
  type: 'object',
1158
+ additionalProperties: false,
1074
1159
  properties: {
1075
1160
  style: {
1076
- type: 'string',
1077
1161
  enum: CASE_STYLES,
1078
1162
  },
1163
+ suffix: {
1164
+ type: 'string',
1165
+ },
1079
1166
  },
1080
1167
  },
1081
1168
  },
1082
- $schema: 'http://json-schema.org/draft-04/schema#',
1083
1169
  type: 'array',
1170
+ maxItems: 1,
1084
1171
  items: {
1085
1172
  type: 'object',
1173
+ additionalProperties: false,
1086
1174
  properties: {
1087
1175
  fileExtension: {
1088
- type: 'string',
1089
1176
  enum: ACCEPTED_EXTENSIONS,
1090
1177
  },
1091
1178
  query: schemaOption,
@@ -1160,13 +1247,7 @@ const rule$3 = {
1160
1247
  },
1161
1248
  };
1162
1249
 
1163
- const FIELDS_KINDS = [
1164
- graphql.Kind.FIELD_DEFINITION,
1165
- graphql.Kind.INPUT_VALUE_DEFINITION,
1166
- graphql.Kind.VARIABLE_DEFINITION,
1167
- graphql.Kind.ARGUMENT,
1168
- graphql.Kind.DIRECTIVE_DEFINITION,
1169
- ];
1250
+ const FIELDS_KINDS = [graphql.Kind.FIELD_DEFINITION, graphql.Kind.INPUT_VALUE_DEFINITION, graphql.Kind.ARGUMENT, graphql.Kind.DIRECTIVE_DEFINITION];
1170
1251
  const KindToDisplayName = {
1171
1252
  // types
1172
1253
  [graphql.Kind.OBJECT_TYPE_DEFINITION]: 'Type',
@@ -1178,13 +1259,13 @@ const KindToDisplayName = {
1178
1259
  // fields
1179
1260
  [graphql.Kind.FIELD_DEFINITION]: 'Field',
1180
1261
  [graphql.Kind.INPUT_VALUE_DEFINITION]: 'Input property',
1181
- [graphql.Kind.VARIABLE_DEFINITION]: 'Variable',
1182
1262
  [graphql.Kind.ARGUMENT]: 'Argument',
1183
1263
  [graphql.Kind.DIRECTIVE_DEFINITION]: 'Directive',
1184
1264
  // rest
1185
1265
  [graphql.Kind.ENUM_VALUE_DEFINITION]: 'Enumeration value',
1186
1266
  [graphql.Kind.OPERATION_DEFINITION]: 'Operation',
1187
1267
  [graphql.Kind.FRAGMENT_DEFINITION]: 'Fragment',
1268
+ [graphql.Kind.VARIABLE_DEFINITION]: 'Variable',
1188
1269
  };
1189
1270
  const StyleToRegex = {
1190
1271
  camelCase: /^[a-z][\dA-Za-z]*$/,
@@ -1202,7 +1283,7 @@ const rule$4 = {
1202
1283
  type: 'suggestion',
1203
1284
  docs: {
1204
1285
  description: 'Require names to follow specified conventions.',
1205
- category: 'Best Practices',
1286
+ category: ['Schema', 'Operations'],
1206
1287
  recommended: true,
1207
1288
  url: 'https://github.com/dotansimha/graphql-eslint/blob/master/docs/rules/naming-convention.md',
1208
1289
  examples: [
@@ -1213,6 +1294,24 @@ const rule$4 = {
1213
1294
  type user {
1214
1295
  first_name: String!
1215
1296
  }
1297
+ `,
1298
+ },
1299
+ {
1300
+ title: 'Incorrect',
1301
+ usage: [{ FragmentDefinition: { style: 'PascalCase', forbiddenSuffixes: ['Fragment'] } }],
1302
+ code: /* GraphQL */ `
1303
+ fragment UserFragment on User {
1304
+ # ...
1305
+ }
1306
+ `,
1307
+ },
1308
+ {
1309
+ title: 'Incorrect',
1310
+ usage: [{ 'FieldDefinition[parent.name.value=Query]': { forbiddenPrefixes: ['get'] } }],
1311
+ code: /* GraphQL */ `
1312
+ type Query {
1313
+ getUsers: [User!]!
1314
+ }
1216
1315
  `,
1217
1316
  },
1218
1317
  {
@@ -1224,23 +1323,31 @@ const rule$4 = {
1224
1323
  }
1225
1324
  `,
1226
1325
  },
1227
- ],
1228
- optionsForConfig: [
1229
1326
  {
1230
- types: 'PascalCase',
1231
- fields: 'camelCase',
1232
- overrides: {
1327
+ title: 'Correct',
1328
+ usage: [{ FragmentDefinition: { style: 'PascalCase', forbiddenSuffixes: ['Fragment'] } }],
1329
+ code: /* GraphQL */ `
1330
+ fragment UserFields on User {
1331
+ # ...
1332
+ }
1333
+ `,
1334
+ },
1335
+ {
1336
+ title: 'Correct',
1337
+ usage: [{ 'FieldDefinition[parent.name.value=Query]': { forbiddenPrefixes: ['get'] } }],
1338
+ code: /* GraphQL */ `
1339
+ type Query {
1340
+ users: [User!]!
1341
+ }
1342
+ `,
1343
+ },
1344
+ ],
1345
+ configOptions: {
1346
+ schema: [
1347
+ {
1348
+ types: 'PascalCase',
1349
+ fields: 'camelCase',
1233
1350
  EnumValueDefinition: 'UPPER_CASE',
1234
- OperationDefinition: {
1235
- style: 'PascalCase',
1236
- forbiddenPrefixes: ['Query', 'Mutation', 'Subscription', 'Get'],
1237
- forbiddenSuffixes: ['Query', 'Mutation', 'Subscription'],
1238
- },
1239
- FragmentDefinition: {
1240
- style: 'PascalCase',
1241
- forbiddenPrefixes: ['Fragment'],
1242
- forbiddenSuffixes: ['Fragment'],
1243
- },
1244
1351
  'FieldDefinition[parent.name.value=Query]': {
1245
1352
  forbiddenPrefixes: ['query', 'get'],
1246
1353
  forbiddenSuffixes: ['Query'],
@@ -1254,8 +1361,23 @@ const rule$4 = {
1254
1361
  forbiddenSuffixes: ['Subscription'],
1255
1362
  },
1256
1363
  },
1257
- },
1258
- ],
1364
+ ],
1365
+ operations: [
1366
+ {
1367
+ VariableDefinition: 'camelCase',
1368
+ OperationDefinition: {
1369
+ style: 'PascalCase',
1370
+ forbiddenPrefixes: ['Query', 'Mutation', 'Subscription', 'Get'],
1371
+ forbiddenSuffixes: ['Query', 'Mutation', 'Subscription'],
1372
+ },
1373
+ FragmentDefinition: {
1374
+ style: 'PascalCase',
1375
+ forbiddenPrefixes: ['Fragment'],
1376
+ forbiddenSuffixes: ['Fragment'],
1377
+ },
1378
+ },
1379
+ ],
1380
+ },
1259
1381
  },
1260
1382
  schema: {
1261
1383
  definitions: {
@@ -1293,12 +1415,19 @@ const rule$4 = {
1293
1415
  properties: {
1294
1416
  types: {
1295
1417
  ...schemaOption$1,
1296
- description: `Includes:\n\n${TYPES_KINDS.map(kind => `- [${kind}](https://spec.graphql.org/October2021/#${kind})`).join('\n')}`,
1418
+ description: `Includes:\n\n${TYPES_KINDS.map(kind => `- \`${kind}\``).join('\n')}`,
1297
1419
  },
1298
1420
  fields: {
1299
1421
  ...schemaOption$1,
1300
- description: `Includes:\n\n${FIELDS_KINDS.map(kind => `- [${kind}](https://spec.graphql.org/October2021/#${kind})`).join('\n')}`,
1422
+ description: `Includes:\n\n${FIELDS_KINDS.map(kind => `- \`${kind}\``).join('\n')}`,
1301
1423
  },
1424
+ ...Object.fromEntries(ALLOWED_KINDS.map(kind => [
1425
+ kind,
1426
+ {
1427
+ ...schemaOption$1,
1428
+ description: `Read more about this kind on [spec.graphql.org](https://spec.graphql.org/October2021/#${kind}).`,
1429
+ },
1430
+ ])),
1302
1431
  allowLeadingUnderscore: {
1303
1432
  type: 'boolean',
1304
1433
  default: false,
@@ -1307,35 +1436,27 @@ const rule$4 = {
1307
1436
  type: 'boolean',
1308
1437
  default: false,
1309
1438
  },
1310
- overrides: {
1311
- type: 'object',
1312
- additionalProperties: false,
1313
- description: [
1314
- 'May contain the following `ASTNode` names:',
1315
- '',
1316
- ...ALLOWED_KINDS.map(kind => `- [${kind}](https://spec.graphql.org/October2021/#${kind})`),
1317
- '',
1318
- "> It's also possible to use a [`selector`](https://eslint.org/docs/developer-guide/selectors) that starts with `ASTNode` name",
1319
- '>',
1320
- '> Example: pattern property `FieldDefinition[parent.name.value=Query]` will match only fields for type `Query`',
1321
- ].join('\n'),
1322
- patternProperties: {
1323
- [`^(${ALLOWED_KINDS.join('|')})(.+)?$`]: schemaOption$1,
1324
- },
1325
- },
1326
1439
  },
1440
+ patternProperties: {
1441
+ [`^(${ALLOWED_KINDS.join('|')})(.+)?$`]: schemaOption$1,
1442
+ },
1443
+ description: [
1444
+ "> It's possible to use a [`selector`](https://eslint.org/docs/developer-guide/selectors) that starts with allowed `ASTNode` names which are described below.",
1445
+ '>',
1446
+ '> Paste or drop code into the editor in [ASTExplorer](https://astexplorer.net) and inspect the generated AST to compose your selector.',
1447
+ '>',
1448
+ '> Example: pattern property `FieldDefinition[parent.name.value=Query]` will match only fields for type `Query`.',
1449
+ ].join('\n'),
1327
1450
  },
1328
1451
  },
1329
1452
  },
1330
1453
  create(context) {
1331
- const options = {
1332
- overrides: {},
1333
- ...context.options[0],
1334
- };
1454
+ const options = context.options[0] || {};
1455
+ const { allowLeadingUnderscore, allowTrailingUnderscore, types, fields, ...restOptions } = options;
1335
1456
  function normalisePropertyOption(kind) {
1336
- let style = options.overrides[kind];
1457
+ let style = options[kind];
1337
1458
  if (!style) {
1338
- style = TYPES_KINDS.includes(kind) ? options.types : options.fields;
1459
+ style = TYPES_KINDS.includes(kind) ? types : fields;
1339
1460
  }
1340
1461
  return typeof style === 'object' ? style : { style };
1341
1462
  }
@@ -1356,10 +1477,10 @@ const rule$4 = {
1356
1477
  }
1357
1478
  function getErrorMessage() {
1358
1479
  let name = nodeName;
1359
- if (options.allowLeadingUnderscore) {
1480
+ if (allowLeadingUnderscore) {
1360
1481
  name = name.replace(/^_*/, '');
1361
1482
  }
1362
- if (options.allowTrailingUnderscore) {
1483
+ if (allowTrailingUnderscore) {
1363
1484
  name = name.replace(/_*$/, '');
1364
1485
  }
1365
1486
  if (prefix && !name.startsWith(prefix)) {
@@ -1393,15 +1514,13 @@ const rule$4 = {
1393
1514
  });
1394
1515
  };
1395
1516
  const listeners = {};
1396
- if (!options.allowLeadingUnderscore) {
1517
+ if (!allowLeadingUnderscore) {
1397
1518
  listeners['Name[value=/^_/]:matches([parent.kind!=Field], [parent.kind=Field][parent.alias])'] = checkUnderscore;
1398
1519
  }
1399
- if (!options.allowTrailingUnderscore) {
1520
+ if (!allowTrailingUnderscore) {
1400
1521
  listeners['Name[value=/_$/]:matches([parent.kind!=Field], [parent.kind=Field][parent.alias])'] = checkUnderscore;
1401
1522
  }
1402
- const selectors = new Set([options.types && TYPES_KINDS, options.fields && FIELDS_KINDS, Object.keys(options.overrides)]
1403
- .flat()
1404
- .filter(Boolean));
1523
+ const selectors = new Set([types && TYPES_KINDS, fields && FIELDS_KINDS, Object.keys(restOptions)].flat().filter(Boolean));
1405
1524
  for (const selector of selectors) {
1406
1525
  listeners[selector] = checkNode(selector);
1407
1526
  }
@@ -1414,7 +1533,7 @@ const rule$5 = {
1414
1533
  meta: {
1415
1534
  type: 'suggestion',
1416
1535
  docs: {
1417
- category: 'Best Practices',
1536
+ category: 'Operations',
1418
1537
  description: 'Require name for your GraphQL operations. This is useful since most GraphQL client libraries are using the operation name for caching purposes.',
1419
1538
  recommended: true,
1420
1539
  url: 'https://github.com/dotansimha/graphql-eslint/blob/master/docs/rules/no-anonymous-operations.md',
@@ -1463,7 +1582,7 @@ const rule$6 = {
1463
1582
  type: 'suggestion',
1464
1583
  docs: {
1465
1584
  url: 'https://github.com/dotansimha/graphql-eslint/blob/master/docs/rules/no-case-insensitive-enum-values-duplicates.md',
1466
- category: 'Best Practices',
1585
+ category: 'Schema',
1467
1586
  recommended: true,
1468
1587
  description: 'Disallow case-insensitive enum values duplicates.',
1469
1588
  examples: [
@@ -1518,7 +1637,7 @@ const rule$7 = {
1518
1637
  meta: {
1519
1638
  type: 'suggestion',
1520
1639
  docs: {
1521
- category: 'Best Practices',
1640
+ category: 'Operations',
1522
1641
  description: `Enforce that deprecated fields or enum values are not in use by operations.`,
1523
1642
  url: `https://github.com/dotansimha/graphql-eslint/blob/master/docs/rules/no-deprecated.md`,
1524
1643
  requiresSchema: true,
@@ -1584,6 +1703,7 @@ const rule$7 = {
1584
1703
  `,
1585
1704
  },
1586
1705
  ],
1706
+ recommended: true,
1587
1707
  },
1588
1708
  messages: {
1589
1709
  [NO_DEPRECATED]: `This {{ type }} is marked as deprecated in your GraphQL schema {{ reason }}`,
@@ -1636,8 +1756,9 @@ const rule$8 = {
1636
1756
  type: 'suggestion',
1637
1757
  docs: {
1638
1758
  description: `Checks for duplicate fields in selection set, variables in operation definition, or in arguments set of a field.`,
1639
- category: 'Stylistic Issues',
1759
+ category: 'Operations',
1640
1760
  url: 'https://github.com/dotansimha/graphql-eslint/blob/master/docs/rules/no-duplicate-fields.md',
1761
+ recommended: true,
1641
1762
  examples: [
1642
1763
  {
1643
1764
  title: 'Incorrect',
@@ -1738,7 +1859,7 @@ const rule$9 = {
1738
1859
  },
1739
1860
  docs: {
1740
1861
  description: 'Requires to use `"""` or `"` for adding a GraphQL description instead of `#`.\nAllows to use hashtag for comments, as long as it\'s not attached to an AST definition.',
1741
- category: 'Best Practices',
1862
+ category: 'Schema',
1742
1863
  url: 'https://github.com/dotansimha/graphql-eslint/blob/master/docs/rules/no-hashtag-description.md',
1743
1864
  examples: [
1744
1865
  {
@@ -1775,6 +1896,7 @@ const rule$9 = {
1775
1896
  `,
1776
1897
  },
1777
1898
  ],
1899
+ recommended: true,
1778
1900
  },
1779
1901
  type: 'suggestion',
1780
1902
  schema: [],
@@ -1803,18 +1925,18 @@ const rule$9 = {
1803
1925
  },
1804
1926
  };
1805
1927
 
1806
- const ROOT_TYPES = ['query', 'mutation', 'subscription'];
1928
+ const ROOT_TYPES = ['mutation', 'subscription'];
1807
1929
  const rule$a = {
1808
1930
  meta: {
1809
1931
  type: 'suggestion',
1810
1932
  docs: {
1811
- category: 'Validation',
1812
- description: 'Disallow using root types for `read-only` or `write-only` schemas.',
1933
+ category: 'Schema',
1934
+ description: 'Disallow using root types `mutation` and/or `subscription`.',
1813
1935
  url: 'https://github.com/dotansimha/graphql-eslint/blob/master/docs/rules/no-root-type.md',
1814
1936
  requiresSchema: true,
1815
1937
  examples: [
1816
1938
  {
1817
- title: 'Incorrect (`read-only` schema)',
1939
+ title: 'Incorrect',
1818
1940
  usage: [{ disallow: ['mutation', 'subscription'] }],
1819
1941
  code: /* GraphQL */ `
1820
1942
  type Mutation {
@@ -1823,16 +1945,7 @@ const rule$a = {
1823
1945
  `,
1824
1946
  },
1825
1947
  {
1826
- title: 'Incorrect (`write-only` schema)',
1827
- usage: [{ disallow: ['query'] }],
1828
- code: /* GraphQL */ `
1829
- type Query {
1830
- users: [User!]!
1831
- }
1832
- `,
1833
- },
1834
- {
1835
- title: 'Correct (`read-only` schema)',
1948
+ title: 'Correct',
1836
1949
  usage: [{ disallow: ['mutation', 'subscription'] }],
1837
1950
  code: /* GraphQL */ `
1838
1951
  type Query {
@@ -1841,7 +1954,6 @@ const rule$a = {
1841
1954
  `,
1842
1955
  },
1843
1956
  ],
1844
- optionsForConfig: [{ disallow: ['subscription'] }],
1845
1957
  },
1846
1958
  schema: {
1847
1959
  type: 'array',
@@ -1868,7 +1980,6 @@ const rule$a = {
1868
1980
  const schema = requireGraphQLSchemaFromContext('no-root-type', context);
1869
1981
  const disallow = new Set(context.options[0].disallow);
1870
1982
  const rootTypeNames = [
1871
- disallow.has('query') && schema.getQueryType(),
1872
1983
  disallow.has('mutation') && schema.getMutationType(),
1873
1984
  disallow.has('subscription') && schema.getSubscriptionType(),
1874
1985
  ]
@@ -1898,7 +2009,7 @@ const rule$b = {
1898
2009
  meta: {
1899
2010
  type: 'suggestion',
1900
2011
  docs: {
1901
- category: 'Best Practices',
2012
+ category: 'Schema',
1902
2013
  description: 'Avoid scalar result type on mutation type to make sure to return a valid state.',
1903
2014
  url: 'https://github.com/dotansimha/graphql-eslint/blob/master/docs/rules/no-scalar-result-type-on-mutation.md',
1904
2015
  requiresSchema: true,
@@ -1955,7 +2066,7 @@ const rule$c = {
1955
2066
  meta: {
1956
2067
  type: 'suggestion',
1957
2068
  docs: {
1958
- category: 'Best Practices',
2069
+ category: 'Schema',
1959
2070
  description: 'Enforces users to avoid using the type name in a field name while defining your schema.',
1960
2071
  recommended: true,
1961
2072
  url: 'https://github.com/dotansimha/graphql-eslint/blob/master/docs/rules/no-typename-prefix.md',
@@ -2011,11 +2122,11 @@ const RULE_NAME = 'no-unreachable-types';
2011
2122
  const rule$d = {
2012
2123
  meta: {
2013
2124
  messages: {
2014
- [UNREACHABLE_TYPE]: `Type "{{ typeName }}" is unreachable`,
2125
+ [UNREACHABLE_TYPE]: 'Type "{{ typeName }}" is unreachable',
2015
2126
  },
2016
2127
  docs: {
2017
2128
  description: `Requires all types to be reachable at some level by root level fields.`,
2018
- category: 'Best Practices',
2129
+ category: 'Schema',
2019
2130
  url: `https://github.com/dotansimha/graphql-eslint/blob/master/docs/rules/${RULE_NAME}.md`,
2020
2131
  requiresSchema: true,
2021
2132
  examples: [
@@ -2046,6 +2157,7 @@ const rule$d = {
2046
2157
  `,
2047
2158
  },
2048
2159
  ],
2160
+ recommended: true,
2049
2161
  },
2050
2162
  fixable: 'code',
2051
2163
  type: 'suggestion',
@@ -2091,7 +2203,7 @@ const rule$e = {
2091
2203
  },
2092
2204
  docs: {
2093
2205
  description: `Requires all fields to be used at some level by siblings operations.`,
2094
- category: 'Best Practices',
2206
+ category: 'Schema',
2095
2207
  url: `https://github.com/dotansimha/graphql-eslint/blob/master/docs/rules/${RULE_NAME$1}.md`,
2096
2208
  requiresSiblings: true,
2097
2209
  requiresSchema: true,
@@ -2277,7 +2389,7 @@ const rule$f = {
2277
2389
  meta: {
2278
2390
  type: 'suggestion',
2279
2391
  docs: {
2280
- category: 'Best Practices',
2392
+ category: 'Schema',
2281
2393
  description: 'Require deletion date on `@deprecated` directive. Suggest removing deprecated things after deprecated date.',
2282
2394
  url: 'https://github.com/dotansimha/graphql-eslint/blob/master/docs/rules/require-deprecation-date.md',
2283
2395
  examples: [
@@ -2380,7 +2492,7 @@ const rule$g = {
2380
2492
  meta: {
2381
2493
  docs: {
2382
2494
  description: `Require all deprecation directives to specify a reason.`,
2383
- category: 'Best Practices',
2495
+ category: 'Schema',
2384
2496
  url: `https://github.com/dotansimha/graphql-eslint/blob/master/docs/rules/require-deprecation-reason.md`,
2385
2497
  recommended: true,
2386
2498
  examples: [
@@ -2441,13 +2553,13 @@ const ALLOWED_KINDS$1 = [
2441
2553
  const rule$h = {
2442
2554
  meta: {
2443
2555
  docs: {
2444
- category: 'Best Practices',
2556
+ category: 'Schema',
2445
2557
  description: 'Enforce descriptions in your type definitions.',
2446
2558
  url: 'https://github.com/dotansimha/graphql-eslint/blob/master/docs/rules/require-description.md',
2447
2559
  examples: [
2448
2560
  {
2449
2561
  title: 'Incorrect',
2450
- usage: [{ types: true, overrides: { FieldDefinition: true } }],
2562
+ usage: [{ types: true, FieldDefinition: true }],
2451
2563
  code: /* GraphQL */ `
2452
2564
  type someTypeName {
2453
2565
  name: String
@@ -2456,7 +2568,7 @@ const rule$h = {
2456
2568
  },
2457
2569
  {
2458
2570
  title: 'Correct',
2459
- usage: [{ types: true, overrides: { FieldDefinition: true } }],
2571
+ usage: [{ types: true, FieldDefinition: true }],
2460
2572
  code: /* GraphQL */ `
2461
2573
  """
2462
2574
  Some type description
@@ -2470,14 +2582,13 @@ const rule$h = {
2470
2582
  `,
2471
2583
  },
2472
2584
  ],
2473
- optionsForConfig: [
2585
+ configOptions: [
2474
2586
  {
2475
2587
  types: true,
2476
- overrides: {
2477
- [graphql.Kind.DIRECTIVE_DEFINITION]: true,
2478
- },
2588
+ [graphql.Kind.DIRECTIVE_DEFINITION]: true,
2479
2589
  },
2480
2590
  ],
2591
+ recommended: true,
2481
2592
  },
2482
2593
  type: 'suggestion',
2483
2594
  messages: {
@@ -2494,22 +2605,23 @@ const rule$h = {
2494
2605
  properties: {
2495
2606
  types: {
2496
2607
  type: 'boolean',
2497
- description: `Includes:\n\n${TYPES_KINDS.map(kind => `- [${kind}](https://spec.graphql.org/October2021/#${kind})`).join('\n')}`,
2498
- },
2499
- overrides: {
2500
- type: 'object',
2501
- description: 'Configuration for precise `ASTNode`',
2502
- additionalProperties: false,
2503
- properties: Object.fromEntries(ALLOWED_KINDS$1.map(kind => [kind, { type: 'boolean' }])),
2608
+ description: `Includes:\n\n${TYPES_KINDS.map(kind => `- \`${kind}\``).join('\n')}`,
2504
2609
  },
2610
+ ...Object.fromEntries([...ALLOWED_KINDS$1].sort().map(kind => [
2611
+ kind,
2612
+ {
2613
+ type: 'boolean',
2614
+ description: `Read more about this kind on [spec.graphql.org](https://spec.graphql.org/October2021/#${kind}).`,
2615
+ },
2616
+ ])),
2505
2617
  },
2506
2618
  },
2507
2619
  },
2508
2620
  },
2509
2621
  create(context) {
2510
- const { types, overrides = {} } = context.options[0];
2622
+ const { types, ...restOptions } = context.options[0];
2511
2623
  const kinds = new Set(types ? TYPES_KINDS : []);
2512
- for (const [kind, isEnabled] of Object.entries(overrides)) {
2624
+ for (const [kind, isEnabled] of Object.entries(restOptions)) {
2513
2625
  if (isEnabled) {
2514
2626
  kinds.add(kind);
2515
2627
  }
@@ -2541,7 +2653,7 @@ const rule$i = {
2541
2653
  meta: {
2542
2654
  type: 'suggestion',
2543
2655
  docs: {
2544
- category: 'Best Practices',
2656
+ category: 'Schema',
2545
2657
  description: 'Allow the client in one round-trip not only to call mutation but also to get a wagon of data to update their application.\n> Currently, no errors are reported for result type `union`, `interface` and `scalar`.',
2546
2658
  url: `https://github.com/dotansimha/graphql-eslint/blob/master/docs/rules/${RULE_NAME$2}.md`,
2547
2659
  requiresSchema: true,
@@ -2709,9 +2821,9 @@ const rule$j = {
2709
2821
  meta: {
2710
2822
  type: 'suggestion',
2711
2823
  docs: {
2712
- category: 'Best Practices',
2713
- description: `Enforce selecting specific fields when they are available on the GraphQL type.`,
2714
- url: `https://github.com/dotansimha/graphql-eslint/blob/master/docs/rules/require-id-when-available.md`,
2824
+ category: 'Operations',
2825
+ description: 'Enforce selecting specific fields when they are available on the GraphQL type.',
2826
+ url: 'https://github.com/dotansimha/graphql-eslint/blob/master/docs/rules/require-id-when-available.md',
2715
2827
  requiresSchema: true,
2716
2828
  requiresSiblings: true,
2717
2829
  examples: [
@@ -2751,17 +2863,17 @@ const rule$j = {
2751
2863
  `,
2752
2864
  },
2753
2865
  ],
2866
+ recommended: true,
2754
2867
  },
2755
2868
  messages: {
2756
- [REQUIRE_ID_WHEN_AVAILABLE]: `Field "{{ fieldName }}" must be selected when it's available on a type. Please make sure to include it in your selection set!\nIf you are using fragments, make sure that all used fragments {{checkedFragments}} specifies the field "{{ fieldName }}".`,
2869
+ [REQUIRE_ID_WHEN_AVAILABLE]: `Field "{{ fieldName }}" must be selected when it's available on a type. Please make sure to include it in your selection set!\nIf you are using fragments, make sure that all used fragments {{ checkedFragments }} specifies the field "{{ fieldName }}".`,
2757
2870
  },
2758
2871
  schema: {
2759
2872
  type: 'array',
2760
- additionalItems: false,
2761
- minItems: 0,
2762
2873
  maxItems: 1,
2763
2874
  items: {
2764
2875
  type: 'object',
2876
+ additionalProperties: false,
2765
2877
  properties: {
2766
2878
  fieldName: {
2767
2879
  type: 'string',
@@ -2844,9 +2956,9 @@ const rule$j = {
2844
2956
  const rule$k = {
2845
2957
  meta: {
2846
2958
  docs: {
2847
- category: 'Best Practices',
2959
+ category: 'Operations',
2848
2960
  description: `Limit the complexity of the GraphQL operations solely by their depth. Based on [graphql-depth-limit](https://github.com/stems/graphql-depth-limit).`,
2849
- url: `https://github.com/dotansimha/graphql-eslint/blob/master/docs/rules/selection-set-depth.md`,
2961
+ url: 'https://github.com/dotansimha/graphql-eslint/blob/master/docs/rules/selection-set-depth.md',
2850
2962
  requiresSiblings: true,
2851
2963
  examples: [
2852
2964
  {
@@ -2889,22 +3001,26 @@ const rule$k = {
2889
3001
  `,
2890
3002
  },
2891
3003
  ],
3004
+ recommended: true,
3005
+ configOptions: [{ maxDepth: 7 }],
2892
3006
  },
2893
3007
  type: 'suggestion',
2894
3008
  schema: {
2895
3009
  type: 'array',
2896
- additionalItems: false,
2897
3010
  minItems: 1,
2898
3011
  maxItems: 1,
2899
3012
  items: {
2900
3013
  type: 'object',
2901
- require: ['maxDepth'],
3014
+ additionalProperties: false,
3015
+ required: ['maxDepth'],
2902
3016
  properties: {
2903
3017
  maxDepth: {
2904
3018
  type: 'number',
2905
3019
  },
2906
3020
  ignore: {
2907
3021
  type: 'array',
3022
+ uniqueItems: true,
3023
+ minItems: 1,
2908
3024
  items: {
2909
3025
  type: 'string',
2910
3026
  },
@@ -2968,7 +3084,7 @@ const rule$l = {
2968
3084
  type: 'suggestion',
2969
3085
  docs: {
2970
3086
  description: 'Requires output types to have one unique identifier unless they do not have a logical one. Exceptions can be used to ignore output types that do not have unique identifiers.',
2971
- category: 'Best Practices',
3087
+ category: 'Schema',
2972
3088
  recommended: true,
2973
3089
  url: 'https://github.com/dotansimha/graphql-eslint/blob/master/docs/rules/strict-id-in-types.md',
2974
3090
  examples: [
@@ -3028,13 +3144,15 @@ const rule$l = {
3028
3144
  ],
3029
3145
  },
3030
3146
  schema: {
3031
- $schema: 'http://json-schema.org/draft-04/schema#',
3032
3147
  type: 'array',
3148
+ maxItems: 1,
3033
3149
  items: {
3034
3150
  type: 'object',
3151
+ additionalProperties: false,
3035
3152
  properties: {
3036
3153
  acceptedIdNames: {
3037
3154
  type: 'array',
3155
+ uniqueItems: true,
3038
3156
  items: {
3039
3157
  type: 'string',
3040
3158
  },
@@ -3042,6 +3160,7 @@ const rule$l = {
3042
3160
  },
3043
3161
  acceptedIdTypes: {
3044
3162
  type: 'array',
3163
+ uniqueItems: true,
3045
3164
  items: {
3046
3165
  type: 'string',
3047
3166
  },
@@ -3052,19 +3171,21 @@ const rule$l = {
3052
3171
  properties: {
3053
3172
  types: {
3054
3173
  type: 'array',
3174
+ uniqueItems: true,
3175
+ minItems: 1,
3055
3176
  description: 'This is used to exclude types with names that match one of the specified values.',
3056
3177
  items: {
3057
3178
  type: 'string',
3058
3179
  },
3059
- default: [],
3060
3180
  },
3061
3181
  suffixes: {
3062
3182
  type: 'array',
3183
+ uniqueItems: true,
3184
+ minItems: 1,
3063
3185
  description: 'This is used to exclude types with names with suffixes that match one of the specified values.',
3064
3186
  items: {
3065
3187
  type: 'string',
3066
3188
  },
3067
- default: [],
3068
3189
  },
3069
3190
  },
3070
3191
  },
@@ -3144,7 +3265,7 @@ const rule$m = {
3144
3265
  meta: {
3145
3266
  type: 'suggestion',
3146
3267
  docs: {
3147
- category: 'Best Practices',
3268
+ category: 'Operations',
3148
3269
  description: `Enforce unique fragment names across your project.`,
3149
3270
  url: `https://github.com/dotansimha/graphql-eslint/blob/master/docs/rules/${RULE_NAME$3}.md`,
3150
3271
  requiresSiblings: true,
@@ -3203,7 +3324,7 @@ const rule$n = {
3203
3324
  meta: {
3204
3325
  type: 'suggestion',
3205
3326
  docs: {
3206
- category: 'Best Practices',
3327
+ category: 'Operations',
3207
3328
  description: `Enforce unique operation names across your project.`,
3208
3329
  url: `https://github.com/dotansimha/graphql-eslint/blob/master/docs/rules/${RULE_NAME$4}.md`,
3209
3330
  requiresSiblings: true,