@graphql-eslint/eslint-plugin 3.0.0-alpha-069461d.0 → 3.0.0-alpha-698204a.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 +59 -91
- package/configs/operations-all.d.ts +19 -0
- package/configs/{recommended.d.ts → operations-recommended.d.ts} +11 -30
- package/configs/schema-all.d.ts +23 -0
- package/configs/schema-recommended.d.ts +44 -0
- package/docs/README.md +9 -17
- package/docs/deprecated-rules.md +21 -0
- package/docs/rules/alphabetize.md +1 -1
- package/docs/rules/description-style.md +4 -2
- 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 +26 -27
- 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/{avoid-duplicate-fields.md → no-duplicate-fields.md} +10 -8
- 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 +7 -1
- package/docs/rules/{avoid-scalar-result-type-on-mutation.md → no-scalar-result-type-on-mutation.md} +7 -7
- package/docs/rules/no-typename-prefix.md +37 -0
- 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 +36 -7
- 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 +566 -599
- package/index.mjs +567 -600
- 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 +18 -8
- package/rules/input-name.d.ts +1 -1
- package/rules/match-document-filename.d.ts +8 -10
- package/rules/naming-convention.d.ts +1 -1
- package/rules/{avoid-duplicate-fields.d.ts → no-duplicate-fields.d.ts} +0 -0
- package/rules/{avoid-scalar-result-type-on-mutation.d.ts → no-scalar-result-type-on-mutation.d.ts} +0 -0
- package/rules/{avoid-typename-prefix.d.ts → no-typename-prefix.d.ts} +0 -0
- package/rules/require-description.d.ts +10 -6
- 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/utils.d.ts +1 -1
- package/configs/all.d.ts +0 -99
- package/docs/rules/avoid-operation-name-prefix.md +0 -50
- package/docs/rules/avoid-typename-prefix.md +0 -37
- package/docs/rules/no-operation-name-suffix.md +0 -38
- package/rules/avoid-operation-name-prefix.d.ts +0 -9
- package/rules/no-operation-name-suffix.d.ts +0 -3
package/index.mjs
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
import { Kind, validate,
|
1
|
+
import { Kind, validate, TokenKind, isScalarType, isNonNullType, isListType, isObjectType as isObjectType$1, visit, visitWithTypeInfo, GraphQLObjectType, GraphQLInterfaceType, TypeInfo, isInterfaceType, Source, GraphQLError } from 'graphql';
|
2
2
|
import { validateSDL } from 'graphql/validation/validate';
|
3
3
|
import { processImport, parseImportLine } from '@graphql-tools/import';
|
4
4
|
import { statSync, existsSync, readFileSync } from 'fs';
|
@@ -12,22 +12,21 @@ 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
|
-
plugins: ['@graphql-eslint'],
|
23
|
+
const schemaRecommendedConfig = {
|
24
|
+
extends: ['plugin:@graphql-eslint/base'],
|
21
25
|
rules: {
|
22
|
-
'@graphql-eslint/
|
23
|
-
'@graphql-eslint/executable-definitions': 'error',
|
24
|
-
'@graphql-eslint/fields-on-correct-type': 'error',
|
25
|
-
'@graphql-eslint/fragments-on-composite-type': 'error',
|
26
|
+
'@graphql-eslint/description-style': 'error',
|
26
27
|
'@graphql-eslint/known-argument-names': 'error',
|
27
28
|
'@graphql-eslint/known-directives': 'error',
|
28
|
-
'@graphql-eslint/known-fragment-names': 'error',
|
29
29
|
'@graphql-eslint/known-type-names': 'error',
|
30
|
-
'@graphql-eslint/lone-anonymous-operation': 'error',
|
31
30
|
'@graphql-eslint/lone-schema-definition': 'error',
|
32
31
|
'@graphql-eslint/naming-convention': [
|
33
32
|
'error',
|
@@ -36,12 +35,6 @@ const recommendedConfig = {
|
|
36
35
|
fields: 'camelCase',
|
37
36
|
overrides: {
|
38
37
|
EnumValueDefinition: 'UPPER_CASE',
|
39
|
-
OperationDefinition: {
|
40
|
-
style: 'PascalCase',
|
41
|
-
forbiddenPrefixes: ['Query', 'Mutation', 'Subscription', 'Get'],
|
42
|
-
forbiddenSuffixes: ['Query', 'Mutation', 'Subscription'],
|
43
|
-
},
|
44
|
-
FragmentDefinition: { style: 'PascalCase', forbiddenPrefixes: ['Fragment'], forbiddenSuffixes: ['Fragment'] },
|
45
38
|
'FieldDefinition[parent.name.value=Query]': {
|
46
39
|
forbiddenPrefixes: ['query', 'get'],
|
47
40
|
forbiddenSuffixes: ['Query'],
|
@@ -57,29 +50,93 @@ const recommendedConfig = {
|
|
57
50
|
},
|
58
51
|
},
|
59
52
|
],
|
60
|
-
'@graphql-eslint/no-anonymous-operations': 'error',
|
61
53
|
'@graphql-eslint/no-case-insensitive-enum-values-duplicates': 'error',
|
54
|
+
'@graphql-eslint/no-hashtag-description': 'error',
|
55
|
+
'@graphql-eslint/no-typename-prefix': 'error',
|
56
|
+
'@graphql-eslint/no-unreachable-types': 'error',
|
57
|
+
'@graphql-eslint/possible-type-extension': 'error',
|
58
|
+
'@graphql-eslint/provided-required-arguments': 'error',
|
59
|
+
'@graphql-eslint/require-deprecation-reason': 'error',
|
60
|
+
'@graphql-eslint/strict-id-in-types': 'error',
|
61
|
+
'@graphql-eslint/unique-directive-names': 'error',
|
62
|
+
'@graphql-eslint/unique-directive-names-per-location': 'error',
|
63
|
+
'@graphql-eslint/unique-enum-value-names': 'error',
|
64
|
+
'@graphql-eslint/unique-field-definition-names': 'error',
|
65
|
+
'@graphql-eslint/unique-operation-types': 'error',
|
66
|
+
'@graphql-eslint/unique-type-names': 'error',
|
67
|
+
},
|
68
|
+
};
|
69
|
+
|
70
|
+
/*
|
71
|
+
* 🚨 IMPORTANT! Do not manually modify this file. Run: `yarn generate-configs`
|
72
|
+
*/
|
73
|
+
const schemaAllConfig = {
|
74
|
+
extends: ['plugin:@graphql-eslint/base', 'plugin:@graphql-eslint/schema-recommended'],
|
75
|
+
rules: {
|
76
|
+
'@graphql-eslint/alphabetize': [
|
77
|
+
'error',
|
78
|
+
{
|
79
|
+
fields: ['ObjectTypeDefinition', 'InterfaceTypeDefinition', 'InputObjectTypeDefinition'],
|
80
|
+
values: ['EnumTypeDefinition'],
|
81
|
+
arguments: ['FieldDefinition', 'Field', 'DirectiveDefinition', 'Directive'],
|
82
|
+
},
|
83
|
+
],
|
84
|
+
'@graphql-eslint/input-name': 'error',
|
85
|
+
'@graphql-eslint/no-root-type': 'off',
|
86
|
+
'@graphql-eslint/no-scalar-result-type-on-mutation': 'error',
|
87
|
+
'@graphql-eslint/no-unused-fields': 'off',
|
88
|
+
'@graphql-eslint/require-deprecation-date': 'error',
|
89
|
+
'@graphql-eslint/require-description': ['error', { types: true, overrides: { DirectiveDefinition: true } }],
|
90
|
+
'@graphql-eslint/require-field-of-type-query-in-mutation-result': 'error',
|
91
|
+
},
|
92
|
+
};
|
93
|
+
|
94
|
+
/*
|
95
|
+
* 🚨 IMPORTANT! Do not manually modify this file. Run: `yarn generate-configs`
|
96
|
+
*/
|
97
|
+
const operationsRecommendedConfig = {
|
98
|
+
extends: ['plugin:@graphql-eslint/base'],
|
99
|
+
rules: {
|
100
|
+
'@graphql-eslint/executable-definitions': 'error',
|
101
|
+
'@graphql-eslint/fields-on-correct-type': 'error',
|
102
|
+
'@graphql-eslint/fragments-on-composite-type': 'error',
|
103
|
+
'@graphql-eslint/known-argument-names': 'error',
|
104
|
+
'@graphql-eslint/known-directives': 'error',
|
105
|
+
'@graphql-eslint/known-fragment-names': 'error',
|
106
|
+
'@graphql-eslint/known-type-names': 'error',
|
107
|
+
'@graphql-eslint/lone-anonymous-operation': 'error',
|
108
|
+
'@graphql-eslint/naming-convention': [
|
109
|
+
'error',
|
110
|
+
{
|
111
|
+
overrides: {
|
112
|
+
Argument: 'camelCase',
|
113
|
+
VariableDefinition: 'camelCase',
|
114
|
+
OperationDefinition: {
|
115
|
+
style: 'PascalCase',
|
116
|
+
forbiddenPrefixes: ['Query', 'Mutation', 'Subscription', 'Get'],
|
117
|
+
forbiddenSuffixes: ['Query', 'Mutation', 'Subscription'],
|
118
|
+
},
|
119
|
+
FragmentDefinition: { style: 'PascalCase', forbiddenPrefixes: ['Fragment'], forbiddenSuffixes: ['Fragment'] },
|
120
|
+
},
|
121
|
+
},
|
122
|
+
],
|
123
|
+
'@graphql-eslint/no-anonymous-operations': 'error',
|
124
|
+
'@graphql-eslint/no-deprecated': 'error',
|
125
|
+
'@graphql-eslint/no-duplicate-fields': 'error',
|
62
126
|
'@graphql-eslint/no-fragment-cycles': 'error',
|
63
|
-
'@graphql-eslint/no-operation-name-suffix': 'error',
|
64
127
|
'@graphql-eslint/no-undefined-variables': 'error',
|
65
128
|
'@graphql-eslint/no-unused-fragments': 'error',
|
66
129
|
'@graphql-eslint/no-unused-variables': 'error',
|
67
130
|
'@graphql-eslint/one-field-subscriptions': 'error',
|
68
131
|
'@graphql-eslint/overlapping-fields-can-be-merged': 'error',
|
69
132
|
'@graphql-eslint/possible-fragment-spread': 'error',
|
70
|
-
'@graphql-eslint/possible-type-extension': 'error',
|
71
133
|
'@graphql-eslint/provided-required-arguments': 'error',
|
72
|
-
'@graphql-eslint/require-
|
134
|
+
'@graphql-eslint/require-id-when-available': 'error',
|
73
135
|
'@graphql-eslint/scalar-leafs': 'error',
|
74
|
-
'@graphql-eslint/
|
136
|
+
'@graphql-eslint/selection-set-depth': ['error', { maxDepth: 7 }],
|
75
137
|
'@graphql-eslint/unique-argument-names': 'error',
|
76
|
-
'@graphql-eslint/unique-directive-names': 'error',
|
77
138
|
'@graphql-eslint/unique-directive-names-per-location': 'error',
|
78
|
-
'@graphql-eslint/unique-enum-value-names': 'error',
|
79
|
-
'@graphql-eslint/unique-field-definition-names': 'error',
|
80
139
|
'@graphql-eslint/unique-input-field-names': 'error',
|
81
|
-
'@graphql-eslint/unique-operation-types': 'error',
|
82
|
-
'@graphql-eslint/unique-type-names': 'error',
|
83
140
|
'@graphql-eslint/unique-variable-names': 'error',
|
84
141
|
'@graphql-eslint/value-literals-of-correct-type': 'error',
|
85
142
|
'@graphql-eslint/variables-are-input-types': 'error',
|
@@ -90,44 +147,32 @@ const recommendedConfig = {
|
|
90
147
|
/*
|
91
148
|
* 🚨 IMPORTANT! Do not manually modify this file. Run: `yarn generate-configs`
|
92
149
|
*/
|
93
|
-
const
|
94
|
-
|
150
|
+
const operationsAllConfig = {
|
151
|
+
extends: ['plugin:@graphql-eslint/base', 'plugin:@graphql-eslint/operations-recommended'],
|
95
152
|
rules: {
|
96
|
-
...recommendedConfig.rules,
|
97
153
|
'@graphql-eslint/alphabetize': [
|
98
154
|
'error',
|
99
155
|
{
|
100
|
-
fields: ['ObjectTypeDefinition', 'InterfaceTypeDefinition', 'InputObjectTypeDefinition'],
|
101
|
-
values: ['EnumTypeDefinition'],
|
102
156
|
selections: ['OperationDefinition', 'FragmentDefinition'],
|
103
157
|
variables: ['OperationDefinition'],
|
104
|
-
arguments: ['
|
158
|
+
arguments: ['Field', 'Directive'],
|
105
159
|
},
|
106
160
|
],
|
107
|
-
'@graphql-eslint/
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
'@graphql-eslint/input-name': 'error',
|
112
|
-
'@graphql-eslint/match-document-filename': 'error',
|
113
|
-
'@graphql-eslint/no-deprecated': 'error',
|
114
|
-
'@graphql-eslint/no-hashtag-description': 'error',
|
115
|
-
'@graphql-eslint/no-root-type': ['error', { disallow: ['subscription'] }],
|
116
|
-
'@graphql-eslint/no-unreachable-types': 'error',
|
117
|
-
'@graphql-eslint/no-unused-fields': 'error',
|
118
|
-
'@graphql-eslint/require-deprecation-date': 'error',
|
119
|
-
'@graphql-eslint/require-description': 'error',
|
120
|
-
'@graphql-eslint/require-field-of-type-query-in-mutation-result': 'error',
|
121
|
-
'@graphql-eslint/require-id-when-available': 'error',
|
122
|
-
'@graphql-eslint/selection-set-depth': 'error',
|
161
|
+
'@graphql-eslint/match-document-filename': [
|
162
|
+
'error',
|
163
|
+
{ query: 'kebab-case', mutation: 'kebab-case', subscription: 'kebab-case', fragment: 'kebab-case' },
|
164
|
+
],
|
123
165
|
'@graphql-eslint/unique-fragment-name': 'error',
|
124
166
|
'@graphql-eslint/unique-operation-name': 'error',
|
125
167
|
},
|
126
168
|
};
|
127
169
|
|
128
170
|
const configs = {
|
129
|
-
|
130
|
-
recommended:
|
171
|
+
base,
|
172
|
+
'schema-recommended': schemaRecommendedConfig,
|
173
|
+
'schema-all': schemaAllConfig,
|
174
|
+
'operations-recommended': operationsRecommendedConfig,
|
175
|
+
'operations-all': operationsAllConfig,
|
131
176
|
};
|
132
177
|
|
133
178
|
function requireSiblingsOperations(ruleName, context) {
|
@@ -340,7 +385,6 @@ const validationToRule = (name, ruleName, docs, getDocumentNode) => {
|
|
340
385
|
docs: {
|
341
386
|
...docs,
|
342
387
|
graphQLJSRuleName: ruleName,
|
343
|
-
category: 'Validation',
|
344
388
|
recommended: true,
|
345
389
|
requiresSchema,
|
346
390
|
url: `https://github.com/dotansimha/graphql-eslint/blob/master/docs/rules/${name}.md`,
|
@@ -377,16 +421,22 @@ const importFiles = (context) => {
|
|
377
421
|
return processImport(context.getFilename());
|
378
422
|
};
|
379
423
|
const GRAPHQL_JS_VALIDATIONS = Object.assign({}, validationToRule('executable-definitions', 'ExecutableDefinitions', {
|
424
|
+
category: 'Operations',
|
380
425
|
description: `A GraphQL document is only valid for execution if all definitions are either operation or fragment definitions.`,
|
381
426
|
}), validationToRule('fields-on-correct-type', 'FieldsOnCorrectType', {
|
427
|
+
category: 'Operations',
|
382
428
|
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`.',
|
383
429
|
}), validationToRule('fragments-on-composite-type', 'FragmentsOnCompositeTypes', {
|
430
|
+
category: 'Operations',
|
384
431
|
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.`,
|
385
432
|
}), validationToRule('known-argument-names', 'KnownArgumentNames', {
|
433
|
+
category: ['Schema', 'Operations'],
|
386
434
|
description: `A GraphQL field is only valid if all supplied arguments are defined by that field.`,
|
387
435
|
}), validationToRule('known-directives', 'KnownDirectives', {
|
436
|
+
category: ['Schema', 'Operations'],
|
388
437
|
description: `A GraphQL document is only valid if all \`@directives\` are known by the schema and legally positioned.`,
|
389
438
|
}), validationToRule('known-fragment-names', 'KnownFragmentNames', {
|
439
|
+
category: 'Operations',
|
390
440
|
description: `A GraphQL document is only valid if all \`...Fragment\` fragment spreads refer to fragments defined in the same document.`,
|
391
441
|
examples: [
|
392
442
|
{
|
@@ -453,17 +503,23 @@ const GRAPHQL_JS_VALIDATIONS = Object.assign({}, validationToRule('executable-de
|
|
453
503
|
},
|
454
504
|
],
|
455
505
|
}, importFiles), validationToRule('known-type-names', 'KnownTypeNames', {
|
506
|
+
category: ['Schema', 'Operations'],
|
456
507
|
description: `A GraphQL document is only valid if referenced types (specifically variable definitions and fragment conditions) are defined by the type schema.`,
|
457
508
|
}), validationToRule('lone-anonymous-operation', 'LoneAnonymousOperation', {
|
509
|
+
category: 'Operations',
|
458
510
|
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.`,
|
459
511
|
}), validationToRule('lone-schema-definition', 'LoneSchemaDefinition', {
|
512
|
+
category: 'Schema',
|
460
513
|
description: `A GraphQL document is only valid if it contains only one schema definition.`,
|
461
514
|
requiresSchema: false,
|
462
515
|
}), validationToRule('no-fragment-cycles', 'NoFragmentCycles', {
|
516
|
+
category: 'Operations',
|
463
517
|
description: `A GraphQL fragment is only valid when it does not have cycles in fragments usage.`,
|
464
518
|
}), validationToRule('no-undefined-variables', 'NoUndefinedVariables', {
|
519
|
+
category: 'Operations',
|
465
520
|
description: `A GraphQL operation is only valid if all variables encountered, both directly and via fragment spreads, are defined by that operation.`,
|
466
521
|
}, importFiles), validationToRule('no-unused-fragments', 'NoUnusedFragments', {
|
522
|
+
category: 'Operations',
|
467
523
|
description: `A GraphQL document is only valid if all fragment definitions are spread within operations, or spread within other fragments spread within operations.`,
|
468
524
|
requiresSiblings: true,
|
469
525
|
}, context => {
|
@@ -493,49 +549,68 @@ const GRAPHQL_JS_VALIDATIONS = Object.assign({}, validationToRule('executable-de
|
|
493
549
|
};
|
494
550
|
return getParentNode(context.getFilename());
|
495
551
|
}), validationToRule('no-unused-variables', 'NoUnusedVariables', {
|
552
|
+
category: 'Operations',
|
496
553
|
description: `A GraphQL operation is only valid if all variables defined by an operation are used, either directly or within a spread fragment.`,
|
497
554
|
}, importFiles), validationToRule('overlapping-fields-can-be-merged', 'OverlappingFieldsCanBeMerged', {
|
555
|
+
category: 'Operations',
|
498
556
|
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.`,
|
499
557
|
}), validationToRule('possible-fragment-spread', 'PossibleFragmentSpreads', {
|
558
|
+
category: 'Operations',
|
500
559
|
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.`,
|
501
560
|
}), validationToRule('possible-type-extension', 'PossibleTypeExtensions', {
|
561
|
+
category: 'Schema',
|
502
562
|
description: `A type extension is only valid if the type is defined and has the same kind.`,
|
503
563
|
requiresSchema: false,
|
504
564
|
}), validationToRule('provided-required-arguments', 'ProvidedRequiredArguments', {
|
565
|
+
category: ['Schema', 'Operations'],
|
505
566
|
description: `A field or directive is only valid if all required (non-null without a default value) field arguments have been provided.`,
|
506
567
|
}), validationToRule('scalar-leafs', 'ScalarLeafs', {
|
568
|
+
category: 'Operations',
|
507
569
|
description: `A GraphQL document is valid only if all leaf fields (fields without sub selections) are of scalar or enum types.`,
|
508
570
|
}), validationToRule('one-field-subscriptions', 'SingleFieldSubscriptions', {
|
571
|
+
category: 'Operations',
|
509
572
|
description: `A GraphQL subscription is valid only if it contains a single root field.`,
|
510
573
|
}), validationToRule('unique-argument-names', 'UniqueArgumentNames', {
|
574
|
+
category: 'Operations',
|
511
575
|
description: `A GraphQL field or directive is only valid if all supplied arguments are uniquely named.`,
|
512
576
|
}), validationToRule('unique-directive-names', 'UniqueDirectiveNames', {
|
577
|
+
category: 'Schema',
|
513
578
|
description: `A GraphQL document is only valid if all defined directives have unique names.`,
|
514
579
|
requiresSchema: false,
|
515
580
|
}), validationToRule('unique-directive-names-per-location', 'UniqueDirectivesPerLocation', {
|
581
|
+
category: ['Schema', 'Operations'],
|
516
582
|
description: `A GraphQL document is only valid if all non-repeatable directives at a given location are uniquely named.`,
|
517
583
|
}), validationToRule('unique-enum-value-names', 'UniqueEnumValueNames', {
|
584
|
+
category: 'Schema',
|
518
585
|
description: `A GraphQL enum type is only valid if all its values are uniquely named.`,
|
519
586
|
requiresSchema: false,
|
520
587
|
}), validationToRule('unique-field-definition-names', 'UniqueFieldDefinitionNames', {
|
588
|
+
category: 'Schema',
|
521
589
|
description: `A GraphQL complex type is only valid if all its fields are uniquely named.`,
|
522
590
|
requiresSchema: false,
|
523
591
|
}), validationToRule('unique-input-field-names', 'UniqueInputFieldNames', {
|
592
|
+
category: 'Operations',
|
524
593
|
description: `A GraphQL input object value is only valid if all supplied fields are uniquely named.`,
|
525
594
|
requiresSchema: false,
|
526
595
|
}), validationToRule('unique-operation-types', 'UniqueOperationTypes', {
|
596
|
+
category: 'Schema',
|
527
597
|
description: `A GraphQL document is only valid if it has only one type per operation.`,
|
528
598
|
requiresSchema: false,
|
529
599
|
}), validationToRule('unique-type-names', 'UniqueTypeNames', {
|
600
|
+
category: 'Schema',
|
530
601
|
description: `A GraphQL document is only valid if all defined types have unique names.`,
|
531
602
|
requiresSchema: false,
|
532
603
|
}), validationToRule('unique-variable-names', 'UniqueVariableNames', {
|
604
|
+
category: 'Operations',
|
533
605
|
description: `A GraphQL operation is only valid if all its variables are uniquely named.`,
|
534
606
|
}), validationToRule('value-literals-of-correct-type', 'ValuesOfCorrectType', {
|
607
|
+
category: 'Operations',
|
535
608
|
description: `A GraphQL document is only valid if all value literals are of the type expected at their position.`,
|
536
609
|
}), validationToRule('variables-are-input-types', 'VariablesAreInputTypes', {
|
610
|
+
category: 'Operations',
|
537
611
|
description: `A GraphQL operation is only valid if all the variables it defines are of input types (scalar, enum, or input object).`,
|
538
612
|
}), validationToRule('variables-in-allowed-position', 'VariablesInAllowedPosition', {
|
613
|
+
category: 'Operations',
|
539
614
|
description: `Variables passed to field arguments conform to type.`,
|
540
615
|
}));
|
541
616
|
|
@@ -561,7 +636,7 @@ const rule = {
|
|
561
636
|
meta: {
|
562
637
|
type: 'suggestion',
|
563
638
|
docs: {
|
564
|
-
category: '
|
639
|
+
category: ['Schema', 'Operations'],
|
565
640
|
description: 'Enforce arrange in alphabetical order for type fields, enum values, input object fields, operation selections and more.',
|
566
641
|
url: 'https://github.com/dotansimha/graphql-eslint/blob/master/docs/rules/alphabetize.md',
|
567
642
|
examples: [
|
@@ -640,15 +715,22 @@ const rule = {
|
|
640
715
|
`,
|
641
716
|
},
|
642
717
|
],
|
643
|
-
|
644
|
-
|
645
|
-
|
646
|
-
|
647
|
-
|
648
|
-
|
649
|
-
|
650
|
-
|
651
|
-
|
718
|
+
configOptions: {
|
719
|
+
schema: [
|
720
|
+
{
|
721
|
+
fields: fieldsEnum,
|
722
|
+
values: valuesEnum,
|
723
|
+
arguments: argumentsEnum,
|
724
|
+
},
|
725
|
+
],
|
726
|
+
operations: [
|
727
|
+
{
|
728
|
+
selections: selectionsEnum,
|
729
|
+
variables: variablesEnum,
|
730
|
+
arguments: [Kind.FIELD, Kind.DIRECTIVE],
|
731
|
+
},
|
732
|
+
],
|
733
|
+
},
|
652
734
|
},
|
653
735
|
messages: {
|
654
736
|
[ALPHABETIZE]: '"{{ currName }}" should be before "{{ prevName }}"',
|
@@ -786,307 +868,7 @@ const rule = {
|
|
786
868
|
},
|
787
869
|
};
|
788
870
|
|
789
|
-
const AVOID_DUPLICATE_FIELDS = 'AVOID_DUPLICATE_FIELDS';
|
790
871
|
const rule$1 = {
|
791
|
-
meta: {
|
792
|
-
type: 'suggestion',
|
793
|
-
docs: {
|
794
|
-
description: `Checks for duplicate fields in selection set, variables in operation definition, or in arguments set of a field.`,
|
795
|
-
category: 'Stylistic Issues',
|
796
|
-
url: 'https://github.com/dotansimha/graphql-eslint/blob/master/docs/rules/avoid-duplicate-fields.md',
|
797
|
-
examples: [
|
798
|
-
{
|
799
|
-
title: 'Incorrect',
|
800
|
-
code: /* GraphQL */ `
|
801
|
-
query {
|
802
|
-
user {
|
803
|
-
name
|
804
|
-
email
|
805
|
-
name # duplicate field
|
806
|
-
}
|
807
|
-
}
|
808
|
-
`,
|
809
|
-
},
|
810
|
-
{
|
811
|
-
title: 'Incorrect',
|
812
|
-
code: /* GraphQL */ `
|
813
|
-
query {
|
814
|
-
users(
|
815
|
-
first: 100
|
816
|
-
skip: 50
|
817
|
-
after: "cji629tngfgou0b73kt7vi5jo"
|
818
|
-
first: 100 # duplicate argument
|
819
|
-
) {
|
820
|
-
id
|
821
|
-
}
|
822
|
-
}
|
823
|
-
`,
|
824
|
-
},
|
825
|
-
{
|
826
|
-
title: 'Incorrect',
|
827
|
-
code: /* GraphQL */ `
|
828
|
-
query (
|
829
|
-
$first: Int!
|
830
|
-
$first: Int! # duplicate variable
|
831
|
-
) {
|
832
|
-
users(first: $first, skip: 50) {
|
833
|
-
id
|
834
|
-
}
|
835
|
-
}
|
836
|
-
`,
|
837
|
-
},
|
838
|
-
],
|
839
|
-
},
|
840
|
-
messages: {
|
841
|
-
[AVOID_DUPLICATE_FIELDS]: `{{ type }} "{{ fieldName }}" defined multiple times`,
|
842
|
-
},
|
843
|
-
schema: [],
|
844
|
-
},
|
845
|
-
create(context) {
|
846
|
-
function checkNode(usedFields, fieldName, type, node) {
|
847
|
-
if (usedFields.has(fieldName)) {
|
848
|
-
context.report({
|
849
|
-
loc: getLocation((node.kind === Kind.FIELD && node.alias ? node.alias : node).loc, fieldName, {
|
850
|
-
offsetEnd: node.kind === Kind.VARIABLE_DEFINITION ? 0 : 1,
|
851
|
-
}),
|
852
|
-
messageId: AVOID_DUPLICATE_FIELDS,
|
853
|
-
data: {
|
854
|
-
type,
|
855
|
-
fieldName,
|
856
|
-
},
|
857
|
-
});
|
858
|
-
}
|
859
|
-
else {
|
860
|
-
usedFields.add(fieldName);
|
861
|
-
}
|
862
|
-
}
|
863
|
-
return {
|
864
|
-
OperationDefinition(node) {
|
865
|
-
const set = new Set();
|
866
|
-
for (const varDef of node.variableDefinitions) {
|
867
|
-
checkNode(set, varDef.variable.name.value, 'Operation variable', varDef);
|
868
|
-
}
|
869
|
-
},
|
870
|
-
Field(node) {
|
871
|
-
const set = new Set();
|
872
|
-
for (const arg of node.arguments) {
|
873
|
-
checkNode(set, arg.name.value, 'Field argument', arg);
|
874
|
-
}
|
875
|
-
},
|
876
|
-
SelectionSet(node) {
|
877
|
-
var _a;
|
878
|
-
const set = new Set();
|
879
|
-
for (const selection of node.selections) {
|
880
|
-
if (selection.kind === Kind.FIELD) {
|
881
|
-
checkNode(set, ((_a = selection.alias) === null || _a === void 0 ? void 0 : _a.value) || selection.name.value, 'Field', selection);
|
882
|
-
}
|
883
|
-
}
|
884
|
-
},
|
885
|
-
};
|
886
|
-
},
|
887
|
-
};
|
888
|
-
|
889
|
-
const AVOID_OPERATION_NAME_PREFIX = 'AVOID_OPERATION_NAME_PREFIX';
|
890
|
-
const rule$2 = {
|
891
|
-
meta: {
|
892
|
-
type: 'suggestion',
|
893
|
-
docs: {
|
894
|
-
description: 'Enforce/avoid operation name prefix, useful if you wish to avoid prefix in your root fields, or avoid using REST terminology in your schema.',
|
895
|
-
category: 'Stylistic Issues',
|
896
|
-
url: 'https://github.com/dotansimha/graphql-eslint/blob/master/docs/rules/avoid-operation-name-prefix.md',
|
897
|
-
examples: [
|
898
|
-
{
|
899
|
-
title: 'Incorrect',
|
900
|
-
usage: [{ keywords: ['get'] }],
|
901
|
-
code: /* GraphQL */ `
|
902
|
-
query getUserDetails {
|
903
|
-
# ...
|
904
|
-
}`,
|
905
|
-
},
|
906
|
-
{
|
907
|
-
title: 'Correct',
|
908
|
-
usage: [{ keywords: ['get'] }],
|
909
|
-
code: /* GraphQL */ `
|
910
|
-
query userDetails {
|
911
|
-
# ...
|
912
|
-
}`,
|
913
|
-
},
|
914
|
-
],
|
915
|
-
},
|
916
|
-
messages: {
|
917
|
-
[AVOID_OPERATION_NAME_PREFIX]: `Forbidden operation name prefix: "{{ invalidPrefix }}"`,
|
918
|
-
},
|
919
|
-
schema: [
|
920
|
-
{
|
921
|
-
additionalProperties: false,
|
922
|
-
type: 'object',
|
923
|
-
required: ['keywords'],
|
924
|
-
properties: {
|
925
|
-
caseSensitive: {
|
926
|
-
default: false,
|
927
|
-
type: 'boolean',
|
928
|
-
},
|
929
|
-
keywords: {
|
930
|
-
additionalItems: false,
|
931
|
-
type: 'array',
|
932
|
-
minItems: 1,
|
933
|
-
items: {
|
934
|
-
type: 'string',
|
935
|
-
},
|
936
|
-
},
|
937
|
-
},
|
938
|
-
},
|
939
|
-
],
|
940
|
-
},
|
941
|
-
create(context) {
|
942
|
-
return {
|
943
|
-
'OperationDefinition, FragmentDefinition'(node) {
|
944
|
-
const config = context.options[0] || { keywords: [], caseSensitive: false };
|
945
|
-
const caseSensitive = config.caseSensitive;
|
946
|
-
const keywords = config.keywords || [];
|
947
|
-
if (node && node.name && node.name.value !== '') {
|
948
|
-
for (const keyword of keywords) {
|
949
|
-
const testKeyword = caseSensitive ? keyword : keyword.toLowerCase();
|
950
|
-
const testName = caseSensitive ? node.name.value : node.name.value.toLowerCase();
|
951
|
-
if (testName.startsWith(testKeyword)) {
|
952
|
-
const { start } = node.name.loc;
|
953
|
-
context.report({
|
954
|
-
loc: {
|
955
|
-
start: {
|
956
|
-
line: start.line,
|
957
|
-
column: start.column - 1,
|
958
|
-
},
|
959
|
-
end: {
|
960
|
-
line: start.line,
|
961
|
-
column: start.column - 1 + testKeyword.length,
|
962
|
-
},
|
963
|
-
},
|
964
|
-
data: {
|
965
|
-
invalidPrefix: keyword,
|
966
|
-
},
|
967
|
-
messageId: AVOID_OPERATION_NAME_PREFIX,
|
968
|
-
});
|
969
|
-
}
|
970
|
-
}
|
971
|
-
}
|
972
|
-
},
|
973
|
-
};
|
974
|
-
},
|
975
|
-
};
|
976
|
-
|
977
|
-
const rule$3 = {
|
978
|
-
meta: {
|
979
|
-
type: 'suggestion',
|
980
|
-
docs: {
|
981
|
-
category: 'Best Practices',
|
982
|
-
description: 'Avoid scalar result type on mutation type to make sure to return a valid state.',
|
983
|
-
url: 'https://github.com/dotansimha/graphql-eslint/blob/master/docs/rules/avoid-scalar-result-type-on-mutation.md',
|
984
|
-
requiresSchema: true,
|
985
|
-
examples: [
|
986
|
-
{
|
987
|
-
title: 'Incorrect',
|
988
|
-
code: /* GraphQL */ `
|
989
|
-
type Mutation {
|
990
|
-
createUser: Boolean
|
991
|
-
}
|
992
|
-
`,
|
993
|
-
},
|
994
|
-
{
|
995
|
-
title: 'Correct',
|
996
|
-
code: /* GraphQL */ `
|
997
|
-
type Mutation {
|
998
|
-
createUser: User!
|
999
|
-
}
|
1000
|
-
`,
|
1001
|
-
},
|
1002
|
-
],
|
1003
|
-
},
|
1004
|
-
schema: [],
|
1005
|
-
},
|
1006
|
-
create(context) {
|
1007
|
-
const schema = requireGraphQLSchemaFromContext('avoid-scalar-result-type-on-mutation', context);
|
1008
|
-
const mutationType = schema.getMutationType();
|
1009
|
-
if (!mutationType) {
|
1010
|
-
return {};
|
1011
|
-
}
|
1012
|
-
const selector = [
|
1013
|
-
`:matches(${Kind.OBJECT_TYPE_DEFINITION}, ${Kind.OBJECT_TYPE_EXTENSION})[name.value=${mutationType.name}]`,
|
1014
|
-
'>',
|
1015
|
-
Kind.FIELD_DEFINITION,
|
1016
|
-
Kind.NAMED_TYPE,
|
1017
|
-
].join(' ');
|
1018
|
-
return {
|
1019
|
-
[selector](node) {
|
1020
|
-
const typeName = node.name.value;
|
1021
|
-
const graphQLType = schema.getType(typeName);
|
1022
|
-
if (isScalarType(graphQLType)) {
|
1023
|
-
context.report({
|
1024
|
-
loc: getLocation(node.loc, typeName),
|
1025
|
-
message: `Unexpected scalar result type "${typeName}"`,
|
1026
|
-
});
|
1027
|
-
}
|
1028
|
-
},
|
1029
|
-
};
|
1030
|
-
},
|
1031
|
-
};
|
1032
|
-
|
1033
|
-
const AVOID_TYPENAME_PREFIX = 'AVOID_TYPENAME_PREFIX';
|
1034
|
-
const rule$4 = {
|
1035
|
-
meta: {
|
1036
|
-
type: 'suggestion',
|
1037
|
-
docs: {
|
1038
|
-
category: 'Best Practices',
|
1039
|
-
description: 'Enforces users to avoid using the type name in a field name while defining your schema.',
|
1040
|
-
recommended: true,
|
1041
|
-
url: 'https://github.com/dotansimha/graphql-eslint/blob/master/docs/rules/avoid-typename-prefix.md',
|
1042
|
-
examples: [
|
1043
|
-
{
|
1044
|
-
title: 'Incorrect',
|
1045
|
-
code: /* GraphQL */ `
|
1046
|
-
type User {
|
1047
|
-
userId: ID!
|
1048
|
-
}
|
1049
|
-
`,
|
1050
|
-
},
|
1051
|
-
{
|
1052
|
-
title: 'Correct',
|
1053
|
-
code: /* GraphQL */ `
|
1054
|
-
type User {
|
1055
|
-
id: ID!
|
1056
|
-
}
|
1057
|
-
`,
|
1058
|
-
},
|
1059
|
-
],
|
1060
|
-
},
|
1061
|
-
messages: {
|
1062
|
-
[AVOID_TYPENAME_PREFIX]: `Field "{{ fieldName }}" starts with the name of the parent type "{{ typeName }}"`,
|
1063
|
-
},
|
1064
|
-
schema: [],
|
1065
|
-
},
|
1066
|
-
create(context) {
|
1067
|
-
return {
|
1068
|
-
'ObjectTypeDefinition, ObjectTypeExtension, InterfaceTypeDefinition, InterfaceTypeExtension'(node) {
|
1069
|
-
const typeName = node.name.value;
|
1070
|
-
const lowerTypeName = typeName.toLowerCase();
|
1071
|
-
for (const field of node.fields) {
|
1072
|
-
const fieldName = field.name.value;
|
1073
|
-
if (fieldName.toLowerCase().startsWith(lowerTypeName)) {
|
1074
|
-
context.report({
|
1075
|
-
data: {
|
1076
|
-
fieldName,
|
1077
|
-
typeName,
|
1078
|
-
},
|
1079
|
-
messageId: AVOID_TYPENAME_PREFIX,
|
1080
|
-
loc: getLocation(field.loc, lowerTypeName),
|
1081
|
-
});
|
1082
|
-
}
|
1083
|
-
}
|
1084
|
-
},
|
1085
|
-
};
|
1086
|
-
},
|
1087
|
-
};
|
1088
|
-
|
1089
|
-
const rule$5 = {
|
1090
872
|
meta: {
|
1091
873
|
type: 'suggestion',
|
1092
874
|
docs: {
|
@@ -1113,20 +895,20 @@ const rule$5 = {
|
|
1113
895
|
},
|
1114
896
|
],
|
1115
897
|
description: 'Require all comments to follow the same style (either block or inline).',
|
1116
|
-
category: '
|
898
|
+
category: 'Schema',
|
1117
899
|
url: 'https://github.com/dotansimha/graphql-eslint/blob/master/docs/rules/description-style.md',
|
900
|
+
recommended: true,
|
1118
901
|
},
|
1119
902
|
schema: [
|
1120
903
|
{
|
1121
904
|
type: 'object',
|
905
|
+
additionalProperties: false,
|
1122
906
|
properties: {
|
1123
907
|
style: {
|
1124
|
-
type: 'string',
|
1125
908
|
enum: ['block', 'inline'],
|
1126
909
|
default: 'inline',
|
1127
910
|
},
|
1128
911
|
},
|
1129
|
-
additionalProperties: false,
|
1130
912
|
},
|
1131
913
|
],
|
1132
914
|
},
|
@@ -1149,12 +931,12 @@ const rule$5 = {
|
|
1149
931
|
const isObjectType = (node) => [Kind.OBJECT_TYPE_DEFINITION, Kind.OBJECT_TYPE_EXTENSION].includes(node.type);
|
1150
932
|
const isQueryType = (node) => isObjectType(node) && node.name.value === 'Query';
|
1151
933
|
const isMutationType = (node) => isObjectType(node) && node.name.value === 'Mutation';
|
1152
|
-
const rule$
|
934
|
+
const rule$2 = {
|
1153
935
|
meta: {
|
1154
936
|
type: 'suggestion',
|
1155
937
|
docs: {
|
1156
938
|
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.',
|
1157
|
-
category: '
|
939
|
+
category: 'Schema',
|
1158
940
|
url: 'https://github.com/dotansimha/graphql-eslint/blob/master/docs/rules/input-name.md',
|
1159
941
|
examples: [
|
1160
942
|
{
|
@@ -1275,11 +1057,11 @@ const CASE_STYLES = [
|
|
1275
1057
|
const schemaOption = {
|
1276
1058
|
oneOf: [{ $ref: '#/definitions/asString' }, { $ref: '#/definitions/asObject' }],
|
1277
1059
|
};
|
1278
|
-
const rule$
|
1060
|
+
const rule$3 = {
|
1279
1061
|
meta: {
|
1280
1062
|
type: 'suggestion',
|
1281
1063
|
docs: {
|
1282
|
-
category: '
|
1064
|
+
category: 'Operations',
|
1283
1065
|
description: 'This rule allows you to enforce that the file name should match the operation name.',
|
1284
1066
|
url: `https://github.com/dotansimha/graphql-eslint/blob/master/docs/rules/match-document-filename.md`,
|
1285
1067
|
examples: [
|
@@ -1353,6 +1135,14 @@ const rule$7 = {
|
|
1353
1135
|
`,
|
1354
1136
|
},
|
1355
1137
|
],
|
1138
|
+
configOptions: [
|
1139
|
+
{
|
1140
|
+
query: CaseStyle.kebabCase,
|
1141
|
+
mutation: CaseStyle.kebabCase,
|
1142
|
+
subscription: CaseStyle.kebabCase,
|
1143
|
+
fragment: CaseStyle.kebabCase,
|
1144
|
+
},
|
1145
|
+
],
|
1356
1146
|
},
|
1357
1147
|
messages: {
|
1358
1148
|
[MATCH_EXTENSION]: `File extension "{{ fileExtension }}" don't match extension "{{ expectedFileExtension }}"`,
|
@@ -1361,27 +1151,29 @@ const rule$7 = {
|
|
1361
1151
|
schema: {
|
1362
1152
|
definitions: {
|
1363
1153
|
asString: {
|
1364
|
-
type: 'string',
|
1365
|
-
description: `One of: ${CASE_STYLES.map(t => `\`${t}\``).join(', ')}`,
|
1366
1154
|
enum: CASE_STYLES,
|
1155
|
+
description: `One of: ${CASE_STYLES.map(t => `\`${t}\``).join(', ')}`,
|
1367
1156
|
},
|
1368
1157
|
asObject: {
|
1369
1158
|
type: 'object',
|
1159
|
+
additionalProperties: false,
|
1370
1160
|
properties: {
|
1371
1161
|
style: {
|
1372
|
-
type: 'string',
|
1373
1162
|
enum: CASE_STYLES,
|
1374
1163
|
},
|
1164
|
+
suffix: {
|
1165
|
+
type: 'string',
|
1166
|
+
},
|
1375
1167
|
},
|
1376
1168
|
},
|
1377
1169
|
},
|
1378
|
-
$schema: 'http://json-schema.org/draft-04/schema#',
|
1379
1170
|
type: 'array',
|
1171
|
+
maxItems: 1,
|
1380
1172
|
items: {
|
1381
1173
|
type: 'object',
|
1174
|
+
additionalProperties: false,
|
1382
1175
|
properties: {
|
1383
1176
|
fileExtension: {
|
1384
|
-
type: 'string',
|
1385
1177
|
enum: ACCEPTED_EXTENSIONS,
|
1386
1178
|
},
|
1387
1179
|
query: schemaOption,
|
@@ -1456,13 +1248,7 @@ const rule$7 = {
|
|
1456
1248
|
},
|
1457
1249
|
};
|
1458
1250
|
|
1459
|
-
const FIELDS_KINDS = [
|
1460
|
-
Kind.FIELD_DEFINITION,
|
1461
|
-
Kind.INPUT_VALUE_DEFINITION,
|
1462
|
-
Kind.VARIABLE_DEFINITION,
|
1463
|
-
Kind.ARGUMENT,
|
1464
|
-
Kind.DIRECTIVE_DEFINITION,
|
1465
|
-
];
|
1251
|
+
const FIELDS_KINDS = [Kind.FIELD_DEFINITION, Kind.INPUT_VALUE_DEFINITION, Kind.ARGUMENT, Kind.DIRECTIVE_DEFINITION];
|
1466
1252
|
const KindToDisplayName = {
|
1467
1253
|
// types
|
1468
1254
|
[Kind.OBJECT_TYPE_DEFINITION]: 'Type',
|
@@ -1474,13 +1260,13 @@ const KindToDisplayName = {
|
|
1474
1260
|
// fields
|
1475
1261
|
[Kind.FIELD_DEFINITION]: 'Field',
|
1476
1262
|
[Kind.INPUT_VALUE_DEFINITION]: 'Input property',
|
1477
|
-
[Kind.VARIABLE_DEFINITION]: 'Variable',
|
1478
1263
|
[Kind.ARGUMENT]: 'Argument',
|
1479
1264
|
[Kind.DIRECTIVE_DEFINITION]: 'Directive',
|
1480
1265
|
// rest
|
1481
1266
|
[Kind.ENUM_VALUE_DEFINITION]: 'Enumeration value',
|
1482
1267
|
[Kind.OPERATION_DEFINITION]: 'Operation',
|
1483
1268
|
[Kind.FRAGMENT_DEFINITION]: 'Fragment',
|
1269
|
+
[Kind.VARIABLE_DEFINITION]: 'Variable',
|
1484
1270
|
};
|
1485
1271
|
const StyleToRegex = {
|
1486
1272
|
camelCase: /^[a-z][\dA-Za-z]*$/,
|
@@ -1493,12 +1279,12 @@ const ALLOWED_STYLES = Object.keys(StyleToRegex);
|
|
1493
1279
|
const schemaOption$1 = {
|
1494
1280
|
oneOf: [{ $ref: '#/definitions/asString' }, { $ref: '#/definitions/asObject' }],
|
1495
1281
|
};
|
1496
|
-
const rule$
|
1282
|
+
const rule$4 = {
|
1497
1283
|
meta: {
|
1498
1284
|
type: 'suggestion',
|
1499
1285
|
docs: {
|
1500
1286
|
description: 'Require names to follow specified conventions.',
|
1501
|
-
category: '
|
1287
|
+
category: ['Schema', 'Operations'],
|
1502
1288
|
recommended: true,
|
1503
1289
|
url: 'https://github.com/dotansimha/graphql-eslint/blob/master/docs/rules/naming-convention.md',
|
1504
1290
|
examples: [
|
@@ -1521,37 +1307,47 @@ const rule$8 = {
|
|
1521
1307
|
`,
|
1522
1308
|
},
|
1523
1309
|
],
|
1524
|
-
|
1525
|
-
|
1526
|
-
|
1527
|
-
|
1528
|
-
|
1529
|
-
|
1530
|
-
|
1531
|
-
|
1532
|
-
|
1533
|
-
|
1534
|
-
|
1535
|
-
|
1536
|
-
|
1537
|
-
|
1538
|
-
|
1539
|
-
|
1540
|
-
|
1541
|
-
|
1542
|
-
|
1543
|
-
},
|
1544
|
-
'FieldDefinition[parent.name.value=Mutation]': {
|
1545
|
-
forbiddenPrefixes: ['mutation'],
|
1546
|
-
forbiddenSuffixes: ['Mutation'],
|
1310
|
+
configOptions: {
|
1311
|
+
schema: [
|
1312
|
+
{
|
1313
|
+
types: 'PascalCase',
|
1314
|
+
fields: 'camelCase',
|
1315
|
+
overrides: {
|
1316
|
+
EnumValueDefinition: 'UPPER_CASE',
|
1317
|
+
'FieldDefinition[parent.name.value=Query]': {
|
1318
|
+
forbiddenPrefixes: ['query', 'get'],
|
1319
|
+
forbiddenSuffixes: ['Query'],
|
1320
|
+
},
|
1321
|
+
'FieldDefinition[parent.name.value=Mutation]': {
|
1322
|
+
forbiddenPrefixes: ['mutation'],
|
1323
|
+
forbiddenSuffixes: ['Mutation'],
|
1324
|
+
},
|
1325
|
+
'FieldDefinition[parent.name.value=Subscription]': {
|
1326
|
+
forbiddenPrefixes: ['subscription'],
|
1327
|
+
forbiddenSuffixes: ['Subscription'],
|
1328
|
+
},
|
1547
1329
|
},
|
1548
|
-
|
1549
|
-
|
1550
|
-
|
1330
|
+
},
|
1331
|
+
],
|
1332
|
+
operations: [
|
1333
|
+
{
|
1334
|
+
overrides: {
|
1335
|
+
Argument: 'camelCase',
|
1336
|
+
VariableDefinition: 'camelCase',
|
1337
|
+
OperationDefinition: {
|
1338
|
+
style: 'PascalCase',
|
1339
|
+
forbiddenPrefixes: ['Query', 'Mutation', 'Subscription', 'Get'],
|
1340
|
+
forbiddenSuffixes: ['Query', 'Mutation', 'Subscription'],
|
1341
|
+
},
|
1342
|
+
FragmentDefinition: {
|
1343
|
+
style: 'PascalCase',
|
1344
|
+
forbiddenPrefixes: ['Fragment'],
|
1345
|
+
forbiddenSuffixes: ['Fragment'],
|
1346
|
+
},
|
1551
1347
|
},
|
1552
1348
|
},
|
1553
|
-
|
1554
|
-
|
1349
|
+
],
|
1350
|
+
},
|
1555
1351
|
},
|
1556
1352
|
schema: {
|
1557
1353
|
definitions: {
|
@@ -1589,11 +1385,11 @@ const rule$8 = {
|
|
1589
1385
|
properties: {
|
1590
1386
|
types: {
|
1591
1387
|
...schemaOption$1,
|
1592
|
-
description: `Includes:\n\n${TYPES_KINDS.map(kind => `-
|
1388
|
+
description: `Includes:\n\n${TYPES_KINDS.map(kind => `- [${kind}](https://spec.graphql.org/October2021/#${kind})`).join('\n')}`,
|
1593
1389
|
},
|
1594
1390
|
fields: {
|
1595
1391
|
...schemaOption$1,
|
1596
|
-
description: `Includes:\n\n${FIELDS_KINDS.map(kind => `-
|
1392
|
+
description: `Includes:\n\n${FIELDS_KINDS.map(kind => `- [${kind}](https://spec.graphql.org/October2021/#${kind})`).join('\n')}`,
|
1597
1393
|
},
|
1598
1394
|
allowLeadingUnderscore: {
|
1599
1395
|
type: 'boolean',
|
@@ -1609,7 +1405,7 @@ const rule$8 = {
|
|
1609
1405
|
description: [
|
1610
1406
|
'May contain the following `ASTNode` names:',
|
1611
1407
|
'',
|
1612
|
-
...ALLOWED_KINDS.map(kind => `-
|
1408
|
+
...ALLOWED_KINDS.map(kind => `- [${kind}](https://spec.graphql.org/October2021/#${kind})`),
|
1613
1409
|
'',
|
1614
1410
|
"> It's also possible to use a [`selector`](https://eslint.org/docs/developer-guide/selectors) that starts with `ASTNode` name",
|
1615
1411
|
'>',
|
@@ -1706,11 +1502,11 @@ const rule$8 = {
|
|
1706
1502
|
};
|
1707
1503
|
|
1708
1504
|
const NO_ANONYMOUS_OPERATIONS = 'NO_ANONYMOUS_OPERATIONS';
|
1709
|
-
const rule$
|
1505
|
+
const rule$5 = {
|
1710
1506
|
meta: {
|
1711
1507
|
type: 'suggestion',
|
1712
1508
|
docs: {
|
1713
|
-
category: '
|
1509
|
+
category: 'Operations',
|
1714
1510
|
description: 'Require name for your GraphQL operations. This is useful since most GraphQL client libraries are using the operation name for caching purposes.',
|
1715
1511
|
recommended: true,
|
1716
1512
|
url: 'https://github.com/dotansimha/graphql-eslint/blob/master/docs/rules/no-anonymous-operations.md',
|
@@ -1754,12 +1550,12 @@ const rule$9 = {
|
|
1754
1550
|
};
|
1755
1551
|
|
1756
1552
|
const ERROR_MESSAGE_ID = 'NO_CASE_INSENSITIVE_ENUM_VALUES_DUPLICATES';
|
1757
|
-
const rule$
|
1553
|
+
const rule$6 = {
|
1758
1554
|
meta: {
|
1759
1555
|
type: 'suggestion',
|
1760
1556
|
docs: {
|
1761
1557
|
url: 'https://github.com/dotansimha/graphql-eslint/blob/master/docs/rules/no-case-insensitive-enum-values-duplicates.md',
|
1762
|
-
category: '
|
1558
|
+
category: 'Schema',
|
1763
1559
|
recommended: true,
|
1764
1560
|
description: 'Disallow case-insensitive enum values duplicates.',
|
1765
1561
|
examples: [
|
@@ -1810,11 +1606,11 @@ const rule$a = {
|
|
1810
1606
|
};
|
1811
1607
|
|
1812
1608
|
const NO_DEPRECATED = 'NO_DEPRECATED';
|
1813
|
-
const rule$
|
1609
|
+
const rule$7 = {
|
1814
1610
|
meta: {
|
1815
1611
|
type: 'suggestion',
|
1816
1612
|
docs: {
|
1817
|
-
category: '
|
1613
|
+
category: 'Operations',
|
1818
1614
|
description: `Enforce that deprecated fields or enum values are not in use by operations.`,
|
1819
1615
|
url: `https://github.com/dotansimha/graphql-eslint/blob/master/docs/rules/no-deprecated.md`,
|
1820
1616
|
requiresSchema: true,
|
@@ -1880,6 +1676,7 @@ const rule$b = {
|
|
1880
1676
|
`,
|
1881
1677
|
},
|
1882
1678
|
],
|
1679
|
+
recommended: true,
|
1883
1680
|
},
|
1884
1681
|
messages: {
|
1885
1682
|
[NO_DEPRECATED]: `This {{ type }} is marked as deprecated in your GraphQL schema {{ reason }}`,
|
@@ -1906,19 +1703,120 @@ const rule$b = {
|
|
1906
1703
|
}
|
1907
1704
|
},
|
1908
1705
|
Field(node) {
|
1909
|
-
requireGraphQLSchemaFromContext('no-deprecated', context);
|
1910
|
-
const typeInfo = node.typeInfo();
|
1911
|
-
if (typeInfo && typeInfo.fieldDef) {
|
1912
|
-
if (typeInfo.fieldDef.deprecationReason) {
|
1913
|
-
const fieldName = node.name.value;
|
1914
|
-
context.report({
|
1915
|
-
loc: getLocation(node.loc, fieldName),
|
1916
|
-
messageId: NO_DEPRECATED,
|
1917
|
-
data: {
|
1918
|
-
type: 'field',
|
1919
|
-
reason: typeInfo.fieldDef.deprecationReason ? `(reason: ${typeInfo.fieldDef.deprecationReason})` : '',
|
1920
|
-
},
|
1921
|
-
});
|
1706
|
+
requireGraphQLSchemaFromContext('no-deprecated', context);
|
1707
|
+
const typeInfo = node.typeInfo();
|
1708
|
+
if (typeInfo && typeInfo.fieldDef) {
|
1709
|
+
if (typeInfo.fieldDef.deprecationReason) {
|
1710
|
+
const fieldName = node.name.value;
|
1711
|
+
context.report({
|
1712
|
+
loc: getLocation(node.loc, fieldName),
|
1713
|
+
messageId: NO_DEPRECATED,
|
1714
|
+
data: {
|
1715
|
+
type: 'field',
|
1716
|
+
reason: typeInfo.fieldDef.deprecationReason ? `(reason: ${typeInfo.fieldDef.deprecationReason})` : '',
|
1717
|
+
},
|
1718
|
+
});
|
1719
|
+
}
|
1720
|
+
}
|
1721
|
+
},
|
1722
|
+
};
|
1723
|
+
},
|
1724
|
+
};
|
1725
|
+
|
1726
|
+
const NO_DUPLICATE_FIELDS = 'NO_DUPLICATE_FIELDS';
|
1727
|
+
const rule$8 = {
|
1728
|
+
meta: {
|
1729
|
+
type: 'suggestion',
|
1730
|
+
docs: {
|
1731
|
+
description: `Checks for duplicate fields in selection set, variables in operation definition, or in arguments set of a field.`,
|
1732
|
+
category: 'Operations',
|
1733
|
+
url: 'https://github.com/dotansimha/graphql-eslint/blob/master/docs/rules/no-duplicate-fields.md',
|
1734
|
+
recommended: true,
|
1735
|
+
examples: [
|
1736
|
+
{
|
1737
|
+
title: 'Incorrect',
|
1738
|
+
code: /* GraphQL */ `
|
1739
|
+
query {
|
1740
|
+
user {
|
1741
|
+
name
|
1742
|
+
email
|
1743
|
+
name # duplicate field
|
1744
|
+
}
|
1745
|
+
}
|
1746
|
+
`,
|
1747
|
+
},
|
1748
|
+
{
|
1749
|
+
title: 'Incorrect',
|
1750
|
+
code: /* GraphQL */ `
|
1751
|
+
query {
|
1752
|
+
users(
|
1753
|
+
first: 100
|
1754
|
+
skip: 50
|
1755
|
+
after: "cji629tngfgou0b73kt7vi5jo"
|
1756
|
+
first: 100 # duplicate argument
|
1757
|
+
) {
|
1758
|
+
id
|
1759
|
+
}
|
1760
|
+
}
|
1761
|
+
`,
|
1762
|
+
},
|
1763
|
+
{
|
1764
|
+
title: 'Incorrect',
|
1765
|
+
code: /* GraphQL */ `
|
1766
|
+
query (
|
1767
|
+
$first: Int!
|
1768
|
+
$first: Int! # duplicate variable
|
1769
|
+
) {
|
1770
|
+
users(first: $first, skip: 50) {
|
1771
|
+
id
|
1772
|
+
}
|
1773
|
+
}
|
1774
|
+
`,
|
1775
|
+
},
|
1776
|
+
],
|
1777
|
+
},
|
1778
|
+
messages: {
|
1779
|
+
[NO_DUPLICATE_FIELDS]: `{{ type }} "{{ fieldName }}" defined multiple times`,
|
1780
|
+
},
|
1781
|
+
schema: [],
|
1782
|
+
},
|
1783
|
+
create(context) {
|
1784
|
+
function checkNode(usedFields, fieldName, type, node) {
|
1785
|
+
if (usedFields.has(fieldName)) {
|
1786
|
+
context.report({
|
1787
|
+
loc: getLocation((node.kind === Kind.FIELD && node.alias ? node.alias : node).loc, fieldName, {
|
1788
|
+
offsetEnd: node.kind === Kind.VARIABLE_DEFINITION ? 0 : 1,
|
1789
|
+
}),
|
1790
|
+
messageId: NO_DUPLICATE_FIELDS,
|
1791
|
+
data: {
|
1792
|
+
type,
|
1793
|
+
fieldName,
|
1794
|
+
},
|
1795
|
+
});
|
1796
|
+
}
|
1797
|
+
else {
|
1798
|
+
usedFields.add(fieldName);
|
1799
|
+
}
|
1800
|
+
}
|
1801
|
+
return {
|
1802
|
+
OperationDefinition(node) {
|
1803
|
+
const set = new Set();
|
1804
|
+
for (const varDef of node.variableDefinitions) {
|
1805
|
+
checkNode(set, varDef.variable.name.value, 'Operation variable', varDef);
|
1806
|
+
}
|
1807
|
+
},
|
1808
|
+
Field(node) {
|
1809
|
+
const set = new Set();
|
1810
|
+
for (const arg of node.arguments) {
|
1811
|
+
checkNode(set, arg.name.value, 'Field argument', arg);
|
1812
|
+
}
|
1813
|
+
},
|
1814
|
+
SelectionSet(node) {
|
1815
|
+
var _a;
|
1816
|
+
const set = new Set();
|
1817
|
+
for (const selection of node.selections) {
|
1818
|
+
if (selection.kind === Kind.FIELD) {
|
1819
|
+
checkNode(set, ((_a = selection.alias) === null || _a === void 0 ? void 0 : _a.value) || selection.name.value, 'Field', selection);
|
1922
1820
|
}
|
1923
1821
|
}
|
1924
1822
|
},
|
@@ -1927,14 +1825,14 @@ const rule$b = {
|
|
1927
1825
|
};
|
1928
1826
|
|
1929
1827
|
const HASHTAG_COMMENT = 'HASHTAG_COMMENT';
|
1930
|
-
const rule$
|
1828
|
+
const rule$9 = {
|
1931
1829
|
meta: {
|
1932
1830
|
messages: {
|
1933
1831
|
[HASHTAG_COMMENT]: 'Using hashtag (#) for adding GraphQL descriptions is not allowed. Prefer using """ for multiline, or " for a single line description.',
|
1934
1832
|
},
|
1935
1833
|
docs: {
|
1936
1834
|
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.',
|
1937
|
-
category: '
|
1835
|
+
category: 'Schema',
|
1938
1836
|
url: 'https://github.com/dotansimha/graphql-eslint/blob/master/docs/rules/no-hashtag-description.md',
|
1939
1837
|
examples: [
|
1940
1838
|
{
|
@@ -1971,6 +1869,7 @@ const rule$c = {
|
|
1971
1869
|
`,
|
1972
1870
|
},
|
1973
1871
|
],
|
1872
|
+
recommended: true,
|
1974
1873
|
},
|
1975
1874
|
type: 'suggestion',
|
1976
1875
|
schema: [],
|
@@ -1999,79 +1898,12 @@ const rule$c = {
|
|
1999
1898
|
},
|
2000
1899
|
};
|
2001
1900
|
|
2002
|
-
const NO_OPERATION_NAME_SUFFIX = 'NO_OPERATION_NAME_SUFFIX';
|
2003
|
-
const rule$d = {
|
2004
|
-
meta: {
|
2005
|
-
fixable: 'code',
|
2006
|
-
type: 'suggestion',
|
2007
|
-
docs: {
|
2008
|
-
category: 'Stylistic Issues',
|
2009
|
-
recommended: true,
|
2010
|
-
description: `Makes sure you are not adding the operation type to the name of the operation.`,
|
2011
|
-
url: `https://github.com/dotansimha/graphql-eslint/blob/master/docs/rules/no-operation-name-suffix.md`,
|
2012
|
-
examples: [
|
2013
|
-
{
|
2014
|
-
title: 'Incorrect',
|
2015
|
-
code: /* GraphQL */ `
|
2016
|
-
query userQuery {
|
2017
|
-
# ...
|
2018
|
-
}
|
2019
|
-
`,
|
2020
|
-
},
|
2021
|
-
{
|
2022
|
-
title: 'Correct',
|
2023
|
-
code: /* GraphQL */ `
|
2024
|
-
query user {
|
2025
|
-
# ...
|
2026
|
-
}
|
2027
|
-
`,
|
2028
|
-
},
|
2029
|
-
],
|
2030
|
-
},
|
2031
|
-
messages: {
|
2032
|
-
[NO_OPERATION_NAME_SUFFIX]: `Unnecessary "{{ invalidSuffix }}" suffix in your operation name!`,
|
2033
|
-
},
|
2034
|
-
schema: [],
|
2035
|
-
},
|
2036
|
-
create(context) {
|
2037
|
-
return {
|
2038
|
-
'OperationDefinition, FragmentDefinition'(node) {
|
2039
|
-
var _a;
|
2040
|
-
const name = ((_a = node.name) === null || _a === void 0 ? void 0 : _a.value) || '';
|
2041
|
-
if (name.length > 0) {
|
2042
|
-
const invalidSuffix = 'operation' in node ? node.operation : 'fragment';
|
2043
|
-
if (name.toLowerCase().endsWith(invalidSuffix)) {
|
2044
|
-
const { start, end } = node.name.loc;
|
2045
|
-
context.report({
|
2046
|
-
loc: {
|
2047
|
-
start: {
|
2048
|
-
column: start.column - 1 + name.length - invalidSuffix.length,
|
2049
|
-
line: start.line,
|
2050
|
-
},
|
2051
|
-
end: {
|
2052
|
-
column: end.column - 1 + name.length,
|
2053
|
-
line: end.line,
|
2054
|
-
},
|
2055
|
-
},
|
2056
|
-
data: {
|
2057
|
-
invalidSuffix,
|
2058
|
-
},
|
2059
|
-
fix: fixer => fixer.removeRange([node.name.range[1] - invalidSuffix.length, node.name.range[1]]),
|
2060
|
-
messageId: NO_OPERATION_NAME_SUFFIX,
|
2061
|
-
});
|
2062
|
-
}
|
2063
|
-
}
|
2064
|
-
},
|
2065
|
-
};
|
2066
|
-
},
|
2067
|
-
};
|
2068
|
-
|
2069
1901
|
const ROOT_TYPES = ['query', 'mutation', 'subscription'];
|
2070
|
-
const rule$
|
1902
|
+
const rule$a = {
|
2071
1903
|
meta: {
|
2072
1904
|
type: 'suggestion',
|
2073
1905
|
docs: {
|
2074
|
-
category: '
|
1906
|
+
category: 'Schema',
|
2075
1907
|
description: 'Disallow using root types for `read-only` or `write-only` schemas.',
|
2076
1908
|
url: 'https://github.com/dotansimha/graphql-eslint/blob/master/docs/rules/no-root-type.md',
|
2077
1909
|
requiresSchema: true,
|
@@ -2104,7 +1936,6 @@ const rule$e = {
|
|
2104
1936
|
`,
|
2105
1937
|
},
|
2106
1938
|
],
|
2107
|
-
optionsForConfig: [{ disallow: ['subscription'] }],
|
2108
1939
|
},
|
2109
1940
|
schema: {
|
2110
1941
|
type: 'array',
|
@@ -2157,16 +1988,128 @@ const rule$e = {
|
|
2157
1988
|
},
|
2158
1989
|
};
|
2159
1990
|
|
1991
|
+
const rule$b = {
|
1992
|
+
meta: {
|
1993
|
+
type: 'suggestion',
|
1994
|
+
docs: {
|
1995
|
+
category: 'Schema',
|
1996
|
+
description: 'Avoid scalar result type on mutation type to make sure to return a valid state.',
|
1997
|
+
url: 'https://github.com/dotansimha/graphql-eslint/blob/master/docs/rules/no-scalar-result-type-on-mutation.md',
|
1998
|
+
requiresSchema: true,
|
1999
|
+
examples: [
|
2000
|
+
{
|
2001
|
+
title: 'Incorrect',
|
2002
|
+
code: /* GraphQL */ `
|
2003
|
+
type Mutation {
|
2004
|
+
createUser: Boolean
|
2005
|
+
}
|
2006
|
+
`,
|
2007
|
+
},
|
2008
|
+
{
|
2009
|
+
title: 'Correct',
|
2010
|
+
code: /* GraphQL */ `
|
2011
|
+
type Mutation {
|
2012
|
+
createUser: User!
|
2013
|
+
}
|
2014
|
+
`,
|
2015
|
+
},
|
2016
|
+
],
|
2017
|
+
},
|
2018
|
+
schema: [],
|
2019
|
+
},
|
2020
|
+
create(context) {
|
2021
|
+
const schema = requireGraphQLSchemaFromContext('no-scalar-result-type-on-mutation', context);
|
2022
|
+
const mutationType = schema.getMutationType();
|
2023
|
+
if (!mutationType) {
|
2024
|
+
return {};
|
2025
|
+
}
|
2026
|
+
const selector = [
|
2027
|
+
`:matches(${Kind.OBJECT_TYPE_DEFINITION}, ${Kind.OBJECT_TYPE_EXTENSION})[name.value=${mutationType.name}]`,
|
2028
|
+
'>',
|
2029
|
+
Kind.FIELD_DEFINITION,
|
2030
|
+
Kind.NAMED_TYPE,
|
2031
|
+
].join(' ');
|
2032
|
+
return {
|
2033
|
+
[selector](node) {
|
2034
|
+
const typeName = node.name.value;
|
2035
|
+
const graphQLType = schema.getType(typeName);
|
2036
|
+
if (isScalarType(graphQLType)) {
|
2037
|
+
context.report({
|
2038
|
+
loc: getLocation(node.loc, typeName),
|
2039
|
+
message: `Unexpected scalar result type "${typeName}"`,
|
2040
|
+
});
|
2041
|
+
}
|
2042
|
+
},
|
2043
|
+
};
|
2044
|
+
},
|
2045
|
+
};
|
2046
|
+
|
2047
|
+
const NO_TYPENAME_PREFIX = 'NO_TYPENAME_PREFIX';
|
2048
|
+
const rule$c = {
|
2049
|
+
meta: {
|
2050
|
+
type: 'suggestion',
|
2051
|
+
docs: {
|
2052
|
+
category: 'Schema',
|
2053
|
+
description: 'Enforces users to avoid using the type name in a field name while defining your schema.',
|
2054
|
+
recommended: true,
|
2055
|
+
url: 'https://github.com/dotansimha/graphql-eslint/blob/master/docs/rules/no-typename-prefix.md',
|
2056
|
+
examples: [
|
2057
|
+
{
|
2058
|
+
title: 'Incorrect',
|
2059
|
+
code: /* GraphQL */ `
|
2060
|
+
type User {
|
2061
|
+
userId: ID!
|
2062
|
+
}
|
2063
|
+
`,
|
2064
|
+
},
|
2065
|
+
{
|
2066
|
+
title: 'Correct',
|
2067
|
+
code: /* GraphQL */ `
|
2068
|
+
type User {
|
2069
|
+
id: ID!
|
2070
|
+
}
|
2071
|
+
`,
|
2072
|
+
},
|
2073
|
+
],
|
2074
|
+
},
|
2075
|
+
messages: {
|
2076
|
+
[NO_TYPENAME_PREFIX]: `Field "{{ fieldName }}" starts with the name of the parent type "{{ typeName }}"`,
|
2077
|
+
},
|
2078
|
+
schema: [],
|
2079
|
+
},
|
2080
|
+
create(context) {
|
2081
|
+
return {
|
2082
|
+
'ObjectTypeDefinition, ObjectTypeExtension, InterfaceTypeDefinition, InterfaceTypeExtension'(node) {
|
2083
|
+
const typeName = node.name.value;
|
2084
|
+
const lowerTypeName = typeName.toLowerCase();
|
2085
|
+
for (const field of node.fields) {
|
2086
|
+
const fieldName = field.name.value;
|
2087
|
+
if (fieldName.toLowerCase().startsWith(lowerTypeName)) {
|
2088
|
+
context.report({
|
2089
|
+
data: {
|
2090
|
+
fieldName,
|
2091
|
+
typeName,
|
2092
|
+
},
|
2093
|
+
messageId: NO_TYPENAME_PREFIX,
|
2094
|
+
loc: getLocation(field.loc, lowerTypeName),
|
2095
|
+
});
|
2096
|
+
}
|
2097
|
+
}
|
2098
|
+
},
|
2099
|
+
};
|
2100
|
+
},
|
2101
|
+
};
|
2102
|
+
|
2160
2103
|
const UNREACHABLE_TYPE = 'UNREACHABLE_TYPE';
|
2161
2104
|
const RULE_NAME = 'no-unreachable-types';
|
2162
|
-
const rule$
|
2105
|
+
const rule$d = {
|
2163
2106
|
meta: {
|
2164
2107
|
messages: {
|
2165
|
-
[UNREACHABLE_TYPE]:
|
2108
|
+
[UNREACHABLE_TYPE]: 'Type "{{ typeName }}" is unreachable',
|
2166
2109
|
},
|
2167
2110
|
docs: {
|
2168
2111
|
description: `Requires all types to be reachable at some level by root level fields.`,
|
2169
|
-
category: '
|
2112
|
+
category: 'Schema',
|
2170
2113
|
url: `https://github.com/dotansimha/graphql-eslint/blob/master/docs/rules/${RULE_NAME}.md`,
|
2171
2114
|
requiresSchema: true,
|
2172
2115
|
examples: [
|
@@ -2197,6 +2140,7 @@ const rule$f = {
|
|
2197
2140
|
`,
|
2198
2141
|
},
|
2199
2142
|
],
|
2143
|
+
recommended: true,
|
2200
2144
|
},
|
2201
2145
|
fixable: 'code',
|
2202
2146
|
type: 'suggestion',
|
@@ -2235,14 +2179,14 @@ const rule$f = {
|
|
2235
2179
|
|
2236
2180
|
const UNUSED_FIELD = 'UNUSED_FIELD';
|
2237
2181
|
const RULE_NAME$1 = 'no-unused-fields';
|
2238
|
-
const rule$
|
2182
|
+
const rule$e = {
|
2239
2183
|
meta: {
|
2240
2184
|
messages: {
|
2241
2185
|
[UNUSED_FIELD]: `Field "{{fieldName}}" is unused`,
|
2242
2186
|
},
|
2243
2187
|
docs: {
|
2244
2188
|
description: `Requires all fields to be used at some level by siblings operations.`,
|
2245
|
-
category: '
|
2189
|
+
category: 'Schema',
|
2246
2190
|
url: `https://github.com/dotansimha/graphql-eslint/blob/master/docs/rules/${RULE_NAME$1}.md`,
|
2247
2191
|
requiresSiblings: true,
|
2248
2192
|
requiresSchema: true,
|
@@ -2424,11 +2368,11 @@ const MESSAGE_REQUIRE_DATE = 'MESSAGE_REQUIRE_DATE';
|
|
2424
2368
|
const MESSAGE_INVALID_FORMAT = 'MESSAGE_INVALID_FORMAT';
|
2425
2369
|
const MESSAGE_INVALID_DATE = 'MESSAGE_INVALID_DATE';
|
2426
2370
|
const MESSAGE_CAN_BE_REMOVED = 'MESSAGE_CAN_BE_REMOVED';
|
2427
|
-
const rule$
|
2371
|
+
const rule$f = {
|
2428
2372
|
meta: {
|
2429
2373
|
type: 'suggestion',
|
2430
2374
|
docs: {
|
2431
|
-
category: '
|
2375
|
+
category: 'Schema',
|
2432
2376
|
description: 'Require deletion date on `@deprecated` directive. Suggest removing deprecated things after deprecated date.',
|
2433
2377
|
url: 'https://github.com/dotansimha/graphql-eslint/blob/master/docs/rules/require-deprecation-date.md',
|
2434
2378
|
examples: [
|
@@ -2527,11 +2471,11 @@ const rule$h = {
|
|
2527
2471
|
},
|
2528
2472
|
};
|
2529
2473
|
|
2530
|
-
const rule$
|
2474
|
+
const rule$g = {
|
2531
2475
|
meta: {
|
2532
2476
|
docs: {
|
2533
2477
|
description: `Require all deprecation directives to specify a reason.`,
|
2534
|
-
category: '
|
2478
|
+
category: 'Schema',
|
2535
2479
|
url: `https://github.com/dotansimha/graphql-eslint/blob/master/docs/rules/require-deprecation-reason.md`,
|
2536
2480
|
recommended: true,
|
2537
2481
|
examples: [
|
@@ -2582,41 +2526,23 @@ const rule$i = {
|
|
2582
2526
|
};
|
2583
2527
|
|
2584
2528
|
const REQUIRE_DESCRIPTION_ERROR = 'REQUIRE_DESCRIPTION_ERROR';
|
2585
|
-
const
|
2586
|
-
|
2587
|
-
Kind.OBJECT_TYPE_DEFINITION,
|
2529
|
+
const ALLOWED_KINDS$1 = [
|
2530
|
+
...TYPES_KINDS,
|
2588
2531
|
Kind.FIELD_DEFINITION,
|
2589
2532
|
Kind.INPUT_VALUE_DEFINITION,
|
2590
|
-
Kind.INTERFACE_TYPE_DEFINITION,
|
2591
|
-
Kind.UNION_TYPE_DEFINITION,
|
2592
|
-
Kind.ENUM_TYPE_DEFINITION,
|
2593
2533
|
Kind.ENUM_VALUE_DEFINITION,
|
2594
|
-
Kind.INPUT_OBJECT_TYPE_DEFINITION,
|
2595
2534
|
Kind.DIRECTIVE_DEFINITION,
|
2596
2535
|
];
|
2597
|
-
|
2598
|
-
if (node) {
|
2599
|
-
if (!node.description || !node.description.value || node.description.value.trim().length === 0) {
|
2600
|
-
context.report({
|
2601
|
-
loc: getLocation(('name' in node ? node.name : node).loc, 'name' in node ? node.name.value : 'schema'),
|
2602
|
-
messageId: REQUIRE_DESCRIPTION_ERROR,
|
2603
|
-
data: {
|
2604
|
-
nodeType: node.kind,
|
2605
|
-
},
|
2606
|
-
});
|
2607
|
-
}
|
2608
|
-
}
|
2609
|
-
}
|
2610
|
-
const rule$j = {
|
2536
|
+
const rule$h = {
|
2611
2537
|
meta: {
|
2612
2538
|
docs: {
|
2613
|
-
category: '
|
2614
|
-
description:
|
2615
|
-
url:
|
2539
|
+
category: 'Schema',
|
2540
|
+
description: 'Enforce descriptions in your type definitions.',
|
2541
|
+
url: 'https://github.com/dotansimha/graphql-eslint/blob/master/docs/rules/require-description.md',
|
2616
2542
|
examples: [
|
2617
2543
|
{
|
2618
2544
|
title: 'Incorrect',
|
2619
|
-
usage: [{
|
2545
|
+
usage: [{ types: true, overrides: { FieldDefinition: true } }],
|
2620
2546
|
code: /* GraphQL */ `
|
2621
2547
|
type someTypeName {
|
2622
2548
|
name: String
|
@@ -2625,7 +2551,7 @@ const rule$j = {
|
|
2625
2551
|
},
|
2626
2552
|
{
|
2627
2553
|
title: 'Correct',
|
2628
|
-
usage: [{
|
2554
|
+
usage: [{ types: true, overrides: { FieldDefinition: true } }],
|
2629
2555
|
code: /* GraphQL */ `
|
2630
2556
|
"""
|
2631
2557
|
Some type description
|
@@ -2639,44 +2565,78 @@ const rule$j = {
|
|
2639
2565
|
`,
|
2640
2566
|
},
|
2641
2567
|
],
|
2568
|
+
configOptions: [
|
2569
|
+
{
|
2570
|
+
types: true,
|
2571
|
+
overrides: {
|
2572
|
+
[Kind.DIRECTIVE_DEFINITION]: true,
|
2573
|
+
},
|
2574
|
+
},
|
2575
|
+
],
|
2642
2576
|
},
|
2643
2577
|
type: 'suggestion',
|
2644
2578
|
messages: {
|
2645
|
-
[REQUIRE_DESCRIPTION_ERROR]:
|
2579
|
+
[REQUIRE_DESCRIPTION_ERROR]: 'Description is required for nodes of type "{{ nodeType }}"',
|
2646
2580
|
},
|
2647
2581
|
schema: {
|
2648
2582
|
type: 'array',
|
2649
|
-
additionalItems: false,
|
2650
2583
|
minItems: 1,
|
2651
2584
|
maxItems: 1,
|
2652
2585
|
items: {
|
2653
2586
|
type: 'object',
|
2654
|
-
|
2587
|
+
additionalProperties: false,
|
2588
|
+
minProperties: 1,
|
2655
2589
|
properties: {
|
2656
|
-
|
2657
|
-
type: '
|
2658
|
-
|
2659
|
-
|
2660
|
-
|
2661
|
-
|
2662
|
-
|
2663
|
-
|
2590
|
+
types: {
|
2591
|
+
type: 'boolean',
|
2592
|
+
description: `Includes:\n\n${TYPES_KINDS.map(kind => `- [${kind}](https://spec.graphql.org/October2021/#${kind})`).join('\n')}`,
|
2593
|
+
},
|
2594
|
+
overrides: {
|
2595
|
+
type: 'object',
|
2596
|
+
description: 'Configuration for precise `ASTNode`',
|
2597
|
+
additionalProperties: false,
|
2598
|
+
properties: Object.fromEntries(ALLOWED_KINDS$1.map(kind => [kind, { type: 'boolean' }])),
|
2664
2599
|
},
|
2665
2600
|
},
|
2666
2601
|
},
|
2667
2602
|
},
|
2668
2603
|
},
|
2669
2604
|
create(context) {
|
2670
|
-
|
2605
|
+
const { types, overrides = {} } = context.options[0];
|
2606
|
+
const kinds = new Set(types ? TYPES_KINDS : []);
|
2607
|
+
for (const [kind, isEnabled] of Object.entries(overrides)) {
|
2608
|
+
if (isEnabled) {
|
2609
|
+
kinds.add(kind);
|
2610
|
+
}
|
2611
|
+
else {
|
2612
|
+
kinds.delete(kind);
|
2613
|
+
}
|
2614
|
+
}
|
2615
|
+
const selector = [...kinds].join(',');
|
2616
|
+
return {
|
2617
|
+
[selector](node) {
|
2618
|
+
var _a;
|
2619
|
+
const description = ((_a = node.description) === null || _a === void 0 ? void 0 : _a.value) || '';
|
2620
|
+
if (description.trim().length === 0) {
|
2621
|
+
context.report({
|
2622
|
+
loc: getLocation(node.name.loc, node.name.value),
|
2623
|
+
messageId: REQUIRE_DESCRIPTION_ERROR,
|
2624
|
+
data: {
|
2625
|
+
nodeType: node.kind,
|
2626
|
+
},
|
2627
|
+
});
|
2628
|
+
}
|
2629
|
+
},
|
2630
|
+
};
|
2671
2631
|
},
|
2672
2632
|
};
|
2673
2633
|
|
2674
2634
|
const RULE_NAME$2 = 'require-field-of-type-query-in-mutation-result';
|
2675
|
-
const rule$
|
2635
|
+
const rule$i = {
|
2676
2636
|
meta: {
|
2677
2637
|
type: 'suggestion',
|
2678
2638
|
docs: {
|
2679
|
-
category: '
|
2639
|
+
category: 'Schema',
|
2680
2640
|
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`.',
|
2681
2641
|
url: `https://github.com/dotansimha/graphql-eslint/blob/master/docs/rules/${RULE_NAME$2}.md`,
|
2682
2642
|
requiresSchema: true,
|
@@ -2840,13 +2800,13 @@ const convertNode = (typeInfo) => (node, key, parent) => {
|
|
2840
2800
|
|
2841
2801
|
const REQUIRE_ID_WHEN_AVAILABLE = 'REQUIRE_ID_WHEN_AVAILABLE';
|
2842
2802
|
const DEFAULT_ID_FIELD_NAME = 'id';
|
2843
|
-
const rule$
|
2803
|
+
const rule$j = {
|
2844
2804
|
meta: {
|
2845
2805
|
type: 'suggestion',
|
2846
2806
|
docs: {
|
2847
|
-
category: '
|
2848
|
-
description:
|
2849
|
-
url:
|
2807
|
+
category: 'Operations',
|
2808
|
+
description: 'Enforce selecting specific fields when they are available on the GraphQL type.',
|
2809
|
+
url: 'https://github.com/dotansimha/graphql-eslint/blob/master/docs/rules/require-id-when-available.md',
|
2850
2810
|
requiresSchema: true,
|
2851
2811
|
requiresSiblings: true,
|
2852
2812
|
examples: [
|
@@ -2886,17 +2846,17 @@ const rule$l = {
|
|
2886
2846
|
`,
|
2887
2847
|
},
|
2888
2848
|
],
|
2849
|
+
recommended: true,
|
2889
2850
|
},
|
2890
2851
|
messages: {
|
2891
|
-
[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 }}".`,
|
2852
|
+
[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 }}".`,
|
2892
2853
|
},
|
2893
2854
|
schema: {
|
2894
2855
|
type: 'array',
|
2895
|
-
additionalItems: false,
|
2896
|
-
minItems: 0,
|
2897
2856
|
maxItems: 1,
|
2898
2857
|
items: {
|
2899
2858
|
type: 'object',
|
2859
|
+
additionalProperties: false,
|
2900
2860
|
properties: {
|
2901
2861
|
fieldName: {
|
2902
2862
|
type: 'string',
|
@@ -2976,12 +2936,12 @@ const rule$l = {
|
|
2976
2936
|
},
|
2977
2937
|
};
|
2978
2938
|
|
2979
|
-
const rule$
|
2939
|
+
const rule$k = {
|
2980
2940
|
meta: {
|
2981
2941
|
docs: {
|
2982
|
-
category: '
|
2942
|
+
category: 'Operations',
|
2983
2943
|
description: `Limit the complexity of the GraphQL operations solely by their depth. Based on [graphql-depth-limit](https://github.com/stems/graphql-depth-limit).`,
|
2984
|
-
url:
|
2944
|
+
url: 'https://github.com/dotansimha/graphql-eslint/blob/master/docs/rules/selection-set-depth.md',
|
2985
2945
|
requiresSiblings: true,
|
2986
2946
|
examples: [
|
2987
2947
|
{
|
@@ -3024,22 +2984,26 @@ const rule$m = {
|
|
3024
2984
|
`,
|
3025
2985
|
},
|
3026
2986
|
],
|
2987
|
+
recommended: true,
|
2988
|
+
configOptions: [{ maxDepth: 7 }],
|
3027
2989
|
},
|
3028
2990
|
type: 'suggestion',
|
3029
2991
|
schema: {
|
3030
2992
|
type: 'array',
|
3031
|
-
additionalItems: false,
|
3032
2993
|
minItems: 1,
|
3033
2994
|
maxItems: 1,
|
3034
2995
|
items: {
|
3035
2996
|
type: 'object',
|
3036
|
-
|
2997
|
+
additionalProperties: false,
|
2998
|
+
required: ['maxDepth'],
|
3037
2999
|
properties: {
|
3038
3000
|
maxDepth: {
|
3039
3001
|
type: 'number',
|
3040
3002
|
},
|
3041
3003
|
ignore: {
|
3042
3004
|
type: 'array',
|
3005
|
+
uniqueItems: true,
|
3006
|
+
minItems: 1,
|
3043
3007
|
items: {
|
3044
3008
|
type: 'string',
|
3045
3009
|
},
|
@@ -3098,12 +3062,12 @@ const shouldIgnoreNode = ({ node, exceptions }) => {
|
|
3098
3062
|
}
|
3099
3063
|
return false;
|
3100
3064
|
};
|
3101
|
-
const rule$
|
3065
|
+
const rule$l = {
|
3102
3066
|
meta: {
|
3103
3067
|
type: 'suggestion',
|
3104
3068
|
docs: {
|
3105
3069
|
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.',
|
3106
|
-
category: '
|
3070
|
+
category: 'Schema',
|
3107
3071
|
recommended: true,
|
3108
3072
|
url: 'https://github.com/dotansimha/graphql-eslint/blob/master/docs/rules/strict-id-in-types.md',
|
3109
3073
|
examples: [
|
@@ -3163,13 +3127,15 @@ const rule$n = {
|
|
3163
3127
|
],
|
3164
3128
|
},
|
3165
3129
|
schema: {
|
3166
|
-
$schema: 'http://json-schema.org/draft-04/schema#',
|
3167
3130
|
type: 'array',
|
3131
|
+
maxItems: 1,
|
3168
3132
|
items: {
|
3169
3133
|
type: 'object',
|
3134
|
+
additionalProperties: false,
|
3170
3135
|
properties: {
|
3171
3136
|
acceptedIdNames: {
|
3172
3137
|
type: 'array',
|
3138
|
+
uniqueItems: true,
|
3173
3139
|
items: {
|
3174
3140
|
type: 'string',
|
3175
3141
|
},
|
@@ -3177,6 +3143,7 @@ const rule$n = {
|
|
3177
3143
|
},
|
3178
3144
|
acceptedIdTypes: {
|
3179
3145
|
type: 'array',
|
3146
|
+
uniqueItems: true,
|
3180
3147
|
items: {
|
3181
3148
|
type: 'string',
|
3182
3149
|
},
|
@@ -3187,19 +3154,21 @@ const rule$n = {
|
|
3187
3154
|
properties: {
|
3188
3155
|
types: {
|
3189
3156
|
type: 'array',
|
3157
|
+
uniqueItems: true,
|
3158
|
+
minItems: 1,
|
3190
3159
|
description: 'This is used to exclude types with names that match one of the specified values.',
|
3191
3160
|
items: {
|
3192
3161
|
type: 'string',
|
3193
3162
|
},
|
3194
|
-
default: [],
|
3195
3163
|
},
|
3196
3164
|
suffixes: {
|
3197
3165
|
type: 'array',
|
3166
|
+
uniqueItems: true,
|
3167
|
+
minItems: 1,
|
3198
3168
|
description: 'This is used to exclude types with names with suffixes that match one of the specified values.',
|
3199
3169
|
items: {
|
3200
3170
|
type: 'string',
|
3201
3171
|
},
|
3202
|
-
default: [],
|
3203
3172
|
},
|
3204
3173
|
},
|
3205
3174
|
},
|
@@ -3275,11 +3244,11 @@ const checkNode = (context, node, ruleName, messageId) => {
|
|
3275
3244
|
});
|
3276
3245
|
}
|
3277
3246
|
};
|
3278
|
-
const rule$
|
3247
|
+
const rule$m = {
|
3279
3248
|
meta: {
|
3280
3249
|
type: 'suggestion',
|
3281
3250
|
docs: {
|
3282
|
-
category: '
|
3251
|
+
category: 'Operations',
|
3283
3252
|
description: `Enforce unique fragment names across your project.`,
|
3284
3253
|
url: `https://github.com/dotansimha/graphql-eslint/blob/master/docs/rules/${RULE_NAME$3}.md`,
|
3285
3254
|
requiresSiblings: true,
|
@@ -3334,11 +3303,11 @@ const rule$o = {
|
|
3334
3303
|
|
3335
3304
|
const RULE_NAME$4 = 'unique-operation-name';
|
3336
3305
|
const UNIQUE_OPERATION_NAME = 'UNIQUE_OPERATION_NAME';
|
3337
|
-
const rule$
|
3306
|
+
const rule$n = {
|
3338
3307
|
meta: {
|
3339
3308
|
type: 'suggestion',
|
3340
3309
|
docs: {
|
3341
|
-
category: '
|
3310
|
+
category: 'Operations',
|
3342
3311
|
description: `Enforce unique operation names across your project.`,
|
3343
3312
|
url: `https://github.com/dotansimha/graphql-eslint/blob/master/docs/rules/${RULE_NAME$4}.md`,
|
3344
3313
|
requiresSiblings: true,
|
@@ -3401,31 +3370,29 @@ const rule$p = {
|
|
3401
3370
|
const rules = {
|
3402
3371
|
...GRAPHQL_JS_VALIDATIONS,
|
3403
3372
|
alphabetize: rule,
|
3404
|
-
'
|
3405
|
-
'
|
3406
|
-
'
|
3407
|
-
'
|
3408
|
-
'
|
3409
|
-
'
|
3410
|
-
'
|
3411
|
-
'
|
3412
|
-
'no-
|
3413
|
-
'no-
|
3414
|
-
'no-
|
3415
|
-
'no-
|
3416
|
-
'no-
|
3417
|
-
'no-
|
3418
|
-
'
|
3419
|
-
'
|
3420
|
-
'require-
|
3421
|
-
'require-
|
3422
|
-
'require-
|
3423
|
-
'
|
3424
|
-
'
|
3425
|
-
'
|
3426
|
-
'
|
3427
|
-
'unique-fragment-name': rule$o,
|
3428
|
-
'unique-operation-name': rule$p,
|
3373
|
+
'description-style': rule$1,
|
3374
|
+
'input-name': rule$2,
|
3375
|
+
'match-document-filename': rule$3,
|
3376
|
+
'naming-convention': rule$4,
|
3377
|
+
'no-anonymous-operations': rule$5,
|
3378
|
+
'no-case-insensitive-enum-values-duplicates': rule$6,
|
3379
|
+
'no-deprecated': rule$7,
|
3380
|
+
'no-duplicate-fields': rule$8,
|
3381
|
+
'no-hashtag-description': rule$9,
|
3382
|
+
'no-root-type': rule$a,
|
3383
|
+
'no-scalar-result-type-on-mutation': rule$b,
|
3384
|
+
'no-typename-prefix': rule$c,
|
3385
|
+
'no-unreachable-types': rule$d,
|
3386
|
+
'no-unused-fields': rule$e,
|
3387
|
+
'require-deprecation-date': rule$f,
|
3388
|
+
'require-deprecation-reason': rule$g,
|
3389
|
+
'require-description': rule$h,
|
3390
|
+
'require-field-of-type-query-in-mutation-result': rule$i,
|
3391
|
+
'require-id-when-available': rule$j,
|
3392
|
+
'selection-set-depth': rule$k,
|
3393
|
+
'strict-id-in-types': rule$l,
|
3394
|
+
'unique-fragment-name': rule$m,
|
3395
|
+
'unique-operation-name': rule$n,
|
3429
3396
|
};
|
3430
3397
|
|
3431
3398
|
const RELEVANT_KEYWORDS = ['gql', 'graphql', '/* GraphQL */'];
|