Skip to content

Commit db22ba5

Browse files
authored
feat: add suggestions for no-typename-prefix, no-root-type, no-case-insensitive-enum-values-duplicates rules (#968)
1 parent a1c8464 commit db22ba5

13 files changed

+110
-33
lines changed

.changeset/olive-bulldogs-notice.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@graphql-eslint/eslint-plugin': minor
3+
---
4+
5+
feat: add suggestions for `no-typename-prefix`, `no-root-type`, `no-case-insensitive-enum-values-duplicates` rules

packages/plugin/src/rules/no-case-insensitive-enum-values-duplicates.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { GraphQLESLintRule } from '../types';
55
const rule: GraphQLESLintRule = {
66
meta: {
77
type: 'suggestion',
8+
hasSuggestions: true,
89
docs: {
910
url: `https://github.com/dotansimha/graphql-eslint/blob/master/docs/rules/no-case-insensitive-enum-values-duplicates.md`,
1011
category: 'Schema',
@@ -47,7 +48,13 @@ const rule: GraphQLESLintRule = {
4748
const enumName = duplicate.name.value;
4849
context.report({
4950
node: duplicate.name,
50-
message: `Case-insensitive enum values duplicates are not allowed! Found: "${enumName}"`,
51+
message: `Case-insensitive enum values duplicates are not allowed! Found: \`${enumName}\`.`,
52+
suggest: [
53+
{
54+
desc: `Remove \`${enumName}\` enum value`,
55+
fix: fixer => fixer.remove(duplicate as any),
56+
},
57+
],
5158
});
5259
}
5360
},

packages/plugin/src/rules/no-root-type.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ type NoRootTypeConfig = { disallow: typeof ROOT_TYPES };
1010
const rule: GraphQLESLintRule<[NoRootTypeConfig]> = {
1111
meta: {
1212
type: 'suggestion',
13+
hasSuggestions: true,
1314
docs: {
1415
category: 'Schema',
1516
description: 'Disallow using root types `mutation` and/or `subscription`.',
@@ -84,7 +85,13 @@ const rule: GraphQLESLintRule<[NoRootTypeConfig]> = {
8485
const typeName = node.value;
8586
context.report({
8687
node,
87-
message: `Root type "${typeName}" is forbidden`,
88+
message: `Root type \`${typeName}\` is forbidden.`,
89+
suggest: [
90+
{
91+
desc: `Remove \`${typeName}\` type`,
92+
fix: fixer => fixer.remove((node as any).parent),
93+
},
94+
],
8895
});
8996
},
9097
};

packages/plugin/src/rules/no-typename-prefix.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ const NO_TYPENAME_PREFIX = 'NO_TYPENAME_PREFIX';
1212
const rule: GraphQLESLintRule = {
1313
meta: {
1414
type: 'suggestion',
15+
hasSuggestions: true,
1516
docs: {
1617
category: 'Schema',
1718
description: 'Enforces users to avoid using the type name in a field name while defining your schema.',
@@ -62,6 +63,13 @@ const rule: GraphQLESLintRule = {
6263
},
6364
messageId: NO_TYPENAME_PREFIX,
6465
node: field.name,
66+
suggest: [
67+
{
68+
desc: `Remove \`${fieldName.slice(0, typeName.length)}\` prefix`,
69+
fix: fixer =>
70+
fixer.replaceText(field.name as any, fieldName.replace(new RegExp(`^${typeName}`, 'i'), '')),
71+
},
72+
],
6573
});
6674
}
6775
}

packages/plugin/src/rules/no-unreachable-types.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ const rule: GraphQLESLintRule = {
8484
data: { typeName },
8585
suggest: [
8686
{
87-
desc: `Remove ${typeName}`,
87+
desc: `Remove \`${typeName}\``,
8888
fix: fixer => fixer.remove(node as any),
8989
},
9090
],

packages/plugin/src/rules/no-unused-fields.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ const rule: GraphQLESLintRule = {
8383
data: { fieldName },
8484
suggest: [
8585
{
86-
desc: `Remove "${fieldName}" field`,
86+
desc: `Remove \`${fieldName}\` field`,
8787
fix(fixer) {
8888
const sourceCode = context.getSourceCode() as any;
8989
const tokenBefore = sourceCode.getTokenBefore(node);

packages/plugin/tests/__snapshots__/no-case-insensitive-enum-values-duplicates.spec.md

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,20 @@ exports[` 1`] = `
44
❌ Error
55

66
> 1 | enum A { TEST TesT }
7-
| ^^^^ Case-insensitive enum values duplicates are not allowed! Found: "TesT"
7+
| ^^^^ Case-insensitive enum values duplicates are not allowed! Found: \`TesT\`.
8+
9+
💡 Suggestion: Remove \`TesT\` enum value
10+
11+
1 | enum A { TEST }
812
`;
913

1014
exports[` 2`] = `
1115
❌ Error
1216

1317
> 1 | extend enum A { TEST TesT }
14-
| ^^^^ Case-insensitive enum values duplicates are not allowed! Found: "TesT"
18+
| ^^^^ Case-insensitive enum values duplicates are not allowed! Found: \`TesT\`.
19+
20+
💡 Suggestion: Remove \`TesT\` enum value
21+
22+
1 | extend enum A { TEST }
1523
`;

packages/plugin/tests/__snapshots__/no-root-type.spec.md

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,11 @@ exports[` 1`] = `
1212
❌ Error
1313

1414
> 1 | type Mutation
15-
| ^^^^^^^^ Root type "Mutation" is forbidden
15+
| ^^^^^^^^ Root type \`Mutation\` is forbidden.
16+
17+
💡 Suggestion: Remove \`Mutation\` type
18+
19+
1 |
1620
`;
1721

1822
exports[` 2`] = `
@@ -27,7 +31,11 @@ exports[` 2`] = `
2731
❌ Error
2832

2933
> 1 | type Subscription
30-
| ^^^^^^^^^^^^ Root type "Subscription" is forbidden
34+
| ^^^^^^^^^^^^ Root type \`Subscription\` is forbidden.
35+
36+
💡 Suggestion: Remove \`Subscription\` type
37+
38+
1 |
3139
`;
3240

3341
exports[` 3`] = `
@@ -42,7 +50,11 @@ exports[` 3`] = `
4250
❌ Error
4351

4452
> 1 | extend type Mutation { foo: ID }
45-
| ^^^^^^^^ Root type "Mutation" is forbidden
53+
| ^^^^^^^^ Root type \`Mutation\` is forbidden.
54+
55+
💡 Suggestion: Remove \`Mutation\` type
56+
57+
1 |
4658
`;
4759

4860
exports[` 4`] = `
@@ -57,5 +69,9 @@ exports[` 4`] = `
5769
❌ Error
5870

5971
> 1 | type MyMutation
60-
| ^^^^^^^^^^ Root type "MyMutation" is forbidden
72+
| ^^^^^^^^^^ Root type \`MyMutation\` is forbidden.
73+
74+
💡 Suggestion: Remove \`MyMutation\` type
75+
76+
1 |
6177
`;

packages/plugin/tests/__snapshots__/no-typename-prefix.spec.md

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,12 @@ exports[` 1`] = `
77
> 2 | userId: ID!
88
| ^^^^^^ Field "userId" starts with the name of the parent type "User"
99
3 | }
10+
11+
💡 Suggestion: Remove \`user\` prefix
12+
13+
1 | type User {
14+
2 | Id: ID!
15+
3 | }
1016
`;
1117

1218
exports[` 2`] = `
@@ -24,12 +30,26 @@ Code
2430
| ^^^^^^ Field "userId" starts with the name of the parent type "User"
2531
3 | userName: String!
2632

33+
💡 Suggestion: Remove \`user\` prefix
34+
35+
1 | type User {
36+
2 | Id: ID!
37+
3 | userName: String!
38+
4 | }
39+
2740
❌ Error 2/2
2841

2942
2 | userId: ID!
3043
> 3 | userName: String!
3144
| ^^^^^^^^ Field "userName" starts with the name of the parent type "User"
3245
4 | }
46+
47+
💡 Suggestion: Remove \`user\` prefix
48+
49+
1 | type User {
50+
2 | userId: ID!
51+
3 | Name: String!
52+
4 | }
3353
`;
3454

3555
exports[` 3`] = `
@@ -39,4 +59,10 @@ exports[` 3`] = `
3959
> 2 | nodeId: ID!
4060
| ^^^^^^ Field "nodeId" starts with the name of the parent type "Node"
4161
3 | }
62+
63+
💡 Suggestion: Remove \`node\` prefix
64+
65+
1 | interface Node {
66+
2 | Id: ID!
67+
3 | }
4268
`;

packages/plugin/tests/__snapshots__/no-unreachable-types.spec.md

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ Code
3333
| ^^^^ Type "Node" is unreachable
3434
6 | id: ID!
3535

36-
💡 Suggestion: Remove Node
36+
💡 Suggestion: Remove \`Node\`
3737

3838
1 | type Query {
3939
2 | node(id: ID!): AnotherNode!
@@ -63,7 +63,7 @@ Code
6363
| ^^^^ Type "User" is unreachable
6464
14 | id: ID!
6565

66-
💡 Suggestion: Remove User
66+
💡 Suggestion: Remove \`User\`
6767

6868
1 | type Query {
6969
2 | node(id: ID!): AnotherNode!
@@ -92,7 +92,7 @@ Code
9292
| ^^^^^^^^^ Type "SuperUser" is unreachable
9393
19 | id: ID!
9494

95-
💡 Suggestion: Remove SuperUser
95+
💡 Suggestion: Remove \`SuperUser\`
9696

9797
1 | type Query {
9898
2 | node(id: ID!): AnotherNode!
@@ -154,7 +154,7 @@ Code
154154
| ^^^^^^^^ Type "DateTime" is unreachable
155155
3 |
156156

157-
💡 Suggestion: Remove DateTime
157+
💡 Suggestion: Remove \`DateTime\`
158158

159159
1 | # ScalarTypeDefinition
160160
2 |
@@ -193,7 +193,7 @@ Code
193193
| ^^^^ Type "Role" is unreachable
194194
6 | ADMIN
195195

196-
💡 Suggestion: Remove Role
196+
💡 Suggestion: Remove \`Role\`
197197

198198
1 | # ScalarTypeDefinition
199199
2 | scalar DateTime
@@ -229,7 +229,7 @@ Code
229229
| ^^^^ Type "auth" is unreachable
230230
12 |
231231

232-
💡 Suggestion: Remove auth
232+
💡 Suggestion: Remove \`auth\`
233233

234234
1 | # ScalarTypeDefinition
235235
2 | scalar DateTime
@@ -268,7 +268,7 @@ Code
268268
| ^^^^^ Type "Union" is unreachable
269269
15 |
270270

271-
💡 Suggestion: Remove Union
271+
💡 Suggestion: Remove \`Union\`
272272

273273
1 | # ScalarTypeDefinition
274274
2 | scalar DateTime
@@ -307,7 +307,7 @@ Code
307307
| ^^^^^^^^^^^ Type "UsersFilter" is unreachable
308308
18 | limit: Int
309309

310-
💡 Suggestion: Remove UsersFilter
310+
💡 Suggestion: Remove \`UsersFilter\`
311311

312312
1 | # ScalarTypeDefinition
313313
2 | scalar DateTime
@@ -344,7 +344,7 @@ Code
344344
| ^^^^^^^ Type "Address" is unreachable
345345
23 | city: String
346346

347-
💡 Suggestion: Remove Address
347+
💡 Suggestion: Remove \`Address\`
348348

349349
1 | # ScalarTypeDefinition
350350
2 | scalar DateTime
@@ -381,7 +381,7 @@ Code
381381
| ^^^^ Type "User" is unreachable
382382
28 | city: String
383383

384-
💡 Suggestion: Remove User
384+
💡 Suggestion: Remove \`User\`
385385

386386
1 | # ScalarTypeDefinition
387387
2 | scalar DateTime
@@ -435,7 +435,7 @@ exports[` 3`] = `
435435
> 18 | scalar DateTime
436436
| ^^^^^^^^ Type "DateTime" is unreachable
437437

438-
💡 Suggestion: Remove DateTime
438+
💡 Suggestion: Remove \`DateTime\`
439439

440440
1 | interface User {
441441
2 | id: String
@@ -487,7 +487,7 @@ Code
487487
| ^^^^ Type "User" is unreachable
488488
2 | id: String
489489

490-
💡 Suggestion: Remove User
490+
💡 Suggestion: Remove \`User\`
491491

492492
1 |
493493
2 |
@@ -515,7 +515,7 @@ Code
515515
| ^^^^^^^^^ Type "SuperUser" is unreachable
516516
10 | id: String
517517

518-
💡 Suggestion: Remove SuperUser
518+
💡 Suggestion: Remove \`SuperUser\`
519519

520520
1 | interface User {
521521
2 | id: String
@@ -543,7 +543,7 @@ Code
543543
| ^^^^^^^^^ Type "SuperUser" is unreachable
544544
15 | detail: String
545545

546-
💡 Suggestion: Remove SuperUser
546+
💡 Suggestion: Remove \`SuperUser\`
547547

548548
1 | interface User {
549549
2 | id: String
@@ -590,7 +590,7 @@ exports[` 5`] = `
590590
> 20 | scalar DateTime
591591
| ^^^^^^^^ Type "DateTime" is unreachable
592592

593-
💡 Suggestion: Remove DateTime
593+
💡 Suggestion: Remove \`DateTime\`
594594

595595
1 | type Query {
596596
2 | node(id: ID!): Node!

0 commit comments

Comments
 (0)