@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.
- package/build.ts +48 -0
- package/dist/config.html.js +2 -0
- package/dist/config.html.js.map +1 -0
- package/dist/eslint.config.d.ts +4 -0
- package/dist/eslint.config.js +2 -0
- package/dist/package.json +67 -0
- package/eslint.config.js +28 -2
- package/package.json +1 -1
- package/src/README.md +132 -0
- package/src/build/create-config-file.ts +70 -0
- package/src/build/create-config.ts +98 -0
- package/src/build/get-react-version.ts +19 -0
- package/src/build/list-utilities.ts +137 -0
- package/src/build/rule-list.ts +283 -0
- package/src/build/update-readme.ts +259 -0
- package/src/build/update-rules.ts +173 -0
- package/src/config.angular.js +122 -0
- package/src/config.astro.js +69 -0
- package/src/config.html.js +73 -0
- package/src/config.react.js +111 -0
- package/src/config.solid.js +34 -0
- package/src/config.storybook.js +31 -0
- package/src/config.tailwind.js +28 -0
- package/src/constants.js +16 -0
- package/src/eslint.config.js +1075 -0
- package/src/eslint.html.js +73 -0
- package/src/setup/a11y.ts +19 -0
- package/src/setup/angular.ts +36 -0
- package/src/setup/astro.ts +14 -0
- package/src/setup/compat.ts +13 -0
- package/src/setup/cspell.ts +100 -0
- package/src/setup/css.ts +15 -0
- package/src/setup/eslint.ts +250 -0
- package/src/setup/gen-rules.ts +85 -0
- package/src/setup/html.ts +17 -0
- package/src/setup/json.ts +17 -0
- package/src/setup/lodash.ts +59 -0
- package/src/setup/markdown.ts +16 -0
- package/src/setup/perfectionist.ts +49 -0
- package/src/setup/react.ts +37 -0
- package/src/setup/solid.ts +21 -0
- package/src/setup/sonar.ts +40 -0
- package/src/setup/storybook.ts +10 -0
- package/src/setup/tailwind.ts +12 -0
- package/src/setup/tanstack-query.ts +8 -0
- package/src/setup/tanstack-router.ts +8 -0
- package/src/setup/typescript-eslint.ts +114 -0
- package/src/setup/unicorn.ts +38 -0
- package/src/tsconfig.json +3 -0
- package/tsconfig.json +3 -0
- /package/{README.md → dist/README.md} +0 -0
- /package/{chunk-WK3YS7OG.js → dist/chunk-WK3YS7OG.js} +0 -0
- /package/{chunk-WK3YS7OG.js.map → dist/chunk-WK3YS7OG.js.map} +0 -0
- /package/{config.angular.d.ts → dist/config.angular.d.ts} +0 -0
- /package/{config.angular.js → dist/config.angular.js} +0 -0
- /package/{config.angular.js.map → dist/config.angular.js.map} +0 -0
- /package/{config.astro.d.ts → dist/config.astro.d.ts} +0 -0
- /package/{config.astro.js → dist/config.astro.js} +0 -0
- /package/{config.astro.js.map → dist/config.astro.js.map} +0 -0
- /package/{config.react.d.ts → dist/config.html.d.ts} +0 -0
- /package/{config.solid.d.ts → dist/config.react.d.ts} +0 -0
- /package/{config.react.js → dist/config.react.js} +0 -0
- /package/{config.react.js.map → dist/config.react.js.map} +0 -0
- /package/{config.storybook.d.ts → dist/config.solid.d.ts} +0 -0
- /package/{config.solid.js → dist/config.solid.js} +0 -0
- /package/{config.solid.js.map → dist/config.solid.js.map} +0 -0
- /package/{eslint.config.d.ts → dist/config.storybook.d.ts} +0 -0
- /package/{config.storybook.js → dist/config.storybook.js} +0 -0
- /package/{config.storybook.js.map → dist/config.storybook.js.map} +0 -0
- /package/{config.tailwind.d.ts → dist/config.tailwind.d.ts} +0 -0
- /package/{config.tailwind.js → dist/config.tailwind.js} +0 -0
- /package/{config.tailwind.js.map → dist/config.tailwind.js.map} +0 -0
- /package/{constants.js → dist/constants.js} +0 -0
- /package/{constants.js.map → dist/constants.js.map} +0 -0
- /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
|
+
});
|