@ethang/eslint-config 19.0.7 → 19.0.9
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/.github/dependabot.yml +13 -13
- package/README.md +82 -83
- package/build/update-readme.js +152 -0
- package/build/update-rules.js +70 -0
- package/build.mjs +7 -0
- package/config.react.js +1 -4
- package/eslint.config.js +683 -119
- package/package.json +12 -11
- package/setup/a11y.js +25 -0
- package/setup/barrel.js +9 -0
- package/setup/compat.js +10 -0
- package/setup/depend.js +11 -0
- package/setup/eslint.js +72 -0
- package/setup/gen-rules.js +34 -0
- package/setup/lodash.js +19 -0
- package/setup/n.js +31 -0
- package/setup/perfectionist.js +78 -0
- package/setup/sonar.js +61 -0
- package/setup/stylistic.js +62 -0
- package/setup/tailwind.js +8 -0
- package/setup/tanstack-query.js +7 -0
- package/setup/typescript-eslint.js +124 -0
- package/setup/unicorn.js +32 -0
- package/tsconfig.json +6 -3
package/.github/dependabot.yml
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
version: 2
|
|
2
|
-
updates:
|
|
3
|
-
- package-ecosystem: "github-actions"
|
|
4
|
-
directory: /
|
|
5
|
-
schedule:
|
|
6
|
-
interval: daily
|
|
7
|
-
target-branch: "master"
|
|
8
|
-
|
|
9
|
-
- package-ecosystem: npm
|
|
10
|
-
directory: /
|
|
11
|
-
schedule:
|
|
12
|
-
interval: daily
|
|
13
|
-
target-branch: "master"
|
|
1
|
+
version: 2
|
|
2
|
+
updates:
|
|
3
|
+
- package-ecosystem: "github-actions"
|
|
4
|
+
directory: /
|
|
5
|
+
schedule:
|
|
6
|
+
interval: daily
|
|
7
|
+
target-branch: "master"
|
|
8
|
+
|
|
9
|
+
- package-ecosystem: npm
|
|
10
|
+
directory: /
|
|
11
|
+
schedule:
|
|
12
|
+
interval: daily
|
|
13
|
+
target-branch: "master"
|
package/README.md
CHANGED
|
@@ -1,83 +1,82 @@
|
|
|
1
|
-
# Opinionated, Strict, Brutal, Unforgiving
|
|
2
|
-
|
|
3
|
-
[View Config](https://eslint-config-ethang.pages.dev/rules)
|
|
4
|
-
|
|
5
|
-
Do **NOT** use this with Prettier! Styling rules are included.
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
import
|
|
48
|
-
import
|
|
49
|
-
import
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
"
|
|
69
|
-
"lint": "eslint",
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
"
|
|
80
|
-
"
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
```
|
|
1
|
+
# Opinionated, Strict, Brutal, Unforgiving
|
|
2
|
+
|
|
3
|
+
[View Config](https://eslint-config-ethang.pages.dev/rules)
|
|
4
|
+
|
|
5
|
+
Do **NOT** use this with Prettier! Styling rules are included.
|
|
6
|
+
|
|
7
|
+
- 873 errored rules.
|
|
8
|
+
- 289 rules from [eslint-plugin-sonarjs](https://github.com/SonarSource/SonarJS/blob/master/packages/jsts/src/rules/README.md)
|
|
9
|
+
- 144 rules from [@eslint/js](https://github.com/eslint/eslint/tree/main/packages/js)
|
|
10
|
+
- 113 rules from [sindresorhus/eslint-plugin-unicorn](https://github.com/sindresorhus/eslint-plugin-unicorn)
|
|
11
|
+
- 103 rules from [@typescript/eslint](https://github.com/typescript-eslint/typescript-eslint)
|
|
12
|
+
- 91 rules from [@stylistic/eslint-plugin](https://eslint.style/)
|
|
13
|
+
- 42 rules from [eslint-plugin-lodash](https://github.com/wix-incubator/eslint-plugin-lodash)
|
|
14
|
+
- 35 rules from [jsx-a11y](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y)
|
|
15
|
+
- 20 rules from [eslint-plugin-n](https://github.com/eslint-community/eslint-plugin-n)
|
|
16
|
+
- 19 rules from [eslint-plugin-perfectionist](https://github.com/azat-io/eslint-plugin-perfectionist)
|
|
17
|
+
- 7 rules from [eslint-plugin-tailwindcss](https://github.com/francoismassart/eslint-plugin-tailwindcss)
|
|
18
|
+
- 4 rules from [eslint-plugin-barrel-files](https://github.com/thepassle/eslint-plugin-barrel-files)
|
|
19
|
+
- 4 rules from [@tanstack/eslint-plugin-query](https://tanstack.com/query/latest/docs/eslint/eslint-plugin-query)
|
|
20
|
+
- 1 rule from [eslint-plugin-depend](https://github.com/es-tooling/eslint-plugin-depend/tree/main)
|
|
21
|
+
- 1 rule from [eslint-plugin-compat](https://github.com/amilajack/eslint-plugin-compat)
|
|
22
|
+
|
|
23
|
+
# Add Even More!
|
|
24
|
+
|
|
25
|
+
- 51 rules for **Astro**
|
|
26
|
+
- `import astroConfig from "@ethang/eslint-config/config.astro.js";`
|
|
27
|
+
- 51 rules from [eslint-plugin-astro](https://github.com/ota-meshi/eslint-plugin-astro)
|
|
28
|
+
- 68 rules for **React**
|
|
29
|
+
- `import reactConfig from "@ethang/eslint-config/config.react.js";`
|
|
30
|
+
- 68 rules from [@eslint-react/eslint-plugin](https://eslint-react.xyz/)
|
|
31
|
+
- 18 rules for **Solid**
|
|
32
|
+
- `import solidConfig from "@ethang/eslint-config/config.solid.js";`
|
|
33
|
+
- 18 rules from [eslint-plugin-solid](https://github.com/solidjs-community/eslint-plugin-solid)
|
|
34
|
+
|
|
35
|
+
# Install
|
|
36
|
+
|
|
37
|
+
`pnpm i -D eslint typescript-eslint @ethang/eslint-config`
|
|
38
|
+
|
|
39
|
+
**Requires TypesScript and tsconfig.json at root directory.**
|
|
40
|
+
|
|
41
|
+
# Config
|
|
42
|
+
|
|
43
|
+
In **eslint.config.js**
|
|
44
|
+
|
|
45
|
+
```js
|
|
46
|
+
import config from "@ethang/eslint-config/eslint.config.js";
|
|
47
|
+
import tseslint from "typescript-eslint";
|
|
48
|
+
import astroConfig from "@ethang/eslint-config/config.astro.js"; // OPTIONAL
|
|
49
|
+
import reactConfig from "@ethang/eslint-config/config.react.js"; // OPTIONAL
|
|
50
|
+
|
|
51
|
+
export default tseslint.config(...config, ...astroConfig, ...reactConfig, {
|
|
52
|
+
languageOptions: {
|
|
53
|
+
parserOptions: {
|
|
54
|
+
project: true,
|
|
55
|
+
tsconfigRootDir: import.meta.dirname,
|
|
56
|
+
},
|
|
57
|
+
},
|
|
58
|
+
rules: {
|
|
59
|
+
// your custom rules here
|
|
60
|
+
},
|
|
61
|
+
});
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
**Scripts**:
|
|
65
|
+
|
|
66
|
+
```json
|
|
67
|
+
"scripts": {
|
|
68
|
+
"lint": "eslint",
|
|
69
|
+
"lint:fix": "eslint . --fix",
|
|
70
|
+
}
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
**Browserslist**
|
|
74
|
+
|
|
75
|
+
This config will also lint for browserslist features. Make sure to set this in package.json. [More info.](https://github.com/browserslist/browserslist)
|
|
76
|
+
|
|
77
|
+
```json
|
|
78
|
+
"browserslist": [
|
|
79
|
+
"defaults and fully supports es6-module",
|
|
80
|
+
"maintained node versions"
|
|
81
|
+
]
|
|
82
|
+
```
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
import { dependRules } from "../setup/depend.js";
|
|
2
|
+
import { barrelRules } from "../setup/barrel.js";
|
|
3
|
+
import { compatRules } from "../setup/compat.js";
|
|
4
|
+
import { eslintRules } from "../setup/eslint.js";
|
|
5
|
+
import { nRules } from "../setup/n.js";
|
|
6
|
+
import { typescriptRules } from "../setup/typescript-eslint.js";
|
|
7
|
+
import { unicornRules } from "../setup/unicorn.js";
|
|
8
|
+
import { lodashRules } from "../setup/lodash.js";
|
|
9
|
+
import { sonarRules } from "../setup/sonar.js";
|
|
10
|
+
import { tanstackQueryRules } from "../setup/tanstack-query.js";
|
|
11
|
+
import { tailwindRules } from "../setup/tailwind.js";
|
|
12
|
+
import { stylisticRules } from "../setup/stylistic.js";
|
|
13
|
+
import { perfectionistRules } from "../setup/perfectionist.js";
|
|
14
|
+
import { a11yRules } from "../setup/a11y.js";
|
|
15
|
+
import { readFileSync, writeFileSync } from "node:fs";
|
|
16
|
+
import { join } from "node:path";
|
|
17
|
+
|
|
18
|
+
export const updateReadme = () => {
|
|
19
|
+
const getRuleCount = (rules) => {
|
|
20
|
+
let count = 0;
|
|
21
|
+
Object.values(rules).forEach((value) => {
|
|
22
|
+
if (value === "error" || (Array.isArray(value) && value[0] === "error")) {
|
|
23
|
+
count += 1;
|
|
24
|
+
}
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
return count;
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
const ruleList = [
|
|
31
|
+
{
|
|
32
|
+
list: dependRules,
|
|
33
|
+
name: "eslint-plugin-depend",
|
|
34
|
+
url: "https://github.com/es-tooling/eslint-plugin-depend/tree/main",
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
list: barrelRules,
|
|
38
|
+
name: "eslint-plugin-barrel-files",
|
|
39
|
+
url: "https://github.com/thepassle/eslint-plugin-barrel-files",
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
list: compatRules,
|
|
43
|
+
name: "eslint-plugin-compat",
|
|
44
|
+
url: "https://github.com/amilajack/eslint-plugin-compat",
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
list: eslintRules,
|
|
48
|
+
name: "@eslint/js",
|
|
49
|
+
url: "https://github.com/eslint/eslint/tree/main/packages/js",
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
list: nRules,
|
|
53
|
+
name: "eslint-plugin-n",
|
|
54
|
+
url: "https://github.com/eslint-community/eslint-plugin-n",
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
list: typescriptRules,
|
|
58
|
+
name: "@typescript/eslint",
|
|
59
|
+
url: "https://github.com/typescript-eslint/typescript-eslint",
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
list: unicornRules,
|
|
63
|
+
name: "sindresorhus/eslint-plugin-unicorn",
|
|
64
|
+
url: "https://github.com/sindresorhus/eslint-plugin-unicorn",
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
list: lodashRules,
|
|
68
|
+
name: "eslint-plugin-lodash",
|
|
69
|
+
url: "https://github.com/wix-incubator/eslint-plugin-lodash",
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
list: sonarRules,
|
|
73
|
+
name: "eslint-plugin-sonarjs",
|
|
74
|
+
url: "https://github.com/SonarSource/SonarJS/blob/master/packages/jsts/src/rules/README.md",
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
list: tanstackQueryRules,
|
|
78
|
+
name: "@tanstack/eslint-plugin-query",
|
|
79
|
+
url: "https://tanstack.com/query/latest/docs/eslint/eslint-plugin-query",
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
list: tailwindRules,
|
|
83
|
+
name: "eslint-plugin-tailwindcss",
|
|
84
|
+
url: "https://github.com/francoismassart/eslint-plugin-tailwindcss",
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
list: stylisticRules,
|
|
88
|
+
name: "@stylistic/eslint-plugin",
|
|
89
|
+
url: "https://eslint.style/",
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
list: perfectionistRules,
|
|
93
|
+
name: "eslint-plugin-perfectionist",
|
|
94
|
+
url: "https://github.com/azat-io/eslint-plugin-perfectionist",
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
list: a11yRules,
|
|
98
|
+
name: "jsx-a11y",
|
|
99
|
+
url: "https://github.com/jsx-eslint/eslint-plugin-jsx-a11y",
|
|
100
|
+
},
|
|
101
|
+
];
|
|
102
|
+
|
|
103
|
+
let total = 0;
|
|
104
|
+
for (const list of ruleList) {
|
|
105
|
+
const count = getRuleCount(list.list);
|
|
106
|
+
total += count;
|
|
107
|
+
list["count"] = count;
|
|
108
|
+
}
|
|
109
|
+
ruleList.sort((a, b) => {
|
|
110
|
+
return b.count - a.count;
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
const ruleDocs = [`- ${total} errored rules.`];
|
|
114
|
+
for (const list of ruleList) {
|
|
115
|
+
ruleDocs.push(
|
|
116
|
+
`- ${list.count} ${list.count <= 1 ? "rule" : "rules"} from [${list.name}](${list.url})`,
|
|
117
|
+
);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
const readme = readFileSync(
|
|
121
|
+
join(import.meta.dirname, "../README.md"),
|
|
122
|
+
"utf8",
|
|
123
|
+
);
|
|
124
|
+
let readmeLines = readme.split("\n");
|
|
125
|
+
|
|
126
|
+
let start = 0;
|
|
127
|
+
let end = 0;
|
|
128
|
+
for (let index = 1; index < readmeLines.length; index++) {
|
|
129
|
+
if (
|
|
130
|
+
readmeLines[index] ===
|
|
131
|
+
"Do **NOT** use this with Prettier! Styling rules are included."
|
|
132
|
+
) {
|
|
133
|
+
start = index;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
if (readmeLines[index] === "# Add Even More!") {
|
|
137
|
+
end = index;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
if (start !== 0 && end !== 0) {
|
|
141
|
+
break;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
readmeLines = [
|
|
146
|
+
...readmeLines.splice(0, start + 2),
|
|
147
|
+
...ruleDocs,
|
|
148
|
+
...readmeLines.splice(end - 7),
|
|
149
|
+
].join("\n");
|
|
150
|
+
|
|
151
|
+
writeFileSync(join(import.meta.dirname, "../README.md"), readmeLines, "utf8");
|
|
152
|
+
};
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { dependRules } from "../setup/depend.js";
|
|
2
|
+
import { barrelRules } from "../setup/barrel.js";
|
|
3
|
+
import { compatRules } from "../setup/compat.js";
|
|
4
|
+
import { eslintRules } from "../setup/eslint.js";
|
|
5
|
+
import { nRules } from "../setup/n.js";
|
|
6
|
+
import { typescriptRules } from "../setup/typescript-eslint.js";
|
|
7
|
+
import { unicornRules } from "../setup/unicorn.js";
|
|
8
|
+
import { lodashRules } from "../setup/lodash.js";
|
|
9
|
+
import { sonarRules } from "../setup/sonar.js";
|
|
10
|
+
import { tanstackQueryRules } from "../setup/tanstack-query.js";
|
|
11
|
+
import { tailwindRules } from "../setup/tailwind.js";
|
|
12
|
+
import { stylisticRules } from "../setup/stylistic.js";
|
|
13
|
+
import { perfectionistRules } from "../setup/perfectionist.js";
|
|
14
|
+
import { a11yRules } from "../setup/a11y.js";
|
|
15
|
+
import { readFileSync, writeFileSync } from "node:fs";
|
|
16
|
+
import { join } from "node:path";
|
|
17
|
+
|
|
18
|
+
export const updateRules = () => {
|
|
19
|
+
const rules = {
|
|
20
|
+
...dependRules,
|
|
21
|
+
...barrelRules,
|
|
22
|
+
...compatRules,
|
|
23
|
+
...eslintRules,
|
|
24
|
+
...nRules,
|
|
25
|
+
...typescriptRules,
|
|
26
|
+
...unicornRules,
|
|
27
|
+
...lodashRules,
|
|
28
|
+
...sonarRules,
|
|
29
|
+
...tanstackQueryRules,
|
|
30
|
+
...tailwindRules,
|
|
31
|
+
...stylisticRules,
|
|
32
|
+
...perfectionistRules,
|
|
33
|
+
...a11yRules,
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
let jsonified = JSON.stringify(rules);
|
|
37
|
+
jsonified = jsonified.slice(1, -1);
|
|
38
|
+
|
|
39
|
+
const config = readFileSync(
|
|
40
|
+
join(import.meta.dirname, "../eslint.config.js"),
|
|
41
|
+
"utf8",
|
|
42
|
+
);
|
|
43
|
+
const lines = config.split("\n");
|
|
44
|
+
|
|
45
|
+
let rulesStart = 0;
|
|
46
|
+
let rulesEnd = 0;
|
|
47
|
+
for (let index = 1; index < lines.length; index++) {
|
|
48
|
+
if (lines[index].endsWith("rules: {")) {
|
|
49
|
+
rulesStart = index;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
if (0 !== rulesStart && lines[index].endsWith("},")) {
|
|
53
|
+
rulesEnd = index;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
const updated = [
|
|
58
|
+
...lines.slice(0, rulesStart),
|
|
59
|
+
"rules: {",
|
|
60
|
+
jsonified,
|
|
61
|
+
"},",
|
|
62
|
+
...lines.slice(rulesEnd + 1),
|
|
63
|
+
].join("\n");
|
|
64
|
+
|
|
65
|
+
writeFileSync(
|
|
66
|
+
join(import.meta.dirname, "../eslint.config.js"),
|
|
67
|
+
updated,
|
|
68
|
+
"utf8",
|
|
69
|
+
);
|
|
70
|
+
};
|
package/build.mjs
CHANGED
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
// @ts-check
|
|
2
2
|
import { projectBuilder } from "@ethang/project-builder/project-builder.js";
|
|
3
|
+
import { updateRules } from "./build/update-rules.js";
|
|
4
|
+
import { updateReadme } from "./build/update-readme.js";
|
|
5
|
+
import { execSync } from "node:child_process";
|
|
6
|
+
|
|
7
|
+
updateRules();
|
|
8
|
+
updateReadme();
|
|
9
|
+
execSync("pnpm lint");
|
|
3
10
|
|
|
4
11
|
await projectBuilder("eslint-config-ethang", "master", {
|
|
5
12
|
isLibrary: true,
|
package/config.react.js
CHANGED
|
@@ -35,10 +35,7 @@ export default tseslint.config({
|
|
|
35
35
|
"react/hooks-extra/no-direct-set-state-in-use-layout-effect": "error",
|
|
36
36
|
"react/hooks-extra/prefer-use-state-lazy-initialization": "error",
|
|
37
37
|
"react/naming-convention/component-name": "error",
|
|
38
|
-
"react/naming-convention/filename": [
|
|
39
|
-
"error",
|
|
40
|
-
{ rule: "kebab-case" },
|
|
41
|
-
],
|
|
38
|
+
"react/naming-convention/filename": ["error", { rule: "kebab-case" }],
|
|
42
39
|
"react/naming-convention/filename-extension": "error",
|
|
43
40
|
"react/naming-convention/use-state": "error",
|
|
44
41
|
"react/no-access-state-in-setstate": "error",
|