@storm-software/linting-tools 1.43.0 → 1.44.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.
- package/.eslintrc.json +97 -0
- package/CHANGELOG.md +31 -0
- package/README.md +1 -1
- package/bin/lint.ts +24 -13
- package/jest.config.ts +11 -0
- package/package.json +10 -6
- package/project.json +111 -0
- package/src/alex/index.ts +67 -0
- package/{biome → src/biome}/biome.json +2 -1
- package/src/cli/index.ts +300 -0
- package/src/eslint/constants.ts +87 -0
- package/src/eslint/graphql/{index.js → index.ts} +4 -7
- package/src/eslint/index.ts +7 -0
- package/src/eslint/javascript/index.ts +22 -0
- package/src/eslint/jest/index.ts +16 -0
- package/src/eslint/json/index.ts +32 -0
- package/src/eslint/next/index.ts +25 -0
- package/src/eslint/react/index.ts +25 -0
- package/src/eslint/rules/import.ts +85 -0
- package/src/eslint/rules/jsx-a11y.ts +8 -0
- package/src/eslint/{react/index.js → rules/react.ts} +3 -39
- package/src/eslint/{javascript/index.js → rules/storm.ts} +3 -139
- package/src/eslint/rules/ts-docs.ts +12 -0
- package/src/eslint/rules/unicorn.ts +23 -0
- package/src/eslint/typescript/index.ts +132 -0
- package/src/ls-lint/.ls-lint.yml +13 -0
- package/src/manypkg/index.ts +164 -0
- package/{taplo → src/taplo}/.taplo.toml +2 -2
- package/tsconfig.json +18 -0
- package/tsconfig.script.json +21 -0
- package/tsconfig.spec.json +13 -0
- package/LICENSE +0 -201
- package/bin/lint.js +0 -333139
- package/ls-lint/.ls-lint.yml +0 -13
- package/src/cli/index.js +0 -328555
- package/src/eslint/jest/index.js +0 -19
- package/src/eslint/json/index.js +0 -95
- package/src/eslint/next/index.js +0 -90
- package/src/eslint/typescript/index.js +0 -569
- package/src/manypkg/index.js +0 -34729
- /package/{alex → src/alex}/.alexignore +0 -0
- /package/{alex → src/alex}/.alexrc +0 -0
- /package/{cspell → src/cspell}/config.json +0 -0
- /package/{cspell → src/cspell}/dictionary.txt +0 -0
- /package/{prettier → src/prettier}/.prettierignore +0 -0
- /package/{prettier → src/prettier}/config.json +0 -0
package/src/cli/index.ts
ADDED
|
@@ -0,0 +1,300 @@
|
|
|
1
|
+
import {
|
|
2
|
+
findWorkspaceRootSafe,
|
|
3
|
+
writeDebug,
|
|
4
|
+
writeError,
|
|
5
|
+
writeFatal,
|
|
6
|
+
writeInfo,
|
|
7
|
+
writeSuccess,
|
|
8
|
+
writeTrace
|
|
9
|
+
} from "@storm-software/config-tools";
|
|
10
|
+
import type { StormConfig } from "@storm-software/config";
|
|
11
|
+
import { lint } from "cspell";
|
|
12
|
+
import { parseCircular, parseDependencyTree, prettyCircular } from "dpdm";
|
|
13
|
+
import { runAlex } from "../alex";
|
|
14
|
+
import { runManypkg } from "../manypkg";
|
|
15
|
+
import { Command, Option } from "commander";
|
|
16
|
+
|
|
17
|
+
let _config: Partial<StormConfig> = {};
|
|
18
|
+
|
|
19
|
+
export function createProgram(config: StormConfig) {
|
|
20
|
+
try {
|
|
21
|
+
_config = config;
|
|
22
|
+
writeInfo(config, "⚡ Running Storm Linting Tools");
|
|
23
|
+
|
|
24
|
+
const root = findWorkspaceRootSafe();
|
|
25
|
+
process.env.STORM_WORKSPACE_ROOT ??= root;
|
|
26
|
+
process.env.NX_WORKSPACE_ROOT_PATH ??= root;
|
|
27
|
+
root && process.chdir(root);
|
|
28
|
+
|
|
29
|
+
const program = new Command("storm-lint");
|
|
30
|
+
program.version("1.0.0", "-v --version", "display CLI version");
|
|
31
|
+
|
|
32
|
+
program
|
|
33
|
+
.description("⚡ Lint the Storm Workspace")
|
|
34
|
+
.showHelpAfterError()
|
|
35
|
+
.showSuggestionAfterError();
|
|
36
|
+
|
|
37
|
+
const cspellConfig = new Option("--cspell-config <file>", "CSpell config file path").default(
|
|
38
|
+
"@storm-software/linting-tools/cspell/config.js"
|
|
39
|
+
);
|
|
40
|
+
|
|
41
|
+
program
|
|
42
|
+
.command("cspell")
|
|
43
|
+
.description("Run spell-check lint for the workspace.")
|
|
44
|
+
.addOption(cspellConfig)
|
|
45
|
+
.action(cspellAction);
|
|
46
|
+
|
|
47
|
+
const alexConfig = new Option("--alex-config <file>", "Alex.js config file path").default(
|
|
48
|
+
"@storm-software/linting-tools/alex/.alexrc"
|
|
49
|
+
);
|
|
50
|
+
|
|
51
|
+
const alexIgnore = new Option("--alex-ignore <file>", "Alex.js Ignore file path").default(
|
|
52
|
+
"@storm-software/linting-tools/alex/.alexignore"
|
|
53
|
+
);
|
|
54
|
+
|
|
55
|
+
program
|
|
56
|
+
.command("alex")
|
|
57
|
+
.description("Run spell-check lint for the workspace.")
|
|
58
|
+
.addOption(alexConfig)
|
|
59
|
+
.addOption(alexIgnore)
|
|
60
|
+
.action(alexAction);
|
|
61
|
+
|
|
62
|
+
program
|
|
63
|
+
.command("deps-version")
|
|
64
|
+
.description("Run dependency version consistency lint for the workspace.")
|
|
65
|
+
.action(depsVersionAction);
|
|
66
|
+
|
|
67
|
+
program
|
|
68
|
+
.command("circular-deps")
|
|
69
|
+
.description("Run circular dependency lint for the workspace.")
|
|
70
|
+
.action(circularDepsAction);
|
|
71
|
+
|
|
72
|
+
const manypkgType = new Option("--manypkg-type <type>", "The manypkg command to run").default(
|
|
73
|
+
"check"
|
|
74
|
+
);
|
|
75
|
+
|
|
76
|
+
const manypkgArgs = new Option(
|
|
77
|
+
"--manypkg-args <args>",
|
|
78
|
+
"The args provided to the manypkg command"
|
|
79
|
+
).default([]);
|
|
80
|
+
|
|
81
|
+
const manypkgFix = new Option(
|
|
82
|
+
"--manypkg-fix <args>",
|
|
83
|
+
"The args provided to the manypkg command"
|
|
84
|
+
).default(true);
|
|
85
|
+
|
|
86
|
+
program
|
|
87
|
+
.command("manypkg")
|
|
88
|
+
.description("Run package lint with Manypkg for the workspace.")
|
|
89
|
+
.addOption(manypkgType)
|
|
90
|
+
.addOption(manypkgArgs)
|
|
91
|
+
.addOption(manypkgFix)
|
|
92
|
+
.action(manypkgAction);
|
|
93
|
+
|
|
94
|
+
const skipCspell = new Option("--skip-cspell", "Should skip CSpell linting");
|
|
95
|
+
|
|
96
|
+
const skipAlex = new Option("--skip-alex", "Should skip Alex language linting");
|
|
97
|
+
|
|
98
|
+
const skipDepsVersion = new Option(
|
|
99
|
+
"--skip-deps-version",
|
|
100
|
+
"Should skip dependency version consistency linting"
|
|
101
|
+
);
|
|
102
|
+
|
|
103
|
+
const skipCircularDeps = new Option(
|
|
104
|
+
"--skip-circular-deps",
|
|
105
|
+
"Should skip circular dependency linting"
|
|
106
|
+
);
|
|
107
|
+
|
|
108
|
+
const skipManypkg = new Option("--skip-manypkg", "Should skip Manypkg linting");
|
|
109
|
+
|
|
110
|
+
program
|
|
111
|
+
.command("all")
|
|
112
|
+
.description("Run all linters for the workspace.")
|
|
113
|
+
.addOption(skipCspell)
|
|
114
|
+
.addOption(skipAlex)
|
|
115
|
+
.addOption(skipDepsVersion)
|
|
116
|
+
.addOption(skipCircularDeps)
|
|
117
|
+
.addOption(skipManypkg)
|
|
118
|
+
.addOption(cspellConfig)
|
|
119
|
+
.addOption(alexConfig)
|
|
120
|
+
.addOption(alexIgnore)
|
|
121
|
+
.addOption(manypkgType)
|
|
122
|
+
.addOption(manypkgArgs)
|
|
123
|
+
.addOption(manypkgFix)
|
|
124
|
+
.action(allAction);
|
|
125
|
+
|
|
126
|
+
return program;
|
|
127
|
+
} catch (e) {
|
|
128
|
+
writeFatal(config, `A fatal error occurred while running the program: ${e.message}`);
|
|
129
|
+
process.exit(1);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
async function allAction({
|
|
134
|
+
skipCspell,
|
|
135
|
+
skipAlex,
|
|
136
|
+
skipDepsVersion,
|
|
137
|
+
skipCircularDeps,
|
|
138
|
+
skipManypkg,
|
|
139
|
+
cspellConfig,
|
|
140
|
+
alexConfig,
|
|
141
|
+
alexIgnore,
|
|
142
|
+
manypkgType,
|
|
143
|
+
manypkgArgs,
|
|
144
|
+
manypkgFix
|
|
145
|
+
}: {
|
|
146
|
+
skipCspell: boolean;
|
|
147
|
+
skipAlex: boolean;
|
|
148
|
+
skipDepsVersion: boolean;
|
|
149
|
+
skipCircularDeps: boolean;
|
|
150
|
+
skipManypkg: boolean;
|
|
151
|
+
cspellConfig: string;
|
|
152
|
+
alexConfig: string;
|
|
153
|
+
alexIgnore: string;
|
|
154
|
+
manypkgType: string;
|
|
155
|
+
manypkgArgs: string[];
|
|
156
|
+
manypkgFix: boolean;
|
|
157
|
+
}) {
|
|
158
|
+
try {
|
|
159
|
+
writeInfo(_config, "⚡ Linting the Storm Workspace");
|
|
160
|
+
|
|
161
|
+
const promises = [] as Promise<any>[];
|
|
162
|
+
if (!skipCspell) {
|
|
163
|
+
promises.push(cspellAction(cspellConfig));
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
if (!skipAlex) {
|
|
167
|
+
promises.push(alexAction(alexConfig, alexIgnore));
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
if (!skipDepsVersion) {
|
|
171
|
+
promises.push(depsVersionAction());
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
if (!skipCircularDeps) {
|
|
175
|
+
promises.push(circularDepsAction());
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
if (!skipManypkg) {
|
|
179
|
+
promises.push(manypkgAction(manypkgType, manypkgArgs, manypkgFix));
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
await Promise.all(promises);
|
|
183
|
+
writeSuccess(_config, "Successfully linted the workspace ✅");
|
|
184
|
+
} catch (e) {
|
|
185
|
+
writeFatal(_config, `A fatal error occurred while linting the workspace: ${e.message}`);
|
|
186
|
+
process.exit(1);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
async function cspellAction(cspellConfig: string) {
|
|
191
|
+
try {
|
|
192
|
+
console.log("⚡Linting the workspace spelling");
|
|
193
|
+
const result = await lint(["**/*.{txt,js,jsx,ts,tsx,md,mdx}"], {
|
|
194
|
+
cache: true,
|
|
195
|
+
summary: true,
|
|
196
|
+
issues: true,
|
|
197
|
+
progress: false,
|
|
198
|
+
relative: true,
|
|
199
|
+
dot: true,
|
|
200
|
+
debug: true,
|
|
201
|
+
gitignore: true,
|
|
202
|
+
root: process.env.STORM_WORKSPACE_ROOT ? process.env.STORM_WORKSPACE_ROOT : process.cwd(),
|
|
203
|
+
defaultConfiguration: false,
|
|
204
|
+
config: cspellConfig
|
|
205
|
+
});
|
|
206
|
+
if (result.errors) {
|
|
207
|
+
writeError(_config, "Spelling linting has failed ❌");
|
|
208
|
+
process.exit(1);
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
writeSuccess(_config, "Spelling linting is complete ✅");
|
|
212
|
+
} catch (e) {
|
|
213
|
+
console.error(e);
|
|
214
|
+
process.exit(1);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
async function alexAction(alexConfig: string, alexIgnore: string) {
|
|
219
|
+
try {
|
|
220
|
+
writeInfo(_config, "⚡ Linting the workspace language with alexjs.com");
|
|
221
|
+
|
|
222
|
+
if (await runAlex(alexConfig, alexIgnore)) {
|
|
223
|
+
writeError(_config, "Language linting has failed ❌");
|
|
224
|
+
process.exit(1);
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
writeSuccess(_config, "Language linting is complete ✅");
|
|
228
|
+
} catch (e) {
|
|
229
|
+
writeFatal(
|
|
230
|
+
_config,
|
|
231
|
+
`A fatal error occurred while language linting the workspace: ${e.message}`
|
|
232
|
+
);
|
|
233
|
+
process.exit(1);
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
async function depsVersionAction() {
|
|
238
|
+
try {
|
|
239
|
+
writeInfo(_config, "⚡ Linting the workspace dependency version consistency");
|
|
240
|
+
|
|
241
|
+
const { CDVC } = await import("check-dependency-version-consistency");
|
|
242
|
+
const cdvc = new CDVC(".", { fix: true });
|
|
243
|
+
|
|
244
|
+
// Show output for dependencies we fixed.
|
|
245
|
+
if (cdvc.hasMismatchingDependenciesFixable) {
|
|
246
|
+
writeDebug(_config, cdvc.toFixedSummary());
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
// Show output for dependencies that still have mismatches.
|
|
250
|
+
if (cdvc.hasMismatchingDependenciesNotFixable) {
|
|
251
|
+
writeError(_config, "Dependency version consistency linting has failed ❌");
|
|
252
|
+
writeError(_config, cdvc.toMismatchSummary());
|
|
253
|
+
process.exit(1);
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
writeSuccess(_config, "Dependency Version linting is complete ✅");
|
|
257
|
+
} catch (e) {
|
|
258
|
+
writeFatal(
|
|
259
|
+
_config,
|
|
260
|
+
`A fatal error occurred while dependency Version linting the workspace: ${e.message}`
|
|
261
|
+
);
|
|
262
|
+
process.exit(1);
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
async function circularDepsAction() {
|
|
267
|
+
try {
|
|
268
|
+
writeInfo(_config, "⚡ Linting the workspace circular dependency");
|
|
269
|
+
|
|
270
|
+
const tree = await parseDependencyTree("**/*.*", {
|
|
271
|
+
tsconfig: "./tsconfig.base.json",
|
|
272
|
+
transform: true,
|
|
273
|
+
skipDynamicImports: false
|
|
274
|
+
});
|
|
275
|
+
|
|
276
|
+
const circulars = parseCircular(tree);
|
|
277
|
+
writeTrace(_config, prettyCircular(circulars));
|
|
278
|
+
|
|
279
|
+
writeSuccess(_config, "Circular dependency linting is complete ✅");
|
|
280
|
+
} catch (e) {
|
|
281
|
+
writeFatal(
|
|
282
|
+
_config,
|
|
283
|
+
`A fatal error occurred while circular dependency linting the workspace: ${e.message}`
|
|
284
|
+
);
|
|
285
|
+
process.exit(1);
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
async function manypkgAction(manypkgType = "check", manypkgArgs: string[], manypkgFix: boolean) {
|
|
290
|
+
try {
|
|
291
|
+
writeInfo(_config, "⚡ Linting the workspace's packages with Manypkg");
|
|
292
|
+
|
|
293
|
+
await runManypkg(manypkgType, manypkgArgs, manypkgFix);
|
|
294
|
+
|
|
295
|
+
writeSuccess(_config, "Manypkg linting is complete ✅");
|
|
296
|
+
} catch (e) {
|
|
297
|
+
writeFatal(_config, `A fatal error occurred while manypkg linting the workspace: ${e.message}`);
|
|
298
|
+
process.exit(1);
|
|
299
|
+
}
|
|
300
|
+
}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
export const RESTRICTED_SYNTAX = [
|
|
2
|
+
{
|
|
3
|
+
// ❌ readFile(…, { encoding: … })
|
|
4
|
+
selector:
|
|
5
|
+
"CallExpression[callee.name=/readFileSync|readFile|writeFileSync|writeFile/] > .arguments:last-child[type=ObjectExpression][properties.length=1] Property[key.name=encoding]",
|
|
6
|
+
message: "Specify encoding as last argument instead of object with encoding key"
|
|
7
|
+
},
|
|
8
|
+
{
|
|
9
|
+
// ❌ readFile(…, {})
|
|
10
|
+
selector:
|
|
11
|
+
"CallExpression[callee.name=/readFileSync|readFile|writeFileSync|writeFile/] > .arguments:last-child[type=ObjectExpression][properties.length=0]",
|
|
12
|
+
message: "Specify encoding as last argument"
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
// ❌ readFileSync(…).toString(…)
|
|
16
|
+
selector: "CallExpression[callee.name=readFileSync][parent.property.name=toString]",
|
|
17
|
+
message: "toString is redundant, specify encoding as last argument"
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
// ❌ ….readFile(…, { encoding: … })
|
|
21
|
+
selector:
|
|
22
|
+
"CallExpression[callee.type=MemberExpression][callee.property.name=/readFileSync|readFile|writeFileSync|writeFile/] > .arguments:last-child[type=ObjectExpression][properties.length=1] Property[key.name=encoding]",
|
|
23
|
+
message: "Specify encoding as last argument instead of object with encoding key"
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
// ❌ ….readFile(…, {})
|
|
27
|
+
selector:
|
|
28
|
+
"CallExpression[callee.type=MemberExpression][callee.property.name=/readFileSync|readFile|writeFileSync|writeFile/] > .arguments:last-child[type=ObjectExpression][properties.length=0]",
|
|
29
|
+
message: "Specify encoding as last argument"
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
// ❌ Boolean(…)
|
|
33
|
+
selector: "CallExpression[callee.name=Boolean][arguments.1.elements.length!=0]",
|
|
34
|
+
message:
|
|
35
|
+
"Prefer `!!…` over `Boolean(…)` because TypeScript infers a narrow literal boolean `type: true` instead of `type: boolean`."
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
// ❌ process.browser
|
|
39
|
+
selector:
|
|
40
|
+
"ExpressionStatement[expression.object.name=process][expression.property.name=browser]",
|
|
41
|
+
message: "`process.browser` is deprecated, use `!!globalThis.window`"
|
|
42
|
+
}
|
|
43
|
+
// {
|
|
44
|
+
// // ❌ let { foo: { bar } } = baz
|
|
45
|
+
// // ✅ let { bar } = baz.foo
|
|
46
|
+
// // ✅ let { foo: { bar } } = await baz
|
|
47
|
+
// selector:
|
|
48
|
+
// 'VariableDeclarator[init.type!=AwaitExpression] > ObjectPattern[properties.length=1][properties.0.value.type=ObjectPattern]',
|
|
49
|
+
// message: 'Do not use nested destructuring.',
|
|
50
|
+
// },
|
|
51
|
+
];
|
|
52
|
+
|
|
53
|
+
export const REACT_RESTRICTED_SYNTAX = [
|
|
54
|
+
...RESTRICTED_SYNTAX,
|
|
55
|
+
{
|
|
56
|
+
// ❌ useMemo(…, [])
|
|
57
|
+
selector:
|
|
58
|
+
"CallExpression[callee.name=useMemo][arguments.1.type=ArrayExpression][arguments.1.elements.length=0]",
|
|
59
|
+
message:
|
|
60
|
+
"`useMemo` with an empty dependency array can't provide a stable reference, use `useRef` instead."
|
|
61
|
+
}
|
|
62
|
+
];
|
|
63
|
+
|
|
64
|
+
export const RESTRICTED_GLOBALS = ["stop", { name: "isNaN", message: "Use Number.isNaN instead" }];
|
|
65
|
+
|
|
66
|
+
export const RESTRICTED_MODULES = [
|
|
67
|
+
{ name: "axios", message: "Use `fetch/node-fetch` instead." },
|
|
68
|
+
{ name: "moment", message: "Use `dayjs/date-fns` instead." },
|
|
69
|
+
{ name: "classnames", message: "Use `clsx` instead because it is faster." },
|
|
70
|
+
{
|
|
71
|
+
name: "lodash/isString.js",
|
|
72
|
+
message: "Use `typeof yourVar === 'string'` instead."
|
|
73
|
+
},
|
|
74
|
+
{ name: "lodash/isArray.js", message: "Use `Array.isArray` instead." },
|
|
75
|
+
{ name: "lodash/flatten.js", message: "Use `Array#flat()` instead." },
|
|
76
|
+
{
|
|
77
|
+
name: "lodash/compact.js",
|
|
78
|
+
message: "Use `Array#filter(Boolean)` instead."
|
|
79
|
+
},
|
|
80
|
+
{ name: "lodash/identity.js", message: "Use `(value) => value` instead." }
|
|
81
|
+
];
|
|
82
|
+
|
|
83
|
+
export const JS_FILES = ["*.js?(x)", "*.mjs"];
|
|
84
|
+
|
|
85
|
+
export const CODE_BLOCK = "**/*.md{,x}/*";
|
|
86
|
+
export const CODE_FILE = "*.{,c,m}{j,t}s{,x}";
|
|
87
|
+
export const TS_FILE = "*.{,c,m}ts{,x}";
|
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
|
|
1
|
+
import type { Linter } from "eslint";
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
var config = {
|
|
3
|
+
const config: Linter.Config = {
|
|
5
4
|
root: true,
|
|
6
5
|
overrides: [
|
|
7
6
|
{
|
|
@@ -122,7 +121,5 @@ var config = {
|
|
|
122
121
|
}
|
|
123
122
|
]
|
|
124
123
|
};
|
|
125
|
-
|
|
126
|
-
export
|
|
127
|
-
graphql_default as default
|
|
128
|
-
};
|
|
124
|
+
|
|
125
|
+
export default config;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { Linter } from "eslint";
|
|
2
|
+
import importRules from "../rules/import";
|
|
3
|
+
import stormRules from "../rules/storm";
|
|
4
|
+
import unicornRules from "../rules/unicorn";
|
|
5
|
+
|
|
6
|
+
const config: Linter.Config = {
|
|
7
|
+
root: true,
|
|
8
|
+
overrides: [
|
|
9
|
+
{
|
|
10
|
+
files: ["*.js", "*.jsx"],
|
|
11
|
+
extends: ["plugin:@nx/javascript"],
|
|
12
|
+
plugins: ["unicorn", "import"],
|
|
13
|
+
rules: {
|
|
14
|
+
...importRules,
|
|
15
|
+
...unicornRules,
|
|
16
|
+
...stormRules
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
]
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
export default config;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { Linter } from "eslint";
|
|
2
|
+
|
|
3
|
+
const config: Linter.Config = {
|
|
4
|
+
root: true,
|
|
5
|
+
overrides: [
|
|
6
|
+
{
|
|
7
|
+
files: ["*.spec.ts", "*.spec.tsx", "*.spec.js", "*.spec.jsx"],
|
|
8
|
+
env: {
|
|
9
|
+
jest: true
|
|
10
|
+
},
|
|
11
|
+
rules: {}
|
|
12
|
+
}
|
|
13
|
+
]
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
export default config;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { Linter } from "eslint";
|
|
2
|
+
import { CODE_BLOCK } from "../constants";
|
|
3
|
+
|
|
4
|
+
const JSONC_FILES = ["tsconfig.json", "tsconfig.base.json", "nx.json", ".vscode/launch.json"];
|
|
5
|
+
const config: Linter.Config = {
|
|
6
|
+
root: true,
|
|
7
|
+
overrides: [
|
|
8
|
+
{
|
|
9
|
+
files: "*.json",
|
|
10
|
+
excludedFiles: JSONC_FILES,
|
|
11
|
+
extends: "plugin:jsonc/recommended-with-json"
|
|
12
|
+
},
|
|
13
|
+
{
|
|
14
|
+
files: ["*.jsonc", ...JSONC_FILES],
|
|
15
|
+
extends: "plugin:jsonc/recommended-with-jsonc"
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
files: "*.json5",
|
|
19
|
+
extends: "plugin:jsonc/recommended-with-json5"
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
files: "*.json{,c,5}",
|
|
23
|
+
excludedFiles: CODE_BLOCK,
|
|
24
|
+
plugins: ["unicorn"],
|
|
25
|
+
rules: {
|
|
26
|
+
"unicorn/filename-case": "error"
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
]
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
export default config;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { JS_FILES } from "../constants";
|
|
2
|
+
|
|
3
|
+
const babelOptions = {
|
|
4
|
+
presets: (() => {
|
|
5
|
+
try {
|
|
6
|
+
require.resolve("next/babel");
|
|
7
|
+
return ["next/babel"];
|
|
8
|
+
} catch (_e) {
|
|
9
|
+
return [];
|
|
10
|
+
}
|
|
11
|
+
})()
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
const config = {
|
|
15
|
+
root: true,
|
|
16
|
+
extends: ["plugin:@next/next/recommended"],
|
|
17
|
+
overrides: [
|
|
18
|
+
{
|
|
19
|
+
files: JS_FILES,
|
|
20
|
+
parserOptions: { babelOptions }
|
|
21
|
+
}
|
|
22
|
+
]
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
export default config;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { Linter } from "eslint";
|
|
2
|
+
import reactRules from "../rules/react";
|
|
3
|
+
import jsxA11yRules from "../rules/ts-docs";
|
|
4
|
+
|
|
5
|
+
const config: Linter.Config = {
|
|
6
|
+
root: true,
|
|
7
|
+
extends: [
|
|
8
|
+
"plugin:react/recommended",
|
|
9
|
+
"plugin:react-hooks/recommended",
|
|
10
|
+
"plugin:jsx-a11y/recommended",
|
|
11
|
+
"plugin:import/react",
|
|
12
|
+
"prettier"
|
|
13
|
+
],
|
|
14
|
+
settings: {
|
|
15
|
+
react: {
|
|
16
|
+
version: "detect"
|
|
17
|
+
}
|
|
18
|
+
},
|
|
19
|
+
rules: {
|
|
20
|
+
...jsxA11yRules,
|
|
21
|
+
...reactRules
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
export default config;
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import type { Linter } from "eslint";
|
|
2
|
+
|
|
3
|
+
const config: Linter.RulesRecord = {
|
|
4
|
+
/**
|
|
5
|
+
* Disallow non-import statements appearing before import statements.
|
|
6
|
+
*
|
|
7
|
+
* 🚫 Not fixable - https://github.com/import-js/eslint-plugin-import/blob/main/docs/rules/first.md
|
|
8
|
+
*/
|
|
9
|
+
"import/first": "error",
|
|
10
|
+
/**
|
|
11
|
+
* Require a newline after the last import/require.
|
|
12
|
+
*
|
|
13
|
+
* 🔧 Fixable - https://github.com/import-js/eslint-plugin-import/blob/main/docs/rules/newline-after-import.md
|
|
14
|
+
*/
|
|
15
|
+
"import/newline-after-import": "warn",
|
|
16
|
+
/**
|
|
17
|
+
* Disallow import of modules using absolute paths.
|
|
18
|
+
*
|
|
19
|
+
* 🚫 Not fixable - https://github.com/import-js/eslint-plugin-import/blob/main/docs/rules/no-absolute-path.md
|
|
20
|
+
*/
|
|
21
|
+
"import/no-absolute-path": "error",
|
|
22
|
+
/**
|
|
23
|
+
* Disallow cyclical dependencies between modules.
|
|
24
|
+
*
|
|
25
|
+
* 🚫 Not fixable - https://github.com/import-js/eslint-plugin-import/blob/main/docs/rules/no-cycle.md
|
|
26
|
+
*/
|
|
27
|
+
"import/no-cycle": "error",
|
|
28
|
+
/**
|
|
29
|
+
* Disallow default exports.
|
|
30
|
+
*
|
|
31
|
+
* 🚫 Not fixable - https://github.com/import-js/eslint-plugin-import/blob/main/docs/rules/no-default-export.md
|
|
32
|
+
*/
|
|
33
|
+
"import/no-default-export": "error",
|
|
34
|
+
/**
|
|
35
|
+
* Disallow the use of extraneous packages.
|
|
36
|
+
*
|
|
37
|
+
* 🚫 Not fixable - https://github.com/import-js/eslint-plugin-import/blob/main/docs/rules/no-extraneous-dependencies.md
|
|
38
|
+
*/
|
|
39
|
+
"import/no-extraneous-dependencies": ["error", { includeInternal: true, includeTypes: true }],
|
|
40
|
+
/**
|
|
41
|
+
* Disallow mutable exports.
|
|
42
|
+
*
|
|
43
|
+
* 🚫 Not fixable - https://github.com/import-js/eslint-plugin-import/blob/main/docs/rules/no-mutable-exports.md
|
|
44
|
+
*/
|
|
45
|
+
"import/no-mutable-exports": "error",
|
|
46
|
+
/**
|
|
47
|
+
* Disallow importing packages through relative paths.
|
|
48
|
+
*
|
|
49
|
+
* 🚫 Not fixable - https://github.com/import-js/eslint-plugin-import/blob/main/docs/rules/no-relative-packages.md
|
|
50
|
+
*/
|
|
51
|
+
"import/no-relative-packages": "warn",
|
|
52
|
+
/**
|
|
53
|
+
* Disallow a module from importing itself.
|
|
54
|
+
*
|
|
55
|
+
* 🚫 Not fixable - https://github.com/import-js/eslint-plugin-import/blob/main/docs/rules/no-self-import.md
|
|
56
|
+
*/
|
|
57
|
+
"import/no-self-import": "error",
|
|
58
|
+
/**
|
|
59
|
+
* Ensures that there are no useless path segments.
|
|
60
|
+
*
|
|
61
|
+
* 🚫 Not fixable - https://github.com/import-js/eslint-plugin-import/blob/main/docs/rules/no-useless-path-segments.md
|
|
62
|
+
*/
|
|
63
|
+
"import/no-useless-path-segments": ["error"],
|
|
64
|
+
/**
|
|
65
|
+
* Enforce a module import order convention.
|
|
66
|
+
*
|
|
67
|
+
* 🔧 Fixable - https://github.com/import-js/eslint-plugin-import/blob/main/docs/rules/order.md
|
|
68
|
+
*/
|
|
69
|
+
"import/order": [
|
|
70
|
+
"warn",
|
|
71
|
+
{
|
|
72
|
+
groups: [
|
|
73
|
+
"builtin", // Node.js built-in modules
|
|
74
|
+
"external", // Packages
|
|
75
|
+
"internal", // Aliased modules
|
|
76
|
+
"parent", // Relative parent
|
|
77
|
+
"sibling", // Relative sibling
|
|
78
|
+
"index" // Relative index
|
|
79
|
+
],
|
|
80
|
+
"newlines-between": "never"
|
|
81
|
+
}
|
|
82
|
+
]
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
export default config;
|
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
|
|
1
|
+
import type { Linter } from "eslint";
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
var config = {
|
|
3
|
+
const config: Linter.RulesRecord = {
|
|
5
4
|
// We recommend using TypeScript over `prop-types`, as `prop-types` can add
|
|
6
5
|
// to a project's build size.
|
|
7
6
|
"react/prop-types": "off",
|
|
@@ -100,40 +99,5 @@ var config = {
|
|
|
100
99
|
*/
|
|
101
100
|
"react/self-closing-comp": "warn"
|
|
102
101
|
};
|
|
103
|
-
var react_default = config;
|
|
104
102
|
|
|
105
|
-
|
|
106
|
-
var config2 = {
|
|
107
|
-
/**
|
|
108
|
-
* Require TSDoc comments conform to the TSDoc specification.
|
|
109
|
-
*
|
|
110
|
-
* 🚫 Not fixable - https://github.com/microsoft/tsdoc/tree/master/eslint-plugin
|
|
111
|
-
*/
|
|
112
|
-
"tsdoc/syntax": "error"
|
|
113
|
-
};
|
|
114
|
-
var ts_docs_default = config2;
|
|
115
|
-
|
|
116
|
-
// packages/linting-tools/src/eslint/react/index.ts
|
|
117
|
-
var config3 = {
|
|
118
|
-
root: true,
|
|
119
|
-
extends: [
|
|
120
|
-
"plugin:react/recommended",
|
|
121
|
-
"plugin:react-hooks/recommended",
|
|
122
|
-
"plugin:jsx-a11y/recommended",
|
|
123
|
-
"plugin:import/react",
|
|
124
|
-
"prettier"
|
|
125
|
-
],
|
|
126
|
-
settings: {
|
|
127
|
-
react: {
|
|
128
|
-
version: "detect"
|
|
129
|
-
}
|
|
130
|
-
},
|
|
131
|
-
rules: {
|
|
132
|
-
...ts_docs_default,
|
|
133
|
-
...react_default
|
|
134
|
-
}
|
|
135
|
-
};
|
|
136
|
-
var react_default2 = config3;
|
|
137
|
-
export {
|
|
138
|
-
react_default2 as default
|
|
139
|
-
};
|
|
103
|
+
export default config;
|