@ethang/eslint-config 19.0.11 → 19.1.1

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 CHANGED
@@ -2,9 +2,10 @@
2
2
 
3
3
  [View Config](https://eslint-config-ethang.pages.dev/rules)
4
4
 
5
- Do **NOT** use this with Prettier! Styling rules are included.
5
+ > [!CAUTION]
6
+ > Do not use this with Prettier! Styling rules are included.
6
7
 
7
- - 873 errored rules.
8
+ - 882 errored rules.
8
9
  - 289 rules from [eslint-plugin-sonarjs](https://github.com/SonarSource/SonarJS/blob/master/packages/jsts/src/rules/README.md)
9
10
  - 144 rules from [@eslint/js](https://github.com/eslint/eslint/tree/main/packages/js)
10
11
  - 113 rules from [sindresorhus/eslint-plugin-unicorn](https://github.com/sindresorhus/eslint-plugin-unicorn)
@@ -15,8 +16,10 @@ Do **NOT** use this with Prettier! Styling rules are included.
15
16
  - 20 rules from [eslint-plugin-n](https://github.com/eslint-community/eslint-plugin-n)
16
17
  - 19 rules from [eslint-plugin-perfectionist](https://github.com/azat-io/eslint-plugin-perfectionist)
17
18
  - 7 rules from [eslint-plugin-tailwindcss](https://github.com/francoismassart/eslint-plugin-tailwindcss)
19
+ - 7 rules from [@eslint/markdown](https://github.com/eslint/markdown)
18
20
  - 4 rules from [eslint-plugin-barrel-files](https://github.com/thepassle/eslint-plugin-barrel-files)
19
21
  - 4 rules from [@tanstack/eslint-plugin-query](https://tanstack.com/query/latest/docs/eslint/eslint-plugin-query)
22
+ - 2 rules from [@eslint/json](https://github.com/eslint/json)
20
23
  - 1 rule from [eslint-plugin-depend](https://github.com/es-tooling/eslint-plugin-depend/tree/main)
21
24
  - 1 rule from [eslint-plugin-compat](https://github.com/amilajack/eslint-plugin-compat)
22
25
 
@@ -61,7 +64,7 @@ export default tseslint.config(...config, ...astroConfig, ...reactConfig, {
61
64
  });
62
65
  ```
63
66
 
64
- **Scripts**:
67
+ **Scripts**
65
68
 
66
69
  ```json
67
70
  "scripts": {
@@ -0,0 +1,39 @@
1
+ import { writeFileSync } from "node:fs";
2
+ import { join } from "node:path";
3
+ import { astroRules } from "../setup/astro.js";
4
+
5
+ export function updateAstroRules() {
6
+ let configFile = "";
7
+
8
+ const rulesJson = JSON.stringify(astroRules).slice(1, -1);
9
+
10
+ const importList = [
11
+ 'import astro from "eslint-plugin-astro";',
12
+ 'import tseslint from "typescript-eslint";',
13
+ 'import { languageOptions } from "./eslint.config.js";',
14
+ 'import { ignores } from "./constants.js";',
15
+ ].sort((a, b) => {
16
+ return a.localeCompare(b);
17
+ });
18
+
19
+ importList.forEach((item) => {
20
+ configFile += `${item}\n`;
21
+ });
22
+
23
+ configFile += `\nexport default tseslint.config({
24
+ files: ["**/*.{astro}"],
25
+ ignores,
26
+ languageOptions,
27
+ plugins: { astro },
28
+ rules: {
29
+ ${rulesJson}
30
+ },
31
+ });
32
+ `;
33
+
34
+ writeFileSync(
35
+ join(import.meta.dirname, "../config.astro.js"),
36
+ configFile,
37
+ "utf8",
38
+ );
39
+ }
@@ -0,0 +1,43 @@
1
+ import { reactRules } from "../setup/react.js";
2
+ import { writeFileSync } from "node:fs";
3
+ import { join } from "node:path";
4
+
5
+ export function updateReactRules() {
6
+ let configFile = "";
7
+
8
+ const rulesJson = JSON.stringify(reactRules).slice(1, -1);
9
+
10
+ const importList = [
11
+ 'import react from "@eslint-react/eslint-plugin";',
12
+ 'import reactHooks from "eslint-plugin-react-hooks";',
13
+ 'import tseslint from "typescript-eslint";',
14
+ 'import { languageOptions } from "./eslint.config.js";',
15
+ 'import { ignores } from "./constants.js";',
16
+ ].sort((a, b) => {
17
+ return a.localeCompare(b);
18
+ });
19
+
20
+ importList.forEach((item) => {
21
+ configFile += `${item}\n`;
22
+ });
23
+
24
+ configFile += `\nexport default tseslint.config({
25
+ files: ["**/*.{jsx,tsx}"],
26
+ ignores,
27
+ languageOptions,
28
+ plugins: {
29
+ react,
30
+ "react-hooks": reactHooks,
31
+ },
32
+ rules: {
33
+ ${rulesJson}
34
+ },
35
+ });
36
+ `;
37
+
38
+ writeFileSync(
39
+ join(import.meta.dirname, "../config.react.js"),
40
+ configFile,
41
+ "utf8",
42
+ );
43
+ }
@@ -12,10 +12,25 @@ import { tailwindRules } from "../setup/tailwind.js";
12
12
  import { stylisticRules } from "../setup/stylistic.js";
13
13
  import { perfectionistRules } from "../setup/perfectionist.js";
14
14
  import { a11yRules } from "../setup/a11y.js";
15
- import { readFileSync, writeFileSync } from "node:fs";
15
+ import { writeFileSync } from "node:fs";
16
16
  import { join } from "node:path";
17
+ import { MarkdownGenerator } from "@ethang/markdown-generator/markdown-generator.js";
18
+ import { markdownRules } from "../setup/markdown.js";
19
+ import { jsonRules } from "../setup/json.js";
20
+ import { astroRules } from "../setup/astro.js";
21
+ import { reactRules } from "../setup/react.js";
22
+ import { solidRules } from "../setup/solid.js";
17
23
 
18
24
  export const updateReadme = () => {
25
+ const md = new MarkdownGenerator();
26
+ md.header(1, "Opinionated, Strict, Brutal, Unforgiving", 2);
27
+ md.link("View Config", "https://eslint-config-ethang.pages.dev/rules", 2);
28
+ md.alert(
29
+ "CAUTION",
30
+ "Do not use this with Prettier! Styling rules are included.",
31
+ 2,
32
+ );
33
+
19
34
  const getRuleCount = (rules) => {
20
35
  let count = 0;
21
36
  Object.values(rules).forEach((value) => {
@@ -98,6 +113,16 @@ export const updateReadme = () => {
98
113
  name: "jsx-a11y",
99
114
  url: "https://github.com/jsx-eslint/eslint-plugin-jsx-a11y",
100
115
  },
116
+ {
117
+ list: markdownRules,
118
+ name: "@eslint/markdown",
119
+ url: "https://github.com/eslint/markdown",
120
+ },
121
+ {
122
+ list: jsonRules,
123
+ name: "@eslint/json",
124
+ url: "https://github.com/eslint/json",
125
+ },
101
126
  ];
102
127
 
103
128
  let total = 0;
@@ -110,43 +135,84 @@ export const updateReadme = () => {
110
135
  return b.count - a.count;
111
136
  });
112
137
 
113
- const ruleDocs = [`- ${total} errored rules.`];
138
+ const ruleDocs = [`${total} errored rules.`];
114
139
  for (const list of ruleList) {
115
140
  ruleDocs.push(
116
- `- ${list.count} ${list.count <= 1 ? "rule" : "rules"} from [${list.name}](${list.url})`,
141
+ `${list.count} ${list.count <= 1 ? "rule" : "rules"} from [${list.name}](${list.url})`,
117
142
  );
118
143
  }
119
144
 
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
- }
145
+ const astroCount = getRuleCount(astroRules);
146
+ const reactCount = getRuleCount(reactRules);
147
+ const solidCount = getRuleCount(solidRules);
135
148
 
136
- if (readmeLines[index] === "# Add Even More!") {
137
- end = index;
138
- }
149
+ md.unorderedList(ruleDocs);
150
+ md.newLine();
151
+ md.header(1, "Add Even More!", 2);
152
+ md.unorderedList([
153
+ `${astroCount} rules for **Astro**`,
154
+ [
155
+ '`import astroConfig from "@ethang/eslint-config/config.astro.js";`',
156
+ `${astroCount} rules from [eslint-plugin-astro](https://github.com/ota-meshi/eslint-plugin-astro)`,
157
+ ],
158
+ `${reactCount} rules for **React**`,
159
+ [
160
+ '`import reactConfig from "@ethang/eslint-config/config.react.js";`',
161
+ `${reactCount} rules from [@eslint-react/eslint-plugin](https://eslint-react.xyz/)`,
162
+ ],
163
+ `${solidCount} rules for **Solid**`,
164
+ [
165
+ '`import solidConfig from "@ethang/eslint-config/config.solid.js";`',
166
+ `${solidCount} rules from [eslint-plugin-solid](https://github.com/solidjs-community/eslint-plugin-solid)`,
167
+ ],
168
+ ]);
169
+ md.newLine();
170
+ md.header(1, "Install", 2);
171
+ md.inlineCode("pnpm i -D eslint typescript-eslint @ethang/eslint-config", 2);
172
+ md.bold("Requires TypesScript and tsconfig.json at root directory.", 2);
173
+ md.header(1, "Config", 2);
174
+ md.text("In **eslint.config.js**", 2);
175
+ md.codeBlock(
176
+ `import config from "@ethang/eslint-config/eslint.config.js";
177
+ import tseslint from "typescript-eslint";
178
+ import astroConfig from "@ethang/eslint-config/config.astro.js"; // OPTIONAL
179
+ import reactConfig from "@ethang/eslint-config/config.react.js"; // OPTIONAL
139
180
 
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");
181
+ export default tseslint.config(...config, ...astroConfig, ...reactConfig, {
182
+ languageOptions: {
183
+ parserOptions: {
184
+ project: true,
185
+ tsconfigRootDir: import.meta.dirname,
186
+ },
187
+ },
188
+ rules: {
189
+ // your custom rules here
190
+ },
191
+ });`,
192
+ "js",
193
+ 2,
194
+ );
195
+ md.bold("Scripts", 2);
196
+ md.codeBlock(
197
+ `"scripts": {
198
+ "lint": "eslint",
199
+ "lint:fix": "eslint . --fix",
200
+ }`,
201
+ "json",
202
+ 2,
203
+ );
204
+ md.bold("Browserslist", 2);
205
+ md.text(
206
+ "This config will also lint for browserslist features. Make sure to set this in package.json. [More info.](https://github.com/browserslist/browserslist)",
207
+ 2,
208
+ );
209
+ md.codeBlock(
210
+ `"browserslist": [
211
+ "defaults and fully supports es6-module",
212
+ "maintained node versions"
213
+ ]`,
214
+ "json",
215
+ );
150
216
 
151
- writeFileSync(join(import.meta.dirname, "../README.md"), readmeLines, "utf8");
217
+ writeFileSync(join(import.meta.dirname, "../README.md"), md.render(), "utf8");
152
218
  };
@@ -15,9 +15,13 @@ import { a11yRules } from "../setup/a11y.js";
15
15
  import { readFileSync, writeFileSync } from "node:fs";
16
16
  import { join } from "node:path";
17
17
  import { deprecatedRules } from "../setup/deprecated.js";
18
+ import { markdownRules } from "../setup/markdown.js";
19
+ import { jsonRules } from "../setup/json.js";
18
20
 
19
21
  export const updateRules = () => {
20
- const rules = {
22
+ let configFile = "";
23
+
24
+ const jsRules = {
21
25
  ...dependRules,
22
26
  ...barrelRules,
23
27
  ...compatRules,
@@ -35,38 +39,89 @@ export const updateRules = () => {
35
39
  ...deprecatedRules,
36
40
  };
37
41
 
38
- let jsonified = JSON.stringify(rules);
39
- jsonified = jsonified.slice(1, -1);
42
+ const jsRulesJon = JSON.stringify(jsRules).slice(1, -1);
43
+ const markdownRulesJson = JSON.stringify(markdownRules).slice(1, -1);
44
+ const jsonRulesJson = JSON.stringify(jsonRules).slice(1, -1);
40
45
 
41
- const config = readFileSync(
42
- join(import.meta.dirname, "../eslint.config.js"),
43
- "utf8",
44
- );
45
- const lines = config.split("\n");
46
+ const importList = [
47
+ 'import parser from "@typescript-eslint/parser";',
48
+ 'import a11y from "eslint-plugin-jsx-a11y/lib/index.js";',
49
+ 'import n from "eslint-plugin-n";',
50
+ 'import unicorn from "eslint-plugin-unicorn";',
51
+ 'import tseslint from "typescript-eslint";',
52
+ 'import sonar from "eslint-plugin-sonarjs";',
53
+ 'import tanstack from "@tanstack/eslint-plugin-query";',
54
+ 'import perfectionist from "eslint-plugin-perfectionist";',
55
+ 'import depend from "eslint-plugin-depend";',
56
+ 'import barrel from "eslint-plugin-barrel-files";',
57
+ 'import compat from "eslint-plugin-compat";',
58
+ 'import lodashConfig from "eslint-plugin-lodash";',
59
+ 'import tailwind from "eslint-plugin-tailwindcss";',
60
+ 'import stylistic from "@stylistic/eslint-plugin";',
61
+ 'import markdown from "@eslint/markdown";',
62
+ 'import json from "@eslint/json";',
63
+ 'import { ignores } from "./constants.js";',
64
+ ].sort((a, b) => {
65
+ return a.localeCompare(b);
66
+ });
46
67
 
47
- let rulesStart = 0;
48
- let rulesEnd = 0;
49
- for (let index = 1; index < lines.length; index++) {
50
- if (lines[index].endsWith("rules: {")) {
51
- rulesStart = index;
52
- }
68
+ importList.forEach((item) => {
69
+ configFile += `${item}\n`;
70
+ });
53
71
 
54
- if (0 !== rulesStart && lines[index].endsWith("},")) {
55
- rulesEnd = index;
56
- }
57
- }
72
+ configFile += `\nexport const languageOptions = {
73
+ parser,
74
+ parserOptions: {
75
+ project: true,
76
+ tsconfigRootDir: import.meta.dirname,
77
+ },
78
+ };
58
79
 
59
- const updated = [
60
- ...lines.slice(0, rulesStart),
61
- "rules: {",
62
- jsonified,
63
- "},",
64
- ...lines.slice(rulesEnd + 1),
65
- ].join("\n");
80
+ export default tseslint.config(
81
+ {
82
+ files: ["**/*.{js,ts,jsx,tsx,cjs,cts,mjs,mts}"],
83
+ ignores,
84
+ languageOptions,
85
+ plugins: {
86
+ "@tanstack/query": tanstack,
87
+ "@typescript-eslint": tseslint.plugin,
88
+ a11y,
89
+ barrel,
90
+ compat,
91
+ depend,
92
+ lodash: lodashConfig,
93
+ n,
94
+ perfectionist,
95
+ sonar,
96
+ stylistic,
97
+ tailwind,
98
+ unicorn,
99
+ },
100
+ rules: {
101
+ ${jsRulesJon}
102
+ },
103
+ },
104
+ {
105
+ files: ["**/*.md"],
106
+ plugins: {
107
+ markdown,
108
+ },
109
+ rules: {
110
+ ${markdownRulesJson}
111
+ },
112
+ },
113
+ {
114
+ files: ["**/*.{json,jsonc,json5}"],
115
+ plugins: { json },
116
+ rules: {
117
+ ${jsonRulesJson}
118
+ },
119
+ },
120
+ );\n`;
66
121
 
67
122
  writeFileSync(
68
123
  join(import.meta.dirname, "../eslint.config.js"),
69
- updated,
124
+ configFile,
70
125
  "utf8",
71
126
  );
72
127
  };
@@ -0,0 +1,39 @@
1
+ import { solidRules } from "../setup/solid.js";
2
+ import { writeFileSync } from "node:fs";
3
+ import { join } from "node:path";
4
+
5
+ export function updateSolidRules() {
6
+ let configFile = "";
7
+
8
+ const rulesJson = JSON.stringify(solidRules).slice(1, -1);
9
+
10
+ const importList = [
11
+ 'import solid from "eslint-plugin-solid";',
12
+ 'import tseslint from "typescript-eslint";',
13
+ 'import { languageOptions } from "./eslint.config.js";',
14
+ 'import { ignores } from "./constants.js";',
15
+ ].sort((a, b) => {
16
+ return a.localeCompare(b);
17
+ });
18
+
19
+ importList.forEach((item) => {
20
+ configFile += `${item}\n`;
21
+ });
22
+
23
+ configFile += `\nexport default tseslint.config({
24
+ files: ["**/*.{jsx,tsx}"],
25
+ ignores,
26
+ languageOptions,
27
+ plugins: { solid },
28
+ rules: {
29
+ ${rulesJson},
30
+ },
31
+ });
32
+ `;
33
+
34
+ writeFileSync(
35
+ join(import.meta.dirname, "../config.solid.js"),
36
+ configFile,
37
+ "utf8",
38
+ );
39
+ }
package/build.mjs CHANGED
@@ -3,8 +3,14 @@ import { projectBuilder } from "@ethang/project-builder/project-builder.js";
3
3
  import { updateRules } from "./build/update-rules.js";
4
4
  import { updateReadme } from "./build/update-readme.js";
5
5
  import { execSync } from "node:child_process";
6
+ import { updateReactRules } from "./build/update-react-rules.js";
7
+ import { updateSolidRules } from "./build/update-solid-rules.js";
8
+ import { updateAstroRules } from "./build/update-astro-rules.js";
6
9
 
7
10
  updateRules();
11
+ updateReactRules();
12
+ updateSolidRules();
13
+ updateAstroRules();
8
14
  updateReadme();
9
15
  execSync("pnpm lint");
10
16
 
package/config.astro.js CHANGED
@@ -1,16 +1,65 @@
1
+ import { ignores } from "./constants.js";
2
+ import { languageOptions } from "./eslint.config.js";
1
3
  import astro from "eslint-plugin-astro";
2
4
  import tseslint from "typescript-eslint";
3
5
 
4
- import { languageOptions } from "./eslint.config.js";
5
- import { ignores } from "./constants.js";
6
- import { astroRules } from "./setup/astro.js";
7
-
8
6
  export default tseslint.config({
9
7
  files: ["**/*.{astro}"],
10
8
  ignores,
11
9
  languageOptions,
12
10
  plugins: { astro },
13
11
  rules: {
14
- ...astroRules,
12
+ "astro/missing-client-only-directive-value": "error",
13
+ "astro/no-conflict-set-directives": "error",
14
+ "astro/no-deprecated-astro-canonicalurl": "error",
15
+ "astro/no-deprecated-astro-fetchcontent": "error",
16
+ "astro/no-deprecated-astro-resolve": "error",
17
+ "astro/no-deprecated-getentrybyslug": "error",
18
+ "astro/no-exports-from-components": "error",
19
+ "astro/no-set-html-directive": 'off"',
20
+ "astro/no-set-text-directive": "error",
21
+ "astro/no-unused-css-selector": "error",
22
+ "astro/no-unused-define-vars-in-style": "error",
23
+ "astro/prefer-class-list-directive": "error",
24
+ "astro/prefer-object-class-list": "error",
25
+ "astro/prefer-split-class-list": "error",
26
+ "astro/semi": "error",
27
+ "astro/valid-compile": "error",
28
+ "astro/jsx-a11y/alt-text": "error",
29
+ "astro/jsx-a11y/anchor-ambiguous-text": "error",
30
+ "astro/jsx-a11y/anchor-has-content": "error",
31
+ "astro/jsx-a11y/anchor-is-valid": "error",
32
+ "astro/jsx-a11y/aria-activedescendant-has-tabindex": "error",
33
+ "astro/jsx-a11y/aria-props": "error",
34
+ "astro/jsx-a11y/aria-proptypes": "error",
35
+ "astro/jsx-a11y/aria-role": "error",
36
+ "astro/jsx-a11y/aria-unsupported-elements": "error",
37
+ "astro/jsx-a11y/autocomplete-valid": "error",
38
+ "astro/jsx-a11y/click-events-have-key-events": "error",
39
+ "astro/jsx-a11y/control-has-associated-label": "error",
40
+ "astro/jsx-a11y/heading-has-content": "error",
41
+ "astro/jsx-a11y/html-has-lang": "error",
42
+ "astro/jsx-a11y/iframe-has-title": "error",
43
+ "astro/jsx-a11y/img-redundant-alt": "error",
44
+ "astro/jsx-a11y/interactive-supports-focus": "error",
45
+ "astro/jsx-a11y/label-has-associated-control": "error",
46
+ "astro/jsx-a11y/lang": "error",
47
+ "astro/jsx-a11y/media-has-caption": "error",
48
+ "astro/jsx-a11y/mouse-events-have-key-events": "error",
49
+ "astro/jsx-a11y/no-access-key": "error",
50
+ "astro/jsx-a11y/no-aria-hidden-on-focusable": "error",
51
+ "astro/jsx-a11y/no-autofocus": "error",
52
+ "astro/jsx-a11y/no-distracting-elements": "error",
53
+ "astro/jsx-a11y/no-interactive-element-to-noninteractive-role": "error",
54
+ "astro/jsx-a11y/no-noninteractive-element-interactions": "error",
55
+ "astro/jsx-a11y/no-noninteractive-element-to-interactive-role": "error",
56
+ "astro/jsx-a11y/no-noninteractive-tabindex": "error",
57
+ "astro/jsx-a11y/no-redundant-roles": "error",
58
+ "astro/jsx-a11y/no-static-element-interactions": "error",
59
+ "astro/jsx-a11y/prefer-tag-over-role": "error",
60
+ "astro/jsx-a11y/role-has-required-aria-props": "error",
61
+ "astro/jsx-a11y/role-supports-aria-props": "error",
62
+ "astro/jsx-a11y/scope": "error",
63
+ "astro/jsx-a11y/tabindex-no-positive": "error",
15
64
  },
16
65
  });
package/config.react.js CHANGED
@@ -1,11 +1,9 @@
1
+ import { ignores } from "./constants.js";
2
+ import { languageOptions } from "./eslint.config.js";
1
3
  import react from "@eslint-react/eslint-plugin";
2
4
  import reactHooks from "eslint-plugin-react-hooks";
3
5
  import tseslint from "typescript-eslint";
4
6
 
5
- import { languageOptions } from "./eslint.config.js";
6
- import { ignores } from "./constants.js";
7
- import { reactRules } from "./setup/react.js";
8
-
9
7
  export default tseslint.config({
10
8
  files: ["**/*.{jsx,tsx}"],
11
9
  ignores,
@@ -15,6 +13,81 @@ export default tseslint.config({
15
13
  "react-hooks": reactHooks,
16
14
  },
17
15
  rules: {
18
- ...reactRules,
16
+ "react-hooks/rules-of-hooks": "off",
17
+ "react-hooks/exhaustive-deps": "off",
18
+ "react/avoid-shorthand-boolean": "off",
19
+ "react/avoid-shorthand-fragment": "off",
20
+ "react/ensure-forward-ref-using-ref": "error",
21
+ "react/no-access-state-in-setstate": "error",
22
+ "react/no-array-index-key": "error",
23
+ "react/no-children-count": "error",
24
+ "react/no-children-for-each": "error",
25
+ "react/no-children-map": "error",
26
+ "react/no-children-only": "error",
27
+ "react/no-children-prop": "error",
28
+ "react/no-children-to-array": "error",
29
+ "react/no-class-component": "error",
30
+ "react/no-clone-element": "error",
31
+ "react/no-comment-textnodes": "error",
32
+ "react/no-complex-conditional-rendering": "error",
33
+ "react/no-complicated-conditional-rendering": "error",
34
+ "react/no-component-will-mount": "error",
35
+ "react/no-component-will-receive-props": "error",
36
+ "react/no-component-will-update": "error",
37
+ "react/no-create-ref": "error",
38
+ "react/no-default-props": "error",
39
+ "react/no-direct-mutation-state": "error",
40
+ "react/no-duplicate-key": "error",
41
+ "react/no-implicit-key": "error",
42
+ "react/no-leaked-conditional-rendering": "error",
43
+ "react/no-missing-component-display-name": "error",
44
+ "react/no-missing-key": "error",
45
+ "react/no-nested-components": "error",
46
+ "react/no-prop-types": "error",
47
+ "react/no-redundant-should-component-update": "error",
48
+ "react/no-set-state-in-component-did-mount": "error",
49
+ "react/no-set-state-in-component-did-update": "error",
50
+ "react/no-set-state-in-component-will-update": "error",
51
+ "react/no-string-refs": "error",
52
+ "react/no-unsafe-component-will-mount": "error",
53
+ "react/no-unsafe-component-will-receive-props": "error",
54
+ "react/no-unsafe-component-will-update": "error",
55
+ "react/no-unstable-context-value": "error",
56
+ "react/no-unstable-default-props": "error",
57
+ "react/no-unused-class-component-members": "error",
58
+ "react/no-unused-state": "error",
59
+ "react/no-useless-fragment": "error",
60
+ "react/prefer-destructuring-assignment": "error",
61
+ "react/prefer-read-only-props": "error",
62
+ "react/prefer-shorthand-boolean": "error",
63
+ "react/prefer-shorthand-fragment": "error",
64
+ "react/dom/no-children-in-void-dom-elements": "error",
65
+ "react/dom/no-dangerously-set-innerhtml": "error",
66
+ "react/dom/no-dangerously-set-innerhtml-with-children": "error",
67
+ "react/dom/no-find-dom-node": "error",
68
+ "react/dom/no-missing-button-type": "error",
69
+ "react/dom/no-missing-iframe-sandbox": "error",
70
+ "react/dom/no-namespace": "error",
71
+ "react/dom/no-render-return-value": "error",
72
+ "react/dom/no-script-url": "error",
73
+ "react/dom/no-unsafe-iframe-sandbox": "error",
74
+ "react/dom/no-unsafe-target-blank": "error",
75
+ "react/web-api/no-leaked-event-listener": "error",
76
+ "react/web-api/no-leaked-interval": "error",
77
+ "react/web-api/no-leaked-timeout": "error",
78
+ "react/hooks-extra/ensure-custom-hooks-using-other-hooks": "error",
79
+ "react/hooks-extra/ensure-use-callback-has-non-empty-deps": "error",
80
+ "react/hooks-extra/ensure-use-memo-has-non-empty-deps": "error",
81
+ "react/hooks-extra/no-direct-set-state-in-use-effect": "error",
82
+ "react/hooks-extra/no-direct-set-state-in-use-layout-effect": "error",
83
+ "react/hooks-extra/prefer-use-state-lazy-initialization": "error",
84
+ "react/naming-convention/component-name": "error",
85
+ "react/naming-convention/filename": ["error", { rule: "kebab-case" }],
86
+ "react/naming-convention/filename-extension": "error",
87
+ "react/naming-convention/use-state": "error",
88
+ "react/debug/class-component": "off",
89
+ "react/debug/function-component": "off",
90
+ "react/debug/is-from-react": "off",
91
+ "react/debug/react-hooks": "off",
19
92
  },
20
93
  });
package/config.solid.js CHANGED
@@ -1,16 +1,33 @@
1
+ import { ignores } from "./constants.js";
2
+ import { languageOptions } from "./eslint.config.js";
1
3
  import solid from "eslint-plugin-solid";
2
4
  import tseslint from "typescript-eslint";
3
5
 
4
- import { languageOptions } from "./eslint.config.js";
5
- import { ignores } from "./constants.js";
6
- import { solidRules } from "./setup/solid.js";
7
-
8
6
  export default tseslint.config({
9
7
  files: ["**/*.{jsx,tsx}"],
10
8
  ignores,
11
9
  languageOptions,
12
10
  plugins: { solid },
13
11
  rules: {
14
- ...solidRules,
12
+ "solid/components-return-once": "error",
13
+ "solid/event-handlers": "error",
14
+ "solid/imports": "error",
15
+ "solid/jsx-no-duplicate-props": "error",
16
+ "solid/jsx-no-undef": "error",
17
+ "solid/jsx-no-script-url": "error",
18
+ "solid/jsx-uses-vars": "error",
19
+ "solid/no-destructure": "error",
20
+ "solid/no-innerhtml": "error",
21
+ "solid/no-proxy-apis": "off",
22
+ "solid/no-react-deps": "error",
23
+ "solid/no-react-specific-props": "error",
24
+ "solid/no-unknown-namespaces": "error",
25
+ "solid/prefer-classlist": "off",
26
+ "solid/prefer-for": "error",
27
+ "solid/prefer-show": "error",
28
+ "solid/reactivity": "error",
29
+ "solid/self-closing-comp": "error",
30
+ "solid/style-prop": "error",
31
+ "solid/no-array-handlers": "error",
15
32
  },
16
33
  });