@sabzidev/eslint-rules 1.0.5 → 1.0.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/README.md +47 -32
- package/dist/index.js +74 -71
- package/package.json +6 -6
package/README.md
CHANGED
|
@@ -26,7 +26,7 @@ A collection of custom ESLint rules for improving code quality, consistency, and
|
|
|
26
26
|
|
|
27
27
|
---
|
|
28
28
|
|
|
29
|
-
##
|
|
29
|
+
## 🚀📦 Installation & Usage
|
|
30
30
|
|
|
31
31
|
Install the package as a development dependency:
|
|
32
32
|
|
|
@@ -34,11 +34,7 @@ Install the package as a development dependency:
|
|
|
34
34
|
pnpm i -D @sabzidev/eslint-rules
|
|
35
35
|
```
|
|
36
36
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
## 🚀 Usage
|
|
40
|
-
|
|
41
|
-
Choose **one** of the following configuration methods for your existing `eslint.config.js` file:
|
|
37
|
+
Choose **one** of the following configuration methods for your `eslint.config.js` file:
|
|
42
38
|
|
|
43
39
|
### ● Recommended Configuration
|
|
44
40
|
|
|
@@ -54,7 +50,7 @@ export default defineConfig([
|
|
|
54
50
|
]);
|
|
55
51
|
```
|
|
56
52
|
|
|
57
|
-
This enables all
|
|
53
|
+
This enables all recommended rules with their predefined severity levels.
|
|
58
54
|
|
|
59
55
|
### ● Custom Configuration
|
|
60
56
|
|
|
@@ -86,11 +82,19 @@ export default defineConfig([
|
|
|
86
82
|
|
|
87
83
|
---
|
|
88
84
|
|
|
89
|
-
## ⭐ Recommended
|
|
85
|
+
## ⭐ Recommended ESLint & Prettier Setup
|
|
90
86
|
|
|
91
|
-
|
|
87
|
+
Install the required dependencies:
|
|
92
88
|
|
|
93
|
-
|
|
89
|
+
```bash
|
|
90
|
+
pnpm i -D eslint prettier @fullstacksjs/eslint-config @sabzidev/eslint-rules eslint-plugin-sonarjs eslint-plugin-unicorn
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
For a comprehensive code-quality setup, combine `ESLint`, `Prettier`, [`@fullstacksjs/eslint-config`](https://npmjs.com/package/@fullstacksjs/eslint-config), [`@sabzidev/eslint-rules`](https://npmjs.com/package/@sabzidev/eslint-rules), [`eslint-plugin-sonarjs`](https://npmjs.com/package/eslint-plugin-sonarjs), and [`eslint-plugin-unicorn`](https://npmjs.com/package/eslint-plugin-unicorn).
|
|
94
|
+
|
|
95
|
+
This setup combines code formatting, code-quality checks, bug detection, maintainability rules, and custom ESLint rules.
|
|
96
|
+
|
|
97
|
+
This setup combines code-quality rules, bug detection, maintainability checks, and custom linting rules.
|
|
94
98
|
|
|
95
99
|
**Configuration for `eslint.config.js`:**
|
|
96
100
|
|
|
@@ -110,28 +114,39 @@ const baseRules = {
|
|
|
110
114
|
eqeqeq: ["error", "always"],
|
|
111
115
|
"no-console": "warn",
|
|
112
116
|
};
|
|
117
|
+
|
|
113
118
|
const plugins = [
|
|
114
119
|
sabzidev.configs.recommended,
|
|
115
120
|
sonarjs.configs.recommended,
|
|
116
121
|
unicorn.configs.recommended,
|
|
117
122
|
];
|
|
123
|
+
|
|
118
124
|
const pluginsRules = {
|
|
119
125
|
"unicorn/filename-case": "off",
|
|
120
|
-
"unicorn/
|
|
121
|
-
|
|
122
|
-
|
|
126
|
+
"unicorn/name-replacements": [
|
|
127
|
+
"error",
|
|
128
|
+
{
|
|
129
|
+
replacements: {
|
|
130
|
+
prop: false,
|
|
131
|
+
props: false,
|
|
132
|
+
param: false,
|
|
133
|
+
params: false,
|
|
134
|
+
ref: false,
|
|
135
|
+
refs: false,
|
|
136
|
+
prev: false,
|
|
137
|
+
e: false,
|
|
138
|
+
res: false,
|
|
139
|
+
err: false,
|
|
140
|
+
},
|
|
141
|
+
},
|
|
142
|
+
],
|
|
123
143
|
"unicorn/no-null": "off",
|
|
144
|
+
"unicorn/prefer-global-this": "off",
|
|
124
145
|
"unicorn/default-export-style": "off",
|
|
125
|
-
|
|
126
|
-
"jsx-a11y/click-events-have-key-events": "off",
|
|
127
|
-
"jsx-a11y/no-noninteractive-element-interactions": "off",
|
|
128
146
|
};
|
|
129
147
|
|
|
130
148
|
const config = defineConfig(
|
|
131
|
-
{
|
|
132
|
-
tailwind: { entryPoint: "./src/input.css" },
|
|
133
|
-
rules: baseRules,
|
|
134
|
-
},
|
|
149
|
+
{ rules: baseRules, tailwind: { entryPoint: "./src/input.css" } },
|
|
135
150
|
|
|
136
151
|
plugins,
|
|
137
152
|
{ rules: pluginsRules },
|
|
@@ -140,23 +155,23 @@ const config = defineConfig(
|
|
|
140
155
|
export default config;
|
|
141
156
|
```
|
|
142
157
|
|
|
143
|
-
**Note:**
|
|
158
|
+
**Note:** Adjust the rules to suit your project and ensure compatibility with your installed plugin versions.
|
|
144
159
|
|
|
145
160
|
---
|
|
146
161
|
|
|
147
162
|
## 📋 Available Rules
|
|
148
163
|
|
|
149
|
-
| Rule | Description
|
|
150
|
-
| :--------------------------------------- |
|
|
151
|
-
| `merge-duplicate-id-and-classname-props` | Merges duplicate
|
|
152
|
-
| `merge-exports` | Merges or organizes export declarations.
|
|
153
|
-
| `no-invalid-id-and-classname-value` | Detects invalid
|
|
154
|
-
| `no-useless-empty-type` | Detects unnecessary empty types.
|
|
155
|
-
| `no-useless-template-literal` | Detects unnecessary template literals.
|
|
156
|
-
| `padding-before-jump-statement` | Enforces padding before jump statements.
|
|
157
|
-
| `sort-comments` | Sorts comments.
|
|
158
|
-
| `sort-jsx-props` | Sorts JSX props.
|
|
159
|
-
| `sort-
|
|
164
|
+
| Rule | Description |
|
|
165
|
+
| :--------------------------------------- | :------------------------------------------------------------------------- |
|
|
166
|
+
| `merge-duplicate-id-and-classname-props` | Merges duplicate id and className props. |
|
|
167
|
+
| `merge-exports` | Merges or organizes export declarations. |
|
|
168
|
+
| `no-invalid-id-and-classname-value` | Detects invalid id and className values. |
|
|
169
|
+
| `no-useless-empty-type` | Detects unnecessary empty types. |
|
|
170
|
+
| `no-useless-template-literal` | Detects unnecessary template literals. |
|
|
171
|
+
| `padding-before-jump-statement` | Enforces padding before jump statements. |
|
|
172
|
+
| `sort-comments` | Sorts comments. |
|
|
173
|
+
| `sort-jsx-props` | Sorts JSX props. |
|
|
174
|
+
| `sort-props` | Sorts object properties, function parameters, and TypeScript type members. |
|
|
160
175
|
|
|
161
176
|
---
|
|
162
177
|
|
package/dist/index.js
CHANGED
|
@@ -1,11 +1,6 @@
|
|
|
1
1
|
var e = {
|
|
2
2
|
name: "@sabzidev/eslint-rules",
|
|
3
3
|
description: "A collection of ESLint rules for better code quality, consistency, and maintainability.",
|
|
4
|
-
repository: {
|
|
5
|
-
type: "git",
|
|
6
|
-
url: "https://github.com/SabziDev/eslint-rules"
|
|
7
|
-
},
|
|
8
|
-
license: "MIT",
|
|
9
4
|
keywords: [
|
|
10
5
|
"SabziDev",
|
|
11
6
|
"eslint",
|
|
@@ -16,8 +11,13 @@ var e = {
|
|
|
16
11
|
"linting",
|
|
17
12
|
"developer-tools"
|
|
18
13
|
],
|
|
14
|
+
repository: {
|
|
15
|
+
type: "git",
|
|
16
|
+
url: "https://github.com/SabziDev/eslint-rules"
|
|
17
|
+
},
|
|
18
|
+
license: "MIT",
|
|
19
19
|
author: "Abolfazl Sabzmohammadi <SabziDev@gmail.com> (https://Sabzi.Dev)",
|
|
20
|
-
version: "1.0.
|
|
20
|
+
version: "1.0.7",
|
|
21
21
|
type: "module",
|
|
22
22
|
main: "./dist/index.js",
|
|
23
23
|
exports: "./dist/index.js",
|
|
@@ -356,10 +356,11 @@ var e = {
|
|
|
356
356
|
});
|
|
357
357
|
} };
|
|
358
358
|
}
|
|
359
|
-
}, l = /* @__PURE__ */ "children.key.id.ref.data.title.desc.htmlFor.type.inputMode.name.value.placeholder.autoComplete.min.max.minLength.maxLength.src.alt.loading.poster.preload.controls.href.target.rel.to.replace.viewTransition".split("."), u = [
|
|
359
|
+
}, l = /* @__PURE__ */ "prop.props.children.param.params.key.id.ref.data.title.desc.htmlFor.type.inputMode.name.value.placeholder.autoComplete.min.max.minLength.maxLength.src.alt.loading.poster.preload.controls.href.target.rel.to.replace.viewTransition".split("."), u = [
|
|
360
360
|
"onClick",
|
|
361
361
|
"onChange",
|
|
362
|
-
"onKeyUp"
|
|
362
|
+
"onKeyUp",
|
|
363
|
+
"onKeyDown"
|
|
363
364
|
], d = {
|
|
364
365
|
"merge-duplicate-id-and-classname-props": t,
|
|
365
366
|
"merge-exports": n,
|
|
@@ -412,7 +413,7 @@ var e = {
|
|
|
412
413
|
} };
|
|
413
414
|
}
|
|
414
415
|
},
|
|
415
|
-
"sort-
|
|
416
|
+
"sort-props": {
|
|
416
417
|
meta: {
|
|
417
418
|
type: "suggestion",
|
|
418
419
|
fixable: "code",
|
|
@@ -432,16 +433,10 @@ var e = {
|
|
|
432
433
|
let t = l.flatMap((t) => e.filter((e) => a(e) === t)), o = e.filter((e) => {
|
|
433
434
|
let t = a(e);
|
|
434
435
|
return !n.has(t) && !r(t) && !["className", "style"].includes(t);
|
|
435
|
-
}), s = e.filter((e) => {
|
|
436
|
-
let t = a(e);
|
|
437
|
-
return r(t);
|
|
438
|
-
}).sort((e, t) => {
|
|
436
|
+
}), s = e.filter((e) => r(a(e))).sort((e, t) => {
|
|
439
437
|
let n = i(a(e)), r = i(a(t));
|
|
440
438
|
return n === 999 && r === 999 ? 0 : n - r;
|
|
441
|
-
}), c = e.filter((e) => {
|
|
442
|
-
let t = a(e);
|
|
443
|
-
return ["className", "style"].includes(t);
|
|
444
|
-
}).sort((e, t) => {
|
|
439
|
+
}), c = e.filter((e) => ["className", "style"].includes(a(e))).sort((e, t) => {
|
|
445
440
|
let n = a(e), r = a(t);
|
|
446
441
|
return n === "className" && r === "style" ? -1 : +(n === "style" && r === "className");
|
|
447
442
|
});
|
|
@@ -453,57 +448,68 @@ var e = {
|
|
|
453
448
|
];
|
|
454
449
|
}, d = (e) => {
|
|
455
450
|
let t = [], n = [];
|
|
456
|
-
for (let r of e)
|
|
457
|
-
|
|
458
|
-
let e = c(n);
|
|
459
|
-
t.push(...e), n = [];
|
|
460
|
-
}
|
|
461
|
-
t.push(r);
|
|
462
|
-
} else n.push(r);
|
|
463
|
-
if (n.length > 0) {
|
|
464
|
-
let e = c(n);
|
|
465
|
-
t.push(...e);
|
|
466
|
-
}
|
|
467
|
-
return t;
|
|
451
|
+
for (let r of e) o(r) ? (n.length > 0 && (t.push(...c(n)), n = []), t.push(r)) : n.push(r);
|
|
452
|
+
return n.length > 0 && t.push(...c(n)), t;
|
|
468
453
|
}, f = (e) => {
|
|
469
454
|
if (e.length <= 1) return e;
|
|
470
455
|
let t = e.filter((e) => !o(e) && s(e)), n = e.filter((e) => !t.includes(e));
|
|
471
456
|
return [...c(t), ...n];
|
|
472
|
-
}, p = (e, t) => {
|
|
473
|
-
if (
|
|
474
|
-
|
|
475
|
-
return !1;
|
|
476
|
-
}, m = (e) => `{ ${e.map((e) => t.getText(e)).join(", ")} }`, h = (e) => e.map((e) => t.getText(e)).join("\n"), g = (n, r) => {
|
|
477
|
-
let { properties: i } = n;
|
|
478
|
-
if (!i || i.length <= 1) return;
|
|
479
|
-
let a = d(i);
|
|
480
|
-
if (!p(i, a)) return;
|
|
481
|
-
let o = i[0], s = i.at(-1), c = o.range[0], l = s.range[1];
|
|
457
|
+
}, p = (e, t) => e.length !== t.length || e.some((e, n) => e !== t[n]), m = (e) => `{ ${e.map((e) => t.getText(e)).join(", ")} }`, h = (e) => e.map((e) => t.getText(e)).join("\n"), g = (t, n, r, i, a) => {
|
|
458
|
+
if (!p(n, r)) return;
|
|
459
|
+
let o = n[0], s = n.at(-1);
|
|
482
460
|
e.report({
|
|
483
|
-
node:
|
|
484
|
-
messageId:
|
|
461
|
+
node: t,
|
|
462
|
+
messageId: i,
|
|
485
463
|
fix(e) {
|
|
486
|
-
let
|
|
487
|
-
return e.replaceTextRange([
|
|
464
|
+
let t = a(r);
|
|
465
|
+
return e.replaceTextRange([o.range[0], s.range[1]], t);
|
|
488
466
|
}
|
|
489
467
|
});
|
|
490
|
-
}, _ = (e) => {
|
|
491
|
-
let {
|
|
492
|
-
if (
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
let
|
|
497
|
-
if (!
|
|
498
|
-
let
|
|
468
|
+
}, _ = (e, n) => {
|
|
469
|
+
let { properties: r } = e;
|
|
470
|
+
if (!r || r.length <= 1) return;
|
|
471
|
+
let i = d(r);
|
|
472
|
+
g(e, r, i, n, (e) => e.map((e) => t.getText(e)).join(", "));
|
|
473
|
+
}, v = (n) => {
|
|
474
|
+
let { params: a } = n;
|
|
475
|
+
if (!a || a.length === 0) return;
|
|
476
|
+
for (let e of a) e.type === "ObjectPattern" && _(e, "wrongParams");
|
|
477
|
+
if (a.length <= 1 || a.some((e) => e.type !== "Identifier")) return;
|
|
478
|
+
let o = (e) => {
|
|
479
|
+
let t = l.indexOf(e);
|
|
480
|
+
return t === -1 ? r(e) ? {
|
|
481
|
+
category: 2,
|
|
482
|
+
priority: i(e)
|
|
483
|
+
} : e === "className" ? {
|
|
484
|
+
category: 3,
|
|
485
|
+
priority: 0
|
|
486
|
+
} : {
|
|
487
|
+
category: e === "style" ? 4 : 1,
|
|
488
|
+
priority: 0
|
|
489
|
+
} : {
|
|
490
|
+
category: 0,
|
|
491
|
+
priority: t
|
|
492
|
+
};
|
|
493
|
+
}, s = a.map((e, t) => ({
|
|
494
|
+
param: e,
|
|
495
|
+
index: t,
|
|
496
|
+
...o(e.name)
|
|
497
|
+
})).sort((e, t) => e.category === t.category ? e.priority === t.priority ? e.index - t.index : e.priority - t.priority : e.category - t.category).map(({ param: e }) => e);
|
|
498
|
+
if (!p(a, s)) return;
|
|
499
|
+
let c = a[0], u = a.at(-1);
|
|
499
500
|
e.report({
|
|
500
|
-
node:
|
|
501
|
-
messageId: "
|
|
501
|
+
node: n,
|
|
502
|
+
messageId: "wrongParams",
|
|
502
503
|
fix(e) {
|
|
503
|
-
let
|
|
504
|
-
return e.replaceTextRange([
|
|
504
|
+
let n = s.map((e) => t.getText(e)).join(", ");
|
|
505
|
+
return e.replaceTextRange([c.range[0], u.range[1]], n);
|
|
505
506
|
}
|
|
506
507
|
});
|
|
508
|
+
}, y = (e) => {
|
|
509
|
+
let t = e.body ?? e.members;
|
|
510
|
+
if (!t || t.length <= 1) return;
|
|
511
|
+
let n = f(t);
|
|
512
|
+
g(e, t, n, "wrongTypeProperties", h);
|
|
507
513
|
};
|
|
508
514
|
return {
|
|
509
515
|
ObjectExpression(t) {
|
|
@@ -514,26 +520,23 @@ var e = {
|
|
|
514
520
|
node: t,
|
|
515
521
|
messageId: "wrongOrder",
|
|
516
522
|
fix(e) {
|
|
517
|
-
|
|
518
|
-
return e.replaceText(t, n);
|
|
523
|
+
return e.replaceText(t, m(r));
|
|
519
524
|
}
|
|
520
525
|
});
|
|
521
526
|
},
|
|
522
527
|
ObjectPattern(e) {
|
|
523
|
-
|
|
524
|
-
},
|
|
525
|
-
TSTypeLiteral(e) {
|
|
526
|
-
v(e);
|
|
527
|
-
},
|
|
528
|
-
TSInterfaceBody(e) {
|
|
529
|
-
v(e);
|
|
530
|
-
},
|
|
531
|
-
TSTypeAliasDeclaration(e) {
|
|
532
|
-
e.typeAnnotation?.type === "TSTypeLiteral" && v(e.typeAnnotation);
|
|
528
|
+
_(e, "wrongDestructure");
|
|
533
529
|
},
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
530
|
+
TSTypeLiteral: y,
|
|
531
|
+
TSInterfaceBody: y,
|
|
532
|
+
FunctionDeclaration: v,
|
|
533
|
+
FunctionExpression: v,
|
|
534
|
+
ArrowFunctionExpression: v,
|
|
535
|
+
TSDeclareFunction: v,
|
|
536
|
+
TSFunctionType: v,
|
|
537
|
+
TSCallSignatureDeclaration: v,
|
|
538
|
+
TSConstructSignatureDeclaration: v,
|
|
539
|
+
TSMethodSignature: v
|
|
537
540
|
};
|
|
538
541
|
}
|
|
539
542
|
}
|
package/package.json
CHANGED
|
@@ -1,11 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sabzidev/eslint-rules",
|
|
3
3
|
"description": "A collection of ESLint rules for better code quality, consistency, and maintainability.",
|
|
4
|
-
"repository": {
|
|
5
|
-
"type": "git",
|
|
6
|
-
"url": "https://github.com/SabziDev/eslint-rules"
|
|
7
|
-
},
|
|
8
|
-
"license": "MIT",
|
|
9
4
|
"keywords": [
|
|
10
5
|
"SabziDev",
|
|
11
6
|
"eslint",
|
|
@@ -16,8 +11,13 @@
|
|
|
16
11
|
"linting",
|
|
17
12
|
"developer-tools"
|
|
18
13
|
],
|
|
14
|
+
"repository": {
|
|
15
|
+
"type": "git",
|
|
16
|
+
"url": "https://github.com/SabziDev/eslint-rules"
|
|
17
|
+
},
|
|
18
|
+
"license": "MIT",
|
|
19
19
|
"author": "Abolfazl Sabzmohammadi <SabziDev@gmail.com> (https://Sabzi.Dev)",
|
|
20
|
-
"version": "1.0.
|
|
20
|
+
"version": "1.0.7",
|
|
21
21
|
"type": "module",
|
|
22
22
|
"main": "./dist/index.js",
|
|
23
23
|
"exports": "./dist/index.js",
|