@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.
- package/README.md +19 -8
- package/configs/base.d.ts +5 -0
- package/configs/index.d.ts +76 -117
- package/configs/operations-all.d.ts +19 -0
- package/configs/operations-recommended.d.ts +50 -0
- package/configs/schema-all.d.ts +17 -0
- package/configs/schema-recommended.d.ts +46 -0
- package/docs/README.md +9 -15
- package/docs/rules/alphabetize.md +1 -1
- package/docs/rules/description-style.md +5 -3
- package/docs/rules/executable-definitions.md +2 -2
- package/docs/rules/fields-on-correct-type.md +2 -2
- package/docs/rules/fragments-on-composite-type.md +2 -2
- package/docs/rules/input-name.md +1 -1
- package/docs/rules/known-argument-names.md +2 -2
- package/docs/rules/known-directives.md +2 -2
- package/docs/rules/known-fragment-names.md +2 -2
- package/docs/rules/known-type-names.md +2 -2
- package/docs/rules/lone-anonymous-operation.md +2 -2
- package/docs/rules/lone-schema-definition.md +2 -2
- package/docs/rules/match-document-filename.md +6 -4
- package/docs/rules/naming-convention.md +180 -41
- package/docs/rules/no-anonymous-operations.md +2 -2
- package/docs/rules/no-case-insensitive-enum-values-duplicates.md +2 -2
- package/docs/rules/no-deprecated.md +3 -1
- package/docs/rules/no-duplicate-fields.md +3 -1
- package/docs/rules/no-fragment-cycles.md +2 -2
- package/docs/rules/no-hashtag-description.md +3 -1
- package/docs/rules/no-root-type.md +4 -15
- package/docs/rules/no-scalar-result-type-on-mutation.md +1 -1
- package/docs/rules/no-typename-prefix.md +2 -2
- package/docs/rules/no-undefined-variables.md +2 -2
- package/docs/rules/no-unreachable-types.md +3 -1
- package/docs/rules/no-unused-fields.md +1 -1
- package/docs/rules/no-unused-fragments.md +2 -2
- package/docs/rules/no-unused-variables.md +2 -2
- package/docs/rules/one-field-subscriptions.md +2 -2
- package/docs/rules/overlapping-fields-can-be-merged.md +2 -2
- package/docs/rules/possible-fragment-spread.md +2 -2
- package/docs/rules/possible-type-extension.md +2 -2
- package/docs/rules/provided-required-arguments.md +2 -2
- package/docs/rules/require-deprecation-date.md +1 -1
- package/docs/rules/require-deprecation-reason.md +2 -2
- package/docs/rules/require-description.md +38 -22
- package/docs/rules/require-field-of-type-query-in-mutation-result.md +1 -1
- package/docs/rules/require-id-when-available.md +3 -1
- package/docs/rules/scalar-leafs.md +2 -2
- package/docs/rules/selection-set-depth.md +9 -2
- package/docs/rules/strict-id-in-types.md +16 -10
- package/docs/rules/unique-argument-names.md +2 -2
- package/docs/rules/unique-directive-names-per-location.md +2 -2
- package/docs/rules/unique-directive-names.md +2 -2
- package/docs/rules/unique-enum-value-names.md +2 -2
- package/docs/rules/unique-field-definition-names.md +2 -2
- package/docs/rules/unique-fragment-name.md +1 -1
- package/docs/rules/unique-input-field-names.md +2 -2
- package/docs/rules/unique-operation-name.md +1 -1
- package/docs/rules/unique-operation-types.md +2 -2
- package/docs/rules/unique-type-names.md +2 -2
- package/docs/rules/unique-variable-names.md +2 -2
- package/docs/rules/value-literals-of-correct-type.md +2 -2
- package/docs/rules/variables-are-input-types.md +2 -2
- package/docs/rules/variables-in-allowed-position.md +2 -2
- package/index.js +329 -208
- package/index.mjs +329 -208
- package/package.json +1 -1
- package/rules/alphabetize.d.ts +8 -10
- package/rules/description-style.d.ts +4 -6
- package/rules/index.d.ts +112 -114
- package/rules/input-name.d.ts +1 -1
- package/rules/match-document-filename.d.ts +8 -10
- package/rules/naming-convention.d.ts +3 -4
- package/rules/no-root-type.d.ts +1 -1
- package/rules/require-description.d.ts +2 -3
- package/rules/require-id-when-available.d.ts +3 -3
- package/rules/selection-set-depth.d.ts +3 -3
- package/rules/strict-id-in-types.d.ts +6 -8
- package/types.d.ts +9 -5
- package/configs/all.d.ts +0 -102
- 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
|
19
|
-
|
20
|
-
|
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
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
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-
|
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-
|
129
|
+
'@graphql-eslint/require-id-when-available': 'error',
|
72
130
|
'@graphql-eslint/scalar-leafs': 'error',
|
73
|
-
'@graphql-eslint/
|
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
|
93
|
-
|
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: ['
|
153
|
+
arguments: ['Field', 'Directive'],
|
104
154
|
},
|
105
155
|
],
|
106
|
-
'@graphql-eslint/
|
107
|
-
|
108
|
-
|
109
|
-
|
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
|
-
|
128
|
-
recommended:
|
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: '
|
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
|
-
|
642
|
-
|
643
|
-
|
644
|
-
|
645
|
-
|
646
|
-
|
647
|
-
|
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: '
|
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: '
|
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] || {
|
833
|
-
const
|
911
|
+
const { style = 'block' } = context.options[0] || {};
|
912
|
+
const isBlock = style === 'block';
|
834
913
|
return {
|
835
|
-
|
836
|
-
|
837
|
-
|
838
|
-
|
839
|
-
|
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: '
|
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: '
|
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: '
|
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
|
-
|
1225
|
-
|
1226
|
-
|
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 => `-
|
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 => `-
|
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
|
-
|
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
|
1451
|
+
let style = options[kind];
|
1331
1452
|
if (!style) {
|
1332
|
-
style = TYPES_KINDS.includes(kind) ?
|
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 (
|
1474
|
+
if (allowLeadingUnderscore) {
|
1354
1475
|
name = name.replace(/^_*/, '');
|
1355
1476
|
}
|
1356
|
-
if (
|
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 (!
|
1511
|
+
if (!allowLeadingUnderscore) {
|
1391
1512
|
listeners['Name[value=/^_/]:matches([parent.kind!=Field], [parent.kind=Field][parent.alias])'] = checkUnderscore;
|
1392
1513
|
}
|
1393
|
-
if (!
|
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([
|
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: '
|
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: '
|
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: '
|
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: '
|
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: '
|
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 = ['
|
1922
|
+
const ROOT_TYPES = ['mutation', 'subscription'];
|
1801
1923
|
const rule$a = {
|
1802
1924
|
meta: {
|
1803
1925
|
type: 'suggestion',
|
1804
1926
|
docs: {
|
1805
|
-
category: '
|
1806
|
-
description: 'Disallow using root types
|
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
|
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: '
|
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: '
|
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: '
|
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]:
|
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: '
|
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: '
|
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: '
|
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: '
|
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: '
|
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,
|
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,
|
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
|
-
|
2579
|
+
configOptions: [
|
2468
2580
|
{
|
2469
2581
|
types: true,
|
2470
|
-
|
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 => `-
|
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,
|
2616
|
+
const { types, ...restOptions } = context.options[0];
|
2505
2617
|
const kinds = new Set(types ? TYPES_KINDS : []);
|
2506
|
-
for (const [kind, isEnabled] of Object.entries(
|
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: '
|
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: '
|
2707
|
-
description:
|
2708
|
-
url:
|
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: '
|
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:
|
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
|
-
|
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: '
|
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: '
|
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: '
|
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,
|