@graphql-eslint/eslint-plugin 3.0.0-alpha-2918431.0 → 3.0.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 CHANGED
@@ -180,6 +180,10 @@ You can find a list of [ESLint directives here](https://eslint.org/docs/2.13.1/u
180
180
 
181
181
  You can find a complete list of [all available rules here](docs/README.md).
182
182
 
183
+ ## Deprecated Rules
184
+
185
+ See [docs/deprecated-rules.md](docs/deprecated-rules.md).
186
+
183
187
  ## Available Configs
184
188
 
185
189
  <!-- prettier-ignore-start -->
@@ -187,10 +191,16 @@ You can find a complete list of [all available rules here](docs/README.md).
187
191
  |:-:|-|
188
192
  |[`schema-recommended`](packages/plugin/src/configs/schema-recommended.ts)|enables all recommended rules|
189
193
  |[`operations-recommended`](packages/plugin/src/configs/operations-recommended.ts) |enables all recommended rules|
190
- |[`schema-all`](packages/plugin/src/configs/schema-all.ts)|enables all rules (except for the rules that require `parserOptions.operations` option)|
194
+ |[`schema-all`](packages/plugin/src/configs/schema-all.ts)|enables all rules, except for those that require `parserOptions.operations` option)|
191
195
  |[`operations-all`](packages/plugin/src/configs/operations-all.ts)|enables all rules|
192
196
  <!-- prettier-ignore-end -->
193
197
 
198
+ > If you are in a project that develops the GraphQL schema, you'll need `schema` rules.
199
+
200
+ > If you are in a project that develops GraphQL operations (query/mutation/subscription), you'll need `operations` rules.
201
+
202
+ > If you are in a monorepo project, you probably need both sets of rules.
203
+
194
204
  ## Config usage
195
205
 
196
206
  For example, to enable the `schema-recommended` config, enable it in your `.eslintrc` file with the `extends` option:
@@ -13,7 +13,10 @@ export declare const configs: {
13
13
  '@graphql-eslint/lone-schema-definition': string;
14
14
  '@graphql-eslint/naming-convention': (string | {
15
15
  types: string;
16
- fields: string;
16
+ FieldDefinition: string;
17
+ InputValueDefinition: string;
18
+ Argument: string;
19
+ DirectiveDefinition: string;
17
20
  EnumValueDefinition: string;
18
21
  'FieldDefinition[parent.name.value=Query]': {
19
22
  forbiddenPrefixes: string[];
@@ -32,9 +35,12 @@ export declare const configs: {
32
35
  '@graphql-eslint/no-hashtag-description': string;
33
36
  '@graphql-eslint/no-typename-prefix': string;
34
37
  '@graphql-eslint/no-unreachable-types': string;
35
- '@graphql-eslint/possible-type-extension': string;
36
38
  '@graphql-eslint/provided-required-arguments': string;
37
39
  '@graphql-eslint/require-deprecation-reason': string;
40
+ '@graphql-eslint/require-description': (string | {
41
+ types: boolean;
42
+ DirectiveDefinition: boolean;
43
+ })[];
38
44
  '@graphql-eslint/strict-id-in-types': string;
39
45
  '@graphql-eslint/unique-directive-names': string;
40
46
  '@graphql-eslint/unique-directive-names-per-location': string;
@@ -56,11 +62,8 @@ export declare const configs: {
56
62
  '@graphql-eslint/no-root-type': string;
57
63
  '@graphql-eslint/no-scalar-result-type-on-mutation': string;
58
64
  '@graphql-eslint/no-unused-fields': string;
65
+ '@graphql-eslint/possible-type-extension': string;
59
66
  '@graphql-eslint/require-deprecation-date': string;
60
- '@graphql-eslint/require-description': (string | {
61
- types: boolean;
62
- DirectiveDefinition: boolean;
63
- })[];
64
67
  '@graphql-eslint/require-field-of-type-query-in-mutation-result': string;
65
68
  };
66
69
  };
@@ -76,7 +79,6 @@ export declare const configs: {
76
79
  '@graphql-eslint/known-type-names': string;
77
80
  '@graphql-eslint/lone-anonymous-operation': string;
78
81
  '@graphql-eslint/naming-convention': (string | {
79
- Argument: string;
80
82
  VariableDefinition: string;
81
83
  OperationDefinition: {
82
84
  style: string;
@@ -10,7 +10,6 @@ declare const _default: {
10
10
  '@graphql-eslint/known-type-names': string;
11
11
  '@graphql-eslint/lone-anonymous-operation': string;
12
12
  '@graphql-eslint/naming-convention': (string | {
13
- Argument: string;
14
13
  VariableDefinition: string;
15
14
  OperationDefinition: {
16
15
  style: string;
@@ -10,11 +10,8 @@ declare const _default: {
10
10
  '@graphql-eslint/no-root-type': string;
11
11
  '@graphql-eslint/no-scalar-result-type-on-mutation': string;
12
12
  '@graphql-eslint/no-unused-fields': string;
13
+ '@graphql-eslint/possible-type-extension': string;
13
14
  '@graphql-eslint/require-deprecation-date': string;
14
- '@graphql-eslint/require-description': (string | {
15
- types: boolean;
16
- DirectiveDefinition: boolean;
17
- })[];
18
15
  '@graphql-eslint/require-field-of-type-query-in-mutation-result': string;
19
16
  };
20
17
  };
@@ -8,7 +8,10 @@ declare const _default: {
8
8
  '@graphql-eslint/lone-schema-definition': string;
9
9
  '@graphql-eslint/naming-convention': (string | {
10
10
  types: string;
11
- fields: string;
11
+ FieldDefinition: string;
12
+ InputValueDefinition: string;
13
+ Argument: string;
14
+ DirectiveDefinition: string;
12
15
  EnumValueDefinition: string;
13
16
  'FieldDefinition[parent.name.value=Query]': {
14
17
  forbiddenPrefixes: string[];
@@ -27,9 +30,12 @@ declare const _default: {
27
30
  '@graphql-eslint/no-hashtag-description': string;
28
31
  '@graphql-eslint/no-typename-prefix': string;
29
32
  '@graphql-eslint/no-unreachable-types': string;
30
- '@graphql-eslint/possible-type-extension': string;
31
33
  '@graphql-eslint/provided-required-arguments': string;
32
34
  '@graphql-eslint/require-deprecation-reason': string;
35
+ '@graphql-eslint/require-description': (string | {
36
+ types: boolean;
37
+ DirectiveDefinition: boolean;
38
+ })[];
33
39
  '@graphql-eslint/strict-id-in-types': string;
34
40
  '@graphql-eslint/unique-directive-names': string;
35
41
  '@graphql-eslint/unique-directive-names-per-location': string;
package/docs/README.md CHANGED
@@ -42,11 +42,11 @@ Name&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbs
42
42
  [one-field-subscriptions](rules/one-field-subscriptions.md)|A GraphQL subscription is valid only if it contains a single root field.|🔮||✅
43
43
  [overlapping-fields-can-be-merged](rules/overlapping-fields-can-be-merged.md)|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.|🔮||✅
44
44
  [possible-fragment-spread](rules/possible-fragment-spread.md)|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.|🔮||✅
45
- [possible-type-extension](rules/possible-type-extension.md)|A type extension is only valid if the type is defined and has the same kind.|🔮||✅
45
+ [possible-type-extension](rules/possible-type-extension.md)|A type extension is only valid if the type is defined and has the same kind.|🔮||
46
46
  [provided-required-arguments](rules/provided-required-arguments.md)|A field or directive is only valid if all required (non-null without a default value) field arguments have been provided.|🔮||✅
47
47
  [require-deprecation-date](rules/require-deprecation-date.md)|Require deletion date on `@deprecated` directive. Suggest removing deprecated things after deprecated date.|🚀||
48
48
  [require-deprecation-reason](rules/require-deprecation-reason.md)|Require all deprecation directives to specify a reason.|🚀||✅
49
- [require-description](rules/require-description.md)|Enforce descriptions in your type definitions.|🚀||
49
+ [require-description](rules/require-description.md)|Enforce descriptions in your type definitions.|🚀||✅
50
50
  [require-field-of-type-query-in-mutation-result](rules/require-field-of-type-query-in-mutation-result.md)|Allow the client in one round-trip not only to call mutation but also to get a wagon of data to update their application.|🚀||
51
51
  [require-id-when-available](rules/require-id-when-available.md)|Enforce selecting specific fields when they are available on the GraphQL type.|🚀||✅
52
52
  [scalar-leafs](rules/scalar-leafs.md)|A GraphQL document is valid only if all leaf fields (fields without sub selections) are of scalar or enum types.|🔮||✅
@@ -14,23 +14,63 @@ Require names to follow specified conventions.
14
14
  ### Incorrect
15
15
 
16
16
  ```graphql
17
- # eslint @graphql-eslint/naming-convention: ['error', { types: 'PascalCase', fields: 'camelCase' }]
17
+ # eslint @graphql-eslint/naming-convention: ['error', { types: 'PascalCase', FieldDefinition: 'camelCase' }]
18
18
 
19
19
  type user {
20
20
  first_name: String!
21
21
  }
22
22
  ```
23
23
 
24
+ ### Incorrect
25
+
26
+ ```graphql
27
+ # eslint @graphql-eslint/naming-convention: ['error', { FragmentDefinition: { style: 'PascalCase', forbiddenSuffixes: ['Fragment'] } }]
28
+
29
+ fragment UserFragment on User {
30
+ # ...
31
+ }
32
+ ```
33
+
34
+ ### Incorrect
35
+
36
+ ```graphql
37
+ # eslint @graphql-eslint/naming-convention: ['error', { 'FieldDefinition[parent.name.value=Query]': { forbiddenPrefixes: ['get'] } }]
38
+
39
+ type Query {
40
+ getUsers: [User!]!
41
+ }
42
+ ```
43
+
24
44
  ### Correct
25
45
 
26
46
  ```graphql
27
- # eslint @graphql-eslint/naming-convention: ['error', { types: 'PascalCase', fields: 'camelCase' }]
47
+ # eslint @graphql-eslint/naming-convention: ['error', { types: 'PascalCase', FieldDefinition: 'camelCase' }]
28
48
 
29
49
  type User {
30
50
  firstName: String
31
51
  }
32
52
  ```
33
53
 
54
+ ### Correct
55
+
56
+ ```graphql
57
+ # eslint @graphql-eslint/naming-convention: ['error', { FragmentDefinition: { style: 'PascalCase', forbiddenSuffixes: ['Fragment'] } }]
58
+
59
+ fragment UserFields on User {
60
+ # ...
61
+ }
62
+ ```
63
+
64
+ ### Correct
65
+
66
+ ```graphql
67
+ # eslint @graphql-eslint/naming-convention: ['error', { 'FieldDefinition[parent.name.value=Query]': { forbiddenPrefixes: ['get'] } }]
68
+
69
+ type Query {
70
+ users: [User!]!
71
+ }
72
+ ```
73
+
34
74
  ## Config Schema
35
75
 
36
76
  > It's possible to use a [`selector`](https://eslint.org/docs/developer-guide/selectors) that starts with allowed `ASTNode` names which are described below.
@@ -41,14 +81,6 @@ type User {
41
81
 
42
82
  The schema defines the following properties:
43
83
 
44
- ### `allowLeadingUnderscore` (boolean)
45
-
46
- Default: `false`
47
-
48
- ### `allowTrailingUnderscore` (boolean)
49
-
50
- Default: `false`
51
-
52
84
  ### `types`
53
85
 
54
86
  Includes:
@@ -65,20 +97,6 @@ The object must be one of the following types:
65
97
  * `asString`
66
98
  * `asObject`
67
99
 
68
- ### `fields`
69
-
70
- Includes:
71
-
72
- - `FieldDefinition`
73
- - `InputValueDefinition`
74
- - `Argument`
75
- - `DirectiveDefinition`
76
-
77
- The object must be one of the following types:
78
-
79
- * `asString`
80
- * `asObject`
81
-
82
100
  ### `Argument`
83
101
 
84
102
  Read more about this kind on [spec.graphql.org](https://spec.graphql.org/October2021/#Argument).
@@ -205,6 +223,14 @@ The object must be one of the following types:
205
223
  * `asString`
206
224
  * `asObject`
207
225
 
226
+ ### `allowLeadingUnderscore` (boolean)
227
+
228
+ Default: `false`
229
+
230
+ ### `allowTrailingUnderscore` (boolean)
231
+
232
+ Default: `false`
233
+
208
234
  ---
209
235
 
210
236
  # Sub Schemas
@@ -1,7 +1,5 @@
1
1
  # `possible-type-extension`
2
2
 
3
- ✅ The `"extends": "plugin:@graphql-eslint/schema-recommended"` property in a configuration file enables this rule.
4
-
5
3
  - Category: `Schema`
6
4
  - Rule name: `@graphql-eslint/possible-type-extension`
7
5
  - Requires GraphQL Schema: `false` [ℹ️](../../README.md#extended-linting-rules-with-graphql-schema)
@@ -1,5 +1,7 @@
1
1
  # `require-description`
2
2
 
3
+ ✅ The `"extends": "plugin:@graphql-eslint/schema-recommended"` property in a configuration file enables this rule.
4
+
3
5
  - Category: `Schema`
4
6
  - Rule name: `@graphql-eslint/require-description`
5
7
  - Requires GraphQL Schema: `false` [ℹ️](../../README.md#extended-linting-rules-with-graphql-schema)
package/index.js CHANGED
@@ -38,7 +38,10 @@ const schemaRecommendedConfig = {
38
38
  'error',
39
39
  {
40
40
  types: 'PascalCase',
41
- fields: 'camelCase',
41
+ FieldDefinition: 'camelCase',
42
+ InputValueDefinition: 'camelCase',
43
+ Argument: 'camelCase',
44
+ DirectiveDefinition: 'camelCase',
42
45
  EnumValueDefinition: 'UPPER_CASE',
43
46
  'FieldDefinition[parent.name.value=Query]': {
44
47
  forbiddenPrefixes: ['query', 'get'],
@@ -58,9 +61,9 @@ const schemaRecommendedConfig = {
58
61
  '@graphql-eslint/no-hashtag-description': 'error',
59
62
  '@graphql-eslint/no-typename-prefix': 'error',
60
63
  '@graphql-eslint/no-unreachable-types': 'error',
61
- '@graphql-eslint/possible-type-extension': 'error',
62
64
  '@graphql-eslint/provided-required-arguments': 'error',
63
65
  '@graphql-eslint/require-deprecation-reason': 'error',
66
+ '@graphql-eslint/require-description': ['error', { types: true, DirectiveDefinition: true }],
64
67
  '@graphql-eslint/strict-id-in-types': 'error',
65
68
  '@graphql-eslint/unique-directive-names': 'error',
66
69
  '@graphql-eslint/unique-directive-names-per-location': 'error',
@@ -89,8 +92,8 @@ const schemaAllConfig = {
89
92
  '@graphql-eslint/no-root-type': 'off',
90
93
  '@graphql-eslint/no-scalar-result-type-on-mutation': 'error',
91
94
  '@graphql-eslint/no-unused-fields': 'off',
95
+ '@graphql-eslint/possible-type-extension': 'off',
92
96
  '@graphql-eslint/require-deprecation-date': 'error',
93
- '@graphql-eslint/require-description': ['error', { types: true, DirectiveDefinition: true }],
94
97
  '@graphql-eslint/require-field-of-type-query-in-mutation-result': 'error',
95
98
  },
96
99
  };
@@ -112,7 +115,6 @@ const operationsRecommendedConfig = {
112
115
  '@graphql-eslint/naming-convention': [
113
116
  'error',
114
117
  {
115
- Argument: 'camelCase',
116
118
  VariableDefinition: 'camelCase',
117
119
  OperationDefinition: {
118
120
  style: 'PascalCase',
@@ -385,9 +387,9 @@ const validationToRule = (name, ruleName, docs, getDocumentNode) => {
385
387
  [name]: {
386
388
  meta: {
387
389
  docs: {
390
+ recommended: true,
388
391
  ...docs,
389
392
  graphQLJSRuleName: ruleName,
390
- recommended: true,
391
393
  requiresSchema,
392
394
  url: `https://github.com/dotansimha/graphql-eslint/blob/master/docs/rules/${name}.md`,
393
395
  description: `${docs.description}\n\n> This rule is a wrapper around a \`graphql-js\` validation function. [You can find its source code here](https://github.com/graphql/graphql-js/blob/main/src/validation/rules/${ruleName}Rule.ts).`,
@@ -563,6 +565,7 @@ const GRAPHQL_JS_VALIDATIONS = Object.assign({}, validationToRule('executable-de
563
565
  category: 'Schema',
564
566
  description: `A type extension is only valid if the type is defined and has the same kind.`,
565
567
  requiresSchema: false,
568
+ recommended: false, // TODO: enable after https://github.com/dotansimha/graphql-eslint/issues/787 will be fixed
566
569
  }), validationToRule('provided-required-arguments', 'ProvidedRequiredArguments', {
567
570
  category: ['Schema', 'Operations'],
568
571
  description: `A field or directive is only valid if all required (non-null without a default value) field arguments have been provided.`,
@@ -1248,7 +1251,6 @@ const rule$3 = {
1248
1251
  },
1249
1252
  };
1250
1253
 
1251
- const FIELDS_KINDS = [graphql.Kind.FIELD_DEFINITION, graphql.Kind.INPUT_VALUE_DEFINITION, graphql.Kind.ARGUMENT, graphql.Kind.DIRECTIVE_DEFINITION];
1252
1254
  const KindToDisplayName = {
1253
1255
  // types
1254
1256
  [graphql.Kind.OBJECT_TYPE_DEFINITION]: 'Type',
@@ -1290,20 +1292,56 @@ const rule$4 = {
1290
1292
  examples: [
1291
1293
  {
1292
1294
  title: 'Incorrect',
1293
- usage: [{ types: 'PascalCase', fields: 'camelCase' }],
1295
+ usage: [{ types: 'PascalCase', FieldDefinition: 'camelCase' }],
1294
1296
  code: /* GraphQL */ `
1295
1297
  type user {
1296
1298
  first_name: String!
1297
1299
  }
1300
+ `,
1301
+ },
1302
+ {
1303
+ title: 'Incorrect',
1304
+ usage: [{ FragmentDefinition: { style: 'PascalCase', forbiddenSuffixes: ['Fragment'] } }],
1305
+ code: /* GraphQL */ `
1306
+ fragment UserFragment on User {
1307
+ # ...
1308
+ }
1309
+ `,
1310
+ },
1311
+ {
1312
+ title: 'Incorrect',
1313
+ usage: [{ 'FieldDefinition[parent.name.value=Query]': { forbiddenPrefixes: ['get'] } }],
1314
+ code: /* GraphQL */ `
1315
+ type Query {
1316
+ getUsers: [User!]!
1317
+ }
1298
1318
  `,
1299
1319
  },
1300
1320
  {
1301
1321
  title: 'Correct',
1302
- usage: [{ types: 'PascalCase', fields: 'camelCase' }],
1322
+ usage: [{ types: 'PascalCase', FieldDefinition: 'camelCase' }],
1303
1323
  code: /* GraphQL */ `
1304
1324
  type User {
1305
1325
  firstName: String
1306
1326
  }
1327
+ `,
1328
+ },
1329
+ {
1330
+ title: 'Correct',
1331
+ usage: [{ FragmentDefinition: { style: 'PascalCase', forbiddenSuffixes: ['Fragment'] } }],
1332
+ code: /* GraphQL */ `
1333
+ fragment UserFields on User {
1334
+ # ...
1335
+ }
1336
+ `,
1337
+ },
1338
+ {
1339
+ title: 'Correct',
1340
+ usage: [{ 'FieldDefinition[parent.name.value=Query]': { forbiddenPrefixes: ['get'] } }],
1341
+ code: /* GraphQL */ `
1342
+ type Query {
1343
+ users: [User!]!
1344
+ }
1307
1345
  `,
1308
1346
  },
1309
1347
  ],
@@ -1311,7 +1349,10 @@ const rule$4 = {
1311
1349
  schema: [
1312
1350
  {
1313
1351
  types: 'PascalCase',
1314
- fields: 'camelCase',
1352
+ FieldDefinition: 'camelCase',
1353
+ InputValueDefinition: 'camelCase',
1354
+ Argument: 'camelCase',
1355
+ DirectiveDefinition: 'camelCase',
1315
1356
  EnumValueDefinition: 'UPPER_CASE',
1316
1357
  'FieldDefinition[parent.name.value=Query]': {
1317
1358
  forbiddenPrefixes: ['query', 'get'],
@@ -1329,7 +1370,6 @@ const rule$4 = {
1329
1370
  ],
1330
1371
  operations: [
1331
1372
  {
1332
- Argument: 'camelCase',
1333
1373
  VariableDefinition: 'camelCase',
1334
1374
  OperationDefinition: {
1335
1375
  style: 'PascalCase',
@@ -1379,22 +1419,10 @@ const rule$4 = {
1379
1419
  type: 'object',
1380
1420
  additionalProperties: false,
1381
1421
  properties: {
1382
- allowLeadingUnderscore: {
1383
- type: 'boolean',
1384
- default: false,
1385
- },
1386
- allowTrailingUnderscore: {
1387
- type: 'boolean',
1388
- default: false,
1389
- },
1390
1422
  types: {
1391
1423
  ...schemaOption$1,
1392
1424
  description: `Includes:\n\n${TYPES_KINDS.map(kind => `- \`${kind}\``).join('\n')}`,
1393
1425
  },
1394
- fields: {
1395
- ...schemaOption$1,
1396
- description: `Includes:\n\n${FIELDS_KINDS.map(kind => `- \`${kind}\``).join('\n')}`,
1397
- },
1398
1426
  ...Object.fromEntries(ALLOWED_KINDS.map(kind => [
1399
1427
  kind,
1400
1428
  {
@@ -1402,6 +1430,14 @@ const rule$4 = {
1402
1430
  description: `Read more about this kind on [spec.graphql.org](https://spec.graphql.org/October2021/#${kind}).`,
1403
1431
  },
1404
1432
  ])),
1433
+ allowLeadingUnderscore: {
1434
+ type: 'boolean',
1435
+ default: false,
1436
+ },
1437
+ allowTrailingUnderscore: {
1438
+ type: 'boolean',
1439
+ default: false,
1440
+ },
1405
1441
  },
1406
1442
  patternProperties: {
1407
1443
  [`^(${ALLOWED_KINDS.join('|')})(.+)?$`]: schemaOption$1,
@@ -1418,12 +1454,9 @@ const rule$4 = {
1418
1454
  },
1419
1455
  create(context) {
1420
1456
  const options = context.options[0] || {};
1421
- const { allowLeadingUnderscore, allowTrailingUnderscore, types, fields, ...restOptions } = options;
1457
+ const { allowLeadingUnderscore, allowTrailingUnderscore, types, ...restOptions } = options;
1422
1458
  function normalisePropertyOption(kind) {
1423
- let style = options[kind];
1424
- if (!style) {
1425
- style = TYPES_KINDS.includes(kind) ? types : fields;
1426
- }
1459
+ const style = restOptions[kind] || types;
1427
1460
  return typeof style === 'object' ? style : { style };
1428
1461
  }
1429
1462
  const checkNode = (selector) => (node) => {
@@ -1486,7 +1519,7 @@ const rule$4 = {
1486
1519
  if (!allowTrailingUnderscore) {
1487
1520
  listeners['Name[value=/_$/]:matches([parent.kind!=Field], [parent.kind=Field][parent.alias])'] = checkUnderscore;
1488
1521
  }
1489
- const selectors = new Set([types && TYPES_KINDS, fields && FIELDS_KINDS, Object.keys(restOptions)].flat().filter(Boolean));
1522
+ const selectors = new Set([types && TYPES_KINDS, Object.keys(restOptions)].flat().filter(Boolean));
1490
1523
  for (const selector of selectors) {
1491
1524
  listeners[selector] = checkNode(selector);
1492
1525
  }
@@ -2554,6 +2587,7 @@ const rule$h = {
2554
2587
  [graphql.Kind.DIRECTIVE_DEFINITION]: true,
2555
2588
  },
2556
2589
  ],
2590
+ recommended: true,
2557
2591
  },
2558
2592
  type: 'suggestion',
2559
2593
  messages: {
package/index.mjs CHANGED
@@ -32,7 +32,10 @@ const schemaRecommendedConfig = {
32
32
  'error',
33
33
  {
34
34
  types: 'PascalCase',
35
- fields: 'camelCase',
35
+ FieldDefinition: 'camelCase',
36
+ InputValueDefinition: 'camelCase',
37
+ Argument: 'camelCase',
38
+ DirectiveDefinition: 'camelCase',
36
39
  EnumValueDefinition: 'UPPER_CASE',
37
40
  'FieldDefinition[parent.name.value=Query]': {
38
41
  forbiddenPrefixes: ['query', 'get'],
@@ -52,9 +55,9 @@ const schemaRecommendedConfig = {
52
55
  '@graphql-eslint/no-hashtag-description': 'error',
53
56
  '@graphql-eslint/no-typename-prefix': 'error',
54
57
  '@graphql-eslint/no-unreachable-types': 'error',
55
- '@graphql-eslint/possible-type-extension': 'error',
56
58
  '@graphql-eslint/provided-required-arguments': 'error',
57
59
  '@graphql-eslint/require-deprecation-reason': 'error',
60
+ '@graphql-eslint/require-description': ['error', { types: true, DirectiveDefinition: true }],
58
61
  '@graphql-eslint/strict-id-in-types': 'error',
59
62
  '@graphql-eslint/unique-directive-names': 'error',
60
63
  '@graphql-eslint/unique-directive-names-per-location': 'error',
@@ -83,8 +86,8 @@ const schemaAllConfig = {
83
86
  '@graphql-eslint/no-root-type': 'off',
84
87
  '@graphql-eslint/no-scalar-result-type-on-mutation': 'error',
85
88
  '@graphql-eslint/no-unused-fields': 'off',
89
+ '@graphql-eslint/possible-type-extension': 'off',
86
90
  '@graphql-eslint/require-deprecation-date': 'error',
87
- '@graphql-eslint/require-description': ['error', { types: true, DirectiveDefinition: true }],
88
91
  '@graphql-eslint/require-field-of-type-query-in-mutation-result': 'error',
89
92
  },
90
93
  };
@@ -106,7 +109,6 @@ const operationsRecommendedConfig = {
106
109
  '@graphql-eslint/naming-convention': [
107
110
  'error',
108
111
  {
109
- Argument: 'camelCase',
110
112
  VariableDefinition: 'camelCase',
111
113
  OperationDefinition: {
112
114
  style: 'PascalCase',
@@ -379,9 +381,9 @@ const validationToRule = (name, ruleName, docs, getDocumentNode) => {
379
381
  [name]: {
380
382
  meta: {
381
383
  docs: {
384
+ recommended: true,
382
385
  ...docs,
383
386
  graphQLJSRuleName: ruleName,
384
- recommended: true,
385
387
  requiresSchema,
386
388
  url: `https://github.com/dotansimha/graphql-eslint/blob/master/docs/rules/${name}.md`,
387
389
  description: `${docs.description}\n\n> This rule is a wrapper around a \`graphql-js\` validation function. [You can find its source code here](https://github.com/graphql/graphql-js/blob/main/src/validation/rules/${ruleName}Rule.ts).`,
@@ -557,6 +559,7 @@ const GRAPHQL_JS_VALIDATIONS = Object.assign({}, validationToRule('executable-de
557
559
  category: 'Schema',
558
560
  description: `A type extension is only valid if the type is defined and has the same kind.`,
559
561
  requiresSchema: false,
562
+ recommended: false, // TODO: enable after https://github.com/dotansimha/graphql-eslint/issues/787 will be fixed
560
563
  }), validationToRule('provided-required-arguments', 'ProvidedRequiredArguments', {
561
564
  category: ['Schema', 'Operations'],
562
565
  description: `A field or directive is only valid if all required (non-null without a default value) field arguments have been provided.`,
@@ -1242,7 +1245,6 @@ const rule$3 = {
1242
1245
  },
1243
1246
  };
1244
1247
 
1245
- const FIELDS_KINDS = [Kind.FIELD_DEFINITION, Kind.INPUT_VALUE_DEFINITION, Kind.ARGUMENT, Kind.DIRECTIVE_DEFINITION];
1246
1248
  const KindToDisplayName = {
1247
1249
  // types
1248
1250
  [Kind.OBJECT_TYPE_DEFINITION]: 'Type',
@@ -1284,20 +1286,56 @@ const rule$4 = {
1284
1286
  examples: [
1285
1287
  {
1286
1288
  title: 'Incorrect',
1287
- usage: [{ types: 'PascalCase', fields: 'camelCase' }],
1289
+ usage: [{ types: 'PascalCase', FieldDefinition: 'camelCase' }],
1288
1290
  code: /* GraphQL */ `
1289
1291
  type user {
1290
1292
  first_name: String!
1291
1293
  }
1294
+ `,
1295
+ },
1296
+ {
1297
+ title: 'Incorrect',
1298
+ usage: [{ FragmentDefinition: { style: 'PascalCase', forbiddenSuffixes: ['Fragment'] } }],
1299
+ code: /* GraphQL */ `
1300
+ fragment UserFragment on User {
1301
+ # ...
1302
+ }
1303
+ `,
1304
+ },
1305
+ {
1306
+ title: 'Incorrect',
1307
+ usage: [{ 'FieldDefinition[parent.name.value=Query]': { forbiddenPrefixes: ['get'] } }],
1308
+ code: /* GraphQL */ `
1309
+ type Query {
1310
+ getUsers: [User!]!
1311
+ }
1292
1312
  `,
1293
1313
  },
1294
1314
  {
1295
1315
  title: 'Correct',
1296
- usage: [{ types: 'PascalCase', fields: 'camelCase' }],
1316
+ usage: [{ types: 'PascalCase', FieldDefinition: 'camelCase' }],
1297
1317
  code: /* GraphQL */ `
1298
1318
  type User {
1299
1319
  firstName: String
1300
1320
  }
1321
+ `,
1322
+ },
1323
+ {
1324
+ title: 'Correct',
1325
+ usage: [{ FragmentDefinition: { style: 'PascalCase', forbiddenSuffixes: ['Fragment'] } }],
1326
+ code: /* GraphQL */ `
1327
+ fragment UserFields on User {
1328
+ # ...
1329
+ }
1330
+ `,
1331
+ },
1332
+ {
1333
+ title: 'Correct',
1334
+ usage: [{ 'FieldDefinition[parent.name.value=Query]': { forbiddenPrefixes: ['get'] } }],
1335
+ code: /* GraphQL */ `
1336
+ type Query {
1337
+ users: [User!]!
1338
+ }
1301
1339
  `,
1302
1340
  },
1303
1341
  ],
@@ -1305,7 +1343,10 @@ const rule$4 = {
1305
1343
  schema: [
1306
1344
  {
1307
1345
  types: 'PascalCase',
1308
- fields: 'camelCase',
1346
+ FieldDefinition: 'camelCase',
1347
+ InputValueDefinition: 'camelCase',
1348
+ Argument: 'camelCase',
1349
+ DirectiveDefinition: 'camelCase',
1309
1350
  EnumValueDefinition: 'UPPER_CASE',
1310
1351
  'FieldDefinition[parent.name.value=Query]': {
1311
1352
  forbiddenPrefixes: ['query', 'get'],
@@ -1323,7 +1364,6 @@ const rule$4 = {
1323
1364
  ],
1324
1365
  operations: [
1325
1366
  {
1326
- Argument: 'camelCase',
1327
1367
  VariableDefinition: 'camelCase',
1328
1368
  OperationDefinition: {
1329
1369
  style: 'PascalCase',
@@ -1373,22 +1413,10 @@ const rule$4 = {
1373
1413
  type: 'object',
1374
1414
  additionalProperties: false,
1375
1415
  properties: {
1376
- allowLeadingUnderscore: {
1377
- type: 'boolean',
1378
- default: false,
1379
- },
1380
- allowTrailingUnderscore: {
1381
- type: 'boolean',
1382
- default: false,
1383
- },
1384
1416
  types: {
1385
1417
  ...schemaOption$1,
1386
1418
  description: `Includes:\n\n${TYPES_KINDS.map(kind => `- \`${kind}\``).join('\n')}`,
1387
1419
  },
1388
- fields: {
1389
- ...schemaOption$1,
1390
- description: `Includes:\n\n${FIELDS_KINDS.map(kind => `- \`${kind}\``).join('\n')}`,
1391
- },
1392
1420
  ...Object.fromEntries(ALLOWED_KINDS.map(kind => [
1393
1421
  kind,
1394
1422
  {
@@ -1396,6 +1424,14 @@ const rule$4 = {
1396
1424
  description: `Read more about this kind on [spec.graphql.org](https://spec.graphql.org/October2021/#${kind}).`,
1397
1425
  },
1398
1426
  ])),
1427
+ allowLeadingUnderscore: {
1428
+ type: 'boolean',
1429
+ default: false,
1430
+ },
1431
+ allowTrailingUnderscore: {
1432
+ type: 'boolean',
1433
+ default: false,
1434
+ },
1399
1435
  },
1400
1436
  patternProperties: {
1401
1437
  [`^(${ALLOWED_KINDS.join('|')})(.+)?$`]: schemaOption$1,
@@ -1412,12 +1448,9 @@ const rule$4 = {
1412
1448
  },
1413
1449
  create(context) {
1414
1450
  const options = context.options[0] || {};
1415
- const { allowLeadingUnderscore, allowTrailingUnderscore, types, fields, ...restOptions } = options;
1451
+ const { allowLeadingUnderscore, allowTrailingUnderscore, types, ...restOptions } = options;
1416
1452
  function normalisePropertyOption(kind) {
1417
- let style = options[kind];
1418
- if (!style) {
1419
- style = TYPES_KINDS.includes(kind) ? types : fields;
1420
- }
1453
+ const style = restOptions[kind] || types;
1421
1454
  return typeof style === 'object' ? style : { style };
1422
1455
  }
1423
1456
  const checkNode = (selector) => (node) => {
@@ -1480,7 +1513,7 @@ const rule$4 = {
1480
1513
  if (!allowTrailingUnderscore) {
1481
1514
  listeners['Name[value=/_$/]:matches([parent.kind!=Field], [parent.kind=Field][parent.alias])'] = checkUnderscore;
1482
1515
  }
1483
- const selectors = new Set([types && TYPES_KINDS, fields && FIELDS_KINDS, Object.keys(restOptions)].flat().filter(Boolean));
1516
+ const selectors = new Set([types && TYPES_KINDS, Object.keys(restOptions)].flat().filter(Boolean));
1484
1517
  for (const selector of selectors) {
1485
1518
  listeners[selector] = checkNode(selector);
1486
1519
  }
@@ -2548,6 +2581,7 @@ const rule$h = {
2548
2581
  [Kind.DIRECTIVE_DEFINITION]: true,
2549
2582
  },
2550
2583
  ],
2584
+ recommended: true,
2551
2585
  },
2552
2586
  type: 'suggestion',
2553
2587
  messages: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@graphql-eslint/eslint-plugin",
3
- "version": "3.0.0-alpha-2918431.0",
3
+ "version": "3.0.0",
4
4
  "sideEffects": false,
5
5
  "peerDependencies": {
6
6
  "graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0"
package/rules/index.d.ts CHANGED
@@ -44,13 +44,6 @@ export declare const rules: {
44
44
  forbiddenPrefixes?: string[];
45
45
  forbiddenSuffixes?: string[];
46
46
  };
47
- fields?: ("PascalCase" | "camelCase" | "UPPER_CASE" | "snake_case") | {
48
- style?: "PascalCase" | "camelCase" | "UPPER_CASE" | "snake_case";
49
- suffix?: string;
50
- prefix?: string;
51
- forbiddenPrefixes?: string[];
52
- forbiddenSuffixes?: string[];
53
- };
54
47
  } & {
55
48
  [x: `OperationDefinition${string}`]: ("PascalCase" | "camelCase" | "UPPER_CASE" | "snake_case") | {
56
49
  style?: "PascalCase" | "camelCase" | "UPPER_CASE" | "snake_case";
@@ -29,7 +29,6 @@ declare type NamingConventionRuleConfig = {
29
29
  allowLeadingUnderscore?: boolean;
30
30
  allowTrailingUnderscore?: boolean;
31
31
  types?: Options;
32
- fields?: Options;
33
32
  } & {
34
33
  [key in `${AllowedKind}${string}`]?: Options;
35
34
  };