@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.mjs CHANGED
@@ -12,12 +12,88 @@ import { CodeFileLoader } from '@graphql-tools/code-file-loader';
12
12
  import { RuleTester, Linter } from 'eslint';
13
13
  import { codeFrameColumns } from '@babel/code-frame';
14
14
 
15
+ const base = {
16
+ parser: '@graphql-eslint/eslint-plugin',
17
+ plugins: ['@graphql-eslint'],
18
+ };
19
+
15
20
  /*
16
21
  * 🚨 IMPORTANT! Do not manually modify this file. Run: `yarn generate-configs`
17
22
  */
18
- const recommendedConfig = {
19
- parser: '@graphql-eslint/eslint-plugin',
20
- plugins: ['@graphql-eslint'],
23
+ const schemaRecommendedConfig = {
24
+ extends: ['plugin:@graphql-eslint/base'],
25
+ rules: {
26
+ '@graphql-eslint/description-style': 'error',
27
+ '@graphql-eslint/known-argument-names': 'error',
28
+ '@graphql-eslint/known-directives': 'error',
29
+ '@graphql-eslint/known-type-names': 'error',
30
+ '@graphql-eslint/lone-schema-definition': 'error',
31
+ '@graphql-eslint/naming-convention': [
32
+ 'error',
33
+ {
34
+ types: 'PascalCase',
35
+ fields: 'camelCase',
36
+ EnumValueDefinition: 'UPPER_CASE',
37
+ 'FieldDefinition[parent.name.value=Query]': {
38
+ forbiddenPrefixes: ['query', 'get'],
39
+ forbiddenSuffixes: ['Query'],
40
+ },
41
+ 'FieldDefinition[parent.name.value=Mutation]': {
42
+ forbiddenPrefixes: ['mutation'],
43
+ forbiddenSuffixes: ['Mutation'],
44
+ },
45
+ 'FieldDefinition[parent.name.value=Subscription]': {
46
+ forbiddenPrefixes: ['subscription'],
47
+ forbiddenSuffixes: ['Subscription'],
48
+ },
49
+ },
50
+ ],
51
+ '@graphql-eslint/no-case-insensitive-enum-values-duplicates': 'error',
52
+ '@graphql-eslint/no-hashtag-description': 'error',
53
+ '@graphql-eslint/no-typename-prefix': 'error',
54
+ '@graphql-eslint/no-unreachable-types': 'error',
55
+ '@graphql-eslint/possible-type-extension': 'error',
56
+ '@graphql-eslint/provided-required-arguments': 'error',
57
+ '@graphql-eslint/require-deprecation-reason': 'error',
58
+ '@graphql-eslint/require-description': ['error', { types: true, DirectiveDefinition: true }],
59
+ '@graphql-eslint/strict-id-in-types': 'error',
60
+ '@graphql-eslint/unique-directive-names': 'error',
61
+ '@graphql-eslint/unique-directive-names-per-location': 'error',
62
+ '@graphql-eslint/unique-enum-value-names': 'error',
63
+ '@graphql-eslint/unique-field-definition-names': 'error',
64
+ '@graphql-eslint/unique-operation-types': 'error',
65
+ '@graphql-eslint/unique-type-names': 'error',
66
+ },
67
+ };
68
+
69
+ /*
70
+ * 🚨 IMPORTANT! Do not manually modify this file. Run: `yarn generate-configs`
71
+ */
72
+ const schemaAllConfig = {
73
+ extends: ['plugin:@graphql-eslint/base', 'plugin:@graphql-eslint/schema-recommended'],
74
+ rules: {
75
+ '@graphql-eslint/alphabetize': [
76
+ 'error',
77
+ {
78
+ fields: ['ObjectTypeDefinition', 'InterfaceTypeDefinition', 'InputObjectTypeDefinition'],
79
+ values: ['EnumTypeDefinition'],
80
+ arguments: ['FieldDefinition', 'Field', 'DirectiveDefinition', 'Directive'],
81
+ },
82
+ ],
83
+ '@graphql-eslint/input-name': 'error',
84
+ '@graphql-eslint/no-root-type': 'off',
85
+ '@graphql-eslint/no-scalar-result-type-on-mutation': 'error',
86
+ '@graphql-eslint/no-unused-fields': 'off',
87
+ '@graphql-eslint/require-deprecation-date': 'error',
88
+ '@graphql-eslint/require-field-of-type-query-in-mutation-result': 'error',
89
+ },
90
+ };
91
+
92
+ /*
93
+ * 🚨 IMPORTANT! Do not manually modify this file. Run: `yarn generate-configs`
94
+ */
95
+ const operationsRecommendedConfig = {
96
+ extends: ['plugin:@graphql-eslint/base'],
21
97
  rules: {
22
98
  '@graphql-eslint/executable-definitions': 'error',
23
99
  '@graphql-eslint/fields-on-correct-type': 'error',
@@ -27,58 +103,35 @@ const recommendedConfig = {
27
103
  '@graphql-eslint/known-fragment-names': 'error',
28
104
  '@graphql-eslint/known-type-names': 'error',
29
105
  '@graphql-eslint/lone-anonymous-operation': 'error',
30
- '@graphql-eslint/lone-schema-definition': 'error',
31
106
  '@graphql-eslint/naming-convention': [
32
107
  'error',
33
108
  {
34
- types: 'PascalCase',
35
- fields: 'camelCase',
36
- overrides: {
37
- EnumValueDefinition: 'UPPER_CASE',
38
- OperationDefinition: {
39
- style: 'PascalCase',
40
- forbiddenPrefixes: ['Query', 'Mutation', 'Subscription', 'Get'],
41
- forbiddenSuffixes: ['Query', 'Mutation', 'Subscription'],
42
- },
43
- FragmentDefinition: { style: 'PascalCase', forbiddenPrefixes: ['Fragment'], forbiddenSuffixes: ['Fragment'] },
44
- 'FieldDefinition[parent.name.value=Query]': {
45
- forbiddenPrefixes: ['query', 'get'],
46
- forbiddenSuffixes: ['Query'],
47
- },
48
- 'FieldDefinition[parent.name.value=Mutation]': {
49
- forbiddenPrefixes: ['mutation'],
50
- forbiddenSuffixes: ['Mutation'],
51
- },
52
- 'FieldDefinition[parent.name.value=Subscription]': {
53
- forbiddenPrefixes: ['subscription'],
54
- forbiddenSuffixes: ['Subscription'],
55
- },
109
+ VariableDefinition: 'camelCase',
110
+ OperationDefinition: {
111
+ style: 'PascalCase',
112
+ forbiddenPrefixes: ['Query', 'Mutation', 'Subscription', 'Get'],
113
+ forbiddenSuffixes: ['Query', 'Mutation', 'Subscription'],
56
114
  },
115
+ FragmentDefinition: { style: 'PascalCase', forbiddenPrefixes: ['Fragment'], forbiddenSuffixes: ['Fragment'] },
57
116
  },
58
117
  ],
59
118
  '@graphql-eslint/no-anonymous-operations': 'error',
60
- '@graphql-eslint/no-case-insensitive-enum-values-duplicates': 'error',
119
+ '@graphql-eslint/no-deprecated': 'error',
120
+ '@graphql-eslint/no-duplicate-fields': 'error',
61
121
  '@graphql-eslint/no-fragment-cycles': 'error',
62
- '@graphql-eslint/no-typename-prefix': 'error',
63
122
  '@graphql-eslint/no-undefined-variables': 'error',
64
123
  '@graphql-eslint/no-unused-fragments': 'error',
65
124
  '@graphql-eslint/no-unused-variables': 'error',
66
125
  '@graphql-eslint/one-field-subscriptions': 'error',
67
126
  '@graphql-eslint/overlapping-fields-can-be-merged': 'error',
68
127
  '@graphql-eslint/possible-fragment-spread': 'error',
69
- '@graphql-eslint/possible-type-extension': 'error',
70
128
  '@graphql-eslint/provided-required-arguments': 'error',
71
- '@graphql-eslint/require-deprecation-reason': 'error',
129
+ '@graphql-eslint/require-id-when-available': 'error',
72
130
  '@graphql-eslint/scalar-leafs': 'error',
73
- '@graphql-eslint/strict-id-in-types': 'error',
131
+ '@graphql-eslint/selection-set-depth': ['error', { maxDepth: 7 }],
74
132
  '@graphql-eslint/unique-argument-names': 'error',
75
- '@graphql-eslint/unique-directive-names': 'error',
76
133
  '@graphql-eslint/unique-directive-names-per-location': 'error',
77
- '@graphql-eslint/unique-enum-value-names': 'error',
78
- '@graphql-eslint/unique-field-definition-names': 'error',
79
134
  '@graphql-eslint/unique-input-field-names': 'error',
80
- '@graphql-eslint/unique-operation-types': 'error',
81
- '@graphql-eslint/unique-type-names': 'error',
82
135
  '@graphql-eslint/unique-variable-names': 'error',
83
136
  '@graphql-eslint/value-literals-of-correct-type': 'error',
84
137
  '@graphql-eslint/variables-are-input-types': 'error',
@@ -89,43 +142,32 @@ const recommendedConfig = {
89
142
  /*
90
143
  * 🚨 IMPORTANT! Do not manually modify this file. Run: `yarn generate-configs`
91
144
  */
92
- const allConfig = {
93
- ...recommendedConfig,
145
+ const operationsAllConfig = {
146
+ extends: ['plugin:@graphql-eslint/base', 'plugin:@graphql-eslint/operations-recommended'],
94
147
  rules: {
95
- ...recommendedConfig.rules,
96
148
  '@graphql-eslint/alphabetize': [
97
149
  'error',
98
150
  {
99
- fields: ['ObjectTypeDefinition', 'InterfaceTypeDefinition', 'InputObjectTypeDefinition'],
100
- values: ['EnumTypeDefinition'],
101
151
  selections: ['OperationDefinition', 'FragmentDefinition'],
102
152
  variables: ['OperationDefinition'],
103
- arguments: ['FieldDefinition', 'Field', 'DirectiveDefinition', 'Directive'],
153
+ arguments: ['Field', 'Directive'],
104
154
  },
105
155
  ],
106
- '@graphql-eslint/description-style': 'error',
107
- '@graphql-eslint/input-name': 'error',
108
- '@graphql-eslint/match-document-filename': 'error',
109
- '@graphql-eslint/no-deprecated': 'error',
110
- '@graphql-eslint/no-duplicate-fields': 'error',
111
- '@graphql-eslint/no-hashtag-description': 'error',
112
- '@graphql-eslint/no-root-type': ['error', { disallow: ['subscription'] }],
113
- '@graphql-eslint/no-scalar-result-type-on-mutation': 'error',
114
- '@graphql-eslint/no-unreachable-types': 'error',
115
- '@graphql-eslint/no-unused-fields': 'error',
116
- '@graphql-eslint/require-deprecation-date': 'error',
117
- '@graphql-eslint/require-description': ['error', { types: true, overrides: { DirectiveDefinition: true } }],
118
- '@graphql-eslint/require-field-of-type-query-in-mutation-result': 'error',
119
- '@graphql-eslint/require-id-when-available': 'error',
120
- '@graphql-eslint/selection-set-depth': 'error',
156
+ '@graphql-eslint/match-document-filename': [
157
+ 'error',
158
+ { query: 'kebab-case', mutation: 'kebab-case', subscription: 'kebab-case', fragment: 'kebab-case' },
159
+ ],
121
160
  '@graphql-eslint/unique-fragment-name': 'error',
122
161
  '@graphql-eslint/unique-operation-name': 'error',
123
162
  },
124
163
  };
125
164
 
126
165
  const configs = {
127
- all: allConfig,
128
- recommended: recommendedConfig,
166
+ base,
167
+ 'schema-recommended': schemaRecommendedConfig,
168
+ 'schema-all': schemaAllConfig,
169
+ 'operations-recommended': operationsRecommendedConfig,
170
+ 'operations-all': operationsAllConfig,
129
171
  };
130
172
 
131
173
  function requireSiblingsOperations(ruleName, context) {
@@ -338,7 +380,6 @@ const validationToRule = (name, ruleName, docs, getDocumentNode) => {
338
380
  docs: {
339
381
  ...docs,
340
382
  graphQLJSRuleName: ruleName,
341
- category: 'Validation',
342
383
  recommended: true,
343
384
  requiresSchema,
344
385
  url: `https://github.com/dotansimha/graphql-eslint/blob/master/docs/rules/${name}.md`,
@@ -375,16 +416,22 @@ const importFiles = (context) => {
375
416
  return processImport(context.getFilename());
376
417
  };
377
418
  const GRAPHQL_JS_VALIDATIONS = Object.assign({}, validationToRule('executable-definitions', 'ExecutableDefinitions', {
419
+ category: 'Operations',
378
420
  description: `A GraphQL document is only valid for execution if all definitions are either operation or fragment definitions.`,
379
421
  }), validationToRule('fields-on-correct-type', 'FieldsOnCorrectType', {
422
+ category: 'Operations',
380
423
  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`.',
381
424
  }), validationToRule('fragments-on-composite-type', 'FragmentsOnCompositeTypes', {
425
+ category: 'Operations',
382
426
  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.`,
383
427
  }), validationToRule('known-argument-names', 'KnownArgumentNames', {
428
+ category: ['Schema', 'Operations'],
384
429
  description: `A GraphQL field is only valid if all supplied arguments are defined by that field.`,
385
430
  }), validationToRule('known-directives', 'KnownDirectives', {
431
+ category: ['Schema', 'Operations'],
386
432
  description: `A GraphQL document is only valid if all \`@directives\` are known by the schema and legally positioned.`,
387
433
  }), validationToRule('known-fragment-names', 'KnownFragmentNames', {
434
+ category: 'Operations',
388
435
  description: `A GraphQL document is only valid if all \`...Fragment\` fragment spreads refer to fragments defined in the same document.`,
389
436
  examples: [
390
437
  {
@@ -451,17 +498,23 @@ const GRAPHQL_JS_VALIDATIONS = Object.assign({}, validationToRule('executable-de
451
498
  },
452
499
  ],
453
500
  }, importFiles), validationToRule('known-type-names', 'KnownTypeNames', {
501
+ category: ['Schema', 'Operations'],
454
502
  description: `A GraphQL document is only valid if referenced types (specifically variable definitions and fragment conditions) are defined by the type schema.`,
455
503
  }), validationToRule('lone-anonymous-operation', 'LoneAnonymousOperation', {
504
+ category: 'Operations',
456
505
  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.`,
457
506
  }), validationToRule('lone-schema-definition', 'LoneSchemaDefinition', {
507
+ category: 'Schema',
458
508
  description: `A GraphQL document is only valid if it contains only one schema definition.`,
459
509
  requiresSchema: false,
460
510
  }), validationToRule('no-fragment-cycles', 'NoFragmentCycles', {
511
+ category: 'Operations',
461
512
  description: `A GraphQL fragment is only valid when it does not have cycles in fragments usage.`,
462
513
  }), validationToRule('no-undefined-variables', 'NoUndefinedVariables', {
514
+ category: 'Operations',
463
515
  description: `A GraphQL operation is only valid if all variables encountered, both directly and via fragment spreads, are defined by that operation.`,
464
516
  }, importFiles), validationToRule('no-unused-fragments', 'NoUnusedFragments', {
517
+ category: 'Operations',
465
518
  description: `A GraphQL document is only valid if all fragment definitions are spread within operations, or spread within other fragments spread within operations.`,
466
519
  requiresSiblings: true,
467
520
  }, context => {
@@ -491,49 +544,68 @@ const GRAPHQL_JS_VALIDATIONS = Object.assign({}, validationToRule('executable-de
491
544
  };
492
545
  return getParentNode(context.getFilename());
493
546
  }), validationToRule('no-unused-variables', 'NoUnusedVariables', {
547
+ category: 'Operations',
494
548
  description: `A GraphQL operation is only valid if all variables defined by an operation are used, either directly or within a spread fragment.`,
495
549
  }, importFiles), validationToRule('overlapping-fields-can-be-merged', 'OverlappingFieldsCanBeMerged', {
550
+ category: 'Operations',
496
551
  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.`,
497
552
  }), validationToRule('possible-fragment-spread', 'PossibleFragmentSpreads', {
553
+ category: 'Operations',
498
554
  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.`,
499
555
  }), validationToRule('possible-type-extension', 'PossibleTypeExtensions', {
556
+ category: 'Schema',
500
557
  description: `A type extension is only valid if the type is defined and has the same kind.`,
501
558
  requiresSchema: false,
502
559
  }), validationToRule('provided-required-arguments', 'ProvidedRequiredArguments', {
560
+ category: ['Schema', 'Operations'],
503
561
  description: `A field or directive is only valid if all required (non-null without a default value) field arguments have been provided.`,
504
562
  }), validationToRule('scalar-leafs', 'ScalarLeafs', {
563
+ category: 'Operations',
505
564
  description: `A GraphQL document is valid only if all leaf fields (fields without sub selections) are of scalar or enum types.`,
506
565
  }), validationToRule('one-field-subscriptions', 'SingleFieldSubscriptions', {
566
+ category: 'Operations',
507
567
  description: `A GraphQL subscription is valid only if it contains a single root field.`,
508
568
  }), validationToRule('unique-argument-names', 'UniqueArgumentNames', {
569
+ category: 'Operations',
509
570
  description: `A GraphQL field or directive is only valid if all supplied arguments are uniquely named.`,
510
571
  }), validationToRule('unique-directive-names', 'UniqueDirectiveNames', {
572
+ category: 'Schema',
511
573
  description: `A GraphQL document is only valid if all defined directives have unique names.`,
512
574
  requiresSchema: false,
513
575
  }), validationToRule('unique-directive-names-per-location', 'UniqueDirectivesPerLocation', {
576
+ category: ['Schema', 'Operations'],
514
577
  description: `A GraphQL document is only valid if all non-repeatable directives at a given location are uniquely named.`,
515
578
  }), validationToRule('unique-enum-value-names', 'UniqueEnumValueNames', {
579
+ category: 'Schema',
516
580
  description: `A GraphQL enum type is only valid if all its values are uniquely named.`,
517
581
  requiresSchema: false,
518
582
  }), validationToRule('unique-field-definition-names', 'UniqueFieldDefinitionNames', {
583
+ category: 'Schema',
519
584
  description: `A GraphQL complex type is only valid if all its fields are uniquely named.`,
520
585
  requiresSchema: false,
521
586
  }), validationToRule('unique-input-field-names', 'UniqueInputFieldNames', {
587
+ category: 'Operations',
522
588
  description: `A GraphQL input object value is only valid if all supplied fields are uniquely named.`,
523
589
  requiresSchema: false,
524
590
  }), validationToRule('unique-operation-types', 'UniqueOperationTypes', {
591
+ category: 'Schema',
525
592
  description: `A GraphQL document is only valid if it has only one type per operation.`,
526
593
  requiresSchema: false,
527
594
  }), validationToRule('unique-type-names', 'UniqueTypeNames', {
595
+ category: 'Schema',
528
596
  description: `A GraphQL document is only valid if all defined types have unique names.`,
529
597
  requiresSchema: false,
530
598
  }), validationToRule('unique-variable-names', 'UniqueVariableNames', {
599
+ category: 'Operations',
531
600
  description: `A GraphQL operation is only valid if all its variables are uniquely named.`,
532
601
  }), validationToRule('value-literals-of-correct-type', 'ValuesOfCorrectType', {
602
+ category: 'Operations',
533
603
  description: `A GraphQL document is only valid if all value literals are of the type expected at their position.`,
534
604
  }), validationToRule('variables-are-input-types', 'VariablesAreInputTypes', {
605
+ category: 'Operations',
535
606
  description: `A GraphQL operation is only valid if all the variables it defines are of input types (scalar, enum, or input object).`,
536
607
  }), validationToRule('variables-in-allowed-position', 'VariablesInAllowedPosition', {
608
+ category: 'Operations',
537
609
  description: `Variables passed to field arguments conform to type.`,
538
610
  }));
539
611
 
@@ -559,7 +631,7 @@ const rule = {
559
631
  meta: {
560
632
  type: 'suggestion',
561
633
  docs: {
562
- category: 'Best Practices',
634
+ category: ['Schema', 'Operations'],
563
635
  description: 'Enforce arrange in alphabetical order for type fields, enum values, input object fields, operation selections and more.',
564
636
  url: 'https://github.com/dotansimha/graphql-eslint/blob/master/docs/rules/alphabetize.md',
565
637
  examples: [
@@ -638,15 +710,22 @@ const rule = {
638
710
  `,
639
711
  },
640
712
  ],
641
- optionsForConfig: [
642
- {
643
- fields: fieldsEnum,
644
- values: valuesEnum,
645
- selections: selectionsEnum,
646
- variables: variablesEnum,
647
- arguments: argumentsEnum,
648
- },
649
- ],
713
+ configOptions: {
714
+ schema: [
715
+ {
716
+ fields: fieldsEnum,
717
+ values: valuesEnum,
718
+ arguments: argumentsEnum,
719
+ },
720
+ ],
721
+ operations: [
722
+ {
723
+ selections: selectionsEnum,
724
+ variables: variablesEnum,
725
+ arguments: [Kind.FIELD, Kind.DIRECTIVE],
726
+ },
727
+ ],
728
+ },
650
729
  },
651
730
  messages: {
652
731
  [ALPHABETIZE]: '"{{ currName }}" should be before "{{ prevName }}"',
@@ -811,34 +890,32 @@ const rule$1 = {
811
890
  },
812
891
  ],
813
892
  description: 'Require all comments to follow the same style (either block or inline).',
814
- category: 'Stylistic Issues',
893
+ category: 'Schema',
815
894
  url: 'https://github.com/dotansimha/graphql-eslint/blob/master/docs/rules/description-style.md',
895
+ recommended: true,
816
896
  },
817
897
  schema: [
818
898
  {
819
899
  type: 'object',
900
+ additionalProperties: false,
820
901
  properties: {
821
902
  style: {
822
- type: 'string',
823
903
  enum: ['block', 'inline'],
824
- default: 'inline',
904
+ default: 'block',
825
905
  },
826
906
  },
827
- additionalProperties: false,
828
907
  },
829
908
  ],
830
909
  },
831
910
  create(context) {
832
- const { style } = context.options[0] || { style: 'inline' };
833
- const wrongDescriptionType = style === 'block' ? 'inline' : 'block';
911
+ const { style = 'block' } = context.options[0] || {};
912
+ const isBlock = style === 'block';
834
913
  return {
835
- '[description.type="StringValue"]': node => {
836
- if (node.description.block !== (style === 'block')) {
837
- context.report({
838
- loc: getLocation(node.description.loc),
839
- message: `Unexpected ${wrongDescriptionType} description`,
840
- });
841
- }
914
+ [`.description[type=StringValue][block!=${isBlock}]`](node) {
915
+ context.report({
916
+ loc: getLocation(node.loc),
917
+ message: `Unexpected ${isBlock ? 'inline' : 'block'} description`,
918
+ });
842
919
  },
843
920
  };
844
921
  },
@@ -852,7 +929,7 @@ const rule$2 = {
852
929
  type: 'suggestion',
853
930
  docs: {
854
931
  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.',
855
- category: 'Stylistic Issues',
932
+ category: 'Schema',
856
933
  url: 'https://github.com/dotansimha/graphql-eslint/blob/master/docs/rules/input-name.md',
857
934
  examples: [
858
935
  {
@@ -977,7 +1054,7 @@ const rule$3 = {
977
1054
  meta: {
978
1055
  type: 'suggestion',
979
1056
  docs: {
980
- category: 'Best Practices',
1057
+ category: 'Operations',
981
1058
  description: 'This rule allows you to enforce that the file name should match the operation name.',
982
1059
  url: `https://github.com/dotansimha/graphql-eslint/blob/master/docs/rules/match-document-filename.md`,
983
1060
  examples: [
@@ -1051,6 +1128,14 @@ const rule$3 = {
1051
1128
  `,
1052
1129
  },
1053
1130
  ],
1131
+ configOptions: [
1132
+ {
1133
+ query: CaseStyle.kebabCase,
1134
+ mutation: CaseStyle.kebabCase,
1135
+ subscription: CaseStyle.kebabCase,
1136
+ fragment: CaseStyle.kebabCase,
1137
+ },
1138
+ ],
1054
1139
  },
1055
1140
  messages: {
1056
1141
  [MATCH_EXTENSION]: `File extension "{{ fileExtension }}" don't match extension "{{ expectedFileExtension }}"`,
@@ -1059,27 +1144,29 @@ const rule$3 = {
1059
1144
  schema: {
1060
1145
  definitions: {
1061
1146
  asString: {
1062
- type: 'string',
1063
- description: `One of: ${CASE_STYLES.map(t => `\`${t}\``).join(', ')}`,
1064
1147
  enum: CASE_STYLES,
1148
+ description: `One of: ${CASE_STYLES.map(t => `\`${t}\``).join(', ')}`,
1065
1149
  },
1066
1150
  asObject: {
1067
1151
  type: 'object',
1152
+ additionalProperties: false,
1068
1153
  properties: {
1069
1154
  style: {
1070
- type: 'string',
1071
1155
  enum: CASE_STYLES,
1072
1156
  },
1157
+ suffix: {
1158
+ type: 'string',
1159
+ },
1073
1160
  },
1074
1161
  },
1075
1162
  },
1076
- $schema: 'http://json-schema.org/draft-04/schema#',
1077
1163
  type: 'array',
1164
+ maxItems: 1,
1078
1165
  items: {
1079
1166
  type: 'object',
1167
+ additionalProperties: false,
1080
1168
  properties: {
1081
1169
  fileExtension: {
1082
- type: 'string',
1083
1170
  enum: ACCEPTED_EXTENSIONS,
1084
1171
  },
1085
1172
  query: schemaOption,
@@ -1154,13 +1241,7 @@ const rule$3 = {
1154
1241
  },
1155
1242
  };
1156
1243
 
1157
- const FIELDS_KINDS = [
1158
- Kind.FIELD_DEFINITION,
1159
- Kind.INPUT_VALUE_DEFINITION,
1160
- Kind.VARIABLE_DEFINITION,
1161
- Kind.ARGUMENT,
1162
- Kind.DIRECTIVE_DEFINITION,
1163
- ];
1244
+ const FIELDS_KINDS = [Kind.FIELD_DEFINITION, Kind.INPUT_VALUE_DEFINITION, Kind.ARGUMENT, Kind.DIRECTIVE_DEFINITION];
1164
1245
  const KindToDisplayName = {
1165
1246
  // types
1166
1247
  [Kind.OBJECT_TYPE_DEFINITION]: 'Type',
@@ -1172,13 +1253,13 @@ const KindToDisplayName = {
1172
1253
  // fields
1173
1254
  [Kind.FIELD_DEFINITION]: 'Field',
1174
1255
  [Kind.INPUT_VALUE_DEFINITION]: 'Input property',
1175
- [Kind.VARIABLE_DEFINITION]: 'Variable',
1176
1256
  [Kind.ARGUMENT]: 'Argument',
1177
1257
  [Kind.DIRECTIVE_DEFINITION]: 'Directive',
1178
1258
  // rest
1179
1259
  [Kind.ENUM_VALUE_DEFINITION]: 'Enumeration value',
1180
1260
  [Kind.OPERATION_DEFINITION]: 'Operation',
1181
1261
  [Kind.FRAGMENT_DEFINITION]: 'Fragment',
1262
+ [Kind.VARIABLE_DEFINITION]: 'Variable',
1182
1263
  };
1183
1264
  const StyleToRegex = {
1184
1265
  camelCase: /^[a-z][\dA-Za-z]*$/,
@@ -1196,7 +1277,7 @@ const rule$4 = {
1196
1277
  type: 'suggestion',
1197
1278
  docs: {
1198
1279
  description: 'Require names to follow specified conventions.',
1199
- category: 'Best Practices',
1280
+ category: ['Schema', 'Operations'],
1200
1281
  recommended: true,
1201
1282
  url: 'https://github.com/dotansimha/graphql-eslint/blob/master/docs/rules/naming-convention.md',
1202
1283
  examples: [
@@ -1207,6 +1288,24 @@ const rule$4 = {
1207
1288
  type user {
1208
1289
  first_name: String!
1209
1290
  }
1291
+ `,
1292
+ },
1293
+ {
1294
+ title: 'Incorrect',
1295
+ usage: [{ FragmentDefinition: { style: 'PascalCase', forbiddenSuffixes: ['Fragment'] } }],
1296
+ code: /* GraphQL */ `
1297
+ fragment UserFragment on User {
1298
+ # ...
1299
+ }
1300
+ `,
1301
+ },
1302
+ {
1303
+ title: 'Incorrect',
1304
+ usage: [{ 'FieldDefinition[parent.name.value=Query]': { forbiddenPrefixes: ['get'] } }],
1305
+ code: /* GraphQL */ `
1306
+ type Query {
1307
+ getUsers: [User!]!
1308
+ }
1210
1309
  `,
1211
1310
  },
1212
1311
  {
@@ -1218,23 +1317,31 @@ const rule$4 = {
1218
1317
  }
1219
1318
  `,
1220
1319
  },
1221
- ],
1222
- optionsForConfig: [
1223
1320
  {
1224
- types: 'PascalCase',
1225
- fields: 'camelCase',
1226
- overrides: {
1321
+ title: 'Correct',
1322
+ usage: [{ FragmentDefinition: { style: 'PascalCase', forbiddenSuffixes: ['Fragment'] } }],
1323
+ code: /* GraphQL */ `
1324
+ fragment UserFields on User {
1325
+ # ...
1326
+ }
1327
+ `,
1328
+ },
1329
+ {
1330
+ title: 'Correct',
1331
+ usage: [{ 'FieldDefinition[parent.name.value=Query]': { forbiddenPrefixes: ['get'] } }],
1332
+ code: /* GraphQL */ `
1333
+ type Query {
1334
+ users: [User!]!
1335
+ }
1336
+ `,
1337
+ },
1338
+ ],
1339
+ configOptions: {
1340
+ schema: [
1341
+ {
1342
+ types: 'PascalCase',
1343
+ fields: 'camelCase',
1227
1344
  EnumValueDefinition: 'UPPER_CASE',
1228
- OperationDefinition: {
1229
- style: 'PascalCase',
1230
- forbiddenPrefixes: ['Query', 'Mutation', 'Subscription', 'Get'],
1231
- forbiddenSuffixes: ['Query', 'Mutation', 'Subscription'],
1232
- },
1233
- FragmentDefinition: {
1234
- style: 'PascalCase',
1235
- forbiddenPrefixes: ['Fragment'],
1236
- forbiddenSuffixes: ['Fragment'],
1237
- },
1238
1345
  'FieldDefinition[parent.name.value=Query]': {
1239
1346
  forbiddenPrefixes: ['query', 'get'],
1240
1347
  forbiddenSuffixes: ['Query'],
@@ -1248,8 +1355,23 @@ const rule$4 = {
1248
1355
  forbiddenSuffixes: ['Subscription'],
1249
1356
  },
1250
1357
  },
1251
- },
1252
- ],
1358
+ ],
1359
+ operations: [
1360
+ {
1361
+ VariableDefinition: 'camelCase',
1362
+ OperationDefinition: {
1363
+ style: 'PascalCase',
1364
+ forbiddenPrefixes: ['Query', 'Mutation', 'Subscription', 'Get'],
1365
+ forbiddenSuffixes: ['Query', 'Mutation', 'Subscription'],
1366
+ },
1367
+ FragmentDefinition: {
1368
+ style: 'PascalCase',
1369
+ forbiddenPrefixes: ['Fragment'],
1370
+ forbiddenSuffixes: ['Fragment'],
1371
+ },
1372
+ },
1373
+ ],
1374
+ },
1253
1375
  },
1254
1376
  schema: {
1255
1377
  definitions: {
@@ -1287,12 +1409,19 @@ const rule$4 = {
1287
1409
  properties: {
1288
1410
  types: {
1289
1411
  ...schemaOption$1,
1290
- description: `Includes:\n\n${TYPES_KINDS.map(kind => `- [${kind}](https://spec.graphql.org/October2021/#${kind})`).join('\n')}`,
1412
+ description: `Includes:\n\n${TYPES_KINDS.map(kind => `- \`${kind}\``).join('\n')}`,
1291
1413
  },
1292
1414
  fields: {
1293
1415
  ...schemaOption$1,
1294
- description: `Includes:\n\n${FIELDS_KINDS.map(kind => `- [${kind}](https://spec.graphql.org/October2021/#${kind})`).join('\n')}`,
1416
+ description: `Includes:\n\n${FIELDS_KINDS.map(kind => `- \`${kind}\``).join('\n')}`,
1295
1417
  },
1418
+ ...Object.fromEntries(ALLOWED_KINDS.map(kind => [
1419
+ kind,
1420
+ {
1421
+ ...schemaOption$1,
1422
+ description: `Read more about this kind on [spec.graphql.org](https://spec.graphql.org/October2021/#${kind}).`,
1423
+ },
1424
+ ])),
1296
1425
  allowLeadingUnderscore: {
1297
1426
  type: 'boolean',
1298
1427
  default: false,
@@ -1301,35 +1430,27 @@ const rule$4 = {
1301
1430
  type: 'boolean',
1302
1431
  default: false,
1303
1432
  },
1304
- overrides: {
1305
- type: 'object',
1306
- additionalProperties: false,
1307
- description: [
1308
- 'May contain the following `ASTNode` names:',
1309
- '',
1310
- ...ALLOWED_KINDS.map(kind => `- [${kind}](https://spec.graphql.org/October2021/#${kind})`),
1311
- '',
1312
- "> It's also possible to use a [`selector`](https://eslint.org/docs/developer-guide/selectors) that starts with `ASTNode` name",
1313
- '>',
1314
- '> Example: pattern property `FieldDefinition[parent.name.value=Query]` will match only fields for type `Query`',
1315
- ].join('\n'),
1316
- patternProperties: {
1317
- [`^(${ALLOWED_KINDS.join('|')})(.+)?$`]: schemaOption$1,
1318
- },
1319
- },
1320
1433
  },
1434
+ patternProperties: {
1435
+ [`^(${ALLOWED_KINDS.join('|')})(.+)?$`]: schemaOption$1,
1436
+ },
1437
+ description: [
1438
+ "> It's possible to use a [`selector`](https://eslint.org/docs/developer-guide/selectors) that starts with allowed `ASTNode` names which are described below.",
1439
+ '>',
1440
+ '> Paste or drop code into the editor in [ASTExplorer](https://astexplorer.net) and inspect the generated AST to compose your selector.',
1441
+ '>',
1442
+ '> Example: pattern property `FieldDefinition[parent.name.value=Query]` will match only fields for type `Query`.',
1443
+ ].join('\n'),
1321
1444
  },
1322
1445
  },
1323
1446
  },
1324
1447
  create(context) {
1325
- const options = {
1326
- overrides: {},
1327
- ...context.options[0],
1328
- };
1448
+ const options = context.options[0] || {};
1449
+ const { allowLeadingUnderscore, allowTrailingUnderscore, types, fields, ...restOptions } = options;
1329
1450
  function normalisePropertyOption(kind) {
1330
- let style = options.overrides[kind];
1451
+ let style = options[kind];
1331
1452
  if (!style) {
1332
- style = TYPES_KINDS.includes(kind) ? options.types : options.fields;
1453
+ style = TYPES_KINDS.includes(kind) ? types : fields;
1333
1454
  }
1334
1455
  return typeof style === 'object' ? style : { style };
1335
1456
  }
@@ -1350,10 +1471,10 @@ const rule$4 = {
1350
1471
  }
1351
1472
  function getErrorMessage() {
1352
1473
  let name = nodeName;
1353
- if (options.allowLeadingUnderscore) {
1474
+ if (allowLeadingUnderscore) {
1354
1475
  name = name.replace(/^_*/, '');
1355
1476
  }
1356
- if (options.allowTrailingUnderscore) {
1477
+ if (allowTrailingUnderscore) {
1357
1478
  name = name.replace(/_*$/, '');
1358
1479
  }
1359
1480
  if (prefix && !name.startsWith(prefix)) {
@@ -1387,15 +1508,13 @@ const rule$4 = {
1387
1508
  });
1388
1509
  };
1389
1510
  const listeners = {};
1390
- if (!options.allowLeadingUnderscore) {
1511
+ if (!allowLeadingUnderscore) {
1391
1512
  listeners['Name[value=/^_/]:matches([parent.kind!=Field], [parent.kind=Field][parent.alias])'] = checkUnderscore;
1392
1513
  }
1393
- if (!options.allowTrailingUnderscore) {
1514
+ if (!allowTrailingUnderscore) {
1394
1515
  listeners['Name[value=/_$/]:matches([parent.kind!=Field], [parent.kind=Field][parent.alias])'] = checkUnderscore;
1395
1516
  }
1396
- const selectors = new Set([options.types && TYPES_KINDS, options.fields && FIELDS_KINDS, Object.keys(options.overrides)]
1397
- .flat()
1398
- .filter(Boolean));
1517
+ const selectors = new Set([types && TYPES_KINDS, fields && FIELDS_KINDS, Object.keys(restOptions)].flat().filter(Boolean));
1399
1518
  for (const selector of selectors) {
1400
1519
  listeners[selector] = checkNode(selector);
1401
1520
  }
@@ -1408,7 +1527,7 @@ const rule$5 = {
1408
1527
  meta: {
1409
1528
  type: 'suggestion',
1410
1529
  docs: {
1411
- category: 'Best Practices',
1530
+ category: 'Operations',
1412
1531
  description: 'Require name for your GraphQL operations. This is useful since most GraphQL client libraries are using the operation name for caching purposes.',
1413
1532
  recommended: true,
1414
1533
  url: 'https://github.com/dotansimha/graphql-eslint/blob/master/docs/rules/no-anonymous-operations.md',
@@ -1457,7 +1576,7 @@ const rule$6 = {
1457
1576
  type: 'suggestion',
1458
1577
  docs: {
1459
1578
  url: 'https://github.com/dotansimha/graphql-eslint/blob/master/docs/rules/no-case-insensitive-enum-values-duplicates.md',
1460
- category: 'Best Practices',
1579
+ category: 'Schema',
1461
1580
  recommended: true,
1462
1581
  description: 'Disallow case-insensitive enum values duplicates.',
1463
1582
  examples: [
@@ -1512,7 +1631,7 @@ const rule$7 = {
1512
1631
  meta: {
1513
1632
  type: 'suggestion',
1514
1633
  docs: {
1515
- category: 'Best Practices',
1634
+ category: 'Operations',
1516
1635
  description: `Enforce that deprecated fields or enum values are not in use by operations.`,
1517
1636
  url: `https://github.com/dotansimha/graphql-eslint/blob/master/docs/rules/no-deprecated.md`,
1518
1637
  requiresSchema: true,
@@ -1578,6 +1697,7 @@ const rule$7 = {
1578
1697
  `,
1579
1698
  },
1580
1699
  ],
1700
+ recommended: true,
1581
1701
  },
1582
1702
  messages: {
1583
1703
  [NO_DEPRECATED]: `This {{ type }} is marked as deprecated in your GraphQL schema {{ reason }}`,
@@ -1630,8 +1750,9 @@ const rule$8 = {
1630
1750
  type: 'suggestion',
1631
1751
  docs: {
1632
1752
  description: `Checks for duplicate fields in selection set, variables in operation definition, or in arguments set of a field.`,
1633
- category: 'Stylistic Issues',
1753
+ category: 'Operations',
1634
1754
  url: 'https://github.com/dotansimha/graphql-eslint/blob/master/docs/rules/no-duplicate-fields.md',
1755
+ recommended: true,
1635
1756
  examples: [
1636
1757
  {
1637
1758
  title: 'Incorrect',
@@ -1732,7 +1853,7 @@ const rule$9 = {
1732
1853
  },
1733
1854
  docs: {
1734
1855
  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.',
1735
- category: 'Best Practices',
1856
+ category: 'Schema',
1736
1857
  url: 'https://github.com/dotansimha/graphql-eslint/blob/master/docs/rules/no-hashtag-description.md',
1737
1858
  examples: [
1738
1859
  {
@@ -1769,6 +1890,7 @@ const rule$9 = {
1769
1890
  `,
1770
1891
  },
1771
1892
  ],
1893
+ recommended: true,
1772
1894
  },
1773
1895
  type: 'suggestion',
1774
1896
  schema: [],
@@ -1797,18 +1919,18 @@ const rule$9 = {
1797
1919
  },
1798
1920
  };
1799
1921
 
1800
- const ROOT_TYPES = ['query', 'mutation', 'subscription'];
1922
+ const ROOT_TYPES = ['mutation', 'subscription'];
1801
1923
  const rule$a = {
1802
1924
  meta: {
1803
1925
  type: 'suggestion',
1804
1926
  docs: {
1805
- category: 'Validation',
1806
- description: 'Disallow using root types for `read-only` or `write-only` schemas.',
1927
+ category: 'Schema',
1928
+ description: 'Disallow using root types `mutation` and/or `subscription`.',
1807
1929
  url: 'https://github.com/dotansimha/graphql-eslint/blob/master/docs/rules/no-root-type.md',
1808
1930
  requiresSchema: true,
1809
1931
  examples: [
1810
1932
  {
1811
- title: 'Incorrect (`read-only` schema)',
1933
+ title: 'Incorrect',
1812
1934
  usage: [{ disallow: ['mutation', 'subscription'] }],
1813
1935
  code: /* GraphQL */ `
1814
1936
  type Mutation {
@@ -1817,16 +1939,7 @@ const rule$a = {
1817
1939
  `,
1818
1940
  },
1819
1941
  {
1820
- title: 'Incorrect (`write-only` schema)',
1821
- usage: [{ disallow: ['query'] }],
1822
- code: /* GraphQL */ `
1823
- type Query {
1824
- users: [User!]!
1825
- }
1826
- `,
1827
- },
1828
- {
1829
- title: 'Correct (`read-only` schema)',
1942
+ title: 'Correct',
1830
1943
  usage: [{ disallow: ['mutation', 'subscription'] }],
1831
1944
  code: /* GraphQL */ `
1832
1945
  type Query {
@@ -1835,7 +1948,6 @@ const rule$a = {
1835
1948
  `,
1836
1949
  },
1837
1950
  ],
1838
- optionsForConfig: [{ disallow: ['subscription'] }],
1839
1951
  },
1840
1952
  schema: {
1841
1953
  type: 'array',
@@ -1862,7 +1974,6 @@ const rule$a = {
1862
1974
  const schema = requireGraphQLSchemaFromContext('no-root-type', context);
1863
1975
  const disallow = new Set(context.options[0].disallow);
1864
1976
  const rootTypeNames = [
1865
- disallow.has('query') && schema.getQueryType(),
1866
1977
  disallow.has('mutation') && schema.getMutationType(),
1867
1978
  disallow.has('subscription') && schema.getSubscriptionType(),
1868
1979
  ]
@@ -1892,7 +2003,7 @@ const rule$b = {
1892
2003
  meta: {
1893
2004
  type: 'suggestion',
1894
2005
  docs: {
1895
- category: 'Best Practices',
2006
+ category: 'Schema',
1896
2007
  description: 'Avoid scalar result type on mutation type to make sure to return a valid state.',
1897
2008
  url: 'https://github.com/dotansimha/graphql-eslint/blob/master/docs/rules/no-scalar-result-type-on-mutation.md',
1898
2009
  requiresSchema: true,
@@ -1949,7 +2060,7 @@ const rule$c = {
1949
2060
  meta: {
1950
2061
  type: 'suggestion',
1951
2062
  docs: {
1952
- category: 'Best Practices',
2063
+ category: 'Schema',
1953
2064
  description: 'Enforces users to avoid using the type name in a field name while defining your schema.',
1954
2065
  recommended: true,
1955
2066
  url: 'https://github.com/dotansimha/graphql-eslint/blob/master/docs/rules/no-typename-prefix.md',
@@ -2005,11 +2116,11 @@ const RULE_NAME = 'no-unreachable-types';
2005
2116
  const rule$d = {
2006
2117
  meta: {
2007
2118
  messages: {
2008
- [UNREACHABLE_TYPE]: `Type "{{ typeName }}" is unreachable`,
2119
+ [UNREACHABLE_TYPE]: 'Type "{{ typeName }}" is unreachable',
2009
2120
  },
2010
2121
  docs: {
2011
2122
  description: `Requires all types to be reachable at some level by root level fields.`,
2012
- category: 'Best Practices',
2123
+ category: 'Schema',
2013
2124
  url: `https://github.com/dotansimha/graphql-eslint/blob/master/docs/rules/${RULE_NAME}.md`,
2014
2125
  requiresSchema: true,
2015
2126
  examples: [
@@ -2040,6 +2151,7 @@ const rule$d = {
2040
2151
  `,
2041
2152
  },
2042
2153
  ],
2154
+ recommended: true,
2043
2155
  },
2044
2156
  fixable: 'code',
2045
2157
  type: 'suggestion',
@@ -2085,7 +2197,7 @@ const rule$e = {
2085
2197
  },
2086
2198
  docs: {
2087
2199
  description: `Requires all fields to be used at some level by siblings operations.`,
2088
- category: 'Best Practices',
2200
+ category: 'Schema',
2089
2201
  url: `https://github.com/dotansimha/graphql-eslint/blob/master/docs/rules/${RULE_NAME$1}.md`,
2090
2202
  requiresSiblings: true,
2091
2203
  requiresSchema: true,
@@ -2271,7 +2383,7 @@ const rule$f = {
2271
2383
  meta: {
2272
2384
  type: 'suggestion',
2273
2385
  docs: {
2274
- category: 'Best Practices',
2386
+ category: 'Schema',
2275
2387
  description: 'Require deletion date on `@deprecated` directive. Suggest removing deprecated things after deprecated date.',
2276
2388
  url: 'https://github.com/dotansimha/graphql-eslint/blob/master/docs/rules/require-deprecation-date.md',
2277
2389
  examples: [
@@ -2374,7 +2486,7 @@ const rule$g = {
2374
2486
  meta: {
2375
2487
  docs: {
2376
2488
  description: `Require all deprecation directives to specify a reason.`,
2377
- category: 'Best Practices',
2489
+ category: 'Schema',
2378
2490
  url: `https://github.com/dotansimha/graphql-eslint/blob/master/docs/rules/require-deprecation-reason.md`,
2379
2491
  recommended: true,
2380
2492
  examples: [
@@ -2435,13 +2547,13 @@ const ALLOWED_KINDS$1 = [
2435
2547
  const rule$h = {
2436
2548
  meta: {
2437
2549
  docs: {
2438
- category: 'Best Practices',
2550
+ category: 'Schema',
2439
2551
  description: 'Enforce descriptions in your type definitions.',
2440
2552
  url: 'https://github.com/dotansimha/graphql-eslint/blob/master/docs/rules/require-description.md',
2441
2553
  examples: [
2442
2554
  {
2443
2555
  title: 'Incorrect',
2444
- usage: [{ types: true, overrides: { FieldDefinition: true } }],
2556
+ usage: [{ types: true, FieldDefinition: true }],
2445
2557
  code: /* GraphQL */ `
2446
2558
  type someTypeName {
2447
2559
  name: String
@@ -2450,7 +2562,7 @@ const rule$h = {
2450
2562
  },
2451
2563
  {
2452
2564
  title: 'Correct',
2453
- usage: [{ types: true, overrides: { FieldDefinition: true } }],
2565
+ usage: [{ types: true, FieldDefinition: true }],
2454
2566
  code: /* GraphQL */ `
2455
2567
  """
2456
2568
  Some type description
@@ -2464,14 +2576,13 @@ const rule$h = {
2464
2576
  `,
2465
2577
  },
2466
2578
  ],
2467
- optionsForConfig: [
2579
+ configOptions: [
2468
2580
  {
2469
2581
  types: true,
2470
- overrides: {
2471
- [Kind.DIRECTIVE_DEFINITION]: true,
2472
- },
2582
+ [Kind.DIRECTIVE_DEFINITION]: true,
2473
2583
  },
2474
2584
  ],
2585
+ recommended: true,
2475
2586
  },
2476
2587
  type: 'suggestion',
2477
2588
  messages: {
@@ -2488,22 +2599,23 @@ const rule$h = {
2488
2599
  properties: {
2489
2600
  types: {
2490
2601
  type: 'boolean',
2491
- description: `Includes:\n\n${TYPES_KINDS.map(kind => `- [${kind}](https://spec.graphql.org/October2021/#${kind})`).join('\n')}`,
2492
- },
2493
- overrides: {
2494
- type: 'object',
2495
- description: 'Configuration for precise `ASTNode`',
2496
- additionalProperties: false,
2497
- properties: Object.fromEntries(ALLOWED_KINDS$1.map(kind => [kind, { type: 'boolean' }])),
2602
+ description: `Includes:\n\n${TYPES_KINDS.map(kind => `- \`${kind}\``).join('\n')}`,
2498
2603
  },
2604
+ ...Object.fromEntries([...ALLOWED_KINDS$1].sort().map(kind => [
2605
+ kind,
2606
+ {
2607
+ type: 'boolean',
2608
+ description: `Read more about this kind on [spec.graphql.org](https://spec.graphql.org/October2021/#${kind}).`,
2609
+ },
2610
+ ])),
2499
2611
  },
2500
2612
  },
2501
2613
  },
2502
2614
  },
2503
2615
  create(context) {
2504
- const { types, overrides = {} } = context.options[0];
2616
+ const { types, ...restOptions } = context.options[0];
2505
2617
  const kinds = new Set(types ? TYPES_KINDS : []);
2506
- for (const [kind, isEnabled] of Object.entries(overrides)) {
2618
+ for (const [kind, isEnabled] of Object.entries(restOptions)) {
2507
2619
  if (isEnabled) {
2508
2620
  kinds.add(kind);
2509
2621
  }
@@ -2535,7 +2647,7 @@ const rule$i = {
2535
2647
  meta: {
2536
2648
  type: 'suggestion',
2537
2649
  docs: {
2538
- category: 'Best Practices',
2650
+ category: 'Schema',
2539
2651
  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`.',
2540
2652
  url: `https://github.com/dotansimha/graphql-eslint/blob/master/docs/rules/${RULE_NAME$2}.md`,
2541
2653
  requiresSchema: true,
@@ -2703,9 +2815,9 @@ const rule$j = {
2703
2815
  meta: {
2704
2816
  type: 'suggestion',
2705
2817
  docs: {
2706
- category: 'Best Practices',
2707
- description: `Enforce selecting specific fields when they are available on the GraphQL type.`,
2708
- url: `https://github.com/dotansimha/graphql-eslint/blob/master/docs/rules/require-id-when-available.md`,
2818
+ category: 'Operations',
2819
+ description: 'Enforce selecting specific fields when they are available on the GraphQL type.',
2820
+ url: 'https://github.com/dotansimha/graphql-eslint/blob/master/docs/rules/require-id-when-available.md',
2709
2821
  requiresSchema: true,
2710
2822
  requiresSiblings: true,
2711
2823
  examples: [
@@ -2745,17 +2857,17 @@ const rule$j = {
2745
2857
  `,
2746
2858
  },
2747
2859
  ],
2860
+ recommended: true,
2748
2861
  },
2749
2862
  messages: {
2750
- [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 }}".`,
2863
+ [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 }}".`,
2751
2864
  },
2752
2865
  schema: {
2753
2866
  type: 'array',
2754
- additionalItems: false,
2755
- minItems: 0,
2756
2867
  maxItems: 1,
2757
2868
  items: {
2758
2869
  type: 'object',
2870
+ additionalProperties: false,
2759
2871
  properties: {
2760
2872
  fieldName: {
2761
2873
  type: 'string',
@@ -2838,9 +2950,9 @@ const rule$j = {
2838
2950
  const rule$k = {
2839
2951
  meta: {
2840
2952
  docs: {
2841
- category: 'Best Practices',
2953
+ category: 'Operations',
2842
2954
  description: `Limit the complexity of the GraphQL operations solely by their depth. Based on [graphql-depth-limit](https://github.com/stems/graphql-depth-limit).`,
2843
- url: `https://github.com/dotansimha/graphql-eslint/blob/master/docs/rules/selection-set-depth.md`,
2955
+ url: 'https://github.com/dotansimha/graphql-eslint/blob/master/docs/rules/selection-set-depth.md',
2844
2956
  requiresSiblings: true,
2845
2957
  examples: [
2846
2958
  {
@@ -2883,22 +2995,26 @@ const rule$k = {
2883
2995
  `,
2884
2996
  },
2885
2997
  ],
2998
+ recommended: true,
2999
+ configOptions: [{ maxDepth: 7 }],
2886
3000
  },
2887
3001
  type: 'suggestion',
2888
3002
  schema: {
2889
3003
  type: 'array',
2890
- additionalItems: false,
2891
3004
  minItems: 1,
2892
3005
  maxItems: 1,
2893
3006
  items: {
2894
3007
  type: 'object',
2895
- require: ['maxDepth'],
3008
+ additionalProperties: false,
3009
+ required: ['maxDepth'],
2896
3010
  properties: {
2897
3011
  maxDepth: {
2898
3012
  type: 'number',
2899
3013
  },
2900
3014
  ignore: {
2901
3015
  type: 'array',
3016
+ uniqueItems: true,
3017
+ minItems: 1,
2902
3018
  items: {
2903
3019
  type: 'string',
2904
3020
  },
@@ -2962,7 +3078,7 @@ const rule$l = {
2962
3078
  type: 'suggestion',
2963
3079
  docs: {
2964
3080
  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.',
2965
- category: 'Best Practices',
3081
+ category: 'Schema',
2966
3082
  recommended: true,
2967
3083
  url: 'https://github.com/dotansimha/graphql-eslint/blob/master/docs/rules/strict-id-in-types.md',
2968
3084
  examples: [
@@ -3022,13 +3138,15 @@ const rule$l = {
3022
3138
  ],
3023
3139
  },
3024
3140
  schema: {
3025
- $schema: 'http://json-schema.org/draft-04/schema#',
3026
3141
  type: 'array',
3142
+ maxItems: 1,
3027
3143
  items: {
3028
3144
  type: 'object',
3145
+ additionalProperties: false,
3029
3146
  properties: {
3030
3147
  acceptedIdNames: {
3031
3148
  type: 'array',
3149
+ uniqueItems: true,
3032
3150
  items: {
3033
3151
  type: 'string',
3034
3152
  },
@@ -3036,6 +3154,7 @@ const rule$l = {
3036
3154
  },
3037
3155
  acceptedIdTypes: {
3038
3156
  type: 'array',
3157
+ uniqueItems: true,
3039
3158
  items: {
3040
3159
  type: 'string',
3041
3160
  },
@@ -3046,19 +3165,21 @@ const rule$l = {
3046
3165
  properties: {
3047
3166
  types: {
3048
3167
  type: 'array',
3168
+ uniqueItems: true,
3169
+ minItems: 1,
3049
3170
  description: 'This is used to exclude types with names that match one of the specified values.',
3050
3171
  items: {
3051
3172
  type: 'string',
3052
3173
  },
3053
- default: [],
3054
3174
  },
3055
3175
  suffixes: {
3056
3176
  type: 'array',
3177
+ uniqueItems: true,
3178
+ minItems: 1,
3057
3179
  description: 'This is used to exclude types with names with suffixes that match one of the specified values.',
3058
3180
  items: {
3059
3181
  type: 'string',
3060
3182
  },
3061
- default: [],
3062
3183
  },
3063
3184
  },
3064
3185
  },
@@ -3138,7 +3259,7 @@ const rule$m = {
3138
3259
  meta: {
3139
3260
  type: 'suggestion',
3140
3261
  docs: {
3141
- category: 'Best Practices',
3262
+ category: 'Operations',
3142
3263
  description: `Enforce unique fragment names across your project.`,
3143
3264
  url: `https://github.com/dotansimha/graphql-eslint/blob/master/docs/rules/${RULE_NAME$3}.md`,
3144
3265
  requiresSiblings: true,
@@ -3197,7 +3318,7 @@ const rule$n = {
3197
3318
  meta: {
3198
3319
  type: 'suggestion',
3199
3320
  docs: {
3200
- category: 'Best Practices',
3321
+ category: 'Operations',
3201
3322
  description: `Enforce unique operation names across your project.`,
3202
3323
  url: `https://github.com/dotansimha/graphql-eslint/blob/master/docs/rules/${RULE_NAME$4}.md`,
3203
3324
  requiresSiblings: true,