@ethang/eslint-config 24.0.1 → 24.0.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 (75) hide show
  1. package/build.ts +48 -0
  2. package/dist/config.html.js +2 -0
  3. package/dist/config.html.js.map +1 -0
  4. package/dist/eslint.config.d.ts +4 -0
  5. package/dist/eslint.config.js +2 -0
  6. package/dist/package.json +67 -0
  7. package/eslint.config.js +28 -2
  8. package/package.json +1 -1
  9. package/src/README.md +132 -0
  10. package/src/build/create-config-file.ts +70 -0
  11. package/src/build/create-config.ts +98 -0
  12. package/src/build/get-react-version.ts +19 -0
  13. package/src/build/list-utilities.ts +137 -0
  14. package/src/build/rule-list.ts +283 -0
  15. package/src/build/update-readme.ts +259 -0
  16. package/src/build/update-rules.ts +173 -0
  17. package/src/config.angular.js +122 -0
  18. package/src/config.astro.js +69 -0
  19. package/src/config.html.js +73 -0
  20. package/src/config.react.js +111 -0
  21. package/src/config.solid.js +34 -0
  22. package/src/config.storybook.js +31 -0
  23. package/src/config.tailwind.js +28 -0
  24. package/src/constants.js +16 -0
  25. package/src/eslint.config.js +1075 -0
  26. package/src/eslint.html.js +73 -0
  27. package/src/setup/a11y.ts +19 -0
  28. package/src/setup/angular.ts +36 -0
  29. package/src/setup/astro.ts +14 -0
  30. package/src/setup/compat.ts +13 -0
  31. package/src/setup/cspell.ts +100 -0
  32. package/src/setup/css.ts +15 -0
  33. package/src/setup/eslint.ts +250 -0
  34. package/src/setup/gen-rules.ts +85 -0
  35. package/src/setup/html.ts +17 -0
  36. package/src/setup/json.ts +17 -0
  37. package/src/setup/lodash.ts +59 -0
  38. package/src/setup/markdown.ts +16 -0
  39. package/src/setup/perfectionist.ts +49 -0
  40. package/src/setup/react.ts +37 -0
  41. package/src/setup/solid.ts +21 -0
  42. package/src/setup/sonar.ts +40 -0
  43. package/src/setup/storybook.ts +10 -0
  44. package/src/setup/tailwind.ts +12 -0
  45. package/src/setup/tanstack-query.ts +8 -0
  46. package/src/setup/tanstack-router.ts +8 -0
  47. package/src/setup/typescript-eslint.ts +114 -0
  48. package/src/setup/unicorn.ts +38 -0
  49. package/src/tsconfig.json +3 -0
  50. package/tsconfig.json +3 -0
  51. /package/{README.md → dist/README.md} +0 -0
  52. /package/{chunk-WK3YS7OG.js → dist/chunk-WK3YS7OG.js} +0 -0
  53. /package/{chunk-WK3YS7OG.js.map → dist/chunk-WK3YS7OG.js.map} +0 -0
  54. /package/{config.angular.d.ts → dist/config.angular.d.ts} +0 -0
  55. /package/{config.angular.js → dist/config.angular.js} +0 -0
  56. /package/{config.angular.js.map → dist/config.angular.js.map} +0 -0
  57. /package/{config.astro.d.ts → dist/config.astro.d.ts} +0 -0
  58. /package/{config.astro.js → dist/config.astro.js} +0 -0
  59. /package/{config.astro.js.map → dist/config.astro.js.map} +0 -0
  60. /package/{config.react.d.ts → dist/config.html.d.ts} +0 -0
  61. /package/{config.solid.d.ts → dist/config.react.d.ts} +0 -0
  62. /package/{config.react.js → dist/config.react.js} +0 -0
  63. /package/{config.react.js.map → dist/config.react.js.map} +0 -0
  64. /package/{config.storybook.d.ts → dist/config.solid.d.ts} +0 -0
  65. /package/{config.solid.js → dist/config.solid.js} +0 -0
  66. /package/{config.solid.js.map → dist/config.solid.js.map} +0 -0
  67. /package/{eslint.config.d.ts → dist/config.storybook.d.ts} +0 -0
  68. /package/{config.storybook.js → dist/config.storybook.js} +0 -0
  69. /package/{config.storybook.js.map → dist/config.storybook.js.map} +0 -0
  70. /package/{config.tailwind.d.ts → dist/config.tailwind.d.ts} +0 -0
  71. /package/{config.tailwind.js → dist/config.tailwind.js} +0 -0
  72. /package/{config.tailwind.js.map → dist/config.tailwind.js.map} +0 -0
  73. /package/{constants.js → dist/constants.js} +0 -0
  74. /package/{constants.js.map → dist/constants.js.map} +0 -0
  75. /package/{eslint.config.js.map → dist/eslint.config.js.map} +0 -0
@@ -0,0 +1,259 @@
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
+ // eslint-disable-next-line sonar/max-lines-per-function
39
+ export const updateReadme = () => {
40
+ const md = new MarkdownGenerator();
41
+ md.header(1, "Relentless. Unapologetic.", 2);
42
+ md.link("View Config", "https://eslint-config-ethang.pages.dev/rules", 2);
43
+ md.alert("CAUTION", "Prettier is already included for styling!", 2);
44
+
45
+ const coreRules = map(
46
+ [
47
+ ...getList("core"),
48
+ ...getList("json"),
49
+ ...getList("css"),
50
+ ...getList("markdown"),
51
+ ],
52
+ (rules) => {
53
+ return {
54
+ ...rules,
55
+ count: 0,
56
+ };
57
+ },
58
+ );
59
+
60
+ let total = 0;
61
+ for (const list of coreRules) {
62
+ const count = getRuleCount(list.list);
63
+ total += count;
64
+ list.count = count;
65
+ }
66
+ coreRules.sort((a, b) => {
67
+ return b.count - a.count;
68
+ });
69
+
70
+ const ruleDocumentation = [`${total} errored rules.`];
71
+ for (const list of coreRules) {
72
+ if (0 < list.count) {
73
+ ruleDocumentation.push(
74
+ `${list.count} ${
75
+ 1 >= list.count ? "rule" : "rules"
76
+ } from [${list.name}](${list.url})`,
77
+ );
78
+ }
79
+ }
80
+
81
+ const htmlRules = getList("html");
82
+ const tailwindRules = getList("tailwind");
83
+ const astroRules = getList("astro");
84
+ const reactRules = getList("react");
85
+ const solidRules = getList("solid");
86
+ const angularRules = getList("angular");
87
+ const angularTemplateRules = getList("angular:template");
88
+ const storybookRules = getList("storybook");
89
+
90
+ let htmlCount = 0;
91
+ for (const htmlRule of htmlRules) {
92
+ htmlCount += getRuleCount(htmlRule.list);
93
+ }
94
+
95
+ let tailwindCount = 0;
96
+ for (const tailwindRule of tailwindRules) {
97
+ tailwindCount += getRuleCount(tailwindRule.list);
98
+ }
99
+
100
+ let astroCount = 0;
101
+ for (const astroRule of astroRules) {
102
+ astroCount += getRuleCount(astroRule.list);
103
+ }
104
+
105
+ let reactCount = 0;
106
+ for (const reactRule of reactRules) {
107
+ reactCount += getRuleCount(reactRule.list);
108
+ }
109
+
110
+ let solidCount = 0;
111
+ for (const solidRule of solidRules) {
112
+ solidCount += getRuleCount(solidRule.list);
113
+ }
114
+
115
+ let angularCount = 0;
116
+ for (const angularRule of [...angularRules, ...angularTemplateRules]) {
117
+ angularCount += getRuleCount(angularRule.list);
118
+ }
119
+
120
+ let storybookCount = 0;
121
+ for (const storybookRule of storybookRules) {
122
+ storybookCount += getRuleCount(storybookRule.list);
123
+ }
124
+
125
+ md.unorderedList(ruleDocumentation);
126
+ md.newLine();
127
+ md.header(1, "Add Even More!", 2);
128
+ md.unorderedList([
129
+ `${angularCount} rules for **Angular**`,
130
+ [
131
+ '`import angularConfig from "@ethang/eslint-config/config.angular.js";`',
132
+ getImports(angularRules),
133
+ getImports(angularTemplateRules),
134
+ ],
135
+ `${astroCount} rules for **Astro**`,
136
+ [
137
+ '`import astroConfig from "@ethang/eslint-config/config.astro.js";`',
138
+ getImports(astroRules),
139
+ ],
140
+ `${htmlCount} rules for **HTML**`,
141
+ [
142
+ `import html from "@ethang/eslint-config/config.html.js";`,
143
+ getImports(htmlRules),
144
+ ],
145
+ `${reactCount} rules for **React**`,
146
+ [
147
+ '`import reactConfig from "@ethang/eslint-config/config.react.js";`',
148
+ getImports(reactRules),
149
+ ],
150
+ `${solidCount} rules for **Solid**`,
151
+ [
152
+ '`import solidConfig from "@ethang/eslint-config/config.solid.js";`',
153
+ getImports(solidRules),
154
+ ],
155
+ `${storybookCount} rules for **Storybook**`,
156
+ [
157
+ '`import storybookConfig from "@ethang/eslint-config/config.storybook.js";`',
158
+ getImports(storybookRules),
159
+ ],
160
+ `${tailwindCount} rules for **Tailwind**`,
161
+ [
162
+ `import tailwindConfig from "@ethang/eslint-config/config.tailwind.js";`,
163
+ getImports(tailwindRules),
164
+ ],
165
+ ]);
166
+ md.newLine();
167
+ md.header(1, "Install", 2);
168
+ md.codeBlock("pnpm i -D eslint @ethang/eslint-config", "powershell", 2);
169
+ md.bold("Requires TypesScript and tsconfig.json at root directory.", 2);
170
+ md.header(1, "Config", 2);
171
+ md.text("In **eslint.config.ts**", 2);
172
+ md.codeBlock(
173
+ `import config from "@ethang/eslint-config/eslint.config.js";
174
+ import { defineConfig } from "eslint/config";
175
+ import path from "node:path";
176
+ import reactConfig from "@ethang/eslint-config/config.react.js"; // OPTIONAL
177
+ import tailwindConfig from "@ethang/eslint-config/config.tailwind.js"; // OPTIONAL
178
+ import htmlConfig from "@ethang/eslint-config/config.html.js"; // OPTIONAL
179
+
180
+ export default defineConfig(
181
+ {
182
+ ignores: [], // Ignored files apply to all following configs
183
+ },
184
+ ...config,
185
+ ...reactConfig,
186
+ ...htmlConfig,
187
+ ...tailwindConfig(path.join(import.meta.dirname, "src", "index.css")),
188
+ {
189
+ languageOptions: {
190
+ parserOptions: {
191
+ project: true,
192
+ tsconfigRootDir: import.meta.dirname,
193
+ },
194
+ },
195
+ rules: {
196
+ // Override rules from above configs
197
+ },
198
+ }
199
+ );`,
200
+ "js",
201
+ 2,
202
+ );
203
+ md.bold("Scripts", 2);
204
+ md.codeBlock(
205
+ `"scripts": {
206
+ "lint": "eslint . --fix --concurrency=auto"
207
+ }`,
208
+ "json",
209
+ 2,
210
+ );
211
+ md.bold("Browserslist", 2);
212
+ md.text(
213
+ "This config will also lint for browserslist features. [More info.](https://github.com/browserslist/browserslist)",
214
+ 2,
215
+ );
216
+ md.text("It's recommended to use ");
217
+ md.link(
218
+ "browserslist-config-baseline",
219
+ "https://github.com/web-platform-dx/browserslist-config-baseline",
220
+ 2,
221
+ );
222
+ md.codeBlock("pnpm i -D browserslist-config-baseline", "powershell", 2);
223
+
224
+ md.codeBlock(
225
+ `"browserslist": [
226
+ "extends browserslist-config-baseline",
227
+ "current node"
228
+ ],`,
229
+ "json",
230
+ 2,
231
+ );
232
+
233
+ md.text("Or a simpler config without an additional dependency.", 2);
234
+
235
+ md.codeBlock(
236
+ `"browserslist": [
237
+ "defaults and fully supports es6-module",
238
+ "current node"
239
+ ],`,
240
+ "json",
241
+ 2,
242
+ );
243
+
244
+ md.bold("Engines", 2);
245
+ md.codeBlock(
246
+ `"engines": {
247
+ "node": ">=24"
248
+ },`,
249
+ "json",
250
+ );
251
+
252
+ writeFileSync(
253
+ path.join(import.meta.dirname, "../README.md"),
254
+ md.render(),
255
+ "utf8",
256
+ );
257
+ };
258
+
259
+ updateReadme();
@@ -0,0 +1,173 @@
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 defineConfig = 'import { defineConfig } from "eslint/config";';
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
+ defineConfig,
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
+ export const htmlFile = [
48
+ {
49
+ importString: "@html-eslint/eslint-plugin",
50
+ label: "HTML",
51
+ name: "html",
52
+ options: {
53
+ extraImports: [defineConfig],
54
+ includeIgnores: true,
55
+ includeLanguageOptions: true,
56
+ },
57
+ },
58
+ ];
59
+
60
+ const astroFile = [
61
+ {
62
+ importString:
63
+ 'import astroConfig from "@ethang/eslint-config/config.astro.ts',
64
+ label: "Astro",
65
+ name: "astro",
66
+ options: {
67
+ extraImports: [defineConfig],
68
+ includeIgnores: true,
69
+ includeLanguageOptions: true,
70
+ },
71
+ },
72
+ ];
73
+
74
+ const reactFile = [
75
+ {
76
+ importString:
77
+ 'import reactConfig from "@ethang/eslint-config/config.react.ts',
78
+ label: "React",
79
+ name: "react",
80
+ options: {
81
+ extraImports: [defineConfig],
82
+ includeIgnores: true,
83
+ includeLanguageOptions: true,
84
+ includeReactVersion: true,
85
+ },
86
+ },
87
+ ];
88
+
89
+ const solidFile = [
90
+ {
91
+ importString:
92
+ 'import solidConfig from "@ethang/eslint-config/config.solid.ts',
93
+ label: "Solid",
94
+ name: "solid",
95
+ options: {
96
+ extraImports: [defineConfig],
97
+ includeIgnores: true,
98
+ includeLanguageOptions: true,
99
+ },
100
+ },
101
+ ];
102
+
103
+ const angularFile = [
104
+ {
105
+ importString:
106
+ 'import angularConfig from "@ethang/eslint-config/config.angular.ts',
107
+ label: "Angular",
108
+ name: "angular",
109
+ options: {
110
+ extraImports: [defineConfig, 'import angular from "angular-eslint";'],
111
+ globalIgnores: ["**/*.spec.ts", "src/main.server.ts"],
112
+ includeIgnores: true,
113
+ includeLanguageOptions: true,
114
+ processor: "angular.processInlineTemplates",
115
+ },
116
+ },
117
+ {
118
+ name: "angular:template",
119
+ options: {
120
+ extraImports: ['import { angularLanguageOptions } from "./constants.js"'],
121
+ includeAngularLanguageOptions: true,
122
+ includeLanguageOptions: false,
123
+ },
124
+ },
125
+ ];
126
+
127
+ const storybookFile = [
128
+ {
129
+ importString:
130
+ 'import storybookConfig from "@ethang/eslint-config/config.storybook.ts',
131
+ label: "Storybook",
132
+ name: "storybook",
133
+ options: {
134
+ extraImports: [defineConfig],
135
+ includeIgnores: true,
136
+ includeLanguageOptions: true,
137
+ },
138
+ },
139
+ ];
140
+
141
+ const tailwindFile = [
142
+ {
143
+ importString:
144
+ 'import tailwindConfig from "@ethang/eslint-config/config.tailwind.ts',
145
+ label: "Tailwind",
146
+ name: "tailwind",
147
+ options: {
148
+ extraImports: [defineConfig],
149
+ extraOptions: "settings: { tailwindcss: { config: pathToConfig } },",
150
+ includeIgnores: true,
151
+ includeLanguageOptions: true,
152
+ },
153
+ },
154
+ ];
155
+
156
+ export const updateRules = async () => {
157
+ await Promise.all([
158
+ createConfigFile(coreFile, "eslint.config.js"),
159
+ createConfigFile(htmlFile, "config.html.js"),
160
+ createConfigFile(astroFile, "config.astro.js"),
161
+ createConfigFile(reactFile, "config.react.js"),
162
+ createConfigFile(solidFile, "config.solid.js"),
163
+ createConfigFile(angularFile, "config.angular.js"),
164
+ createConfigFile(storybookFile, "config.storybook.js"),
165
+ createConfigFile(
166
+ tailwindFile,
167
+ "config.tailwind.js",
168
+ "/** @type {string} */ pathToConfig",
169
+ ),
170
+ ]);
171
+ };
172
+
173
+ await updateRules();
@@ -0,0 +1,122 @@
1
+ // @ts-nocheck
2
+ import { angularLanguageOptions } from "./constants.js";
3
+ import { defineConfig } from "eslint/config";
4
+ import { ignores, languageOptions } from "./constants.js";
5
+ import angular from "angular-eslint";
6
+ import angularTemplate from "@angular-eslint/eslint-plugin-template";
7
+ import angularTS from "@angular-eslint/eslint-plugin";
8
+
9
+ export default defineConfig(
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-developer-preview": "error",
39
+ "@angular-eslint/no-duplicates-in-metadata-arrays": "error",
40
+ "@angular-eslint/no-empty-lifecycle-method": "error",
41
+ "@angular-eslint/no-experimental": "error",
42
+ "@angular-eslint/no-forward-ref": "error",
43
+ "@angular-eslint/no-input-prefix": "error",
44
+ "@angular-eslint/no-input-rename": "error",
45
+ "@angular-eslint/no-inputs-metadata-property": "error",
46
+ "@angular-eslint/no-lifecycle-call": "error",
47
+ "@angular-eslint/no-output-native": "error",
48
+ "@angular-eslint/no-output-on-prefix": "error",
49
+ "@angular-eslint/no-output-rename": "error",
50
+ "@angular-eslint/no-outputs-metadata-property": "error",
51
+ "@angular-eslint/no-pipe-impure": "error",
52
+ "@angular-eslint/no-queries-metadata-property": "error",
53
+ "@angular-eslint/no-uncalled-signals": "error",
54
+ "@angular-eslint/pipe-prefix": "error",
55
+ "@angular-eslint/prefer-host-metadata-property": "error",
56
+ "@angular-eslint/prefer-inject": "error",
57
+ "@angular-eslint/prefer-on-push-component-change-detection": "error",
58
+ "@angular-eslint/prefer-output-emitter-ref": "error",
59
+ "@angular-eslint/prefer-output-readonly": "error",
60
+ "@angular-eslint/prefer-signal-model": "error",
61
+ "@angular-eslint/prefer-signals": "error",
62
+ "@angular-eslint/prefer-standalone": "error",
63
+ "@angular-eslint/relative-url-prefix": "error",
64
+ "@angular-eslint/require-lifecycle-on-prototype": "error",
65
+ "@angular-eslint/require-localize-metadata": "error",
66
+ "@angular-eslint/runtime-localize": "error",
67
+ "@angular-eslint/sort-keys-in-type-decorator": "error",
68
+ "@angular-eslint/sort-lifecycle-methods": "error",
69
+ "@angular-eslint/use-component-selector": "error",
70
+ "@angular-eslint/use-component-view-encapsulation": "error",
71
+ "@angular-eslint/use-injectable-provided-in": "error",
72
+ "@angular-eslint/use-lifecycle-interface": "error",
73
+ "@angular-eslint/use-pipe-transform-interface": "error",
74
+ },
75
+ },
76
+ {
77
+ files: ["**/*.html"],
78
+ languageOptions: angularLanguageOptions,
79
+ plugins: {
80
+ "@angular-eslint/template": angularTemplate,
81
+ },
82
+ rules: {
83
+ "@angular-eslint/template/alt-text": "error",
84
+ "@angular-eslint/template/attributes-order": "error",
85
+ "@angular-eslint/template/banana-in-box": "error",
86
+ "@angular-eslint/template/button-has-type": "error",
87
+ "@angular-eslint/template/click-events-have-key-events": "error",
88
+ "@angular-eslint/template/conditional-complexity": "error",
89
+ "@angular-eslint/template/cyclomatic-complexity": "error",
90
+ "@angular-eslint/template/elements-content": "error",
91
+ "@angular-eslint/template/eqeqeq": "error",
92
+ "@angular-eslint/template/i18n": "off",
93
+ "@angular-eslint/template/interactive-supports-focus": "error",
94
+ "@angular-eslint/template/label-has-associated-control": "error",
95
+ "@angular-eslint/template/mouse-events-have-key-events": "error",
96
+ "@angular-eslint/template/no-any": "error",
97
+ "@angular-eslint/template/no-autofocus": "error",
98
+ "@angular-eslint/template/no-call-expression": "off",
99
+ "@angular-eslint/template/no-distracting-elements": "error",
100
+ "@angular-eslint/template/no-duplicate-attributes": "error",
101
+ "@angular-eslint/template/no-empty-control-flow": "error",
102
+ "@angular-eslint/template/no-inline-styles": "error",
103
+ "@angular-eslint/template/no-interpolation-in-attributes": "error",
104
+ "@angular-eslint/template/no-negated-async": "error",
105
+ "@angular-eslint/template/no-nested-tags": "error",
106
+ "@angular-eslint/template/no-positive-tabindex": "error",
107
+ "@angular-eslint/template/prefer-at-else": "error",
108
+ "@angular-eslint/template/prefer-at-empty": "error",
109
+ "@angular-eslint/template/prefer-built-in-pipes": "error",
110
+ "@angular-eslint/template/prefer-contextual-for-variables": "error",
111
+ "@angular-eslint/template/prefer-control-flow": "error",
112
+ "@angular-eslint/template/prefer-ngsrc": "warn",
113
+ "@angular-eslint/template/prefer-self-closing-tags": "error",
114
+ "@angular-eslint/template/prefer-static-string-properties": "error",
115
+ "@angular-eslint/template/prefer-template-literal": "error",
116
+ "@angular-eslint/template/role-has-required-aria": "error",
117
+ "@angular-eslint/template/table-scope": "error",
118
+ "@angular-eslint/template/use-track-by-function": "error",
119
+ "@angular-eslint/template/valid-aria": "error",
120
+ },
121
+ },
122
+ );
@@ -0,0 +1,69 @@
1
+ // @ts-nocheck
2
+ import { defineConfig } from "eslint/config";
3
+ import { ignores, languageOptions } from "./constants.js";
4
+ import astro from "eslint-plugin-astro";
5
+
6
+ export default defineConfig({
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-unsafe-inline-scripts": "error",
60
+ "astro/no-unused-css-selector": "error",
61
+ "astro/no-unused-define-vars-in-style": "error",
62
+ "astro/prefer-class-list-directive": "error",
63
+ "astro/prefer-object-class-list": "error",
64
+ "astro/prefer-split-class-list": "error",
65
+ "astro/semi": "error",
66
+ "astro/sort-attributes": "error",
67
+ "astro/valid-compile": "error",
68
+ },
69
+ });