Skip to content

Commit 5b35139

Browse files
Add options to input-name rule. Addresses #276 (#286)
* Add caseSensitiveInputType, checkMutations, checkQueries options to input-name rule caseSensitiveInputType: When false the input type name must be <mutationName>Input but is not case sensitive. checkMutations (default true): Apply this rule to mutations. checkQueries (default false): Apply this rule to queries. Also fixed documentation error which says that checkInputType defaults to true, when infact it defaults to false. * added changeset Co-authored-by: Dotan Simha <[email protected]>
1 parent 619d9eb commit 5b35139

File tree

3 files changed

+102
-12
lines changed

3 files changed

+102
-12
lines changed

.changeset/early-turkeys-admire.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+
Add options to input-name rule.

packages/plugin/src/rules/input-name.ts

Lines changed: 53 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
import { GraphQLESLintRule } from '../types';
22

3-
type InputNameRuleConfig = [
4-
{
5-
checkInputType?: boolean;
6-
}
7-
];
3+
type InputNameRuleConfig = {
4+
checkInputType?: boolean;
5+
caseSensitiveInputType?: boolean;
6+
checkQueries?: boolean;
7+
checkMutations?: boolean;
8+
};
89

9-
const rule: GraphQLESLintRule<InputNameRuleConfig> = {
10+
const rule: GraphQLESLintRule<InputNameRuleConfig[]> = {
1011
meta: {
1112
type: 'suggestion',
1213
docs: {
@@ -52,31 +53,65 @@ const rule: GraphQLESLintRule<InputNameRuleConfig> = {
5253
properties: {
5354
checkInputType: {
5455
type: 'boolean',
55-
default: 'true',
56+
default: false,
57+
description: 'Check that the input type name follows the convention <mutationName>Input',
58+
},
59+
caseSensitiveInputType: {
60+
type: 'boolean',
61+
default: true,
62+
description: 'Allow for case discrepancies in the input type name',
63+
},
64+
checkQueries: {
65+
type: 'boolean',
66+
default: false,
67+
description: 'Apply the rule to Queries',
68+
},
69+
checkMutations: {
70+
type: 'boolean',
71+
default: true,
72+
description: 'Apply the rule to Mutations',
5673
},
5774
},
5875
additionalProperties: false,
5976
},
6077
],
6178
},
6279
create(context) {
80+
const options: InputNameRuleConfig = {
81+
caseSensitiveInputType: true,
82+
checkInputType: false,
83+
checkMutations: true,
84+
checkQueries: false,
85+
...context?.options?.[0],
86+
};
87+
6388
const isMutationType = node => {
6489
return (
6590
(node.type === 'ObjectTypeDefinition' || node.type === 'ObjectTypeExtension') && node.name.value === 'Mutation'
6691
);
6792
};
6893

94+
const isQueryType = node => {
95+
return (
96+
(node.type === 'ObjectTypeDefinition' || node.type === 'ObjectTypeExtension') && node.name.value === 'Query'
97+
);
98+
};
99+
100+
const shouldCheckType = node =>
101+
(options.checkMutations && isMutationType(node)) || (options.checkQueries && isQueryType(node));
102+
69103
const listeners = {
70104
'FieldDefinition > InputValueDefinition': node => {
71-
if (node.name.value !== 'input' && isMutationType(node.parent.parent)) {
105+
if (node.name.value !== 'input' && shouldCheckType(node.parent.parent)) {
72106
context.report({
73107
node: node.name,
74108
message: `Input "${node.name.value}" should be called "input"`,
75109
});
76110
}
77111
},
78112
};
79-
if (context.options && context.options[0] && context.options[0].checkInputType) {
113+
114+
if (options?.checkInputType) {
80115
listeners['FieldDefinition > InputValueDefinition NamedType'] = node => {
81116
const findInputType = item => {
82117
let currentNode = item;
@@ -87,11 +122,17 @@ const rule: GraphQLESLintRule<InputNameRuleConfig> = {
87122
};
88123

89124
const inputValueNode = findInputType(node);
90-
if (isMutationType(inputValueNode.parent.parent)) {
125+
if (shouldCheckType(inputValueNode.parent.parent)) {
91126
const mutationName = `${inputValueNode.parent.name.value}Input`;
92127

93-
if (node.name.value !== mutationName) {
94-
context.report({ node, message: `InputType "${node.name.value}" name should be "${mutationName}"` });
128+
if (options.caseSensitiveInputType) {
129+
if (node.name.value !== mutationName) {
130+
context.report({ node, message: `InputType "${node.name.value}" name should be "${mutationName}"` });
131+
}
132+
} else {
133+
if (node.name.value.toLowerCase() !== mutationName.toLowerCase()) {
134+
context.report({ node, message: `InputType "${node.name.value}" name should be "${mutationName}"` });
135+
}
95136
}
96137
}
97138
};

packages/plugin/tests/input-name.spec.ts

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@ const ruleTester = new GraphQLRuleTester();
55

66
ruleTester.runGraphQLTests('input-name', rule, {
77
valid: [
8+
{
9+
code: 'type Mutation { SetMessage(input: SetMessageInput): String }',
10+
options: [{ checkInputType: true }],
11+
},
812
{
913
code: 'type Mutation { SetMessage(input: SetMessageInput): String }',
1014
options: [{ checkInputType: true }],
@@ -25,6 +29,31 @@ ruleTester.runGraphQLTests('input-name', rule, {
2529
'type Mutation { CreateMessage(input: String): String }',
2630
'extend type Mutation { CreateMessage(input: String): String }',
2731
'type Query { message(id: ID): Message }',
32+
'extend type Query { message(id: ID): Message }',
33+
{
34+
code: 'type Mutation { userCreate(input: UserCreateInput): String }',
35+
options: [{ checkInputType: true, caseSensitiveInputType: false }],
36+
},
37+
{
38+
code: 'type Mutation { userCreate(input: userCreateInput): String }',
39+
options: [{ checkInputType: true, caseSensitiveInputType: true }],
40+
},
41+
{
42+
code: 'type Mutation { SetMessage(input: NonConforming): String }',
43+
options: [{ checkMutations: false, checkInputType: true }],
44+
},
45+
{
46+
code: 'type Mutation { SetMessage(input: String): String }',
47+
options: [{ checkMutations: true, checkInputType: false }],
48+
},
49+
{
50+
code: 'type Query { getMessage(input: NonConforming): String }',
51+
options: [{ checkQueries: false, checkInputType: true }],
52+
},
53+
{
54+
code: 'type Query { getMessage(input: String): String }',
55+
options: [{ checkQueries: true, checkInputType: false }],
56+
},
2857
],
2958
invalid: [
3059
{
@@ -75,5 +104,20 @@ ruleTester.runGraphQLTests('input-name', rule, {
75104
options: [{ checkInputType: false }],
76105
errors: 2,
77106
},
107+
{
108+
code: 'type Mutation { userCreate(input: String): String }',
109+
options: [{ checkInputType: true, caseSensitiveInputType: false }],
110+
errors: 1,
111+
},
112+
{
113+
code: 'type Mutation { userCreate(input: UserCreateInput): String }',
114+
options: [{ checkInputType: true, caseSensitiveInputType: true }],
115+
errors: 1,
116+
},
117+
{
118+
code: 'type Query { getUser(input: GetUserInput): String }',
119+
options: [{ checkQueries: true, checkInputType: true, caseSensitiveInputType: true }],
120+
errors: 1,
121+
},
78122
],
79123
});

0 commit comments

Comments
 (0)