eslint-plugin-code-style 1.11.4 → 1.11.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/CHANGELOG.md +37 -0
- package/index.js +12 -35
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,40 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
---
|
|
9
9
|
|
|
10
|
+
## [1.11.7] - 2026-02-04
|
|
11
|
+
|
|
12
|
+
### Changed
|
|
13
|
+
|
|
14
|
+
- **`no-hardcoded-strings`**
|
|
15
|
+
- Remove UI component pattern exemption - ALL enum-like attribute values are now flagged (e.g., `variant="primary"`, `size="large"`, `color="danger"`)
|
|
16
|
+
- Enforce consistent use of enums for component props to prevent typos
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
## [1.11.6] - 2026-02-04
|
|
21
|
+
|
|
22
|
+
### Changed
|
|
23
|
+
|
|
24
|
+
- **`no-hardcoded-strings`**
|
|
25
|
+
- Flag `type` attribute in JSX elements (e.g., `<input type="text" />`) - should use enums to prevent typos
|
|
26
|
+
- Remove `type` from default ignored attributes list
|
|
27
|
+
- Remove "text" from UI component pattern (conflicts with input type)
|
|
28
|
+
- Update error message for JSX attributes: "should be imported from @/enums (preferred) or @/data to prevent typos"
|
|
29
|
+
|
|
30
|
+
---
|
|
31
|
+
|
|
32
|
+
## [1.11.5] - 2026-02-04
|
|
33
|
+
|
|
34
|
+
### Fixed
|
|
35
|
+
|
|
36
|
+
- **`no-hardcoded-strings`**
|
|
37
|
+
- Flag hardcoded strings in component default params (e.g., `type = "text"`, `variant = "ghost"`)
|
|
38
|
+
- Flag hardcoded strings in ternary expressions (e.g., `showPassword ? "text" : "password"`)
|
|
39
|
+
- Remove overly broad HTML input type exemption from general string checks
|
|
40
|
+
- Remove "text" from CSS cursor pattern (conflicts with common input type usage)
|
|
41
|
+
|
|
42
|
+
---
|
|
43
|
+
|
|
10
44
|
## [1.11.4] - 2026-02-04
|
|
11
45
|
|
|
12
46
|
### Fixed
|
|
@@ -1504,6 +1538,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
1504
1538
|
|
|
1505
1539
|
---
|
|
1506
1540
|
|
|
1541
|
+
[1.11.7]: https://github.com/Mohamed-Elhawary/eslint-plugin-code-style/compare/v1.11.6...v1.11.7
|
|
1542
|
+
[1.11.6]: https://github.com/Mohamed-Elhawary/eslint-plugin-code-style/compare/v1.11.5...v1.11.6
|
|
1543
|
+
[1.11.5]: https://github.com/Mohamed-Elhawary/eslint-plugin-code-style/compare/v1.11.4...v1.11.5
|
|
1507
1544
|
[1.11.4]: https://github.com/Mohamed-Elhawary/eslint-plugin-code-style/compare/v1.11.3...v1.11.4
|
|
1508
1545
|
[1.11.3]: https://github.com/Mohamed-Elhawary/eslint-plugin-code-style/compare/v1.11.2...v1.11.3
|
|
1509
1546
|
[1.11.2]: https://github.com/Mohamed-Elhawary/eslint-plugin-code-style/compare/v1.11.1...v1.11.2
|
package/index.js
CHANGED
|
@@ -14561,7 +14561,7 @@ const noHardcodedStrings = {
|
|
|
14561
14561
|
"textDecoration", // SVG
|
|
14562
14562
|
"transform", // SVG
|
|
14563
14563
|
"translate",
|
|
14564
|
-
"type"
|
|
14564
|
+
// "type" removed - should use enums for input/button types to prevent typos
|
|
14565
14565
|
"vectorEffect", // SVG
|
|
14566
14566
|
"useMap",
|
|
14567
14567
|
"value",
|
|
@@ -14646,8 +14646,8 @@ const noHardcodedStrings = {
|
|
|
14646
14646
|
/^[a-zA-Z]+\d*[_a-zA-Z0-9]*(_[a-zA-Z0-9]+)+$/,
|
|
14647
14647
|
// Color names (CSS named colors used in SVG)
|
|
14648
14648
|
/^(white|black|red|green|blue|yellow|orange|purple|pink|brown|gray|grey|cyan|magenta|transparent)$/i,
|
|
14649
|
-
// CSS cursor values
|
|
14650
|
-
/^(auto|default|none|context-menu|help|pointer|progress|wait|cell|crosshair|
|
|
14649
|
+
// CSS cursor values (excluding "text" as it conflicts with input type)
|
|
14650
|
+
/^(auto|default|none|context-menu|help|pointer|progress|wait|cell|crosshair|vertical-text|alias|copy|move|no-drop|not-allowed|grab|grabbing|all-scroll|col-resize|row-resize|n-resize|e-resize|s-resize|w-resize|ne-resize|nw-resize|se-resize|sw-resize|ew-resize|ns-resize|nesw-resize|nwse-resize|zoom-in|zoom-out)$/,
|
|
14651
14651
|
// CSS display/visibility values
|
|
14652
14652
|
/^(block|inline|inline-block|flex|inline-flex|grid|inline-grid|flow-root|contents|table|table-row|table-cell|list-item|none|visible|hidden|collapse)$/,
|
|
14653
14653
|
// CSS position values
|
|
@@ -14801,9 +14801,6 @@ const noHardcodedStrings = {
|
|
|
14801
14801
|
});
|
|
14802
14802
|
};
|
|
14803
14803
|
|
|
14804
|
-
// UI component patterns - only ignored in JSX attributes, not in logic
|
|
14805
|
-
const uiComponentPattern = /^(primary|secondary|tertiary|ghost|outline|link|muted|danger|warning|info|success|error|default|subtle|solid|soft|plain|flat|elevated|filled|tonal|text|contained|standard|xs|sm|md|lg|xl|2xl|3xl|4xl|5xl|xxs|xxl|small|medium|large|tiny|huge|compact|comfortable|spacious|left|right|center|top|bottom|start|end|middle|baseline|stretch|between|around|evenly|horizontal|vertical|row|column|inline|block|flex|grid|auto|none|hidden|visible|static|relative|absolute|fixed|sticky|on|off|hover|focus|click|blur|always|never)$/;
|
|
14806
|
-
|
|
14807
14804
|
// HTML input types - standard browser input types, not hardcoded strings
|
|
14808
14805
|
const htmlInputTypes = new Set([
|
|
14809
14806
|
"button",
|
|
@@ -14923,21 +14920,6 @@ const noHardcodedStrings = {
|
|
|
14923
14920
|
return false;
|
|
14924
14921
|
};
|
|
14925
14922
|
|
|
14926
|
-
// Check if string is in a default parameter for input type
|
|
14927
|
-
const isInputTypeDefaultParamHandler = (node) => {
|
|
14928
|
-
// Check if we're in an AssignmentPattern (default param)
|
|
14929
|
-
if (node.parent && node.parent.type === "AssignmentPattern") {
|
|
14930
|
-
const assignPattern = node.parent;
|
|
14931
|
-
|
|
14932
|
-
// Check if the parameter name is "type"
|
|
14933
|
-
if (assignPattern.left && assignPattern.left.type === "Identifier" && assignPattern.left.name === "type") {
|
|
14934
|
-
return true;
|
|
14935
|
-
}
|
|
14936
|
-
}
|
|
14937
|
-
|
|
14938
|
-
return false;
|
|
14939
|
-
};
|
|
14940
|
-
|
|
14941
14923
|
// Check if this is a module-level exported string that should be flagged
|
|
14942
14924
|
const isExportedHardcodedStringHandler = (node) => {
|
|
14943
14925
|
let current = node.parent;
|
|
@@ -14995,19 +14977,23 @@ const noHardcodedStrings = {
|
|
|
14995
14977
|
const isSingleWord = !/\s/.test(str) && str.length <= 30;
|
|
14996
14978
|
const isAllLowercase = /^[a-z_]+$/.test(str);
|
|
14997
14979
|
|
|
14980
|
+
// For JSX attributes (type, variant, etc.), prefer enums to prevent typos
|
|
14981
|
+
const isJsxAttribute = context.includes("attribute");
|
|
14982
|
+
|
|
14998
14983
|
if (isSingleWord && isAllLowercase) {
|
|
14999
|
-
|
|
14984
|
+
if (isJsxAttribute) {
|
|
14985
|
+
return `Hardcoded "${truncatedStr}"${contextPart} should be imported from @/enums (preferred) or @/data to prevent typos (e.g., import { InputTypeEnum } from "@/enums")`;
|
|
14986
|
+
}
|
|
14987
|
+
|
|
14988
|
+
return `Hardcoded "${truncatedStr}"${contextPart} should be imported from @/enums (preferred) or @/data (e.g., import { StatusEnum } from "@/enums")`;
|
|
15000
14989
|
}
|
|
15001
14990
|
|
|
15002
14991
|
// UI string: starts with capital, has spaces, or multiple words
|
|
15003
|
-
return `Hardcoded UI string "${truncatedStr}"${contextPart} should be imported from @/strings or @/constants
|
|
14992
|
+
return `Hardcoded UI string "${truncatedStr}"${contextPart} should be imported from @/strings or @/constants (e.g., import { strings } from "@/strings")`;
|
|
15004
14993
|
};
|
|
15005
14994
|
|
|
15006
14995
|
// Check if a string matches any ignore pattern
|
|
15007
14996
|
const shouldIgnoreStringHandler = (str) => {
|
|
15008
|
-
// Skip HTML input types (text, password, email, etc.)
|
|
15009
|
-
if (isHtmlInputTypeHandler(str)) return true;
|
|
15010
|
-
|
|
15011
14997
|
// Skip Tailwind/CSS class strings
|
|
15012
14998
|
if (isTailwindClassStringHandler(str)) return true;
|
|
15013
14999
|
|
|
@@ -15279,9 +15265,6 @@ const noHardcodedStrings = {
|
|
|
15279
15265
|
if (node.value.type === "Literal" && typeof node.value.value === "string") {
|
|
15280
15266
|
const str = node.value.value;
|
|
15281
15267
|
|
|
15282
|
-
// Skip UI component patterns in JSX attributes (variant, size, position props)
|
|
15283
|
-
if (uiComponentPattern.test(str)) return;
|
|
15284
|
-
|
|
15285
15268
|
if (shouldIgnoreStringHandler(str)) return;
|
|
15286
15269
|
|
|
15287
15270
|
// Check if it looks like user-facing text
|
|
@@ -15303,9 +15286,6 @@ const noHardcodedStrings = {
|
|
|
15303
15286
|
if (expression.type === "Literal" && typeof expression.value === "string") {
|
|
15304
15287
|
const str = expression.value;
|
|
15305
15288
|
|
|
15306
|
-
// Skip UI component patterns in JSX attributes (variant, size, position props)
|
|
15307
|
-
if (uiComponentPattern.test(str)) return;
|
|
15308
|
-
|
|
15309
15289
|
if (shouldIgnoreStringHandler(str)) return;
|
|
15310
15290
|
|
|
15311
15291
|
if (!/[a-zA-Z]/.test(str)) return;
|
|
@@ -15328,9 +15308,6 @@ const noHardcodedStrings = {
|
|
|
15328
15308
|
// Skip if inside a style object (style={{ transform: "..." }})
|
|
15329
15309
|
if (isInsideStyleObjectHandler(node)) return;
|
|
15330
15310
|
|
|
15331
|
-
// Skip input type default params (e.g., type = "text")
|
|
15332
|
-
if (isInputTypeDefaultParamHandler(node)) return;
|
|
15333
|
-
|
|
15334
15311
|
// Check for exported hardcoded strings (e.g., export const tokenKey = "auth_token")
|
|
15335
15312
|
// These should be flagged even at module level, regardless of whether the value
|
|
15336
15313
|
// looks "technical" - the point is exposing hardcoded strings in exports
|
package/package.json
CHANGED