eslint-plugin-react-naming-convention
Advanced tools
Comparing version
import * as _typescript_eslint_utils_ts_eslint from '@typescript-eslint/utils/ts-eslint'; | ||
import { RulePreset } from '@eslint-react/shared'; | ||
type MessageID$2 = "useJsxFileExtension" | "useJsxFileExtensionAsNeeded"; | ||
type MessageID$1 = "useJsxFileExtension" | "useNonJsxFileExtension"; | ||
type MessageID$1 = "filenameCaseMismatch" | "filenameEmpty"; | ||
type MessageID = "filenameEmpty" | "filenameInvalid"; | ||
type MessageID = "usePascalCase" | "useConstantCase"; | ||
declare const _default: { | ||
@@ -20,3 +18,3 @@ configs: { | ||
readonly rules: { | ||
readonly "component-name": _typescript_eslint_utils_ts_eslint.RuleModule<MessageID, readonly [("CONSTANT_CASE" | "PascalCase") | { | ||
readonly "component-name": _typescript_eslint_utils_ts_eslint.RuleModule<"invalid", readonly [("CONSTANT_CASE" | "PascalCase") | { | ||
allowAllCaps?: boolean; | ||
@@ -28,4 +26,4 @@ allowLeadingUnderscore?: boolean; | ||
} | undefined], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>; | ||
readonly "context-name": _typescript_eslint_utils_ts_eslint.RuleModule<"contextName", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>; | ||
readonly filename: _typescript_eslint_utils_ts_eslint.RuleModule<MessageID$1, readonly [("PascalCase" | "camelCase" | "kebab-case" | "snake_case") | { | ||
readonly "context-name": _typescript_eslint_utils_ts_eslint.RuleModule<"invalid", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>; | ||
readonly filename: _typescript_eslint_utils_ts_eslint.RuleModule<MessageID, readonly [("PascalCase" | "camelCase" | "kebab-case" | "snake_case") | { | ||
excepts?: readonly string[]; | ||
@@ -35,3 +33,3 @@ extensions?: readonly string[]; | ||
} | undefined], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>; | ||
readonly "filename-extension": _typescript_eslint_utils_ts_eslint.RuleModule<MessageID$2, readonly [("always" | "as-needed") | { | ||
readonly "filename-extension": _typescript_eslint_utils_ts_eslint.RuleModule<MessageID$1, readonly [("always" | "as-needed") | { | ||
allow?: "always" | "as-needed"; | ||
@@ -41,3 +39,3 @@ extensions?: readonly string[]; | ||
} | undefined], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>; | ||
readonly "use-state": _typescript_eslint_utils_ts_eslint.RuleModule<"badValueOrSetterName", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>; | ||
readonly "use-state": _typescript_eslint_utils_ts_eslint.RuleModule<"invalid", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>; | ||
}; | ||
@@ -59,3 +57,3 @@ }; | ||
rules: { | ||
readonly "component-name": _typescript_eslint_utils_ts_eslint.RuleModule<MessageID, readonly [("CONSTANT_CASE" | "PascalCase") | { | ||
readonly "component-name": _typescript_eslint_utils_ts_eslint.RuleModule<"invalid", readonly [("CONSTANT_CASE" | "PascalCase") | { | ||
allowAllCaps?: boolean; | ||
@@ -67,4 +65,4 @@ allowLeadingUnderscore?: boolean; | ||
} | undefined], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>; | ||
readonly "context-name": _typescript_eslint_utils_ts_eslint.RuleModule<"contextName", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>; | ||
readonly filename: _typescript_eslint_utils_ts_eslint.RuleModule<MessageID$1, readonly [("PascalCase" | "camelCase" | "kebab-case" | "snake_case") | { | ||
readonly "context-name": _typescript_eslint_utils_ts_eslint.RuleModule<"invalid", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>; | ||
readonly filename: _typescript_eslint_utils_ts_eslint.RuleModule<MessageID, readonly [("PascalCase" | "camelCase" | "kebab-case" | "snake_case") | { | ||
excepts?: readonly string[]; | ||
@@ -74,3 +72,3 @@ extensions?: readonly string[]; | ||
} | undefined], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>; | ||
readonly "filename-extension": _typescript_eslint_utils_ts_eslint.RuleModule<MessageID$2, readonly [("always" | "as-needed") | { | ||
readonly "filename-extension": _typescript_eslint_utils_ts_eslint.RuleModule<MessageID$1, readonly [("always" | "as-needed") | { | ||
allow?: "always" | "as-needed"; | ||
@@ -80,3 +78,3 @@ extensions?: readonly string[]; | ||
} | undefined], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>; | ||
readonly "use-state": _typescript_eslint_utils_ts_eslint.RuleModule<"badValueOrSetterName", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>; | ||
readonly "use-state": _typescript_eslint_utils_ts_eslint.RuleModule<"invalid", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>; | ||
}; | ||
@@ -83,0 +81,0 @@ }; |
@@ -5,5 +5,4 @@ 'use strict'; | ||
var core = require('@eslint-react/core'); | ||
var shared = require('@eslint-react/shared'); | ||
var eff = require('@eslint-react/eff'); | ||
var JSX = require('@eslint-react/jsx'); | ||
var shared = require('@eslint-react/shared'); | ||
var types = require('@typescript-eslint/types'); | ||
@@ -35,3 +34,2 @@ var tsPattern = require('ts-pattern'); | ||
var AST__namespace = /*#__PURE__*/_interopNamespace(AST); | ||
var JSX__namespace = /*#__PURE__*/_interopNamespace(JSX); | ||
var path__default = /*#__PURE__*/_interopDefault(path); | ||
@@ -59,12 +57,9 @@ | ||
var name2 = "eslint-plugin-react-naming-convention"; | ||
var version = "1.29.1-beta.5"; | ||
var version = "1.29.1-beta.7"; | ||
var createRule = shared.createRuleForPlugin("naming-convention"); | ||
// src/rules/component-name.ts | ||
var RULE_NAME = "component-name"; | ||
var defaultOptions = [ | ||
{ | ||
allowAllCaps: false, | ||
allowLeadingUnderscore: false, | ||
allowNamespace: false, | ||
excepts: [], | ||
@@ -86,3 +81,11 @@ rule: "PascalCase" | ||
allowAllCaps: { type: "boolean" }, | ||
/** | ||
* @todo Remove in the next major version | ||
* @deprecated | ||
*/ | ||
allowLeadingUnderscore: { type: "boolean" }, | ||
/** | ||
* @todo Remove in the next major version | ||
* @deprecated | ||
*/ | ||
allowNamespace: { type: "boolean" }, | ||
@@ -102,32 +105,3 @@ excepts: { | ||
]; | ||
function normalizeOptions(options) { | ||
const opts = options[0]; | ||
const defaultOpts = defaultOptions[0]; | ||
if (opts == null) return defaultOpts; | ||
return { | ||
...defaultOpts, | ||
...typeof opts === "string" ? { rule: opts } : { | ||
...opts, | ||
excepts: opts.excepts?.map((pattern) => new RegExp(pattern, "u")) ?? [] | ||
} | ||
}; | ||
} | ||
function getViolationMessage(name3, options) { | ||
if (name3 == null) return eff._; | ||
if (options.excepts.some((regex) => regex.test(name3))) return eff._; | ||
let normalized = name3.split(".").at(-1) ?? name3; | ||
if (options.allowNamespace) normalized = normalized.replace(":", ""); | ||
if (options.allowLeadingUnderscore) normalized = normalized.replace(/^_/, ""); | ||
switch (options.rule) { | ||
case "CONSTANT_CASE": | ||
return shared.RE_CONSTANT_CASE.test(normalized) ? eff._ : "useConstantCase"; | ||
case "PascalCase": | ||
if (normalized.length > 3 && /^[A-Z]+$/u.test(normalized)) { | ||
return options.allowAllCaps ? eff._ : "usePascalCase"; | ||
} | ||
return shared.RE_PASCAL_CASE.test(normalized) ? eff._ : "usePascalCase"; | ||
default: | ||
return eff._; | ||
} | ||
} | ||
var RULE_NAME = "component-name"; | ||
var component_name_default = createRule({ | ||
@@ -138,7 +112,6 @@ meta: { | ||
docs: { | ||
description: "enforce component naming convention to 'PascalCase' or 'CONSTANT_CASE'" | ||
description: "enforce naming convention for components" | ||
}, | ||
messages: { | ||
useConstantCase: "Component name '{{name}}' must be in CONSTANT_CASE.", | ||
usePascalCase: "Component name '{{name}}' must be in PascalCase." | ||
invalid: "A component name '{{name}}' does not match {{rule}}." | ||
}, | ||
@@ -150,2 +123,3 @@ schema | ||
const options = normalizeOptions(context.options); | ||
const { rule } = options; | ||
const collector = core.useComponentCollector(context); | ||
@@ -156,17 +130,2 @@ const collectorLegacy = core.useComponentCollectorLegacy(); | ||
...collectorLegacy.listeners, | ||
JSXOpeningElement(node) { | ||
const name3 = JSX__namespace.getElementName(node.parent); | ||
if (/^[a-z]/u.test(name3)) { | ||
return; | ||
} | ||
const violation = getViolationMessage(name3, options); | ||
if (violation == null) return; | ||
context.report({ | ||
messageId: violation, | ||
node, | ||
data: { | ||
name: name3 | ||
} | ||
}); | ||
}, | ||
"Program:exit"(node) { | ||
@@ -179,10 +138,7 @@ const functionComponents = collector.ctx.getAllComponents(node); | ||
const name3 = id.name; | ||
const violation = getViolationMessage(name3, options); | ||
if (violation == null) continue; | ||
if (isValidName(name3, options)) return; | ||
context.report({ | ||
messageId: violation, | ||
messageId: "invalid", | ||
node: id, | ||
data: { | ||
name: name3 | ||
} | ||
data: { name: name3, rule } | ||
}); | ||
@@ -194,10 +150,7 @@ } | ||
const name3 = id.name; | ||
const violation = getViolationMessage(name3, options); | ||
if (violation == null) continue; | ||
if (isValidName(name3, options)) continue; | ||
context.report({ | ||
messageId: violation, | ||
messageId: "invalid", | ||
node: id, | ||
data: { | ||
case: options.rule | ||
} | ||
data: { name: name3, rule } | ||
}); | ||
@@ -210,2 +163,28 @@ } | ||
}); | ||
function normalizeOptions(options) { | ||
const opts = options[0]; | ||
const defaultOpts = defaultOptions[0]; | ||
if (opts == null) return defaultOpts; | ||
return { | ||
...defaultOpts, | ||
...typeof opts === "string" ? { rule: opts } : { | ||
...opts, | ||
excepts: opts.excepts?.map((pattern) => new RegExp(pattern, "u")) ?? [] | ||
} | ||
}; | ||
} | ||
function isValidName(name3, options) { | ||
if (name3 == null) return true; | ||
if (options.excepts.some((regex) => regex.test(name3))) return true; | ||
const normalized = name3.split(".").at(-1) ?? name3; | ||
switch (options.rule) { | ||
case "CONSTANT_CASE": | ||
return shared.RE_CONSTANT_CASE.test(normalized); | ||
case "PascalCase": | ||
if (normalized.length > 3 && /^[A-Z]+$/u.test(normalized)) { | ||
return options.allowAllCaps; | ||
} | ||
return shared.RE_PASCAL_CASE.test(normalized); | ||
} | ||
} | ||
var RULE_NAME2 = "context-name"; | ||
@@ -216,6 +195,6 @@ var context_name_default = createRule({ | ||
docs: { | ||
description: "enforces context name to be a valid component name with the suffix 'Context'" | ||
description: "enforce context name to be a valid component name with the suffix 'Context'" | ||
}, | ||
messages: { | ||
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'." | ||
invalid: "A context name must be a valid component name with the suffix 'Context'." | ||
}, | ||
@@ -235,3 +214,3 @@ schema: [] | ||
context.report({ | ||
messageId: "contextName", | ||
messageId: "invalid", | ||
node: id | ||
@@ -289,4 +268,4 @@ }); | ||
messages: { | ||
filenameCaseMismatch: "A file with name '{{name}}' does not match {{rule}}. Should rename to '{{suggestion}}'.", | ||
filenameEmpty: "A file must have non-empty name." | ||
filenameEmpty: "A file must have non-empty name.", | ||
filenameInvalid: "A file with name '{{name}}' does not match {{rule}}. Rename it to '{{suggestion}}'." | ||
}, | ||
@@ -319,3 +298,3 @@ schema: schema2 | ||
context.report({ | ||
messageId: "filenameCaseMismatch", | ||
messageId: "filenameInvalid", | ||
node, | ||
@@ -378,3 +357,3 @@ data: { | ||
useJsxFileExtension: "Use {{extensions}} file extension for JSX files.", | ||
useJsxFileExtensionAsNeeded: "Do not use {{extensions}} file extension for files without JSX." | ||
useNonJsxFileExtension: "Do not use {{extensions}} file extension for files without JSX." | ||
}, | ||
@@ -418,3 +397,3 @@ schema: schema3 | ||
context.report({ | ||
messageId: "useJsxFileExtensionAsNeeded", | ||
messageId: "useNonJsxFileExtension", | ||
node, | ||
@@ -443,3 +422,3 @@ data: { | ||
messages: { | ||
badValueOrSetterName: "An useState call is not destructured into value + setter pair." | ||
invalid: "An useState call is not destructured into value + setter pair." | ||
}, | ||
@@ -453,7 +432,7 @@ schema: [] | ||
if (node.parent.type !== types.AST_NODE_TYPES.VariableDeclarator) { | ||
context.report({ messageId: "badValueOrSetterName", node }); | ||
context.report({ messageId: "invalid", node }); | ||
} | ||
const id = core.getInstanceId(node); | ||
if (id?.type !== types.AST_NODE_TYPES.ArrayPattern) { | ||
context.report({ messageId: "badValueOrSetterName", node }); | ||
context.report({ messageId: "invalid", node }); | ||
return; | ||
@@ -463,3 +442,3 @@ } | ||
if (value == null || setter == null) { | ||
context.report({ messageId: "badValueOrSetterName", node }); | ||
context.report({ messageId: "invalid", node }); | ||
return; | ||
@@ -469,3 +448,3 @@ } | ||
if (setterName == null || !setterName.startsWith("set")) { | ||
context.report({ messageId: "badValueOrSetterName", node }); | ||
context.report({ messageId: "invalid", node }); | ||
return; | ||
@@ -483,3 +462,3 @@ } | ||
if (valueName == null || `set_${valueName}` !== stringTs.snakeCase(setterName)) { | ||
context.report({ messageId: "badValueOrSetterName", node }); | ||
context.report({ messageId: "invalid", node }); | ||
return; | ||
@@ -500,7 +479,7 @@ } | ||
rules: { | ||
"component-name": component_name_default, | ||
"context-name": context_name_default, | ||
filename: filename_default, | ||
"filename-extension": filename_extension_default, | ||
"use-state": use_state_default | ||
["component-name"]: component_name_default, | ||
["context-name"]: context_name_default, | ||
["filename"]: filename_default, | ||
["filename-extension"]: filename_extension_default, | ||
["use-state"]: use_state_default | ||
} | ||
@@ -507,0 +486,0 @@ }; |
{ | ||
"name": "eslint-plugin-react-naming-convention", | ||
"version": "1.29.1-beta.5", | ||
"version": "1.29.1-beta.7", | ||
"description": "ESLint React's ESLint plugin for naming convention related rules.", | ||
@@ -52,8 +52,8 @@ "keywords": [ | ||
"ts-pattern": "^5.6.2", | ||
"@eslint-react/ast": "1.29.1-beta.5", | ||
"@eslint-react/core": "1.29.1-beta.5", | ||
"@eslint-react/eff": "1.29.1-beta.5", | ||
"@eslint-react/jsx": "1.29.1-beta.5", | ||
"@eslint-react/shared": "1.29.1-beta.5", | ||
"@eslint-react/var": "1.29.1-beta.5" | ||
"@eslint-react/ast": "1.29.1-beta.7", | ||
"@eslint-react/core": "1.29.1-beta.7", | ||
"@eslint-react/eff": "1.29.1-beta.7", | ||
"@eslint-react/jsx": "1.29.1-beta.7", | ||
"@eslint-react/shared": "1.29.1-beta.7", | ||
"@eslint-react/var": "1.29.1-beta.7" | ||
}, | ||
@@ -60,0 +60,0 @@ "devDependencies": { |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
41556
-5.1%1005
-4.01%+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed