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 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$2 = "useJsxFileExtension" | "useJsxFileExtensionAsNeeded";
4
+ type MessageID$1 = "useJsxFileExtension" | "useNonJsxFileExtension";
5
5
 
6
- type MessageID$1 = "filenameCaseMismatch" | "filenameEmpty";
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<MessageID, readonly [("CONSTANT_CASE" | "PascalCase") | {
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<"contextName", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
28
- readonly filename: _typescript_eslint_utils_ts_eslint.RuleModule<MessageID$1, readonly [("PascalCase" | "camelCase" | "kebab-case" | "snake_case") | {
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$2, readonly [("always" | "as-needed") | {
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<"badValueOrSetterName", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
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<MessageID, readonly [("CONSTANT_CASE" | "PascalCase") | {
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<"contextName", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
63
- readonly filename: _typescript_eslint_utils_ts_eslint.RuleModule<MessageID$1, readonly [("PascalCase" | "camelCase" | "kebab-case" | "snake_case") | {
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$2, readonly [("always" | "as-needed") | {
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<"badValueOrSetterName", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
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$2 = "useJsxFileExtension" | "useJsxFileExtensionAsNeeded";
4
+ type MessageID$1 = "useJsxFileExtension" | "useNonJsxFileExtension";
5
5
 
6
- type MessageID$1 = "filenameCaseMismatch" | "filenameEmpty";
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<MessageID, readonly [("CONSTANT_CASE" | "PascalCase") | {
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<"contextName", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
28
- readonly filename: _typescript_eslint_utils_ts_eslint.RuleModule<MessageID$1, readonly [("PascalCase" | "camelCase" | "kebab-case" | "snake_case") | {
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$2, readonly [("always" | "as-needed") | {
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<"badValueOrSetterName", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
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<MessageID, readonly [("CONSTANT_CASE" | "PascalCase") | {
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<"contextName", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
63
- readonly filename: _typescript_eslint_utils_ts_eslint.RuleModule<MessageID$1, readonly [("PascalCase" | "camelCase" | "kebab-case" | "snake_case") | {
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$2, readonly [("always" | "as-needed") | {
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<"badValueOrSetterName", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
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 tsPattern = require('ts-pattern');
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.4";
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
- if (opts == null) {
101
- return defaultOptions[0];
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
- ...opts,
108
- excepts: opts.excepts?.map((pattern) => new RegExp(pattern, "u")) ?? []
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 getViolationMessage(name3, options) {
112
- if (name3 == null) return eff._;
113
- const {
114
- allowAllCaps = false,
115
- allowLeadingUnderscore = false,
116
- allowNamespace = false,
117
- excepts,
118
- rule
119
- } = options;
120
- if (excepts.some((regex) => regex.test(name3))) {
121
- return eff._;
122
- }
123
- let normalized = name3.normalize("NFKD").replace(/[\u0300-\u036F]/g, "");
124
- normalized = normalized.split(".").at(-1) ?? normalized;
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 component naming convention to 'PascalCase' or 'CONSTANT_CASE'"
131
+ description: "enforce naming convention for components"
144
132
  },
145
133
  messages: {
146
- useConstantCase: "Component name '{{name}}' must be in CONSTANT_CASE.",
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
- const violation = getViolationMessage(name3, options);
165
- if (violation == null) return;
152
+ if (isValidComponentName(name3, options)) return;
166
153
  context.report({
167
- messageId: violation,
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
- const violation = getViolationMessage(name3, options);
182
- if (violation == null) continue;
166
+ if (isValidComponentName(name3, options)) return;
183
167
  context.report({
184
- messageId: violation,
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
- const violation = getViolationMessage(name3, options);
196
- if (violation == null) continue;
177
+ if (isValidComponentName(name3, options)) continue;
197
178
  context.report({
198
- messageId: violation,
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: "enforces context name to be a valid component name with the suffix 'Context'"
194
+ description: "enforce context name to be a valid component name with the suffix 'Context'"
216
195
  },
217
196
  messages: {
218
- contextName: "In React 19, you can render '<Context>' as a provider instead of '<Context.Provider>', it's name must be a valid component name with the suffix 'Context'."
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]/.test(name3) && name3.endsWith("Context")) return;
210
+ if (name3 != null && /^[A-Z]/u.test(name3) && name3.endsWith("Context")) return;
232
211
  context.report({
233
- messageId: "contextName",
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
- filenameCaseMismatch: "A file with name '{{name}}' does not match {{rule}}. Should rename to '{{suggestion}}'.",
287
- filenameEmpty: "A file must have non-empty name."
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: "filenameCaseMismatch",
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
- useJsxFileExtensionAsNeeded: "Do not use {{extensions}} file extension for files without JSX."
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: "useJsxFileExtensionAsNeeded",
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
- badValueOrSetterName: "An useState call is not destructured into value + setter pair."
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: "badValueOrSetterName", node });
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: "badValueOrSetterName", node });
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: "badValueOrSetterName", node });
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: "badValueOrSetterName", node });
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: "badValueOrSetterName", node });
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, RE_CONSTANT_CASE, RE_PASCAL_CASE, RE_CAMEL_CASE, RE_KEBAB_CASE, RE_SNAKE_CASE } from '@eslint-react/shared';
6
- import { match, P } from 'ts-pattern';
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.4";
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
- if (opts == null) {
75
- return defaultOptions[0];
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
- ...opts,
82
- excepts: opts.excepts?.map((pattern) => new RegExp(pattern, "u")) ?? []
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 getViolationMessage(name3, options) {
86
- if (name3 == null) return _;
87
- const {
88
- allowAllCaps = false,
89
- allowLeadingUnderscore = false,
90
- allowNamespace = false,
91
- excepts,
92
- rule
93
- } = options;
94
- if (excepts.some((regex) => regex.test(name3))) {
95
- return _;
96
- }
97
- let normalized = name3.normalize("NFKD").replace(/[\u0300-\u036F]/g, "");
98
- normalized = normalized.split(".").at(-1) ?? normalized;
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 component naming convention to 'PascalCase' or 'CONSTANT_CASE'"
105
+ description: "enforce naming convention for components"
118
106
  },
119
107
  messages: {
120
- useConstantCase: "Component name '{{name}}' must be in CONSTANT_CASE.",
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
- const violation = getViolationMessage(name3, options);
139
- if (violation == null) return;
126
+ if (isValidComponentName(name3, options)) return;
140
127
  context.report({
141
- messageId: violation,
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
- const violation = getViolationMessage(name3, options);
156
- if (violation == null) continue;
140
+ if (isValidComponentName(name3, options)) return;
157
141
  context.report({
158
- messageId: violation,
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
- const violation = getViolationMessage(name3, options);
170
- if (violation == null) continue;
151
+ if (isValidComponentName(name3, options)) continue;
171
152
  context.report({
172
- messageId: violation,
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: "enforces context name to be a valid component name with the suffix 'Context'"
168
+ description: "enforce context name to be a valid component name with the suffix 'Context'"
190
169
  },
191
170
  messages: {
192
- contextName: "In React 19, you can render '<Context>' as a provider instead of '<Context.Provider>', it's name must be a valid component name with the suffix 'Context'."
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]/.test(name3) && name3.endsWith("Context")) return;
184
+ if (name3 != null && /^[A-Z]/u.test(name3) && name3.endsWith("Context")) return;
206
185
  context.report({
207
- messageId: "contextName",
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
- filenameCaseMismatch: "A file with name '{{name}}' does not match {{rule}}. Should rename to '{{suggestion}}'.",
261
- filenameEmpty: "A file must have non-empty name."
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: "filenameCaseMismatch",
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
- useJsxFileExtensionAsNeeded: "Do not use {{extensions}} file extension for files without JSX."
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: "useJsxFileExtensionAsNeeded",
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
- badValueOrSetterName: "An useState call is not destructured into value + setter pair."
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: "badValueOrSetterName", node });
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: "badValueOrSetterName", node });
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: "badValueOrSetterName", node });
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: "badValueOrSetterName", node });
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: "badValueOrSetterName", node });
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.4",
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.4",
53
- "@eslint-react/core": "1.29.1-next.4",
54
- "@eslint-react/eff": "1.29.1-next.4",
55
- "@eslint-react/jsx": "1.29.1-next.4",
56
- "@eslint-react/var": "1.29.1-next.4",
57
- "@eslint-react/shared": "1.29.1-next.4"
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",