@ethang/eslint-config 21.2.4 → 21.4.0

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 (64) hide show
  1. package/build.ts +34 -0
  2. package/{README.md → dist/README.md} +2 -2
  3. package/dist/config.react.js +2 -0
  4. package/dist/config.react.js.map +1 -0
  5. package/dist/eslint.config.js +2 -0
  6. package/dist/package.json +68 -0
  7. package/eslint.config.js +26 -2
  8. package/package.json +7 -7
  9. package/src/README.md +100 -0
  10. package/src/build/create-config-file.ts +57 -0
  11. package/src/build/create-config.ts +96 -0
  12. package/src/build/get-react-version.ts +19 -0
  13. package/src/build/list-utilities.ts +124 -0
  14. package/src/build/rule-list.ts +284 -0
  15. package/src/build/update-readme.ts +195 -0
  16. package/src/build/update-rules.ts +124 -0
  17. package/src/config.angular.js +107 -0
  18. package/src/config.astro.js +68 -0
  19. package/src/config.react.js +117 -0
  20. package/src/config.solid.js +34 -0
  21. package/src/constants.js +16 -0
  22. package/src/eslint.config.js +1051 -0
  23. package/src/setup/a11y.ts +19 -0
  24. package/src/setup/angular.ts +40 -0
  25. package/src/setup/astro.ts +14 -0
  26. package/src/setup/barrel.ts +17 -0
  27. package/src/setup/compat.ts +13 -0
  28. package/src/setup/cspell.ts +83 -0
  29. package/src/setup/css.ts +12 -0
  30. package/src/setup/depend.ts +14 -0
  31. package/src/setup/eslint.ts +246 -0
  32. package/src/setup/gen-rules.ts +75 -0
  33. package/src/setup/json.ts +17 -0
  34. package/src/setup/lodash.ts +58 -0
  35. package/src/setup/markdown.ts +16 -0
  36. package/src/setup/n.ts +86 -0
  37. package/src/setup/perfectionist.ts +68 -0
  38. package/src/setup/react.ts +82 -0
  39. package/src/setup/solid.ts +21 -0
  40. package/src/setup/sonar.ts +39 -0
  41. package/src/setup/tailwind.ts +10 -0
  42. package/src/setup/tanstack-query.ts +9 -0
  43. package/src/setup/tanstack-router.ts +9 -0
  44. package/src/setup/typescript-eslint.ts +118 -0
  45. package/src/setup/unicorn.ts +38 -0
  46. package/tsconfig.json +5 -0
  47. package/config.react.js +0 -2
  48. package/config.react.js.map +0 -1
  49. /package/{chunk-WK3YS7OG.js → dist/chunk-WK3YS7OG.js} +0 -0
  50. /package/{chunk-WK3YS7OG.js.map → dist/chunk-WK3YS7OG.js.map} +0 -0
  51. /package/{config.angular.d.ts → dist/config.angular.d.ts} +0 -0
  52. /package/{config.angular.js → dist/config.angular.js} +0 -0
  53. /package/{config.angular.js.map → dist/config.angular.js.map} +0 -0
  54. /package/{config.astro.d.ts → dist/config.astro.d.ts} +0 -0
  55. /package/{config.astro.js → dist/config.astro.js} +0 -0
  56. /package/{config.astro.js.map → dist/config.astro.js.map} +0 -0
  57. /package/{config.react.d.ts → dist/config.react.d.ts} +0 -0
  58. /package/{config.solid.d.ts → dist/config.solid.d.ts} +0 -0
  59. /package/{config.solid.js → dist/config.solid.js} +0 -0
  60. /package/{config.solid.js.map → dist/config.solid.js.map} +0 -0
  61. /package/{constants.js → dist/constants.js} +0 -0
  62. /package/{constants.js.map → dist/constants.js.map} +0 -0
  63. /package/{eslint.config.d.ts → dist/eslint.config.d.ts} +0 -0
  64. /package/{eslint.config.js.map → dist/eslint.config.js.map} +0 -0
@@ -0,0 +1,195 @@
1
+ import { MarkdownGenerator } from "@ethang/markdown-generator/markdown-generator.js";
2
+ import filter from "lodash/filter.js";
3
+ import flow from "lodash/flow.js";
4
+ import isArray from "lodash/isArray.js";
5
+ import map from "lodash/map.js";
6
+ import values from "lodash/values.js";
7
+ import { writeFileSync } from "node:fs";
8
+ import path from "node:path";
9
+
10
+ import type { genRules } from "../setup/gen-rules.ts";
11
+
12
+ import { getList } from "./list-utilities.ts";
13
+
14
+ const getRuleCount = (rules: ReturnType<typeof genRules>) => {
15
+ let count = 0;
16
+ for (const value of values(rules)) {
17
+ if ("error" === value || (isArray(value) && "error" === value[0])) {
18
+ count += 1;
19
+ }
20
+ }
21
+
22
+ return count;
23
+ };
24
+
25
+ const getImports = flow(
26
+ (rules: ReturnType<typeof getList>) => {
27
+ return filter(rules, (rule) => {
28
+ return 0 < getRuleCount(rule.list);
29
+ });
30
+ },
31
+ (filteredRules) => {
32
+ return map(filteredRules, (rule) => {
33
+ return `${getRuleCount(rule.list)} rules from [${rule.name}](${rule.url})`;
34
+ });
35
+ },
36
+ );
37
+
38
+ export const updateReadme = () => {
39
+ const md = new MarkdownGenerator();
40
+ md.header(1, "Relentless. Unapologetic.", 2);
41
+ md.link("View Config", "https://eslint-config-ethang.pages.dev/rules", 2);
42
+ md.alert("CAUTION", "Prettier is already included for styling!", 2);
43
+
44
+ const coreRules = map(
45
+ [
46
+ ...getList("core"),
47
+ ...getList("json"),
48
+ ...getList("css"),
49
+ ...getList("markdown"),
50
+ ],
51
+ (rules) => {
52
+ return {
53
+ ...rules,
54
+ count: 0,
55
+ };
56
+ },
57
+ );
58
+
59
+ let total = 0;
60
+ for (const list of coreRules) {
61
+ const count = getRuleCount(list.list);
62
+ total += count;
63
+ list.count = count;
64
+ }
65
+ coreRules.sort((a, b) => {
66
+ return b.count - a.count;
67
+ });
68
+
69
+ const ruleDocumentation = [`${total} errored rules.`];
70
+ for (const list of coreRules) {
71
+ if (0 < list.count) {
72
+ ruleDocumentation.push(
73
+ `${list.count} ${
74
+ 1 >= list.count ? "rule" : "rules"
75
+ } from [${list.name}](${list.url})`,
76
+ );
77
+ }
78
+ }
79
+
80
+ const astroRules = getList("astro");
81
+ const reactRules = getList("react");
82
+ const solidRules = getList("solid");
83
+ const angularRules = getList("angular");
84
+ const angularTemplateRules = getList("angular:template");
85
+
86
+ let astroCount = 0;
87
+ for (const astroRule of astroRules) {
88
+ astroCount += getRuleCount(astroRule.list);
89
+ }
90
+
91
+ let reactCount = 0;
92
+ for (const reactRule of reactRules) {
93
+ reactCount += getRuleCount(reactRule.list);
94
+ }
95
+
96
+ let solidCount = 0;
97
+ for (const solidRule of solidRules) {
98
+ solidCount += getRuleCount(solidRule.list);
99
+ }
100
+
101
+ let angularCount = 0;
102
+ for (const angularRule of [...angularRules, ...angularTemplateRules]) {
103
+ angularCount += getRuleCount(angularRule.list);
104
+ }
105
+
106
+ md.unorderedList(ruleDocumentation);
107
+ md.newLine();
108
+ md.header(1, "Add Even More!", 2);
109
+ md.unorderedList([
110
+ `${angularCount} rules for **Angular**`,
111
+ [
112
+ '`import angularConfig from "@ethang/eslint-config/config.angular.js";`',
113
+ getImports(angularRules),
114
+ getImports(angularTemplateRules),
115
+ ],
116
+ `${astroCount} rules for **Astro**`,
117
+ [
118
+ '`import astroConfig from "@ethang/eslint-config/config.astro.js";`',
119
+ getImports(astroRules),
120
+ ],
121
+ `${reactCount} rules for **React**`,
122
+ [
123
+ '`import reactConfig from "@ethang/eslint-config/config.react.js";`',
124
+ getImports(reactRules),
125
+ ],
126
+ `${solidCount} rules for **Solid**`,
127
+ [
128
+ '`import solidConfig from "@ethang/eslint-config/config.solid.js";`',
129
+ getImports(solidRules),
130
+ ],
131
+ ]);
132
+ md.newLine();
133
+ md.header(1, "Install", 2);
134
+ md.inlineCode("pnpm i -D eslint typescript-eslint @ethang/eslint-config", 2);
135
+ md.bold("Requires TypesScript and tsconfig.json at root directory.", 2);
136
+ md.header(1, "Config", 2);
137
+ md.text("In **eslint.config.js**", 2);
138
+ md.codeBlock(
139
+ `import config from "@ethang/eslint-config/eslint.config.js";
140
+ import tseslint from "typescript-eslint";
141
+ import astroConfig from "@ethang/eslint-config/config.astro.js"; // OPTIONAL
142
+ import reactConfig from "@ethang/eslint-config/config.react.js"; // OPTIONAL
143
+
144
+ export default tseslint.config(
145
+ {
146
+ ignores: [], // Ignored files apply to all following configs
147
+ },
148
+ ...config,
149
+ ...astroConfig,
150
+ ...reactConfig,
151
+ {
152
+ languageOptions: {
153
+ parserOptions: {
154
+ project: true,
155
+ tsconfigRootDir: import.meta.dirname,
156
+ },
157
+ },
158
+ rules: {
159
+ // Override rules from above configs
160
+ },
161
+ }
162
+ );`,
163
+ "js",
164
+ 2,
165
+ );
166
+ md.bold("Scripts", 2);
167
+ md.codeBlock(
168
+ `"scripts": {
169
+ "lint": "eslint",
170
+ "lint:fix": "eslint . --fix",
171
+ }`,
172
+ "json",
173
+ 2,
174
+ );
175
+ md.bold("Browserslist", 2);
176
+ md.text(
177
+ "This config will also lint for browserslist features. Make sure to set this in package.json. [More info.](https://github.com/browserslist/browserslist)",
178
+ 2,
179
+ );
180
+ md.codeBlock(
181
+ `"browserslist": [
182
+ "defaults and fully supports es6-module",
183
+ "maintained node versions"
184
+ ]`,
185
+ "json",
186
+ );
187
+
188
+ writeFileSync(
189
+ path.join(import.meta.dirname, "../README.md"),
190
+ md.render(),
191
+ "utf8",
192
+ );
193
+ };
194
+
195
+ updateReadme();
@@ -0,0 +1,124 @@
1
+ import type { ConfigOptions } from "./create-config.ts";
2
+
3
+ import { createConfigFile } from "./create-config-file.ts";
4
+
5
+ export type ConfigFile = {
6
+ importString?: string;
7
+ label?: string;
8
+ name: string;
9
+ options?: ConfigOptions;
10
+ };
11
+
12
+ const importTsEslint = 'import tseslint from "typescript-eslint";';
13
+
14
+ export const coreFile = [
15
+ {
16
+ importString: 'import config from "@ethang/eslint-config/eslint.config.js',
17
+ label: "Core",
18
+ name: "core",
19
+ options: {
20
+ extraImports: [
21
+ 'import { fixupPluginRules } from "@eslint/compat";', // TODO remove with v9 compat
22
+ 'import eslintConfigPrettier from "eslint-config-prettier";',
23
+ 'import eslintPluginPrettierRecommended from "eslint-plugin-prettier/recommended";',
24
+ ],
25
+ includeIgnores: true,
26
+ includeLanguageOptions: true,
27
+ includeReactVersion: true,
28
+ },
29
+ },
30
+ {
31
+ name: "markdown",
32
+ },
33
+ {
34
+ name: "css",
35
+ },
36
+ {
37
+ name: "json",
38
+ },
39
+ {
40
+ name: "jsonc",
41
+ },
42
+ {
43
+ name: "json5",
44
+ },
45
+ ];
46
+
47
+ const astroFile = [
48
+ {
49
+ importString:
50
+ 'import astroConfig from "@ethang/eslint-config/config.astro.ts',
51
+ label: "Astro",
52
+ name: "astro",
53
+ options: {
54
+ extraImports: [importTsEslint],
55
+ includeIgnores: true,
56
+ includeLanguageOptions: true,
57
+ },
58
+ },
59
+ ];
60
+
61
+ const reactFile = [
62
+ {
63
+ importString:
64
+ 'import reactConfig from "@ethang/eslint-config/config.react.ts',
65
+ label: "React",
66
+ name: "react",
67
+ options: {
68
+ extraImports: [importTsEslint],
69
+ includeIgnores: true,
70
+ includeLanguageOptions: true,
71
+ includeReactVersion: true,
72
+ },
73
+ },
74
+ ];
75
+
76
+ const solidFile = [
77
+ {
78
+ importString:
79
+ 'import solidConfig from "@ethang/eslint-config/config.solid.ts',
80
+ label: "Solid",
81
+ name: "solid",
82
+ options: {
83
+ extraImports: [importTsEslint],
84
+ includeIgnores: true,
85
+ includeLanguageOptions: true,
86
+ },
87
+ },
88
+ ];
89
+
90
+ const angularFile = [
91
+ {
92
+ importString:
93
+ 'import angularConfig from "@ethang/eslint-config/config.angular.ts',
94
+ label: "Angular",
95
+ name: "angular",
96
+ options: {
97
+ extraImports: [importTsEslint, 'import angular from "angular-eslint";'],
98
+ globalIgnores: ["**/*.spec.ts", "src/main.server.ts"],
99
+ includeIgnores: true,
100
+ includeLanguageOptions: true,
101
+ processor: "angular.processInlineTemplates",
102
+ },
103
+ },
104
+ {
105
+ name: "angular:template",
106
+ options: {
107
+ extraImports: ['import { angularLanguageOptions } from "./constants.js"'],
108
+ includeAngularLanguageOptions: true,
109
+ includeLanguageOptions: false,
110
+ },
111
+ },
112
+ ];
113
+
114
+ export const updateRules = async () => {
115
+ await Promise.all([
116
+ createConfigFile(coreFile, "eslint.config.js"),
117
+ createConfigFile(astroFile, "config.astro.js"),
118
+ createConfigFile(reactFile, "config.react.js"),
119
+ createConfigFile(solidFile, "config.solid.js"),
120
+ createConfigFile(angularFile, "config.angular.js"),
121
+ ]);
122
+ };
123
+
124
+ await updateRules();
@@ -0,0 +1,107 @@
1
+ // @ts-nocheck
2
+ import { angularLanguageOptions } from "./constants.js";
3
+ import { ignores, languageOptions } from "./constants.js";
4
+ import angular from "angular-eslint";
5
+ import angularTemplate from "@angular-eslint/eslint-plugin-template";
6
+ import angularTS from "@angular-eslint/eslint-plugin";
7
+ import tseslint from "typescript-eslint";
8
+
9
+ export default tseslint.config(
10
+ {
11
+ ignores: ["**/*.spec.ts", "src/main.server.ts"],
12
+ },
13
+ {
14
+ files: ["**/*.ts"],
15
+ ignores,
16
+ languageOptions,
17
+ processor: angular.processInlineTemplates,
18
+ plugins: {
19
+ "@angular-eslint": angularTS,
20
+ },
21
+ rules: {
22
+ "@angular-eslint/component-class-suffix": "error",
23
+ "@angular-eslint/component-max-inline-declarations": "error",
24
+ "@angular-eslint/component-selector": [
25
+ "error",
26
+ { prefix: "app", style: "kebab-case", type: "element" },
27
+ ],
28
+ "@angular-eslint/consistent-component-styles": "error",
29
+ "@angular-eslint/contextual-decorator": "error",
30
+ "@angular-eslint/contextual-lifecycle": "error",
31
+ "@angular-eslint/directive-class-suffix": "error",
32
+ "@angular-eslint/directive-selector": [
33
+ "error",
34
+ { prefix: "app", style: "camelCase", type: "attribute" },
35
+ ],
36
+ "@angular-eslint/no-async-lifecycle-method": "error",
37
+ "@angular-eslint/no-attribute-decorator": "error",
38
+ "@angular-eslint/no-conflicting-lifecycle": "error",
39
+ "@angular-eslint/no-duplicates-in-metadata-arrays": "error",
40
+ "@angular-eslint/no-empty-lifecycle-method": "error",
41
+ "@angular-eslint/no-forward-ref": "error",
42
+ "@angular-eslint/no-input-prefix": "error",
43
+ "@angular-eslint/no-input-rename": "error",
44
+ "@angular-eslint/no-inputs-metadata-property": "error",
45
+ "@angular-eslint/no-lifecycle-call": "error",
46
+ "@angular-eslint/no-output-native": "error",
47
+ "@angular-eslint/no-output-on-prefix": "error",
48
+ "@angular-eslint/no-output-rename": "error",
49
+ "@angular-eslint/no-outputs-metadata-property": "error",
50
+ "@angular-eslint/no-pipe-impure": "error",
51
+ "@angular-eslint/no-queries-metadata-property": "error",
52
+ "@angular-eslint/pipe-prefix": "error",
53
+ "@angular-eslint/prefer-on-push-component-change-detection": "error",
54
+ "@angular-eslint/prefer-output-readonly": "error",
55
+ "@angular-eslint/prefer-signals": "error",
56
+ "@angular-eslint/prefer-standalone": "error",
57
+ "@angular-eslint/relative-url-prefix": "error",
58
+ "@angular-eslint/require-localize-metadata": "error",
59
+ "@angular-eslint/runtime-localize": "error",
60
+ "@angular-eslint/sort-lifecycle-methods": "error",
61
+ "@angular-eslint/use-component-selector": "error",
62
+ "@angular-eslint/use-component-view-encapsulation": "error",
63
+ "@angular-eslint/use-injectable-provided-in": "error",
64
+ "@angular-eslint/use-lifecycle-interface": "error",
65
+ "@angular-eslint/use-pipe-transform-interface": "error",
66
+ },
67
+ },
68
+ {
69
+ files: ["**/*.html"],
70
+ languageOptions: angularLanguageOptions,
71
+ plugins: {
72
+ "@angular-eslint/template": angularTemplate,
73
+ },
74
+ rules: {
75
+ "@angular-eslint/template/alt-text": "error",
76
+ "@angular-eslint/template/attributes-order": "error",
77
+ "@angular-eslint/template/banana-in-box": "error",
78
+ "@angular-eslint/template/button-has-type": "error",
79
+ "@angular-eslint/template/click-events-have-key-events": "error",
80
+ "@angular-eslint/template/conditional-complexity": "error",
81
+ "@angular-eslint/template/cyclomatic-complexity": "error",
82
+ "@angular-eslint/template/elements-content": "error",
83
+ "@angular-eslint/template/eqeqeq": "error",
84
+ "@angular-eslint/template/i18n": "off",
85
+ "@angular-eslint/template/interactive-supports-focus": "error",
86
+ "@angular-eslint/template/label-has-associated-control": "error",
87
+ "@angular-eslint/template/mouse-events-have-key-events": "error",
88
+ "@angular-eslint/template/no-any": "error",
89
+ "@angular-eslint/template/no-autofocus": "error",
90
+ "@angular-eslint/template/no-call-expression": "off",
91
+ "@angular-eslint/template/no-distracting-elements": "error",
92
+ "@angular-eslint/template/no-duplicate-attributes": "error",
93
+ "@angular-eslint/template/no-inline-styles": "error",
94
+ "@angular-eslint/template/no-interpolation-in-attributes": "error",
95
+ "@angular-eslint/template/no-negated-async": "error",
96
+ "@angular-eslint/template/no-positive-tabindex": "error",
97
+ "@angular-eslint/template/prefer-control-flow": "error",
98
+ "@angular-eslint/template/prefer-ngsrc": "warn",
99
+ "@angular-eslint/template/prefer-self-closing-tags": "error",
100
+ "@angular-eslint/template/prefer-static-string-properties": "error",
101
+ "@angular-eslint/template/role-has-required-aria": "error",
102
+ "@angular-eslint/template/table-scope": "error",
103
+ "@angular-eslint/template/use-track-by-function": "error",
104
+ "@angular-eslint/template/valid-aria": "error",
105
+ },
106
+ },
107
+ );
@@ -0,0 +1,68 @@
1
+ // @ts-nocheck
2
+ import { ignores, languageOptions } from "./constants.js";
3
+ import astro from "eslint-plugin-astro";
4
+ import tseslint from "typescript-eslint";
5
+
6
+ export default tseslint.config({
7
+ files: ["**/*.{astro}"],
8
+ ignores,
9
+ languageOptions,
10
+ plugins: {
11
+ astro: astro,
12
+ },
13
+ rules: {
14
+ "astro/jsx-a11y/alt-text": "error",
15
+ "astro/jsx-a11y/anchor-ambiguous-text": "error",
16
+ "astro/jsx-a11y/anchor-has-content": "error",
17
+ "astro/jsx-a11y/anchor-is-valid": "error",
18
+ "astro/jsx-a11y/aria-activedescendant-has-tabindex": "error",
19
+ "astro/jsx-a11y/aria-props": "error",
20
+ "astro/jsx-a11y/aria-proptypes": "error",
21
+ "astro/jsx-a11y/aria-role": "error",
22
+ "astro/jsx-a11y/aria-unsupported-elements": "error",
23
+ "astro/jsx-a11y/autocomplete-valid": "error",
24
+ "astro/jsx-a11y/click-events-have-key-events": "error",
25
+ "astro/jsx-a11y/control-has-associated-label": "error",
26
+ "astro/jsx-a11y/heading-has-content": "error",
27
+ "astro/jsx-a11y/html-has-lang": "error",
28
+ "astro/jsx-a11y/iframe-has-title": "error",
29
+ "astro/jsx-a11y/img-redundant-alt": "error",
30
+ "astro/jsx-a11y/interactive-supports-focus": "error",
31
+ "astro/jsx-a11y/label-has-associated-control": "error",
32
+ "astro/jsx-a11y/lang": "error",
33
+ "astro/jsx-a11y/media-has-caption": "error",
34
+ "astro/jsx-a11y/mouse-events-have-key-events": "error",
35
+ "astro/jsx-a11y/no-access-key": "error",
36
+ "astro/jsx-a11y/no-aria-hidden-on-focusable": "error",
37
+ "astro/jsx-a11y/no-autofocus": "error",
38
+ "astro/jsx-a11y/no-distracting-elements": "error",
39
+ "astro/jsx-a11y/no-interactive-element-to-noninteractive-role": "error",
40
+ "astro/jsx-a11y/no-noninteractive-element-interactions": "error",
41
+ "astro/jsx-a11y/no-noninteractive-element-to-interactive-role": "error",
42
+ "astro/jsx-a11y/no-noninteractive-tabindex": "error",
43
+ "astro/jsx-a11y/no-redundant-roles": "error",
44
+ "astro/jsx-a11y/no-static-element-interactions": "error",
45
+ "astro/jsx-a11y/prefer-tag-over-role": "error",
46
+ "astro/jsx-a11y/role-has-required-aria-props": "error",
47
+ "astro/jsx-a11y/role-supports-aria-props": "error",
48
+ "astro/jsx-a11y/scope": "error",
49
+ "astro/jsx-a11y/tabindex-no-positive": "error",
50
+ "astro/missing-client-only-directive-value": "error",
51
+ "astro/no-conflict-set-directives": "error",
52
+ "astro/no-deprecated-astro-canonicalurl": "error",
53
+ "astro/no-deprecated-astro-fetchcontent": "error",
54
+ "astro/no-deprecated-astro-resolve": "error",
55
+ "astro/no-deprecated-getentrybyslug": "error",
56
+ "astro/no-exports-from-components": "error",
57
+ "astro/no-set-html-directive": "off",
58
+ "astro/no-set-text-directive": "error",
59
+ "astro/no-unused-css-selector": "error",
60
+ "astro/no-unused-define-vars-in-style": "error",
61
+ "astro/prefer-class-list-directive": "error",
62
+ "astro/prefer-object-class-list": "error",
63
+ "astro/prefer-split-class-list": "error",
64
+ "astro/semi": "error",
65
+ "astro/sort-attributes": "error",
66
+ "astro/valid-compile": "error",
67
+ },
68
+ });
@@ -0,0 +1,117 @@
1
+ // @ts-nocheck
2
+ import { ignores, languageOptions } from "./constants.js";
3
+ import react from "@eslint-react/eslint-plugin";
4
+ import reactCompiler from "eslint-plugin-react-compiler";
5
+ import reactHooks from "eslint-plugin-react-hooks";
6
+ import tseslint from "typescript-eslint";
7
+
8
+ export default tseslint.config({
9
+ files: ["**/*.{jsx,tsx}"],
10
+ ignores,
11
+ languageOptions,
12
+ settings: {
13
+ react: { version: "19.0.0" },
14
+ },
15
+ plugins: {
16
+ react: react,
17
+ "react-hooks": reactHooks,
18
+ "react-compiler": reactCompiler,
19
+ },
20
+ rules: {
21
+ "react/avoid-shorthand-boolean": "off",
22
+ "react/avoid-shorthand-fragment": "off",
23
+ "react/debug/class-component": "off",
24
+ "react/debug/function-component": "off",
25
+ "react/debug/hook": "off",
26
+ "react/debug/is-from-react": "off",
27
+ "react/debug/react-hooks": "off",
28
+ "react/dom/no-children-in-void-dom-elements": "error",
29
+ "react/dom/no-dangerously-set-innerhtml": "error",
30
+ "react/dom/no-dangerously-set-innerhtml-with-children": "error",
31
+ "react/dom/no-find-dom-node": "error",
32
+ "react/dom/no-flush-sync": "error",
33
+ "react/dom/no-missing-button-type": "error",
34
+ "react/dom/no-missing-iframe-sandbox": "error",
35
+ "react/dom/no-namespace": "error",
36
+ "react/dom/no-render-return-value": "error",
37
+ "react/dom/no-script-url": "error",
38
+ "react/dom/no-unknown-property": "error",
39
+ "react/dom/no-unsafe-iframe-sandbox": "error",
40
+ "react/dom/no-unsafe-target-blank": "error",
41
+ "react/dom/no-void-elements-with-children": "error",
42
+ "react/ensure-forward-ref-using-ref": "error",
43
+ "react/hooks-extra/ensure-custom-hooks-using-other-hooks": "error",
44
+ "react/hooks-extra/ensure-use-callback-has-non-empty-deps": "error",
45
+ "react/hooks-extra/ensure-use-memo-has-non-empty-deps": "error",
46
+ "react/hooks-extra/no-direct-set-state-in-use-effect": "error",
47
+ "react/hooks-extra/no-direct-set-state-in-use-layout-effect": "error",
48
+ "react/hooks-extra/no-redundant-custom-hook": "error",
49
+ "react/hooks-extra/no-unnecessary-use-callback": "error",
50
+ "react/hooks-extra/no-unnecessary-use-memo": "error",
51
+ "react/hooks-extra/no-useless-custom-hooks": "error",
52
+ "react/hooks-extra/prefer-use-state-lazy-initialization": "error",
53
+ "react/jsx-no-duplicate-props": "error",
54
+ "react/jsx-uses-vars": "error",
55
+ "react/naming-convention/component-name": "error",
56
+ "react/naming-convention/filename": ["error", { rule: "kebab-case" }],
57
+ "react/naming-convention/filename-extension": "error",
58
+ "react/naming-convention/use-state": "error",
59
+ "react/no-access-state-in-setstate": "error",
60
+ "react/no-array-index-key": "error",
61
+ "react/no-children-count": "error",
62
+ "react/no-children-for-each": "error",
63
+ "react/no-children-map": "error",
64
+ "react/no-children-only": "error",
65
+ "react/no-children-prop": "error",
66
+ "react/no-children-to-array": "error",
67
+ "react/no-class-component": "error",
68
+ "react/no-clone-element": "error",
69
+ "react/no-comment-textnodes": "error",
70
+ "react/no-complex-conditional-rendering": "error",
71
+ "react/no-complicated-conditional-rendering": "error",
72
+ "react/no-component-will-mount": "error",
73
+ "react/no-component-will-receive-props": "error",
74
+ "react/no-component-will-update": "error",
75
+ "react/no-context-provider": "error",
76
+ "react/no-create-ref": "error",
77
+ "react/no-default-props": "error",
78
+ "react/no-direct-mutation-state": "error",
79
+ "react/no-duplicate-jsx-props": "error",
80
+ "react/no-duplicate-key": "error",
81
+ "react/no-forward-ref": "error",
82
+ "react/no-implicit-key": "error",
83
+ "react/no-leaked-conditional-rendering": "error",
84
+ "react/no-missing-component-display-name": "error",
85
+ "react/no-missing-context-display-name": "error",
86
+ "react/no-missing-key": "error",
87
+ "react/no-nested-components": "error",
88
+ "react/no-prop-types": "error",
89
+ "react/no-redundant-should-component-update": "error",
90
+ "react/no-set-state-in-component-did-mount": "error",
91
+ "react/no-set-state-in-component-did-update": "error",
92
+ "react/no-set-state-in-component-will-update": "error",
93
+ "react/no-string-refs": "error",
94
+ "react/no-unsafe-component-will-mount": "error",
95
+ "react/no-unsafe-component-will-receive-props": "error",
96
+ "react/no-unsafe-component-will-update": "error",
97
+ "react/no-unstable-context-value": "error",
98
+ "react/no-unstable-default-props": "error",
99
+ "react/no-unused-class-component-members": "error",
100
+ "react/no-unused-state": "error",
101
+ "react/no-use-context": "error",
102
+ "react/no-useless-fragment": "error",
103
+ "react/prefer-destructuring-assignment": "error",
104
+ "react/prefer-react-namespace-import": "error",
105
+ "react/prefer-read-only-props": "error",
106
+ "react/prefer-shorthand-boolean": "error",
107
+ "react/prefer-shorthand-fragment": "error",
108
+ "react/use-jsx-vars": "error",
109
+ "react/web-api/no-leaked-event-listener": "error",
110
+ "react/web-api/no-leaked-interval": "error",
111
+ "react/web-api/no-leaked-resize-observer": "error",
112
+ "react/web-api/no-leaked-timeout": "error",
113
+ "react-hooks/exhaustive-deps": "error",
114
+ "react-hooks/rules-of-hooks": "error",
115
+ "react-compiler/react-compiler": "error",
116
+ },
117
+ });
@@ -0,0 +1,34 @@
1
+ // @ts-nocheck
2
+ import { ignores, languageOptions } from "./constants.js";
3
+ import solid from "eslint-plugin-solid";
4
+ import tseslint from "typescript-eslint";
5
+
6
+ export default tseslint.config({
7
+ files: ["**/*.{jsx,tsx}"],
8
+ ignores,
9
+ languageOptions,
10
+ plugins: {
11
+ solid: solid,
12
+ },
13
+ rules: {
14
+ "solid/components-return-once": "error",
15
+ "solid/event-handlers": "error",
16
+ "solid/imports": "error",
17
+ "solid/jsx-no-duplicate-props": "error",
18
+ "solid/jsx-no-script-url": "error",
19
+ "solid/jsx-no-undef": "error",
20
+ "solid/jsx-uses-vars": "error",
21
+ "solid/no-array-handlers": "error",
22
+ "solid/no-destructure": "error",
23
+ "solid/no-innerhtml": "error",
24
+ "solid/no-proxy-apis": "off",
25
+ "solid/no-react-deps": "error",
26
+ "solid/no-react-specific-props": "error",
27
+ "solid/no-unknown-namespaces": "error",
28
+ "solid/prefer-for": "error",
29
+ "solid/prefer-show": "error",
30
+ "solid/reactivity": "error",
31
+ "solid/self-closing-comp": "error",
32
+ "solid/style-prop": "error",
33
+ },
34
+ });
@@ -0,0 +1,16 @@
1
+ import angularTemplateParser from "@angular-eslint/template-parser";
2
+ import { parser } from "typescript-eslint";
3
+
4
+ export const ignores = ["eslint.config.js", "node_modules", "dist"];
5
+
6
+ export const languageOptions = {
7
+ parser,
8
+ parserOptions: {
9
+ project: true,
10
+ tsconfigRootDir: import.meta.dirname,
11
+ },
12
+ };
13
+
14
+ export const angularLanguageOptions = {
15
+ parser: angularTemplateParser,
16
+ };