@naturalcycles/dev-lib 15.5.0 → 15.6.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/cfg/biome.jsonc +77 -0
- package/cfg/init/biome.jsonc +4 -0
- package/cfg/lint-staged.config.js +20 -8
- package/dist/bin/dev-lib.js +11 -0
- package/dist/index.d.ts +1 -1
- package/dist/lint.util.d.ts +1 -0
- package/dist/lint.util.js +26 -6
- package/package.json +2 -1
- package/readme.md +21 -2
package/cfg/biome.jsonc
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://biomejs.dev/schemas/1.8.3/schema.json",
|
|
3
|
+
"files": {
|
|
4
|
+
"ignore": ["**/__exclude", "*.compact.json"]
|
|
5
|
+
},
|
|
6
|
+
"formatter": {
|
|
7
|
+
"enabled": true,
|
|
8
|
+
"formatWithErrors": false,
|
|
9
|
+
"indentStyle": "space",
|
|
10
|
+
"indentWidth": 2,
|
|
11
|
+
"lineEnding": "lf",
|
|
12
|
+
"lineWidth": 100,
|
|
13
|
+
"attributePosition": "auto"
|
|
14
|
+
},
|
|
15
|
+
"organizeImports": { "enabled": true },
|
|
16
|
+
"linter": {
|
|
17
|
+
"enabled": true,
|
|
18
|
+
"rules": {
|
|
19
|
+
"recommended": true,
|
|
20
|
+
"performance": {
|
|
21
|
+
"noDelete": "off" // todo
|
|
22
|
+
},
|
|
23
|
+
"correctness": {
|
|
24
|
+
// noUnusedImports + noUnusedVariables can replace eslint-plugin-unused-vars!
|
|
25
|
+
"noUnusedImports": "error",
|
|
26
|
+
"noUnusedVariables": "error",
|
|
27
|
+
"useArrayLiterals": "error"
|
|
28
|
+
},
|
|
29
|
+
"style": {
|
|
30
|
+
"useShorthandFunctionType": "error",
|
|
31
|
+
"useShorthandAssign": "error",
|
|
32
|
+
"useForOf": "error",
|
|
33
|
+
"useConsistentArrayType": "error",
|
|
34
|
+
"useShorthandArrayType": "error",
|
|
35
|
+
"noDefaultExport": "error",
|
|
36
|
+
"noCommaOperator": "error",
|
|
37
|
+
"noArguments": "error",
|
|
38
|
+
"noNonNullAssertion": "off",
|
|
39
|
+
"useImportType": "off",
|
|
40
|
+
"noParameterAssign": "off",
|
|
41
|
+
"useTemplate": "off",
|
|
42
|
+
"useNumberNamespace": "off",
|
|
43
|
+
"noUnusedTemplateLiteral": "off"
|
|
44
|
+
},
|
|
45
|
+
"suspicious": {
|
|
46
|
+
"noExplicitAny": "off",
|
|
47
|
+
"noAssignInExpressions": "off",
|
|
48
|
+
"noAsyncPromiseExecutor": "off",
|
|
49
|
+
"noPrototypeBuiltins": "off",
|
|
50
|
+
"noGlobalIsNan": "off", // todo,
|
|
51
|
+
"noThenProperty": "off",
|
|
52
|
+
"noImportAssign": "off",
|
|
53
|
+
"noEmptyInterface": "off"
|
|
54
|
+
},
|
|
55
|
+
"complexity": {
|
|
56
|
+
"noForEach": "off",
|
|
57
|
+
"noUselessThisAlias": "off",
|
|
58
|
+
"useLiteralKeys": "off",
|
|
59
|
+
"noBannedTypes": "off"
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
},
|
|
63
|
+
"javascript": {
|
|
64
|
+
"formatter": {
|
|
65
|
+
"jsxQuoteStyle": "double",
|
|
66
|
+
"quoteProperties": "asNeeded",
|
|
67
|
+
"trailingCommas": "all",
|
|
68
|
+
"semicolons": "asNeeded",
|
|
69
|
+
"arrowParentheses": "asNeeded",
|
|
70
|
+
"bracketSpacing": true,
|
|
71
|
+
"bracketSameLine": false,
|
|
72
|
+
"quoteStyle": "single",
|
|
73
|
+
"attributePosition": "auto"
|
|
74
|
+
}
|
|
75
|
+
},
|
|
76
|
+
"overrides": [{ "include": ["tsconfig.json", "tsconfig.*.json"] }]
|
|
77
|
+
}
|
|
@@ -34,6 +34,10 @@ const stylelintExists =
|
|
|
34
34
|
fs.existsSync('node_modules/stylelint-config-standard-scss')
|
|
35
35
|
const stylelintCmd = stylelintExists ? `stylelint --fix --config ${stylelintConfigPath}` : undefined
|
|
36
36
|
|
|
37
|
+
const biomeInstalled = fs.existsSync('node_modules/@biomejs/biome')
|
|
38
|
+
const biomeConfigPath = biomeInstalled && ['biome.jsonc'].find(p => fs.existsSync(p))
|
|
39
|
+
const biomeCmd = biomeConfigPath && `biome lint --write --unsafe --`
|
|
40
|
+
|
|
37
41
|
if (!eslintConfigPathRoot) {
|
|
38
42
|
console.log('eslint is skipped, because ./eslint.config.js is not present')
|
|
39
43
|
}
|
|
@@ -47,11 +51,15 @@ if (!stylelintCmd) {
|
|
|
47
51
|
}
|
|
48
52
|
|
|
49
53
|
const linters = {
|
|
50
|
-
// *.{ts,tsx,vue} files: eslint, prettier
|
|
54
|
+
// *.{ts,tsx,vue} files: biome, eslint, prettier
|
|
51
55
|
'./src/**/*.{ts,tsx,vue}': match => {
|
|
52
56
|
const filesList = getFilesList(match)
|
|
53
57
|
if (!filesList) return []
|
|
54
|
-
return [
|
|
58
|
+
return [
|
|
59
|
+
biomeCmd,
|
|
60
|
+
eslintConfigPathRoot && `${eslintCmd} --config ${eslintConfigPathRoot}`,
|
|
61
|
+
prettierCmd,
|
|
62
|
+
]
|
|
55
63
|
.filter(Boolean)
|
|
56
64
|
.map(s => `${s} ${filesList}`)
|
|
57
65
|
},
|
|
@@ -74,20 +82,21 @@ const linters = {
|
|
|
74
82
|
// prettierCmd].map(s => `${s} ${filesList}`)
|
|
75
83
|
// },
|
|
76
84
|
|
|
77
|
-
// Files for Stylelint + Prettier
|
|
85
|
+
// Files for Biome + Stylelint + Prettier
|
|
78
86
|
[`./{${prettierDirs}}/**/*.{${stylelintExtensions}}`]: match => {
|
|
79
87
|
const filesList = getFilesList(match)
|
|
80
88
|
if (!filesList) return []
|
|
81
|
-
return [stylelintCmd, prettierCmd].filter(Boolean).map(s => `${s} ${filesList}`)
|
|
89
|
+
return [biomeCmd, stylelintCmd, prettierCmd].filter(Boolean).map(s => `${s} ${filesList}`)
|
|
82
90
|
},
|
|
83
91
|
|
|
84
|
-
// Files in root dir
|
|
92
|
+
// Files in root dir: prettier
|
|
85
93
|
[`./*.{${prettierExtensionsAll}}`]: match => {
|
|
86
94
|
const filesList = getFilesList(match)
|
|
87
95
|
if (!filesList || !prettierCmd) return []
|
|
88
96
|
return [prettierCmd].map(s => `${s} ${filesList}`)
|
|
89
97
|
},
|
|
90
98
|
|
|
99
|
+
// ktlint
|
|
91
100
|
'**/*.{kt,kts}': match => {
|
|
92
101
|
const filesList = getFilesList(match)
|
|
93
102
|
if (!filesList) return []
|
|
@@ -122,11 +131,12 @@ if (fs.existsSync(`./scripts`)) {
|
|
|
122
131
|
fs.existsSync(p),
|
|
123
132
|
)
|
|
124
133
|
Object.assign(linters, {
|
|
125
|
-
// eslint, Prettier
|
|
134
|
+
// biome, eslint, Prettier
|
|
126
135
|
'./scripts/**/*.{ts,tsx}': match => {
|
|
127
136
|
const filesList = getFilesList(match)
|
|
128
137
|
if (!filesList) return []
|
|
129
138
|
return [
|
|
139
|
+
biomeCmd,
|
|
130
140
|
eslintConfigPathScripts &&
|
|
131
141
|
`${eslintCmd} --config ${eslintConfigPathScripts} --parser-options=project:./scripts/tsconfig.json`,
|
|
132
142
|
prettierCmd,
|
|
@@ -144,11 +154,12 @@ if (fs.existsSync(`./e2e`)) {
|
|
|
144
154
|
)
|
|
145
155
|
|
|
146
156
|
Object.assign(linters, {
|
|
147
|
-
// eslint, Prettier
|
|
157
|
+
// biome, eslint, Prettier
|
|
148
158
|
'./e2e/**/*.{ts,tsx}': match => {
|
|
149
159
|
const filesList = getFilesList(match)
|
|
150
160
|
if (!filesList) return []
|
|
151
161
|
return [
|
|
162
|
+
biomeCmd,
|
|
152
163
|
eslintConfigPathE2e &&
|
|
153
164
|
`${eslintCmd} --config ${eslintConfigPathE2e} --parser-options=project:./e2e/tsconfig.json`,
|
|
154
165
|
prettierCmd,
|
|
@@ -166,11 +177,12 @@ if (fs.existsSync(`./playwright`)) {
|
|
|
166
177
|
)
|
|
167
178
|
|
|
168
179
|
Object.assign(linters, {
|
|
169
|
-
// eslint, Prettier
|
|
180
|
+
// biome, eslint, Prettier
|
|
170
181
|
'./playwright/**/*.{ts,tsx}': match => {
|
|
171
182
|
const filesList = getFilesList(match)
|
|
172
183
|
if (!filesList) return []
|
|
173
184
|
return [
|
|
185
|
+
biomeCmd,
|
|
174
186
|
eslintConfigPathE2e &&
|
|
175
187
|
`${eslintCmd} --config ${eslintConfigPathE2e} --parser-options=project:./playwright/tsconfig.json`,
|
|
176
188
|
prettierCmd,
|
package/dist/bin/dev-lib.js
CHANGED
|
@@ -67,6 +67,17 @@ const commands = [
|
|
|
67
67
|
desc: 'Run eslint on all files with "auto-fix" disabled. Useful for debugging.',
|
|
68
68
|
interactiveOnly: true,
|
|
69
69
|
},
|
|
70
|
+
{
|
|
71
|
+
name: 'biome',
|
|
72
|
+
fn: () => (0, lint_util_1.runBiome)(true),
|
|
73
|
+
desc: 'Run biome linter on all files.',
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
name: 'biome --no-fix',
|
|
77
|
+
fn: () => (0, lint_util_1.runBiome)(true, false),
|
|
78
|
+
desc: 'Run biome linter on all files with "auto-fix" disabled. Useful for debugging.',
|
|
79
|
+
interactiveOnly: true,
|
|
80
|
+
},
|
|
70
81
|
{ name: 'prettier', fn: lint_util_1.runPrettier, desc: 'Run prettier on all files.' },
|
|
71
82
|
{ name: 'stylelint', fn: lint_util_1.stylelintAll, desc: 'Run stylelint on all files.' },
|
|
72
83
|
{ name: 'commitlint', fn: lint_util_1.runCommitlintCommand, desc: 'Run commitlint.', cliOnly: true },
|
package/dist/index.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export {};
|
|
1
|
+
export type {};
|
package/dist/lint.util.d.ts
CHANGED
|
@@ -14,4 +14,5 @@ export declare function runPrettier(): void;
|
|
|
14
14
|
export declare function stylelintAll(): void;
|
|
15
15
|
export declare function lintStagedCommand(): Promise<void>;
|
|
16
16
|
export declare function runCommitlintCommand(): void;
|
|
17
|
+
export declare function runBiome(verbose?: boolean, fix?: boolean): void;
|
|
17
18
|
export {};
|
package/dist/lint.util.js
CHANGED
|
@@ -6,6 +6,7 @@ exports.runPrettier = runPrettier;
|
|
|
6
6
|
exports.stylelintAll = stylelintAll;
|
|
7
7
|
exports.lintStagedCommand = lintStagedCommand;
|
|
8
8
|
exports.runCommitlintCommand = runCommitlintCommand;
|
|
9
|
+
exports.runBiome = runBiome;
|
|
9
10
|
const tslib_1 = require("tslib");
|
|
10
11
|
const node_child_process_1 = tslib_1.__importDefault(require("node:child_process"));
|
|
11
12
|
const node_fs_1 = tslib_1.__importDefault(require("node:fs"));
|
|
@@ -35,6 +36,10 @@ async function lintAllCommand() {
|
|
|
35
36
|
console.log('lint-all: git shows changes before run:');
|
|
36
37
|
console.log(gitStatusAtStart);
|
|
37
38
|
}
|
|
39
|
+
// Fast linters (that run in <1 second) go first
|
|
40
|
+
runActionLint();
|
|
41
|
+
runBiome();
|
|
42
|
+
// From this point we start the "slow" linters, with ESLint leading the way
|
|
38
43
|
// We run eslint BEFORE Prettier, because eslint can delete e.g unused imports.
|
|
39
44
|
await eslintAll();
|
|
40
45
|
if (node_fs_1.default.existsSync(`node_modules/stylelint`) &&
|
|
@@ -42,7 +47,6 @@ async function lintAllCommand() {
|
|
|
42
47
|
stylelintAll();
|
|
43
48
|
}
|
|
44
49
|
runPrettier();
|
|
45
|
-
runActionLint();
|
|
46
50
|
await runKTLint();
|
|
47
51
|
console.log(`${(0, nodejs_lib_1.boldGrey)('lint-all')} ${(0, nodejs_lib_1.dimGrey)(`took ` + (0, js_lib_1._since)(started))}`);
|
|
48
52
|
if (needToTrackChanges) {
|
|
@@ -181,7 +185,8 @@ async function lintStagedCommand() {
|
|
|
181
185
|
// const lintStaged = require('lint-staged')
|
|
182
186
|
// lint-staged is ESM since 12.0
|
|
183
187
|
// const lintStaged = await import('lint-staged')
|
|
184
|
-
|
|
188
|
+
/* eslint-disable no-eval */
|
|
189
|
+
// biome-ignore lint/security/noGlobalEval: ok
|
|
185
190
|
const { default: lintStaged } = await eval(`import('lint-staged')`);
|
|
186
191
|
const success = await lintStaged({
|
|
187
192
|
configPath: config,
|
|
@@ -206,10 +211,10 @@ function runCommitlintCommand() {
|
|
|
206
211
|
});
|
|
207
212
|
}
|
|
208
213
|
async function runKTLint() {
|
|
209
|
-
if (node_fs_1.default.existsSync(`node_modules/@naturalcycles/ktlint`))
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
214
|
+
if (!node_fs_1.default.existsSync(`node_modules/@naturalcycles/ktlint`))
|
|
215
|
+
return;
|
|
216
|
+
const ktlintLib = require('@naturalcycles/ktlint');
|
|
217
|
+
await ktlintLib.ktlintAll();
|
|
213
218
|
}
|
|
214
219
|
function runActionLint() {
|
|
215
220
|
// Only run if there is a folder of `.github/workflows`, otherwise actionlint will fail
|
|
@@ -224,6 +229,21 @@ function runActionLint() {
|
|
|
224
229
|
console.log(`actionlint is not installed and won't be run.\nThis is how to install it: https://github.com/rhysd/actionlint/blob/main/docs/install.md`);
|
|
225
230
|
}
|
|
226
231
|
}
|
|
232
|
+
function runBiome(verbose = false, fix = true) {
|
|
233
|
+
if (!node_fs_1.default.existsSync(`node_modules/@biomejs/biome`)) {
|
|
234
|
+
if (verbose)
|
|
235
|
+
console.log(`biome is not installed (checked in node_modules/@biomejs), skipping`);
|
|
236
|
+
return;
|
|
237
|
+
}
|
|
238
|
+
const configPath = `biome.jsonc`;
|
|
239
|
+
if (!node_fs_1.default.existsSync(configPath)) {
|
|
240
|
+
if (verbose)
|
|
241
|
+
console.log(`biome is installed, but biome.jsonc config file is missing`);
|
|
242
|
+
return;
|
|
243
|
+
}
|
|
244
|
+
const dirs = [`src`, `scripts`, `e2e`, `playwright`].filter(d => node_fs_1.default.existsSync(d));
|
|
245
|
+
(0, nodejs_lib_1.execVoidCommandSync)(`biome`, [`lint`, fix && '--write', fix && '--unsafe', ...dirs].filter(js_lib_1._isTruthy));
|
|
246
|
+
}
|
|
227
247
|
function canRunBinary(name) {
|
|
228
248
|
try {
|
|
229
249
|
execSync(`which ${name}`);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@naturalcycles/dev-lib",
|
|
3
|
-
"version": "15.
|
|
3
|
+
"version": "15.6.0",
|
|
4
4
|
"scripts": {
|
|
5
5
|
"prepare": "husky",
|
|
6
6
|
"tsn-debug": "tsn testScript.ts",
|
|
@@ -51,6 +51,7 @@
|
|
|
51
51
|
"yargs": "^17.0.0"
|
|
52
52
|
},
|
|
53
53
|
"devDependencies": {
|
|
54
|
+
"@biomejs/biome": "^1.8.3",
|
|
54
55
|
"jest": "^29.0.0",
|
|
55
56
|
"stylelint": "^16.0.2",
|
|
56
57
|
"stylelint-config-standard-scss": "^13.0.0"
|
package/readme.md
CHANGED
|
@@ -11,6 +11,17 @@
|
|
|
11
11
|
[](https://snyk.io/package/npm/@naturalcycles/dev-lib)
|
|
12
12
|
[](https://github.com/NaturalCycles/dev-lib/actions)
|
|
13
13
|
|
|
14
|
+
## Tools that dev-lib enables
|
|
15
|
+
|
|
16
|
+
- Prettier
|
|
17
|
+
- ESLint
|
|
18
|
+
- Biome
|
|
19
|
+
- Stylelint
|
|
20
|
+
- Jest
|
|
21
|
+
- ktlint
|
|
22
|
+
- actionlint
|
|
23
|
+
- lint-staged
|
|
24
|
+
|
|
14
25
|
## How to use
|
|
15
26
|
|
|
16
27
|
Install it:
|
|
@@ -20,7 +31,7 @@ Install it:
|
|
|
20
31
|
This unlocks all commands listed below, e.g:
|
|
21
32
|
|
|
22
33
|
yarn dev-lib test
|
|
23
|
-
yarn dev-lib lint
|
|
34
|
+
yarn dev-lib lint
|
|
24
35
|
|
|
25
36
|
`yarn dev-lib` runs "interactive mode" that lets you explore available commands.
|
|
26
37
|
|
|
@@ -143,12 +154,13 @@ If you need to execute shards **in parallel**, you can follow e.g
|
|
|
143
154
|
|
|
144
155
|
#### Lint commands
|
|
145
156
|
|
|
146
|
-
- `lint`: runs ESLint, Stylelint, Prettier, actionlint, ktlint in the right order.
|
|
157
|
+
- `lint`: runs Biome, ESLint, Stylelint, Prettier, actionlint, ktlint in the right order.
|
|
147
158
|
|
|
148
159
|
- `--commitOnChanges` will commit lint-modified changes and push them
|
|
149
160
|
- `--failOnChanges` will exit with status 1 in the end (will fail the command)
|
|
150
161
|
|
|
151
162
|
- `eslint`: runs `eslint` on needed paths
|
|
163
|
+
- `biome`: runs `biome` on needed paths
|
|
152
164
|
- `stylelint`: runs `stylelint` on needed paths
|
|
153
165
|
- `prettier`: runs just Prettier on needed paths
|
|
154
166
|
|
|
@@ -163,6 +175,12 @@ For Stylelint to be run, you need to manually install it in the target project:
|
|
|
163
175
|
|
|
164
176
|
`yarn add -D stylelint stylelint-config-standard-scss`
|
|
165
177
|
|
|
178
|
+
For Biome to run you need to install it like this:
|
|
179
|
+
|
|
180
|
+
`yarn add -D @biomejs/biome`
|
|
181
|
+
|
|
182
|
+
and add `biome.jsonc` config to the root.
|
|
183
|
+
|
|
166
184
|
##### ktlint
|
|
167
185
|
|
|
168
186
|
`ktlint` will be used by lint-staged for all `**/*.{kt,kts}` files.
|
|
@@ -198,6 +216,7 @@ These files are meant to be extended in target project, so act as _recommended d
|
|
|
198
216
|
- `lint-staged.config.js`
|
|
199
217
|
- `prettier.config.js`
|
|
200
218
|
- `eslint.config.js`
|
|
219
|
+
- `biome.jsonc`
|
|
201
220
|
- `jest.config.js`
|
|
202
221
|
|
|
203
222
|
## eslint
|