eslint-plugin-react-naming-convention 1.29.1-next.4 → 1.29.1-next.6
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/dist/index.d.mts +12 -14
- package/dist/index.d.ts +12 -14
- package/dist/index.js +51 -72
- package/dist/index.mjs +52 -73
- package/package.json +7 -7
package/dist/index.d.mts
CHANGED
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
import * as _typescript_eslint_utils_ts_eslint from '@typescript-eslint/utils/ts-eslint';
|
|
2
2
|
import { RulePreset } from '@eslint-react/shared';
|
|
3
3
|
|
|
4
|
-
type MessageID$
|
|
4
|
+
type MessageID$1 = "useJsxFileExtension" | "useNonJsxFileExtension";
|
|
5
5
|
|
|
6
|
-
type MessageID
|
|
7
|
-
|
|
8
|
-
type MessageID = "usePascalCase" | "useConstantCase";
|
|
6
|
+
type MessageID = "filenameEmpty" | "filenameInvalid";
|
|
9
7
|
|
|
10
8
|
declare const _default: {
|
|
11
9
|
configs: {
|
|
@@ -17,25 +15,25 @@ declare const _default: {
|
|
|
17
15
|
readonly version: string;
|
|
18
16
|
};
|
|
19
17
|
readonly rules: {
|
|
20
|
-
readonly "component-name": _typescript_eslint_utils_ts_eslint.RuleModule<
|
|
18
|
+
readonly "component-name": _typescript_eslint_utils_ts_eslint.RuleModule<"invalid", readonly [("CONSTANT_CASE" | "PascalCase") | {
|
|
21
19
|
allowAllCaps?: boolean;
|
|
22
20
|
allowLeadingUnderscore?: boolean;
|
|
23
21
|
allowNamespace?: boolean;
|
|
24
22
|
excepts?: readonly string[];
|
|
25
23
|
rule?: "CONSTANT_CASE" | "PascalCase";
|
|
26
24
|
} | undefined], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
|
|
27
|
-
readonly "context-name": _typescript_eslint_utils_ts_eslint.RuleModule<"
|
|
28
|
-
readonly filename: _typescript_eslint_utils_ts_eslint.RuleModule<MessageID
|
|
25
|
+
readonly "context-name": _typescript_eslint_utils_ts_eslint.RuleModule<"invalid", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
|
|
26
|
+
readonly filename: _typescript_eslint_utils_ts_eslint.RuleModule<MessageID, readonly [("PascalCase" | "camelCase" | "kebab-case" | "snake_case") | {
|
|
29
27
|
excepts?: readonly string[];
|
|
30
28
|
extensions?: readonly string[];
|
|
31
29
|
rule?: "PascalCase" | "camelCase" | "kebab-case" | "snake_case";
|
|
32
30
|
} | undefined], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
|
|
33
|
-
readonly "filename-extension": _typescript_eslint_utils_ts_eslint.RuleModule<MessageID$
|
|
31
|
+
readonly "filename-extension": _typescript_eslint_utils_ts_eslint.RuleModule<MessageID$1, readonly [("always" | "as-needed") | {
|
|
34
32
|
allow?: "always" | "as-needed";
|
|
35
33
|
extensions?: readonly string[];
|
|
36
34
|
ignoreFilesWithoutCode?: boolean;
|
|
37
35
|
} | undefined], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
|
|
38
|
-
readonly "use-state": _typescript_eslint_utils_ts_eslint.RuleModule<"
|
|
36
|
+
readonly "use-state": _typescript_eslint_utils_ts_eslint.RuleModule<"invalid", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
|
|
39
37
|
};
|
|
40
38
|
};
|
|
41
39
|
};
|
|
@@ -52,25 +50,25 @@ declare const _default: {
|
|
|
52
50
|
readonly version: string;
|
|
53
51
|
};
|
|
54
52
|
rules: {
|
|
55
|
-
readonly "component-name": _typescript_eslint_utils_ts_eslint.RuleModule<
|
|
53
|
+
readonly "component-name": _typescript_eslint_utils_ts_eslint.RuleModule<"invalid", readonly [("CONSTANT_CASE" | "PascalCase") | {
|
|
56
54
|
allowAllCaps?: boolean;
|
|
57
55
|
allowLeadingUnderscore?: boolean;
|
|
58
56
|
allowNamespace?: boolean;
|
|
59
57
|
excepts?: readonly string[];
|
|
60
58
|
rule?: "CONSTANT_CASE" | "PascalCase";
|
|
61
59
|
} | undefined], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
|
|
62
|
-
readonly "context-name": _typescript_eslint_utils_ts_eslint.RuleModule<"
|
|
63
|
-
readonly filename: _typescript_eslint_utils_ts_eslint.RuleModule<MessageID
|
|
60
|
+
readonly "context-name": _typescript_eslint_utils_ts_eslint.RuleModule<"invalid", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
|
|
61
|
+
readonly filename: _typescript_eslint_utils_ts_eslint.RuleModule<MessageID, readonly [("PascalCase" | "camelCase" | "kebab-case" | "snake_case") | {
|
|
64
62
|
excepts?: readonly string[];
|
|
65
63
|
extensions?: readonly string[];
|
|
66
64
|
rule?: "PascalCase" | "camelCase" | "kebab-case" | "snake_case";
|
|
67
65
|
} | undefined], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
|
|
68
|
-
readonly "filename-extension": _typescript_eslint_utils_ts_eslint.RuleModule<MessageID$
|
|
66
|
+
readonly "filename-extension": _typescript_eslint_utils_ts_eslint.RuleModule<MessageID$1, readonly [("always" | "as-needed") | {
|
|
69
67
|
allow?: "always" | "as-needed";
|
|
70
68
|
extensions?: readonly string[];
|
|
71
69
|
ignoreFilesWithoutCode?: boolean;
|
|
72
70
|
} | undefined], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
|
|
73
|
-
readonly "use-state": _typescript_eslint_utils_ts_eslint.RuleModule<"
|
|
71
|
+
readonly "use-state": _typescript_eslint_utils_ts_eslint.RuleModule<"invalid", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
|
|
74
72
|
};
|
|
75
73
|
};
|
|
76
74
|
|
package/dist/index.d.ts
CHANGED
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
import * as _typescript_eslint_utils_ts_eslint from '@typescript-eslint/utils/ts-eslint';
|
|
2
2
|
import { RulePreset } from '@eslint-react/shared';
|
|
3
3
|
|
|
4
|
-
type MessageID$
|
|
4
|
+
type MessageID$1 = "useJsxFileExtension" | "useNonJsxFileExtension";
|
|
5
5
|
|
|
6
|
-
type MessageID
|
|
7
|
-
|
|
8
|
-
type MessageID = "usePascalCase" | "useConstantCase";
|
|
6
|
+
type MessageID = "filenameEmpty" | "filenameInvalid";
|
|
9
7
|
|
|
10
8
|
declare const _default: {
|
|
11
9
|
configs: {
|
|
@@ -17,25 +15,25 @@ declare const _default: {
|
|
|
17
15
|
readonly version: string;
|
|
18
16
|
};
|
|
19
17
|
readonly rules: {
|
|
20
|
-
readonly "component-name": _typescript_eslint_utils_ts_eslint.RuleModule<
|
|
18
|
+
readonly "component-name": _typescript_eslint_utils_ts_eslint.RuleModule<"invalid", readonly [("CONSTANT_CASE" | "PascalCase") | {
|
|
21
19
|
allowAllCaps?: boolean;
|
|
22
20
|
allowLeadingUnderscore?: boolean;
|
|
23
21
|
allowNamespace?: boolean;
|
|
24
22
|
excepts?: readonly string[];
|
|
25
23
|
rule?: "CONSTANT_CASE" | "PascalCase";
|
|
26
24
|
} | undefined], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
|
|
27
|
-
readonly "context-name": _typescript_eslint_utils_ts_eslint.RuleModule<"
|
|
28
|
-
readonly filename: _typescript_eslint_utils_ts_eslint.RuleModule<MessageID
|
|
25
|
+
readonly "context-name": _typescript_eslint_utils_ts_eslint.RuleModule<"invalid", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
|
|
26
|
+
readonly filename: _typescript_eslint_utils_ts_eslint.RuleModule<MessageID, readonly [("PascalCase" | "camelCase" | "kebab-case" | "snake_case") | {
|
|
29
27
|
excepts?: readonly string[];
|
|
30
28
|
extensions?: readonly string[];
|
|
31
29
|
rule?: "PascalCase" | "camelCase" | "kebab-case" | "snake_case";
|
|
32
30
|
} | undefined], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
|
|
33
|
-
readonly "filename-extension": _typescript_eslint_utils_ts_eslint.RuleModule<MessageID$
|
|
31
|
+
readonly "filename-extension": _typescript_eslint_utils_ts_eslint.RuleModule<MessageID$1, readonly [("always" | "as-needed") | {
|
|
34
32
|
allow?: "always" | "as-needed";
|
|
35
33
|
extensions?: readonly string[];
|
|
36
34
|
ignoreFilesWithoutCode?: boolean;
|
|
37
35
|
} | undefined], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
|
|
38
|
-
readonly "use-state": _typescript_eslint_utils_ts_eslint.RuleModule<"
|
|
36
|
+
readonly "use-state": _typescript_eslint_utils_ts_eslint.RuleModule<"invalid", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
|
|
39
37
|
};
|
|
40
38
|
};
|
|
41
39
|
};
|
|
@@ -52,25 +50,25 @@ declare const _default: {
|
|
|
52
50
|
readonly version: string;
|
|
53
51
|
};
|
|
54
52
|
rules: {
|
|
55
|
-
readonly "component-name": _typescript_eslint_utils_ts_eslint.RuleModule<
|
|
53
|
+
readonly "component-name": _typescript_eslint_utils_ts_eslint.RuleModule<"invalid", readonly [("CONSTANT_CASE" | "PascalCase") | {
|
|
56
54
|
allowAllCaps?: boolean;
|
|
57
55
|
allowLeadingUnderscore?: boolean;
|
|
58
56
|
allowNamespace?: boolean;
|
|
59
57
|
excepts?: readonly string[];
|
|
60
58
|
rule?: "CONSTANT_CASE" | "PascalCase";
|
|
61
59
|
} | undefined], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
|
|
62
|
-
readonly "context-name": _typescript_eslint_utils_ts_eslint.RuleModule<"
|
|
63
|
-
readonly filename: _typescript_eslint_utils_ts_eslint.RuleModule<MessageID
|
|
60
|
+
readonly "context-name": _typescript_eslint_utils_ts_eslint.RuleModule<"invalid", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
|
|
61
|
+
readonly filename: _typescript_eslint_utils_ts_eslint.RuleModule<MessageID, readonly [("PascalCase" | "camelCase" | "kebab-case" | "snake_case") | {
|
|
64
62
|
excepts?: readonly string[];
|
|
65
63
|
extensions?: readonly string[];
|
|
66
64
|
rule?: "PascalCase" | "camelCase" | "kebab-case" | "snake_case";
|
|
67
65
|
} | undefined], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
|
|
68
|
-
readonly "filename-extension": _typescript_eslint_utils_ts_eslint.RuleModule<MessageID$
|
|
66
|
+
readonly "filename-extension": _typescript_eslint_utils_ts_eslint.RuleModule<MessageID$1, readonly [("always" | "as-needed") | {
|
|
69
67
|
allow?: "always" | "as-needed";
|
|
70
68
|
extensions?: readonly string[];
|
|
71
69
|
ignoreFilesWithoutCode?: boolean;
|
|
72
70
|
} | undefined], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
|
|
73
|
-
readonly "use-state": _typescript_eslint_utils_ts_eslint.RuleModule<"
|
|
71
|
+
readonly "use-state": _typescript_eslint_utils_ts_eslint.RuleModule<"invalid", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
|
|
74
72
|
};
|
|
75
73
|
};
|
|
76
74
|
|
package/dist/index.js
CHANGED
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
var AST = require('@eslint-react/ast');
|
|
4
4
|
var core = require('@eslint-react/core');
|
|
5
|
-
var eff = require('@eslint-react/eff');
|
|
6
5
|
var JSX = require('@eslint-react/jsx');
|
|
7
6
|
var shared = require('@eslint-react/shared');
|
|
8
|
-
var
|
|
7
|
+
var eff = require('@eslint-react/eff');
|
|
9
8
|
var types = require('@typescript-eslint/types');
|
|
9
|
+
var tsPattern = require('ts-pattern');
|
|
10
10
|
var path = require('path');
|
|
11
11
|
var stringTs = require('string-ts');
|
|
12
12
|
|
|
@@ -54,7 +54,7 @@ var rules = {
|
|
|
54
54
|
|
|
55
55
|
// package.json
|
|
56
56
|
var name2 = "eslint-plugin-react-naming-convention";
|
|
57
|
-
var version = "1.29.1-next.
|
|
57
|
+
var version = "1.29.1-next.6";
|
|
58
58
|
var createRule = shared.createRuleForPlugin("naming-convention");
|
|
59
59
|
|
|
60
60
|
// src/rules/component-name.ts
|
|
@@ -97,60 +97,48 @@ var schema = [
|
|
|
97
97
|
];
|
|
98
98
|
function normalizeOptions(options) {
|
|
99
99
|
const opts = options[0];
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
}
|
|
103
|
-
if (typeof opts === "string") {
|
|
104
|
-
return { ...defaultOptions[0], rule: opts };
|
|
105
|
-
}
|
|
100
|
+
const defaultOpts = defaultOptions[0];
|
|
101
|
+
if (opts == null) return defaultOpts;
|
|
106
102
|
return {
|
|
107
|
-
...
|
|
108
|
-
|
|
103
|
+
...defaultOpts,
|
|
104
|
+
...typeof opts === "string" ? { rule: opts } : {
|
|
105
|
+
...opts,
|
|
106
|
+
excepts: opts.excepts?.map((pattern) => new RegExp(pattern, "u")) ?? []
|
|
107
|
+
}
|
|
109
108
|
};
|
|
110
109
|
}
|
|
111
|
-
function
|
|
112
|
-
if (name3 == null) return
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
if (allowNamespace) {
|
|
126
|
-
normalized = normalized.replace(":", "");
|
|
127
|
-
}
|
|
128
|
-
if (allowLeadingUnderscore) {
|
|
129
|
-
normalized = normalized.replace(/^_/, "");
|
|
110
|
+
function isValidComponentName(name3, options) {
|
|
111
|
+
if (name3 == null) return true;
|
|
112
|
+
if (options.excepts.some((regex) => regex.test(name3))) return true;
|
|
113
|
+
let normalized = name3.split(".").at(-1) ?? name3;
|
|
114
|
+
if (options.allowNamespace) normalized = normalized.replace(":", "");
|
|
115
|
+
if (options.allowLeadingUnderscore) normalized = normalized.replace(/^_/, "");
|
|
116
|
+
switch (options.rule) {
|
|
117
|
+
case "CONSTANT_CASE":
|
|
118
|
+
return shared.RE_CONSTANT_CASE.test(normalized);
|
|
119
|
+
case "PascalCase":
|
|
120
|
+
if (normalized.length > 3 && /^[A-Z]+$/u.test(normalized)) {
|
|
121
|
+
return options.allowAllCaps;
|
|
122
|
+
}
|
|
123
|
+
return shared.RE_PASCAL_CASE.test(normalized);
|
|
130
124
|
}
|
|
131
|
-
return tsPattern.match(rule).with("CONSTANT_CASE", () => shared.RE_CONSTANT_CASE.test(normalized) ? eff._ : "useConstantCase").with("PascalCase", () => {
|
|
132
|
-
if (normalized.length > 3 && /^[A-Z]+$/u.test(normalized)) {
|
|
133
|
-
return allowAllCaps ? eff._ : "usePascalCase";
|
|
134
|
-
}
|
|
135
|
-
return shared.RE_PASCAL_CASE.test(normalized) ? eff._ : "usePascalCase";
|
|
136
|
-
}).otherwise(() => eff._);
|
|
137
125
|
}
|
|
138
126
|
var component_name_default = createRule({
|
|
139
127
|
meta: {
|
|
140
128
|
type: "problem",
|
|
141
129
|
defaultOptions: [...defaultOptions],
|
|
142
130
|
docs: {
|
|
143
|
-
description: "enforce
|
|
131
|
+
description: "enforce naming convention for components"
|
|
144
132
|
},
|
|
145
133
|
messages: {
|
|
146
|
-
|
|
147
|
-
usePascalCase: "Component name '{{name}}' must be in PascalCase."
|
|
134
|
+
invalid: "A component name '{{name}}' does not match {{rule}}."
|
|
148
135
|
},
|
|
149
136
|
schema
|
|
150
137
|
},
|
|
151
138
|
name: RULE_NAME,
|
|
152
139
|
create(context) {
|
|
153
140
|
const options = normalizeOptions(context.options);
|
|
141
|
+
const { rule } = options;
|
|
154
142
|
const collector = core.useComponentCollector(context);
|
|
155
143
|
const collectorLegacy = core.useComponentCollectorLegacy();
|
|
156
144
|
return {
|
|
@@ -161,14 +149,11 @@ var component_name_default = createRule({
|
|
|
161
149
|
if (/^[a-z]/u.test(name3)) {
|
|
162
150
|
return;
|
|
163
151
|
}
|
|
164
|
-
|
|
165
|
-
if (violation == null) return;
|
|
152
|
+
if (isValidComponentName(name3, options)) return;
|
|
166
153
|
context.report({
|
|
167
|
-
messageId:
|
|
154
|
+
messageId: "invalid",
|
|
168
155
|
node,
|
|
169
|
-
data: {
|
|
170
|
-
name: name3
|
|
171
|
-
}
|
|
156
|
+
data: { name: name3, rule }
|
|
172
157
|
});
|
|
173
158
|
},
|
|
174
159
|
"Program:exit"(node) {
|
|
@@ -178,28 +163,22 @@ var component_name_default = createRule({
|
|
|
178
163
|
const id = AST__namespace.getFunctionIdentifier(component);
|
|
179
164
|
if (id?.name == null) continue;
|
|
180
165
|
const name3 = id.name;
|
|
181
|
-
|
|
182
|
-
if (violation == null) continue;
|
|
166
|
+
if (isValidComponentName(name3, options)) return;
|
|
183
167
|
context.report({
|
|
184
|
-
messageId:
|
|
168
|
+
messageId: "invalid",
|
|
185
169
|
node: id,
|
|
186
|
-
data: {
|
|
187
|
-
name: name3
|
|
188
|
-
}
|
|
170
|
+
data: { name: name3, rule }
|
|
189
171
|
});
|
|
190
172
|
}
|
|
191
173
|
for (const { node: component } of classComponents.values()) {
|
|
192
174
|
const id = AST__namespace.getClassIdentifier(component);
|
|
193
175
|
if (id?.name == null) continue;
|
|
194
176
|
const name3 = id.name;
|
|
195
|
-
|
|
196
|
-
if (violation == null) continue;
|
|
177
|
+
if (isValidComponentName(name3, options)) continue;
|
|
197
178
|
context.report({
|
|
198
|
-
messageId:
|
|
179
|
+
messageId: "invalid",
|
|
199
180
|
node: id,
|
|
200
|
-
data: {
|
|
201
|
-
case: options.rule
|
|
202
|
-
}
|
|
181
|
+
data: { name: name3, rule }
|
|
203
182
|
});
|
|
204
183
|
}
|
|
205
184
|
}
|
|
@@ -212,10 +191,10 @@ var context_name_default = createRule({
|
|
|
212
191
|
meta: {
|
|
213
192
|
type: "problem",
|
|
214
193
|
docs: {
|
|
215
|
-
description: "
|
|
194
|
+
description: "enforce context name to be a valid component name with the suffix 'Context'"
|
|
216
195
|
},
|
|
217
196
|
messages: {
|
|
218
|
-
|
|
197
|
+
invalid: "A context name must be a valid component name with the suffix 'Context'."
|
|
219
198
|
},
|
|
220
199
|
schema: []
|
|
221
200
|
},
|
|
@@ -228,9 +207,9 @@ var context_name_default = createRule({
|
|
|
228
207
|
const id = core.getInstanceId(node);
|
|
229
208
|
if (id == null) return;
|
|
230
209
|
const name3 = tsPattern.match(id).with({ type: types.AST_NODE_TYPES.Identifier, name: tsPattern.P.select() }, eff.identity).with({ type: types.AST_NODE_TYPES.MemberExpression, property: { name: tsPattern.P.select(tsPattern.P.string) } }, eff.identity).otherwise(() => eff._);
|
|
231
|
-
if (name3 != null && /^[A-Z]
|
|
210
|
+
if (name3 != null && /^[A-Z]/u.test(name3) && name3.endsWith("Context")) return;
|
|
232
211
|
context.report({
|
|
233
|
-
messageId: "
|
|
212
|
+
messageId: "invalid",
|
|
234
213
|
node: id
|
|
235
214
|
});
|
|
236
215
|
}
|
|
@@ -283,8 +262,8 @@ var filename_default = createRule({
|
|
|
283
262
|
description: "enforce naming convention for JSX filenames"
|
|
284
263
|
},
|
|
285
264
|
messages: {
|
|
286
|
-
|
|
287
|
-
|
|
265
|
+
filenameEmpty: "A file must have non-empty name.",
|
|
266
|
+
filenameInvalid: "A file with name '{{name}}' does not match {{rule}}. Rename it to '{{suggestion}}'."
|
|
288
267
|
},
|
|
289
268
|
schema: schema2
|
|
290
269
|
},
|
|
@@ -312,7 +291,7 @@ var filename_default = createRule({
|
|
|
312
291
|
return;
|
|
313
292
|
}
|
|
314
293
|
context.report({
|
|
315
|
-
messageId: "
|
|
294
|
+
messageId: "filenameInvalid",
|
|
316
295
|
node,
|
|
317
296
|
data: {
|
|
318
297
|
name: context.filename,
|
|
@@ -370,7 +349,7 @@ var filename_extension_default = createRule({
|
|
|
370
349
|
},
|
|
371
350
|
messages: {
|
|
372
351
|
useJsxFileExtension: "Use {{extensions}} file extension for JSX files.",
|
|
373
|
-
|
|
352
|
+
useNonJsxFileExtension: "Do not use {{extensions}} file extension for files without JSX."
|
|
374
353
|
},
|
|
375
354
|
schema: schema3
|
|
376
355
|
},
|
|
@@ -409,7 +388,7 @@ var filename_extension_default = createRule({
|
|
|
409
388
|
}
|
|
410
389
|
if (!hasJSXNode && isJSXExt && allow === "as-needed") {
|
|
411
390
|
context.report({
|
|
412
|
-
messageId: "
|
|
391
|
+
messageId: "useNonJsxFileExtension",
|
|
413
392
|
node,
|
|
414
393
|
data: {
|
|
415
394
|
extensions: extensionsString
|
|
@@ -433,7 +412,7 @@ var use_state_default = createRule({
|
|
|
433
412
|
[Symbol.for("rule_features")]: RULE_FEATURES
|
|
434
413
|
},
|
|
435
414
|
messages: {
|
|
436
|
-
|
|
415
|
+
invalid: "An useState call is not destructured into value + setter pair."
|
|
437
416
|
},
|
|
438
417
|
schema: []
|
|
439
418
|
},
|
|
@@ -442,21 +421,21 @@ var use_state_default = createRule({
|
|
|
442
421
|
return {
|
|
443
422
|
"CallExpression[callee.name='useState']"(node) {
|
|
444
423
|
if (node.parent.type !== types.AST_NODE_TYPES.VariableDeclarator) {
|
|
445
|
-
context.report({ messageId: "
|
|
424
|
+
context.report({ messageId: "invalid", node });
|
|
446
425
|
}
|
|
447
426
|
const id = core.getInstanceId(node);
|
|
448
427
|
if (id?.type !== types.AST_NODE_TYPES.ArrayPattern) {
|
|
449
|
-
context.report({ messageId: "
|
|
428
|
+
context.report({ messageId: "invalid", node });
|
|
450
429
|
return;
|
|
451
430
|
}
|
|
452
431
|
const [value, setter] = id.elements;
|
|
453
432
|
if (value == null || setter == null) {
|
|
454
|
-
context.report({ messageId: "
|
|
433
|
+
context.report({ messageId: "invalid", node });
|
|
455
434
|
return;
|
|
456
435
|
}
|
|
457
436
|
const setterName = tsPattern.match(setter).with({ type: types.AST_NODE_TYPES.Identifier }, (id2) => id2.name).otherwise(() => eff._);
|
|
458
437
|
if (setterName == null || !setterName.startsWith("set")) {
|
|
459
|
-
context.report({ messageId: "
|
|
438
|
+
context.report({ messageId: "invalid", node });
|
|
460
439
|
return;
|
|
461
440
|
}
|
|
462
441
|
const valueName = tsPattern.match(value).with({ type: types.AST_NODE_TYPES.Identifier }, (id2) => id2.name).with({ type: types.AST_NODE_TYPES.ObjectPattern }, ({ properties }) => {
|
|
@@ -469,7 +448,7 @@ var use_state_default = createRule({
|
|
|
469
448
|
return values.join("_");
|
|
470
449
|
}).otherwise(() => eff._);
|
|
471
450
|
if (valueName == null || `set_${valueName}` !== stringTs.snakeCase(setterName)) {
|
|
472
|
-
context.report({ messageId: "
|
|
451
|
+
context.report({ messageId: "invalid", node });
|
|
473
452
|
return;
|
|
474
453
|
}
|
|
475
454
|
}
|
package/dist/index.mjs
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import * as AST from '@eslint-react/ast';
|
|
2
2
|
import { useComponentCollector, useComponentCollectorLegacy, isCreateContextCall, getInstanceId } from '@eslint-react/core';
|
|
3
|
-
import { identity, _, isObject } from '@eslint-react/eff';
|
|
4
3
|
import * as JSX from '@eslint-react/jsx';
|
|
5
|
-
import { createRuleForPlugin,
|
|
6
|
-
import {
|
|
4
|
+
import { createRuleForPlugin, RE_PASCAL_CASE, RE_CONSTANT_CASE, RE_CAMEL_CASE, RE_KEBAB_CASE, RE_SNAKE_CASE } from '@eslint-react/shared';
|
|
5
|
+
import { identity, _, isObject } from '@eslint-react/eff';
|
|
7
6
|
import { AST_NODE_TYPES } from '@typescript-eslint/types';
|
|
7
|
+
import { match, P } from 'ts-pattern';
|
|
8
8
|
import path from 'node:path';
|
|
9
9
|
import { snakeCase, pascalCase, camelCase, kebabCase } from 'string-ts';
|
|
10
10
|
|
|
@@ -28,7 +28,7 @@ var rules = {
|
|
|
28
28
|
|
|
29
29
|
// package.json
|
|
30
30
|
var name2 = "eslint-plugin-react-naming-convention";
|
|
31
|
-
var version = "1.29.1-next.
|
|
31
|
+
var version = "1.29.1-next.6";
|
|
32
32
|
var createRule = createRuleForPlugin("naming-convention");
|
|
33
33
|
|
|
34
34
|
// src/rules/component-name.ts
|
|
@@ -71,60 +71,48 @@ var schema = [
|
|
|
71
71
|
];
|
|
72
72
|
function normalizeOptions(options) {
|
|
73
73
|
const opts = options[0];
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
}
|
|
77
|
-
if (typeof opts === "string") {
|
|
78
|
-
return { ...defaultOptions[0], rule: opts };
|
|
79
|
-
}
|
|
74
|
+
const defaultOpts = defaultOptions[0];
|
|
75
|
+
if (opts == null) return defaultOpts;
|
|
80
76
|
return {
|
|
81
|
-
...
|
|
82
|
-
|
|
77
|
+
...defaultOpts,
|
|
78
|
+
...typeof opts === "string" ? { rule: opts } : {
|
|
79
|
+
...opts,
|
|
80
|
+
excepts: opts.excepts?.map((pattern) => new RegExp(pattern, "u")) ?? []
|
|
81
|
+
}
|
|
83
82
|
};
|
|
84
83
|
}
|
|
85
|
-
function
|
|
86
|
-
if (name3 == null) return
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
if (allowNamespace) {
|
|
100
|
-
normalized = normalized.replace(":", "");
|
|
101
|
-
}
|
|
102
|
-
if (allowLeadingUnderscore) {
|
|
103
|
-
normalized = normalized.replace(/^_/, "");
|
|
84
|
+
function isValidComponentName(name3, options) {
|
|
85
|
+
if (name3 == null) return true;
|
|
86
|
+
if (options.excepts.some((regex) => regex.test(name3))) return true;
|
|
87
|
+
let normalized = name3.split(".").at(-1) ?? name3;
|
|
88
|
+
if (options.allowNamespace) normalized = normalized.replace(":", "");
|
|
89
|
+
if (options.allowLeadingUnderscore) normalized = normalized.replace(/^_/, "");
|
|
90
|
+
switch (options.rule) {
|
|
91
|
+
case "CONSTANT_CASE":
|
|
92
|
+
return RE_CONSTANT_CASE.test(normalized);
|
|
93
|
+
case "PascalCase":
|
|
94
|
+
if (normalized.length > 3 && /^[A-Z]+$/u.test(normalized)) {
|
|
95
|
+
return options.allowAllCaps;
|
|
96
|
+
}
|
|
97
|
+
return RE_PASCAL_CASE.test(normalized);
|
|
104
98
|
}
|
|
105
|
-
return match(rule).with("CONSTANT_CASE", () => RE_CONSTANT_CASE.test(normalized) ? _ : "useConstantCase").with("PascalCase", () => {
|
|
106
|
-
if (normalized.length > 3 && /^[A-Z]+$/u.test(normalized)) {
|
|
107
|
-
return allowAllCaps ? _ : "usePascalCase";
|
|
108
|
-
}
|
|
109
|
-
return RE_PASCAL_CASE.test(normalized) ? _ : "usePascalCase";
|
|
110
|
-
}).otherwise(() => _);
|
|
111
99
|
}
|
|
112
100
|
var component_name_default = createRule({
|
|
113
101
|
meta: {
|
|
114
102
|
type: "problem",
|
|
115
103
|
defaultOptions: [...defaultOptions],
|
|
116
104
|
docs: {
|
|
117
|
-
description: "enforce
|
|
105
|
+
description: "enforce naming convention for components"
|
|
118
106
|
},
|
|
119
107
|
messages: {
|
|
120
|
-
|
|
121
|
-
usePascalCase: "Component name '{{name}}' must be in PascalCase."
|
|
108
|
+
invalid: "A component name '{{name}}' does not match {{rule}}."
|
|
122
109
|
},
|
|
123
110
|
schema
|
|
124
111
|
},
|
|
125
112
|
name: RULE_NAME,
|
|
126
113
|
create(context) {
|
|
127
114
|
const options = normalizeOptions(context.options);
|
|
115
|
+
const { rule } = options;
|
|
128
116
|
const collector = useComponentCollector(context);
|
|
129
117
|
const collectorLegacy = useComponentCollectorLegacy();
|
|
130
118
|
return {
|
|
@@ -135,14 +123,11 @@ var component_name_default = createRule({
|
|
|
135
123
|
if (/^[a-z]/u.test(name3)) {
|
|
136
124
|
return;
|
|
137
125
|
}
|
|
138
|
-
|
|
139
|
-
if (violation == null) return;
|
|
126
|
+
if (isValidComponentName(name3, options)) return;
|
|
140
127
|
context.report({
|
|
141
|
-
messageId:
|
|
128
|
+
messageId: "invalid",
|
|
142
129
|
node,
|
|
143
|
-
data: {
|
|
144
|
-
name: name3
|
|
145
|
-
}
|
|
130
|
+
data: { name: name3, rule }
|
|
146
131
|
});
|
|
147
132
|
},
|
|
148
133
|
"Program:exit"(node) {
|
|
@@ -152,28 +137,22 @@ var component_name_default = createRule({
|
|
|
152
137
|
const id = AST.getFunctionIdentifier(component);
|
|
153
138
|
if (id?.name == null) continue;
|
|
154
139
|
const name3 = id.name;
|
|
155
|
-
|
|
156
|
-
if (violation == null) continue;
|
|
140
|
+
if (isValidComponentName(name3, options)) return;
|
|
157
141
|
context.report({
|
|
158
|
-
messageId:
|
|
142
|
+
messageId: "invalid",
|
|
159
143
|
node: id,
|
|
160
|
-
data: {
|
|
161
|
-
name: name3
|
|
162
|
-
}
|
|
144
|
+
data: { name: name3, rule }
|
|
163
145
|
});
|
|
164
146
|
}
|
|
165
147
|
for (const { node: component } of classComponents.values()) {
|
|
166
148
|
const id = AST.getClassIdentifier(component);
|
|
167
149
|
if (id?.name == null) continue;
|
|
168
150
|
const name3 = id.name;
|
|
169
|
-
|
|
170
|
-
if (violation == null) continue;
|
|
151
|
+
if (isValidComponentName(name3, options)) continue;
|
|
171
152
|
context.report({
|
|
172
|
-
messageId:
|
|
153
|
+
messageId: "invalid",
|
|
173
154
|
node: id,
|
|
174
|
-
data: {
|
|
175
|
-
case: options.rule
|
|
176
|
-
}
|
|
155
|
+
data: { name: name3, rule }
|
|
177
156
|
});
|
|
178
157
|
}
|
|
179
158
|
}
|
|
@@ -186,10 +165,10 @@ var context_name_default = createRule({
|
|
|
186
165
|
meta: {
|
|
187
166
|
type: "problem",
|
|
188
167
|
docs: {
|
|
189
|
-
description: "
|
|
168
|
+
description: "enforce context name to be a valid component name with the suffix 'Context'"
|
|
190
169
|
},
|
|
191
170
|
messages: {
|
|
192
|
-
|
|
171
|
+
invalid: "A context name must be a valid component name with the suffix 'Context'."
|
|
193
172
|
},
|
|
194
173
|
schema: []
|
|
195
174
|
},
|
|
@@ -202,9 +181,9 @@ var context_name_default = createRule({
|
|
|
202
181
|
const id = getInstanceId(node);
|
|
203
182
|
if (id == null) return;
|
|
204
183
|
const name3 = match(id).with({ type: AST_NODE_TYPES.Identifier, name: P.select() }, identity).with({ type: AST_NODE_TYPES.MemberExpression, property: { name: P.select(P.string) } }, identity).otherwise(() => _);
|
|
205
|
-
if (name3 != null && /^[A-Z]
|
|
184
|
+
if (name3 != null && /^[A-Z]/u.test(name3) && name3.endsWith("Context")) return;
|
|
206
185
|
context.report({
|
|
207
|
-
messageId: "
|
|
186
|
+
messageId: "invalid",
|
|
208
187
|
node: id
|
|
209
188
|
});
|
|
210
189
|
}
|
|
@@ -257,8 +236,8 @@ var filename_default = createRule({
|
|
|
257
236
|
description: "enforce naming convention for JSX filenames"
|
|
258
237
|
},
|
|
259
238
|
messages: {
|
|
260
|
-
|
|
261
|
-
|
|
239
|
+
filenameEmpty: "A file must have non-empty name.",
|
|
240
|
+
filenameInvalid: "A file with name '{{name}}' does not match {{rule}}. Rename it to '{{suggestion}}'."
|
|
262
241
|
},
|
|
263
242
|
schema: schema2
|
|
264
243
|
},
|
|
@@ -286,7 +265,7 @@ var filename_default = createRule({
|
|
|
286
265
|
return;
|
|
287
266
|
}
|
|
288
267
|
context.report({
|
|
289
|
-
messageId: "
|
|
268
|
+
messageId: "filenameInvalid",
|
|
290
269
|
node,
|
|
291
270
|
data: {
|
|
292
271
|
name: context.filename,
|
|
@@ -344,7 +323,7 @@ var filename_extension_default = createRule({
|
|
|
344
323
|
},
|
|
345
324
|
messages: {
|
|
346
325
|
useJsxFileExtension: "Use {{extensions}} file extension for JSX files.",
|
|
347
|
-
|
|
326
|
+
useNonJsxFileExtension: "Do not use {{extensions}} file extension for files without JSX."
|
|
348
327
|
},
|
|
349
328
|
schema: schema3
|
|
350
329
|
},
|
|
@@ -383,7 +362,7 @@ var filename_extension_default = createRule({
|
|
|
383
362
|
}
|
|
384
363
|
if (!hasJSXNode && isJSXExt && allow === "as-needed") {
|
|
385
364
|
context.report({
|
|
386
|
-
messageId: "
|
|
365
|
+
messageId: "useNonJsxFileExtension",
|
|
387
366
|
node,
|
|
388
367
|
data: {
|
|
389
368
|
extensions: extensionsString
|
|
@@ -407,7 +386,7 @@ var use_state_default = createRule({
|
|
|
407
386
|
[Symbol.for("rule_features")]: RULE_FEATURES
|
|
408
387
|
},
|
|
409
388
|
messages: {
|
|
410
|
-
|
|
389
|
+
invalid: "An useState call is not destructured into value + setter pair."
|
|
411
390
|
},
|
|
412
391
|
schema: []
|
|
413
392
|
},
|
|
@@ -416,21 +395,21 @@ var use_state_default = createRule({
|
|
|
416
395
|
return {
|
|
417
396
|
"CallExpression[callee.name='useState']"(node) {
|
|
418
397
|
if (node.parent.type !== AST_NODE_TYPES.VariableDeclarator) {
|
|
419
|
-
context.report({ messageId: "
|
|
398
|
+
context.report({ messageId: "invalid", node });
|
|
420
399
|
}
|
|
421
400
|
const id = getInstanceId(node);
|
|
422
401
|
if (id?.type !== AST_NODE_TYPES.ArrayPattern) {
|
|
423
|
-
context.report({ messageId: "
|
|
402
|
+
context.report({ messageId: "invalid", node });
|
|
424
403
|
return;
|
|
425
404
|
}
|
|
426
405
|
const [value, setter] = id.elements;
|
|
427
406
|
if (value == null || setter == null) {
|
|
428
|
-
context.report({ messageId: "
|
|
407
|
+
context.report({ messageId: "invalid", node });
|
|
429
408
|
return;
|
|
430
409
|
}
|
|
431
410
|
const setterName = match(setter).with({ type: AST_NODE_TYPES.Identifier }, (id2) => id2.name).otherwise(() => _);
|
|
432
411
|
if (setterName == null || !setterName.startsWith("set")) {
|
|
433
|
-
context.report({ messageId: "
|
|
412
|
+
context.report({ messageId: "invalid", node });
|
|
434
413
|
return;
|
|
435
414
|
}
|
|
436
415
|
const valueName = match(value).with({ type: AST_NODE_TYPES.Identifier }, (id2) => id2.name).with({ type: AST_NODE_TYPES.ObjectPattern }, ({ properties }) => {
|
|
@@ -443,7 +422,7 @@ var use_state_default = createRule({
|
|
|
443
422
|
return values.join("_");
|
|
444
423
|
}).otherwise(() => _);
|
|
445
424
|
if (valueName == null || `set_${valueName}` !== snakeCase(setterName)) {
|
|
446
|
-
context.report({ messageId: "
|
|
425
|
+
context.report({ messageId: "invalid", node });
|
|
447
426
|
return;
|
|
448
427
|
}
|
|
449
428
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "eslint-plugin-react-naming-convention",
|
|
3
|
-
"version": "1.29.1-next.
|
|
3
|
+
"version": "1.29.1-next.6",
|
|
4
4
|
"description": "ESLint React's ESLint plugin for naming convention related rules.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"react",
|
|
@@ -49,12 +49,12 @@
|
|
|
49
49
|
"@typescript-eslint/utils": "^8.25.0",
|
|
50
50
|
"string-ts": "^2.2.1",
|
|
51
51
|
"ts-pattern": "^5.6.2",
|
|
52
|
-
"@eslint-react/ast": "1.29.1-next.
|
|
53
|
-
"@eslint-react/
|
|
54
|
-
"@eslint-react/
|
|
55
|
-
"@eslint-react/
|
|
56
|
-
"@eslint-react/
|
|
57
|
-
"@eslint-react/
|
|
52
|
+
"@eslint-react/ast": "1.29.1-next.6",
|
|
53
|
+
"@eslint-react/eff": "1.29.1-next.6",
|
|
54
|
+
"@eslint-react/jsx": "1.29.1-next.6",
|
|
55
|
+
"@eslint-react/shared": "1.29.1-next.6",
|
|
56
|
+
"@eslint-react/core": "1.29.1-next.6",
|
|
57
|
+
"@eslint-react/var": "1.29.1-next.6"
|
|
58
58
|
},
|
|
59
59
|
"devDependencies": {
|
|
60
60
|
"@types/react": "^19.0.10",
|