eslint-plugin-react-naming-convention 1.29.1-beta.5 → 1.29.1-beta.7
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 +65 -86
- package/dist/index.mjs +65 -85
- 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,9 +2,8 @@
|
|
|
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
|
-
var JSX = require('@eslint-react/jsx');
|
|
7
5
|
var shared = require('@eslint-react/shared');
|
|
6
|
+
var eff = require('@eslint-react/eff');
|
|
8
7
|
var types = require('@typescript-eslint/types');
|
|
9
8
|
var tsPattern = require('ts-pattern');
|
|
10
9
|
var path = require('path');
|
|
@@ -31,7 +30,6 @@ function _interopNamespace(e) {
|
|
|
31
30
|
}
|
|
32
31
|
|
|
33
32
|
var AST__namespace = /*#__PURE__*/_interopNamespace(AST);
|
|
34
|
-
var JSX__namespace = /*#__PURE__*/_interopNamespace(JSX);
|
|
35
33
|
var path__default = /*#__PURE__*/_interopDefault(path);
|
|
36
34
|
|
|
37
35
|
var __defProp = Object.defineProperty;
|
|
@@ -54,16 +52,13 @@ var rules = {
|
|
|
54
52
|
|
|
55
53
|
// package.json
|
|
56
54
|
var name2 = "eslint-plugin-react-naming-convention";
|
|
57
|
-
var version = "1.29.1-beta.
|
|
55
|
+
var version = "1.29.1-beta.7";
|
|
58
56
|
var createRule = shared.createRuleForPlugin("naming-convention");
|
|
59
57
|
|
|
60
58
|
// src/rules/component-name.ts
|
|
61
|
-
var RULE_NAME = "component-name";
|
|
62
59
|
var defaultOptions = [
|
|
63
60
|
{
|
|
64
61
|
allowAllCaps: false,
|
|
65
|
-
allowLeadingUnderscore: false,
|
|
66
|
-
allowNamespace: false,
|
|
67
62
|
excepts: [],
|
|
68
63
|
rule: "PascalCase"
|
|
69
64
|
}
|
|
@@ -80,7 +75,15 @@ var schema = [
|
|
|
80
75
|
additionalProperties: false,
|
|
81
76
|
properties: {
|
|
82
77
|
allowAllCaps: { type: "boolean" },
|
|
78
|
+
/**
|
|
79
|
+
* @todo Remove in the next major version
|
|
80
|
+
* @deprecated
|
|
81
|
+
*/
|
|
83
82
|
allowLeadingUnderscore: { type: "boolean" },
|
|
83
|
+
/**
|
|
84
|
+
* @todo Remove in the next major version
|
|
85
|
+
* @deprecated
|
|
86
|
+
*/
|
|
84
87
|
allowNamespace: { type: "boolean" },
|
|
85
88
|
excepts: {
|
|
86
89
|
type: "array",
|
|
@@ -95,72 +98,28 @@ var schema = [
|
|
|
95
98
|
]
|
|
96
99
|
}
|
|
97
100
|
];
|
|
98
|
-
|
|
99
|
-
const opts = options[0];
|
|
100
|
-
const defaultOpts = defaultOptions[0];
|
|
101
|
-
if (opts == null) return defaultOpts;
|
|
102
|
-
return {
|
|
103
|
-
...defaultOpts,
|
|
104
|
-
...typeof opts === "string" ? { rule: opts } : {
|
|
105
|
-
...opts,
|
|
106
|
-
excepts: opts.excepts?.map((pattern) => new RegExp(pattern, "u")) ?? []
|
|
107
|
-
}
|
|
108
|
-
};
|
|
109
|
-
}
|
|
110
|
-
function getViolationMessage(name3, options) {
|
|
111
|
-
if (name3 == null) return eff._;
|
|
112
|
-
if (options.excepts.some((regex) => regex.test(name3))) return eff._;
|
|
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) ? eff._ : "useConstantCase";
|
|
119
|
-
case "PascalCase":
|
|
120
|
-
if (normalized.length > 3 && /^[A-Z]+$/u.test(normalized)) {
|
|
121
|
-
return options.allowAllCaps ? eff._ : "usePascalCase";
|
|
122
|
-
}
|
|
123
|
-
return shared.RE_PASCAL_CASE.test(normalized) ? eff._ : "usePascalCase";
|
|
124
|
-
default:
|
|
125
|
-
return eff._;
|
|
126
|
-
}
|
|
127
|
-
}
|
|
101
|
+
var RULE_NAME = "component-name";
|
|
128
102
|
var component_name_default = createRule({
|
|
129
103
|
meta: {
|
|
130
104
|
type: "problem",
|
|
131
105
|
defaultOptions: [...defaultOptions],
|
|
132
106
|
docs: {
|
|
133
|
-
description: "enforce
|
|
107
|
+
description: "enforce naming convention for components"
|
|
134
108
|
},
|
|
135
109
|
messages: {
|
|
136
|
-
|
|
137
|
-
usePascalCase: "Component name '{{name}}' must be in PascalCase."
|
|
110
|
+
invalid: "A component name '{{name}}' does not match {{rule}}."
|
|
138
111
|
},
|
|
139
112
|
schema
|
|
140
113
|
},
|
|
141
114
|
name: RULE_NAME,
|
|
142
115
|
create(context) {
|
|
143
116
|
const options = normalizeOptions(context.options);
|
|
117
|
+
const { rule } = options;
|
|
144
118
|
const collector = core.useComponentCollector(context);
|
|
145
119
|
const collectorLegacy = core.useComponentCollectorLegacy();
|
|
146
120
|
return {
|
|
147
121
|
...collector.listeners,
|
|
148
122
|
...collectorLegacy.listeners,
|
|
149
|
-
JSXOpeningElement(node) {
|
|
150
|
-
const name3 = JSX__namespace.getElementName(node.parent);
|
|
151
|
-
if (/^[a-z]/u.test(name3)) {
|
|
152
|
-
return;
|
|
153
|
-
}
|
|
154
|
-
const violation = getViolationMessage(name3, options);
|
|
155
|
-
if (violation == null) return;
|
|
156
|
-
context.report({
|
|
157
|
-
messageId: violation,
|
|
158
|
-
node,
|
|
159
|
-
data: {
|
|
160
|
-
name: name3
|
|
161
|
-
}
|
|
162
|
-
});
|
|
163
|
-
},
|
|
164
123
|
"Program:exit"(node) {
|
|
165
124
|
const functionComponents = collector.ctx.getAllComponents(node);
|
|
166
125
|
const classComponents = collectorLegacy.ctx.getAllComponents(node);
|
|
@@ -168,28 +127,22 @@ var component_name_default = createRule({
|
|
|
168
127
|
const id = AST__namespace.getFunctionIdentifier(component);
|
|
169
128
|
if (id?.name == null) continue;
|
|
170
129
|
const name3 = id.name;
|
|
171
|
-
|
|
172
|
-
if (violation == null) continue;
|
|
130
|
+
if (isValidName(name3, options)) return;
|
|
173
131
|
context.report({
|
|
174
|
-
messageId:
|
|
132
|
+
messageId: "invalid",
|
|
175
133
|
node: id,
|
|
176
|
-
data: {
|
|
177
|
-
name: name3
|
|
178
|
-
}
|
|
134
|
+
data: { name: name3, rule }
|
|
179
135
|
});
|
|
180
136
|
}
|
|
181
137
|
for (const { node: component } of classComponents.values()) {
|
|
182
138
|
const id = AST__namespace.getClassIdentifier(component);
|
|
183
139
|
if (id?.name == null) continue;
|
|
184
140
|
const name3 = id.name;
|
|
185
|
-
|
|
186
|
-
if (violation == null) continue;
|
|
141
|
+
if (isValidName(name3, options)) continue;
|
|
187
142
|
context.report({
|
|
188
|
-
messageId:
|
|
143
|
+
messageId: "invalid",
|
|
189
144
|
node: id,
|
|
190
|
-
data: {
|
|
191
|
-
case: options.rule
|
|
192
|
-
}
|
|
145
|
+
data: { name: name3, rule }
|
|
193
146
|
});
|
|
194
147
|
}
|
|
195
148
|
}
|
|
@@ -197,15 +150,41 @@ var component_name_default = createRule({
|
|
|
197
150
|
},
|
|
198
151
|
defaultOptions
|
|
199
152
|
});
|
|
153
|
+
function normalizeOptions(options) {
|
|
154
|
+
const opts = options[0];
|
|
155
|
+
const defaultOpts = defaultOptions[0];
|
|
156
|
+
if (opts == null) return defaultOpts;
|
|
157
|
+
return {
|
|
158
|
+
...defaultOpts,
|
|
159
|
+
...typeof opts === "string" ? { rule: opts } : {
|
|
160
|
+
...opts,
|
|
161
|
+
excepts: opts.excepts?.map((pattern) => new RegExp(pattern, "u")) ?? []
|
|
162
|
+
}
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
function isValidName(name3, options) {
|
|
166
|
+
if (name3 == null) return true;
|
|
167
|
+
if (options.excepts.some((regex) => regex.test(name3))) return true;
|
|
168
|
+
const normalized = name3.split(".").at(-1) ?? name3;
|
|
169
|
+
switch (options.rule) {
|
|
170
|
+
case "CONSTANT_CASE":
|
|
171
|
+
return shared.RE_CONSTANT_CASE.test(normalized);
|
|
172
|
+
case "PascalCase":
|
|
173
|
+
if (normalized.length > 3 && /^[A-Z]+$/u.test(normalized)) {
|
|
174
|
+
return options.allowAllCaps;
|
|
175
|
+
}
|
|
176
|
+
return shared.RE_PASCAL_CASE.test(normalized);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
200
179
|
var RULE_NAME2 = "context-name";
|
|
201
180
|
var context_name_default = createRule({
|
|
202
181
|
meta: {
|
|
203
182
|
type: "problem",
|
|
204
183
|
docs: {
|
|
205
|
-
description: "
|
|
184
|
+
description: "enforce context name to be a valid component name with the suffix 'Context'"
|
|
206
185
|
},
|
|
207
186
|
messages: {
|
|
208
|
-
|
|
187
|
+
invalid: "A context name must be a valid component name with the suffix 'Context'."
|
|
209
188
|
},
|
|
210
189
|
schema: []
|
|
211
190
|
},
|
|
@@ -220,7 +199,7 @@ var context_name_default = createRule({
|
|
|
220
199
|
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._);
|
|
221
200
|
if (name3 != null && /^[A-Z]/u.test(name3) && name3.endsWith("Context")) return;
|
|
222
201
|
context.report({
|
|
223
|
-
messageId: "
|
|
202
|
+
messageId: "invalid",
|
|
224
203
|
node: id
|
|
225
204
|
});
|
|
226
205
|
}
|
|
@@ -273,8 +252,8 @@ var filename_default = createRule({
|
|
|
273
252
|
description: "enforce naming convention for JSX filenames"
|
|
274
253
|
},
|
|
275
254
|
messages: {
|
|
276
|
-
|
|
277
|
-
|
|
255
|
+
filenameEmpty: "A file must have non-empty name.",
|
|
256
|
+
filenameInvalid: "A file with name '{{name}}' does not match {{rule}}. Rename it to '{{suggestion}}'."
|
|
278
257
|
},
|
|
279
258
|
schema: schema2
|
|
280
259
|
},
|
|
@@ -302,7 +281,7 @@ var filename_default = createRule({
|
|
|
302
281
|
return;
|
|
303
282
|
}
|
|
304
283
|
context.report({
|
|
305
|
-
messageId: "
|
|
284
|
+
messageId: "filenameInvalid",
|
|
306
285
|
node,
|
|
307
286
|
data: {
|
|
308
287
|
name: context.filename,
|
|
@@ -360,7 +339,7 @@ var filename_extension_default = createRule({
|
|
|
360
339
|
},
|
|
361
340
|
messages: {
|
|
362
341
|
useJsxFileExtension: "Use {{extensions}} file extension for JSX files.",
|
|
363
|
-
|
|
342
|
+
useNonJsxFileExtension: "Do not use {{extensions}} file extension for files without JSX."
|
|
364
343
|
},
|
|
365
344
|
schema: schema3
|
|
366
345
|
},
|
|
@@ -399,7 +378,7 @@ var filename_extension_default = createRule({
|
|
|
399
378
|
}
|
|
400
379
|
if (!hasJSXNode && isJSXExt && allow === "as-needed") {
|
|
401
380
|
context.report({
|
|
402
|
-
messageId: "
|
|
381
|
+
messageId: "useNonJsxFileExtension",
|
|
403
382
|
node,
|
|
404
383
|
data: {
|
|
405
384
|
extensions: extensionsString
|
|
@@ -423,7 +402,7 @@ var use_state_default = createRule({
|
|
|
423
402
|
[Symbol.for("rule_features")]: RULE_FEATURES
|
|
424
403
|
},
|
|
425
404
|
messages: {
|
|
426
|
-
|
|
405
|
+
invalid: "An useState call is not destructured into value + setter pair."
|
|
427
406
|
},
|
|
428
407
|
schema: []
|
|
429
408
|
},
|
|
@@ -432,21 +411,21 @@ var use_state_default = createRule({
|
|
|
432
411
|
return {
|
|
433
412
|
"CallExpression[callee.name='useState']"(node) {
|
|
434
413
|
if (node.parent.type !== types.AST_NODE_TYPES.VariableDeclarator) {
|
|
435
|
-
context.report({ messageId: "
|
|
414
|
+
context.report({ messageId: "invalid", node });
|
|
436
415
|
}
|
|
437
416
|
const id = core.getInstanceId(node);
|
|
438
417
|
if (id?.type !== types.AST_NODE_TYPES.ArrayPattern) {
|
|
439
|
-
context.report({ messageId: "
|
|
418
|
+
context.report({ messageId: "invalid", node });
|
|
440
419
|
return;
|
|
441
420
|
}
|
|
442
421
|
const [value, setter] = id.elements;
|
|
443
422
|
if (value == null || setter == null) {
|
|
444
|
-
context.report({ messageId: "
|
|
423
|
+
context.report({ messageId: "invalid", node });
|
|
445
424
|
return;
|
|
446
425
|
}
|
|
447
426
|
const setterName = tsPattern.match(setter).with({ type: types.AST_NODE_TYPES.Identifier }, (id2) => id2.name).otherwise(() => eff._);
|
|
448
427
|
if (setterName == null || !setterName.startsWith("set")) {
|
|
449
|
-
context.report({ messageId: "
|
|
428
|
+
context.report({ messageId: "invalid", node });
|
|
450
429
|
return;
|
|
451
430
|
}
|
|
452
431
|
const valueName = tsPattern.match(value).with({ type: types.AST_NODE_TYPES.Identifier }, (id2) => id2.name).with({ type: types.AST_NODE_TYPES.ObjectPattern }, ({ properties }) => {
|
|
@@ -459,7 +438,7 @@ var use_state_default = createRule({
|
|
|
459
438
|
return values.join("_");
|
|
460
439
|
}).otherwise(() => eff._);
|
|
461
440
|
if (valueName == null || `set_${valueName}` !== stringTs.snakeCase(setterName)) {
|
|
462
|
-
context.report({ messageId: "
|
|
441
|
+
context.report({ messageId: "invalid", node });
|
|
463
442
|
return;
|
|
464
443
|
}
|
|
465
444
|
}
|
|
@@ -475,11 +454,11 @@ var plugin = {
|
|
|
475
454
|
version
|
|
476
455
|
},
|
|
477
456
|
rules: {
|
|
478
|
-
"component-name": component_name_default,
|
|
479
|
-
"context-name": context_name_default,
|
|
480
|
-
filename: filename_default,
|
|
481
|
-
"filename-extension": filename_extension_default,
|
|
482
|
-
"use-state": use_state_default
|
|
457
|
+
["component-name"]: component_name_default,
|
|
458
|
+
["context-name"]: context_name_default,
|
|
459
|
+
["filename"]: filename_default,
|
|
460
|
+
["filename-extension"]: filename_extension_default,
|
|
461
|
+
["use-state"]: use_state_default
|
|
483
462
|
}
|
|
484
463
|
};
|
|
485
464
|
|
package/dist/index.mjs
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
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
|
-
import * as JSX from '@eslint-react/jsx';
|
|
5
3
|
import { createRuleForPlugin, RE_PASCAL_CASE, RE_CONSTANT_CASE, RE_CAMEL_CASE, RE_KEBAB_CASE, RE_SNAKE_CASE } from '@eslint-react/shared';
|
|
4
|
+
import { identity, _, isObject } from '@eslint-react/eff';
|
|
6
5
|
import { AST_NODE_TYPES } from '@typescript-eslint/types';
|
|
7
6
|
import { match, P } from 'ts-pattern';
|
|
8
7
|
import path from 'node:path';
|
|
@@ -28,16 +27,13 @@ var rules = {
|
|
|
28
27
|
|
|
29
28
|
// package.json
|
|
30
29
|
var name2 = "eslint-plugin-react-naming-convention";
|
|
31
|
-
var version = "1.29.1-beta.
|
|
30
|
+
var version = "1.29.1-beta.7";
|
|
32
31
|
var createRule = createRuleForPlugin("naming-convention");
|
|
33
32
|
|
|
34
33
|
// src/rules/component-name.ts
|
|
35
|
-
var RULE_NAME = "component-name";
|
|
36
34
|
var defaultOptions = [
|
|
37
35
|
{
|
|
38
36
|
allowAllCaps: false,
|
|
39
|
-
allowLeadingUnderscore: false,
|
|
40
|
-
allowNamespace: false,
|
|
41
37
|
excepts: [],
|
|
42
38
|
rule: "PascalCase"
|
|
43
39
|
}
|
|
@@ -54,7 +50,15 @@ var schema = [
|
|
|
54
50
|
additionalProperties: false,
|
|
55
51
|
properties: {
|
|
56
52
|
allowAllCaps: { type: "boolean" },
|
|
53
|
+
/**
|
|
54
|
+
* @todo Remove in the next major version
|
|
55
|
+
* @deprecated
|
|
56
|
+
*/
|
|
57
57
|
allowLeadingUnderscore: { type: "boolean" },
|
|
58
|
+
/**
|
|
59
|
+
* @todo Remove in the next major version
|
|
60
|
+
* @deprecated
|
|
61
|
+
*/
|
|
58
62
|
allowNamespace: { type: "boolean" },
|
|
59
63
|
excepts: {
|
|
60
64
|
type: "array",
|
|
@@ -69,72 +73,28 @@ var schema = [
|
|
|
69
73
|
]
|
|
70
74
|
}
|
|
71
75
|
];
|
|
72
|
-
|
|
73
|
-
const opts = options[0];
|
|
74
|
-
const defaultOpts = defaultOptions[0];
|
|
75
|
-
if (opts == null) return defaultOpts;
|
|
76
|
-
return {
|
|
77
|
-
...defaultOpts,
|
|
78
|
-
...typeof opts === "string" ? { rule: opts } : {
|
|
79
|
-
...opts,
|
|
80
|
-
excepts: opts.excepts?.map((pattern) => new RegExp(pattern, "u")) ?? []
|
|
81
|
-
}
|
|
82
|
-
};
|
|
83
|
-
}
|
|
84
|
-
function getViolationMessage(name3, options) {
|
|
85
|
-
if (name3 == null) return _;
|
|
86
|
-
if (options.excepts.some((regex) => regex.test(name3))) return _;
|
|
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) ? _ : "useConstantCase";
|
|
93
|
-
case "PascalCase":
|
|
94
|
-
if (normalized.length > 3 && /^[A-Z]+$/u.test(normalized)) {
|
|
95
|
-
return options.allowAllCaps ? _ : "usePascalCase";
|
|
96
|
-
}
|
|
97
|
-
return RE_PASCAL_CASE.test(normalized) ? _ : "usePascalCase";
|
|
98
|
-
default:
|
|
99
|
-
return _;
|
|
100
|
-
}
|
|
101
|
-
}
|
|
76
|
+
var RULE_NAME = "component-name";
|
|
102
77
|
var component_name_default = createRule({
|
|
103
78
|
meta: {
|
|
104
79
|
type: "problem",
|
|
105
80
|
defaultOptions: [...defaultOptions],
|
|
106
81
|
docs: {
|
|
107
|
-
description: "enforce
|
|
82
|
+
description: "enforce naming convention for components"
|
|
108
83
|
},
|
|
109
84
|
messages: {
|
|
110
|
-
|
|
111
|
-
usePascalCase: "Component name '{{name}}' must be in PascalCase."
|
|
85
|
+
invalid: "A component name '{{name}}' does not match {{rule}}."
|
|
112
86
|
},
|
|
113
87
|
schema
|
|
114
88
|
},
|
|
115
89
|
name: RULE_NAME,
|
|
116
90
|
create(context) {
|
|
117
91
|
const options = normalizeOptions(context.options);
|
|
92
|
+
const { rule } = options;
|
|
118
93
|
const collector = useComponentCollector(context);
|
|
119
94
|
const collectorLegacy = useComponentCollectorLegacy();
|
|
120
95
|
return {
|
|
121
96
|
...collector.listeners,
|
|
122
97
|
...collectorLegacy.listeners,
|
|
123
|
-
JSXOpeningElement(node) {
|
|
124
|
-
const name3 = JSX.getElementName(node.parent);
|
|
125
|
-
if (/^[a-z]/u.test(name3)) {
|
|
126
|
-
return;
|
|
127
|
-
}
|
|
128
|
-
const violation = getViolationMessage(name3, options);
|
|
129
|
-
if (violation == null) return;
|
|
130
|
-
context.report({
|
|
131
|
-
messageId: violation,
|
|
132
|
-
node,
|
|
133
|
-
data: {
|
|
134
|
-
name: name3
|
|
135
|
-
}
|
|
136
|
-
});
|
|
137
|
-
},
|
|
138
98
|
"Program:exit"(node) {
|
|
139
99
|
const functionComponents = collector.ctx.getAllComponents(node);
|
|
140
100
|
const classComponents = collectorLegacy.ctx.getAllComponents(node);
|
|
@@ -142,28 +102,22 @@ var component_name_default = createRule({
|
|
|
142
102
|
const id = AST.getFunctionIdentifier(component);
|
|
143
103
|
if (id?.name == null) continue;
|
|
144
104
|
const name3 = id.name;
|
|
145
|
-
|
|
146
|
-
if (violation == null) continue;
|
|
105
|
+
if (isValidName(name3, options)) return;
|
|
147
106
|
context.report({
|
|
148
|
-
messageId:
|
|
107
|
+
messageId: "invalid",
|
|
149
108
|
node: id,
|
|
150
|
-
data: {
|
|
151
|
-
name: name3
|
|
152
|
-
}
|
|
109
|
+
data: { name: name3, rule }
|
|
153
110
|
});
|
|
154
111
|
}
|
|
155
112
|
for (const { node: component } of classComponents.values()) {
|
|
156
113
|
const id = AST.getClassIdentifier(component);
|
|
157
114
|
if (id?.name == null) continue;
|
|
158
115
|
const name3 = id.name;
|
|
159
|
-
|
|
160
|
-
if (violation == null) continue;
|
|
116
|
+
if (isValidName(name3, options)) continue;
|
|
161
117
|
context.report({
|
|
162
|
-
messageId:
|
|
118
|
+
messageId: "invalid",
|
|
163
119
|
node: id,
|
|
164
|
-
data: {
|
|
165
|
-
case: options.rule
|
|
166
|
-
}
|
|
120
|
+
data: { name: name3, rule }
|
|
167
121
|
});
|
|
168
122
|
}
|
|
169
123
|
}
|
|
@@ -171,15 +125,41 @@ var component_name_default = createRule({
|
|
|
171
125
|
},
|
|
172
126
|
defaultOptions
|
|
173
127
|
});
|
|
128
|
+
function normalizeOptions(options) {
|
|
129
|
+
const opts = options[0];
|
|
130
|
+
const defaultOpts = defaultOptions[0];
|
|
131
|
+
if (opts == null) return defaultOpts;
|
|
132
|
+
return {
|
|
133
|
+
...defaultOpts,
|
|
134
|
+
...typeof opts === "string" ? { rule: opts } : {
|
|
135
|
+
...opts,
|
|
136
|
+
excepts: opts.excepts?.map((pattern) => new RegExp(pattern, "u")) ?? []
|
|
137
|
+
}
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
function isValidName(name3, options) {
|
|
141
|
+
if (name3 == null) return true;
|
|
142
|
+
if (options.excepts.some((regex) => regex.test(name3))) return true;
|
|
143
|
+
const normalized = name3.split(".").at(-1) ?? name3;
|
|
144
|
+
switch (options.rule) {
|
|
145
|
+
case "CONSTANT_CASE":
|
|
146
|
+
return RE_CONSTANT_CASE.test(normalized);
|
|
147
|
+
case "PascalCase":
|
|
148
|
+
if (normalized.length > 3 && /^[A-Z]+$/u.test(normalized)) {
|
|
149
|
+
return options.allowAllCaps;
|
|
150
|
+
}
|
|
151
|
+
return RE_PASCAL_CASE.test(normalized);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
174
154
|
var RULE_NAME2 = "context-name";
|
|
175
155
|
var context_name_default = createRule({
|
|
176
156
|
meta: {
|
|
177
157
|
type: "problem",
|
|
178
158
|
docs: {
|
|
179
|
-
description: "
|
|
159
|
+
description: "enforce context name to be a valid component name with the suffix 'Context'"
|
|
180
160
|
},
|
|
181
161
|
messages: {
|
|
182
|
-
|
|
162
|
+
invalid: "A context name must be a valid component name with the suffix 'Context'."
|
|
183
163
|
},
|
|
184
164
|
schema: []
|
|
185
165
|
},
|
|
@@ -194,7 +174,7 @@ var context_name_default = createRule({
|
|
|
194
174
|
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(() => _);
|
|
195
175
|
if (name3 != null && /^[A-Z]/u.test(name3) && name3.endsWith("Context")) return;
|
|
196
176
|
context.report({
|
|
197
|
-
messageId: "
|
|
177
|
+
messageId: "invalid",
|
|
198
178
|
node: id
|
|
199
179
|
});
|
|
200
180
|
}
|
|
@@ -247,8 +227,8 @@ var filename_default = createRule({
|
|
|
247
227
|
description: "enforce naming convention for JSX filenames"
|
|
248
228
|
},
|
|
249
229
|
messages: {
|
|
250
|
-
|
|
251
|
-
|
|
230
|
+
filenameEmpty: "A file must have non-empty name.",
|
|
231
|
+
filenameInvalid: "A file with name '{{name}}' does not match {{rule}}. Rename it to '{{suggestion}}'."
|
|
252
232
|
},
|
|
253
233
|
schema: schema2
|
|
254
234
|
},
|
|
@@ -276,7 +256,7 @@ var filename_default = createRule({
|
|
|
276
256
|
return;
|
|
277
257
|
}
|
|
278
258
|
context.report({
|
|
279
|
-
messageId: "
|
|
259
|
+
messageId: "filenameInvalid",
|
|
280
260
|
node,
|
|
281
261
|
data: {
|
|
282
262
|
name: context.filename,
|
|
@@ -334,7 +314,7 @@ var filename_extension_default = createRule({
|
|
|
334
314
|
},
|
|
335
315
|
messages: {
|
|
336
316
|
useJsxFileExtension: "Use {{extensions}} file extension for JSX files.",
|
|
337
|
-
|
|
317
|
+
useNonJsxFileExtension: "Do not use {{extensions}} file extension for files without JSX."
|
|
338
318
|
},
|
|
339
319
|
schema: schema3
|
|
340
320
|
},
|
|
@@ -373,7 +353,7 @@ var filename_extension_default = createRule({
|
|
|
373
353
|
}
|
|
374
354
|
if (!hasJSXNode && isJSXExt && allow === "as-needed") {
|
|
375
355
|
context.report({
|
|
376
|
-
messageId: "
|
|
356
|
+
messageId: "useNonJsxFileExtension",
|
|
377
357
|
node,
|
|
378
358
|
data: {
|
|
379
359
|
extensions: extensionsString
|
|
@@ -397,7 +377,7 @@ var use_state_default = createRule({
|
|
|
397
377
|
[Symbol.for("rule_features")]: RULE_FEATURES
|
|
398
378
|
},
|
|
399
379
|
messages: {
|
|
400
|
-
|
|
380
|
+
invalid: "An useState call is not destructured into value + setter pair."
|
|
401
381
|
},
|
|
402
382
|
schema: []
|
|
403
383
|
},
|
|
@@ -406,21 +386,21 @@ var use_state_default = createRule({
|
|
|
406
386
|
return {
|
|
407
387
|
"CallExpression[callee.name='useState']"(node) {
|
|
408
388
|
if (node.parent.type !== AST_NODE_TYPES.VariableDeclarator) {
|
|
409
|
-
context.report({ messageId: "
|
|
389
|
+
context.report({ messageId: "invalid", node });
|
|
410
390
|
}
|
|
411
391
|
const id = getInstanceId(node);
|
|
412
392
|
if (id?.type !== AST_NODE_TYPES.ArrayPattern) {
|
|
413
|
-
context.report({ messageId: "
|
|
393
|
+
context.report({ messageId: "invalid", node });
|
|
414
394
|
return;
|
|
415
395
|
}
|
|
416
396
|
const [value, setter] = id.elements;
|
|
417
397
|
if (value == null || setter == null) {
|
|
418
|
-
context.report({ messageId: "
|
|
398
|
+
context.report({ messageId: "invalid", node });
|
|
419
399
|
return;
|
|
420
400
|
}
|
|
421
401
|
const setterName = match(setter).with({ type: AST_NODE_TYPES.Identifier }, (id2) => id2.name).otherwise(() => _);
|
|
422
402
|
if (setterName == null || !setterName.startsWith("set")) {
|
|
423
|
-
context.report({ messageId: "
|
|
403
|
+
context.report({ messageId: "invalid", node });
|
|
424
404
|
return;
|
|
425
405
|
}
|
|
426
406
|
const valueName = match(value).with({ type: AST_NODE_TYPES.Identifier }, (id2) => id2.name).with({ type: AST_NODE_TYPES.ObjectPattern }, ({ properties }) => {
|
|
@@ -433,7 +413,7 @@ var use_state_default = createRule({
|
|
|
433
413
|
return values.join("_");
|
|
434
414
|
}).otherwise(() => _);
|
|
435
415
|
if (valueName == null || `set_${valueName}` !== snakeCase(setterName)) {
|
|
436
|
-
context.report({ messageId: "
|
|
416
|
+
context.report({ messageId: "invalid", node });
|
|
437
417
|
return;
|
|
438
418
|
}
|
|
439
419
|
}
|
|
@@ -449,11 +429,11 @@ var plugin = {
|
|
|
449
429
|
version
|
|
450
430
|
},
|
|
451
431
|
rules: {
|
|
452
|
-
"component-name": component_name_default,
|
|
453
|
-
"context-name": context_name_default,
|
|
454
|
-
filename: filename_default,
|
|
455
|
-
"filename-extension": filename_extension_default,
|
|
456
|
-
"use-state": use_state_default
|
|
432
|
+
["component-name"]: component_name_default,
|
|
433
|
+
["context-name"]: context_name_default,
|
|
434
|
+
["filename"]: filename_default,
|
|
435
|
+
["filename-extension"]: filename_extension_default,
|
|
436
|
+
["use-state"]: use_state_default
|
|
457
437
|
}
|
|
458
438
|
};
|
|
459
439
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "eslint-plugin-react-naming-convention",
|
|
3
|
-
"version": "1.29.1-beta.
|
|
3
|
+
"version": "1.29.1-beta.7",
|
|
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-beta.
|
|
53
|
-
"@eslint-react/core": "1.29.1-beta.
|
|
54
|
-
"@eslint-react/eff": "1.29.1-beta.
|
|
55
|
-
"@eslint-react/jsx": "1.29.1-beta.
|
|
56
|
-
"@eslint-react/shared": "1.29.1-beta.
|
|
57
|
-
"@eslint-react/var": "1.29.1-beta.
|
|
52
|
+
"@eslint-react/ast": "1.29.1-beta.7",
|
|
53
|
+
"@eslint-react/core": "1.29.1-beta.7",
|
|
54
|
+
"@eslint-react/eff": "1.29.1-beta.7",
|
|
55
|
+
"@eslint-react/jsx": "1.29.1-beta.7",
|
|
56
|
+
"@eslint-react/shared": "1.29.1-beta.7",
|
|
57
|
+
"@eslint-react/var": "1.29.1-beta.7"
|
|
58
58
|
},
|
|
59
59
|
"devDependencies": {
|
|
60
60
|
"@types/react": "^19.0.10",
|