eslint-plugin-code-style 1.5.0 → 1.5.2

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.
Files changed (3) hide show
  1. package/README.md +5 -5
  2. package/index.js +39 -15
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -19,7 +19,7 @@
19
19
 
20
20
  **A powerful ESLint plugin for enforcing consistent code formatting and style rules in React/JSX projects.**
21
21
 
22
- *64 auto-fixable rules to keep your codebase clean and consistent*
22
+ *65 rules (59 auto-fixable) to keep your codebase clean and consistent*
23
23
 
24
24
  </div>
25
25
 
@@ -27,7 +27,7 @@
27
27
 
28
28
  ## 🎯 Why This Plugin?
29
29
 
30
- This plugin provides **64 custom auto-fixable rules** for code formatting. Built for **ESLint v9 flat configs**.
30
+ This plugin provides **65 custom rules** (59 auto-fixable) for code formatting. Built for **ESLint v9 flat configs**.
31
31
 
32
32
  > **Note:** ESLint [deprecated 79 formatting rules](https://eslint.org/blog/2023/10/deprecating-formatting-rules/) in v8.53.0. Our recommended configs use `@stylistic/eslint-plugin` as the replacement for these deprecated rules.
33
33
 
@@ -36,7 +36,7 @@ This plugin provides **64 custom auto-fixable rules** for code formatting. Built
36
36
  - **Works alongside existing tools** — Complements ESLint's built-in rules and packages like eslint-plugin-react, eslint-plugin-import, etc
37
37
  - **Self-sufficient rules** — Each rule handles complete formatting independently
38
38
  - **Consistency at scale** — Reduces code-style differences between team members by enforcing uniform formatting across your projects
39
- - **Highly automated** — 58 of 64 rules support auto-fix with `eslint --fix`
39
+ - **Highly automated** — 59 of 65 rules support auto-fix with `eslint --fix`
40
40
 
41
41
  When combined with ESLint's native rules and other popular plugins, this package helps create a complete code style solution that keeps your codebase clean and consistent.
42
42
 
@@ -97,7 +97,7 @@ We provide **ready-to-use ESLint flat configuration files** that combine `eslint
97
97
  <td width="50%">
98
98
 
99
99
  ### 🔧 Auto-Fixable Rules
100
- **58 rules** support automatic fixing with `eslint --fix`. 6 rules are report-only (require manual changes).
100
+ **59 rules** support automatic fixing with `eslint --fix`. 6 rules are report-only (require manual changes).
101
101
 
102
102
  </td>
103
103
  <td width="50%">
@@ -3034,7 +3034,7 @@ const UseAuth = () => {}; // hooks should be camelCase
3034
3034
 
3035
3035
  ## 🔧 Auto-fixing
3036
3036
 
3037
- All rules support auto-fixing. Run ESLint with the `--fix` flag:
3037
+ 59 of 65 rules support auto-fixing. Run ESLint with the `--fix` flag:
3038
3038
 
3039
3039
  ```bash
3040
3040
  # Fix all files in src directory
package/index.js CHANGED
@@ -1809,10 +1809,26 @@ const functionDeclarationStyle = {
1809
1809
  }
1810
1810
 
1811
1811
  // Build type parameters if present (generics)
1812
+ // For arrow functions in TSX files, use trailing comma to avoid JSX ambiguity: <T,>
1812
1813
  let typeParams = "";
1813
1814
 
1814
1815
  if (node.typeParameters) {
1815
- typeParams = sourceCode.getText(node.typeParameters);
1816
+ const typeParamsText = sourceCode.getText(node.typeParameters);
1817
+
1818
+ // Add trailing comma if single type parameter to avoid JSX parsing issues
1819
+ // <T> becomes <T,> but <T, U> stays as is
1820
+ if (node.typeParameters.params && node.typeParameters.params.length === 1) {
1821
+ // Check if it already has a trailing comma
1822
+ const innerText = typeParamsText.slice(1, -1).trim();
1823
+
1824
+ if (!innerText.endsWith(",")) {
1825
+ typeParams = `<${innerText},>`;
1826
+ } else {
1827
+ typeParams = typeParamsText;
1828
+ }
1829
+ } else {
1830
+ typeParams = typeParamsText;
1831
+ }
1816
1832
  }
1817
1833
 
1818
1834
  // Check if async
@@ -1832,11 +1848,12 @@ const functionDeclarationStyle = {
1832
1848
  fix(fixer) {
1833
1849
  const fixTarget = isExported ? parentNode : node;
1834
1850
 
1835
- const replacement = `${exportPrefix}const ${name} = ${asyncPrefix}(${paramsText})${returnType} => ${bodyText};`;
1851
+ // For arrow functions with generics: const fn = <T,>(param: T) => ...
1852
+ const replacement = `${exportPrefix}const ${name} = ${typeParams}${asyncPrefix}(${paramsText})${returnType} => ${bodyText};`;
1836
1853
 
1837
1854
  return fixer.replaceText(fixTarget, replacement);
1838
1855
  },
1839
- message: `Expected a function expression. Use \`const ${name} = ${asyncPrefix}(${paramsText})${returnType} => ...\` instead.`,
1856
+ message: `Expected a function expression. Use \`const ${name} = ${typeParams}${asyncPrefix}(${paramsText})${returnType} => ...\` instead.`,
1840
1857
  node: node.id,
1841
1858
  });
1842
1859
  },
@@ -2184,17 +2201,23 @@ const functionNamingConvention = {
2184
2201
  const classBody = node.parent;
2185
2202
 
2186
2203
  if (classBody && classBody.type === "ClassBody") {
2187
- const sourceCode = context.sourceCode || context.getSourceCode();
2188
- const classText = sourceCode.getText(classBody);
2189
-
2190
2204
  // Find usages like this.methodName or super.methodName
2191
2205
  const classNode = classBody.parent;
2192
2206
 
2193
2207
  if (classNode) {
2208
+ const visited = new Set();
2209
+
2194
2210
  const searchPatternHandler = (n) => {
2211
+ // Avoid circular references and already visited nodes
2212
+ if (!n || typeof n !== "object" || visited.has(n)) return;
2213
+
2214
+ visited.add(n);
2215
+
2195
2216
  if (n.type === "MemberExpression" &&
2217
+ n.property &&
2196
2218
  n.property.type === "Identifier" &&
2197
2219
  n.property.name === name &&
2220
+ n.object &&
2198
2221
  (n.object.type === "ThisExpression" || n.object.type === "Super")) {
2199
2222
  // Don't fix the definition itself
2200
2223
  if (n.property !== key) {
@@ -2202,18 +2225,19 @@ const functionNamingConvention = {
2202
2225
  }
2203
2226
  }
2204
2227
 
2205
- // Recursively search
2206
- for (const childKey of Object.keys(n)) {
2228
+ // Recursively search only AST child properties (skip parent, tokens, etc.)
2229
+ const childKeys = ["body", "declarations", "expression", "left", "right",
2230
+ "callee", "arguments", "object", "property", "consequent", "alternate",
2231
+ "test", "init", "update", "params", "elements", "properties", "value",
2232
+ "key", "argument", "block", "handler", "finalizer", "cases"];
2233
+
2234
+ for (const childKey of childKeys) {
2207
2235
  const child = n[childKey];
2208
2236
 
2209
- if (child && typeof child === "object") {
2237
+ if (child) {
2210
2238
  if (Array.isArray(child)) {
2211
- child.forEach((item) => {
2212
- if (item && typeof item === "object" && item.type) {
2213
- searchPatternHandler(item);
2214
- }
2215
- });
2216
- } else if (child.type) {
2239
+ child.forEach((item) => searchPatternHandler(item));
2240
+ } else {
2217
2241
  searchPatternHandler(child);
2218
2242
  }
2219
2243
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eslint-plugin-code-style",
3
- "version": "1.5.0",
3
+ "version": "1.5.2",
4
4
  "description": "A custom ESLint plugin for enforcing consistent code formatting and style rules in React/JSX projects",
5
5
  "main": "index.js",
6
6
  "types": "index.d.ts",