@ovt2/biome-react-kit 0.0.0-stage → 2.1.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/README.md +99 -2
- package/bin/cli.mjs +280 -0
- package/package.json +43 -4
- package/presets/base.json +45 -0
- package/presets/next.json +10 -0
- package/presets/strict.json +23 -0
- package/templates/pre-commit +2 -0
package/README.md
CHANGED
|
@@ -1,3 +1,100 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @ovt2/biome-react-kit
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Shared Biome lint/format/check preset for our React apps.
|
|
4
|
+
|
|
5
|
+
## Setup
|
|
6
|
+
|
|
7
|
+
One command installs Biome and the kit, writes `biome.json`, adds the
|
|
8
|
+
`check`/`check:fix` scripts, and wires up the pre-commit hook and CI workflow:
|
|
9
|
+
|
|
10
|
+
```sh
|
|
11
|
+
bunx @ovt2/biome-react-kit init
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
Options:
|
|
15
|
+
|
|
16
|
+
| Flag | Effect |
|
|
17
|
+
| ----------------- | -------------------------------------------------- |
|
|
18
|
+
| `--preset <name>` | `base` (default), `strict`, or `next` |
|
|
19
|
+
| `--no-hooks` | Skip husky + the pre-commit hook |
|
|
20
|
+
| `--no-ci` | Skip the GitHub Actions workflow |
|
|
21
|
+
| `--skip-install` | Print the install commands instead of running them |
|
|
22
|
+
| `-h, --help` | Show usage |
|
|
23
|
+
|
|
24
|
+
`init` never overwrites an existing `biome.json`/`biome.jsonc`, script, hook,
|
|
25
|
+
or workflow file — running it again is safe and only reports what's missing.
|
|
26
|
+
|
|
27
|
+
`init` itself always runs through `bunx` (the script is a Bun executable),
|
|
28
|
+
but it doesn't require your project to use Bun: it detects your package
|
|
29
|
+
manager from the `packageManager` field in `package.json`, or otherwise from
|
|
30
|
+
whichever lockfile is present (`bun.lock`, `package-lock.json`,
|
|
31
|
+
`pnpm-lock.yaml`, `yarn.lock`), and uses that package manager's install
|
|
32
|
+
command and CI setup. It falls back to Bun only when none of those is
|
|
33
|
+
found. The pre-commit hook always calls the locally installed
|
|
34
|
+
`node_modules/.bin/biome`, so it works the same regardless of which package
|
|
35
|
+
manager installed it.
|
|
36
|
+
|
|
37
|
+
### Manual setup
|
|
38
|
+
|
|
39
|
+
```sh
|
|
40
|
+
bun add -d -E @biomejs/biome @ovt2/biome-react-kit
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
Create `biome.json`:
|
|
44
|
+
|
|
45
|
+
```json
|
|
46
|
+
{ "extends": ["@ovt2/biome-react-kit/biome"] }
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## Presets
|
|
50
|
+
|
|
51
|
+
| Name | Extends path | Use case |
|
|
52
|
+
| ------------------------------------ | ----------------------- | ------------------------------------------------------------------------------------------------ |
|
|
53
|
+
| `@ovt2/biome-react-kit/biome` | `./presets/base.json` | Default: recommended rules + React domain, warns on unused code/console. |
|
|
54
|
+
| `@ovt2/biome-react-kit/biome/strict` | `./presets/strict.json` | Base rules raised to errors (unused code, `any`, non-null assertions, console, exhaustive deps). |
|
|
55
|
+
| `@ovt2/biome-react-kit/biome/next` | `./presets/next.json` | Base preset plus the Next.js lint domain. |
|
|
56
|
+
|
|
57
|
+
Presets intentionally don't set `files.includes` — setting it in your own
|
|
58
|
+
`biome.json` would _replace_ the kit's, not merge with it. For Next.js apps,
|
|
59
|
+
add your own ignores:
|
|
60
|
+
|
|
61
|
+
```json
|
|
62
|
+
{
|
|
63
|
+
"extends": ["@ovt2/biome-react-kit/biome/next"],
|
|
64
|
+
"files": { "includes": ["**", "!**/.next", "!**/out", "!**/next-env.d.ts"] }
|
|
65
|
+
}
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
Add scripts:
|
|
69
|
+
|
|
70
|
+
```json
|
|
71
|
+
"check": "biome check .",
|
|
72
|
+
"check:fix": "biome check --write ."
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
## Pre-commit hook
|
|
76
|
+
|
|
77
|
+
Run Biome on staged files before every commit so formatting and fixable lint
|
|
78
|
+
issues never reach the repo:
|
|
79
|
+
|
|
80
|
+
```sh
|
|
81
|
+
bun add -d husky
|
|
82
|
+
bunx husky init
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
Replace the contents of `.husky/pre-commit` with:
|
|
86
|
+
|
|
87
|
+
```sh
|
|
88
|
+
./node_modules/.bin/biome check --write --staged --no-errors-on-unmatched --files-ignore-unknown=true
|
|
89
|
+
git update-index --again
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
Commits with unfixable errors (e.g. an unsafe-fix-only rule set to error)
|
|
93
|
+
will be blocked until you resolve them.
|
|
94
|
+
|
|
95
|
+
## Migrating from ESLint/Prettier
|
|
96
|
+
|
|
97
|
+
```sh
|
|
98
|
+
bunx biome migrate eslint --write
|
|
99
|
+
bunx biome migrate prettier --write
|
|
100
|
+
```
|
package/bin/cli.mjs
ADDED
|
@@ -0,0 +1,280 @@
|
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
|
+
import { existsSync } from "node:fs";
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
import { parseArgs } from "node:util";
|
|
5
|
+
import { $ } from "bun";
|
|
6
|
+
|
|
7
|
+
const KIT_DIR = join(import.meta.dir, "..");
|
|
8
|
+
const KIT_PKG = await Bun.file(join(KIT_DIR, "package.json")).json();
|
|
9
|
+
const KIT_NAME = KIT_PKG.name;
|
|
10
|
+
const KIT_VERSION = KIT_PKG.version;
|
|
11
|
+
|
|
12
|
+
const PRESET_PATHS = {
|
|
13
|
+
base: "biome",
|
|
14
|
+
strict: "biome/strict",
|
|
15
|
+
next: "biome/next",
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
const PACKAGE_MANAGERS = {
|
|
19
|
+
bun: {
|
|
20
|
+
lockfile: "bun.lock",
|
|
21
|
+
install: (pkgs) => ["bun", "add", "--dev", "--exact", ...pkgs],
|
|
22
|
+
runCheckCi: "bunx biome ci --reporter=github .",
|
|
23
|
+
setupSteps: [
|
|
24
|
+
" - uses: oven-sh/setup-bun@v2",
|
|
25
|
+
" - run: bun install --frozen-lockfile",
|
|
26
|
+
],
|
|
27
|
+
},
|
|
28
|
+
npm: {
|
|
29
|
+
lockfile: "package-lock.json",
|
|
30
|
+
install: (pkgs) => ["npm", "install", "--save-dev", "--save-exact", ...pkgs],
|
|
31
|
+
runCheckCi: "npx biome ci --reporter=github .",
|
|
32
|
+
setupSteps: [
|
|
33
|
+
" - uses: actions/setup-node@v4",
|
|
34
|
+
" with:",
|
|
35
|
+
" node-version: 20",
|
|
36
|
+
" cache: npm",
|
|
37
|
+
" - run: npm ci",
|
|
38
|
+
],
|
|
39
|
+
},
|
|
40
|
+
pnpm: {
|
|
41
|
+
lockfile: "pnpm-lock.yaml",
|
|
42
|
+
install: (pkgs) => ["pnpm", "add", "--save-dev", "--save-exact", ...pkgs],
|
|
43
|
+
runCheckCi: "pnpm exec biome ci --reporter=github .",
|
|
44
|
+
setupSteps: [
|
|
45
|
+
" - uses: pnpm/action-setup@v4",
|
|
46
|
+
" - uses: actions/setup-node@v4",
|
|
47
|
+
" with:",
|
|
48
|
+
" node-version: 20",
|
|
49
|
+
" cache: pnpm",
|
|
50
|
+
" - run: pnpm install --frozen-lockfile",
|
|
51
|
+
],
|
|
52
|
+
},
|
|
53
|
+
yarn: {
|
|
54
|
+
lockfile: "yarn.lock",
|
|
55
|
+
install: (pkgs) => ["yarn", "add", "--dev", "--exact", ...pkgs],
|
|
56
|
+
runCheckCi: "yarn biome ci --reporter=github .",
|
|
57
|
+
setupSteps: [
|
|
58
|
+
" - uses: actions/setup-node@v4",
|
|
59
|
+
" with:",
|
|
60
|
+
" node-version: 20",
|
|
61
|
+
" cache: yarn",
|
|
62
|
+
" - run: yarn install --frozen-lockfile",
|
|
63
|
+
],
|
|
64
|
+
},
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
const HELP = `Usage: bunx ${KIT_NAME} init [options]
|
|
68
|
+
|
|
69
|
+
Options:
|
|
70
|
+
--preset <base|strict|next> Which preset to extend (default: base)
|
|
71
|
+
--no-hooks Skip husky + pre-commit hook setup
|
|
72
|
+
--no-ci Skip the GitHub Actions workflow
|
|
73
|
+
--skip-install Print install commands instead of running them
|
|
74
|
+
-h, --help Show this help
|
|
75
|
+
|
|
76
|
+
The package manager (bun, npm, pnpm, or yarn) is detected from the
|
|
77
|
+
"packageManager" field in package.json or from whichever lockfile is
|
|
78
|
+
present in the current directory. Bun is used as the fallback when
|
|
79
|
+
neither is found.
|
|
80
|
+
`;
|
|
81
|
+
|
|
82
|
+
function fail(message) {
|
|
83
|
+
console.error(`✘ ${message}`);
|
|
84
|
+
process.exit(1);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
function ok(message) {
|
|
88
|
+
console.log(`✔ ${message}`);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
function warn(message) {
|
|
92
|
+
console.log(`! ${message}`);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
function detectPackageManager(cwd, pkg) {
|
|
96
|
+
const declared = pkg.packageManager?.split("@")[0];
|
|
97
|
+
if (declared && declared in PACKAGE_MANAGERS) return declared;
|
|
98
|
+
for (const [name, pm] of Object.entries(PACKAGE_MANAGERS)) {
|
|
99
|
+
if (existsSync(join(cwd, pm.lockfile))) return name;
|
|
100
|
+
}
|
|
101
|
+
return "bun";
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
function binPath(cwd, name) {
|
|
105
|
+
return join(cwd, "node_modules", ".bin", name);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
const { values, positionals } = parseArgs({
|
|
109
|
+
args: Bun.argv.slice(2),
|
|
110
|
+
options: {
|
|
111
|
+
preset: { type: "string", default: "base" },
|
|
112
|
+
"no-hooks": { type: "boolean", default: false },
|
|
113
|
+
"no-ci": { type: "boolean", default: false },
|
|
114
|
+
"skip-install": { type: "boolean", default: false },
|
|
115
|
+
help: { type: "boolean", short: "h", default: false },
|
|
116
|
+
},
|
|
117
|
+
allowPositionals: true,
|
|
118
|
+
strict: false,
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
if (values.help) {
|
|
122
|
+
console.log(HELP);
|
|
123
|
+
process.exit(0);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
const command = positionals[0] ?? "init";
|
|
127
|
+
if (command !== "init") {
|
|
128
|
+
fail(`Unknown command "${command}". Usage: bunx ${KIT_NAME} init [options]`);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
if (!(values.preset in PRESET_PATHS)) {
|
|
132
|
+
fail(
|
|
133
|
+
`Invalid preset "${values.preset}". Valid presets: ${Object.keys(PRESET_PATHS).join(", ")}.`,
|
|
134
|
+
);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
const cwd = process.cwd();
|
|
138
|
+
const pkgPath = join(cwd, "package.json");
|
|
139
|
+
if (!existsSync(pkgPath)) {
|
|
140
|
+
fail("No package.json found in the current directory.");
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
const pkg = await Bun.file(pkgPath).json();
|
|
144
|
+
const pmName = detectPackageManager(cwd, pkg);
|
|
145
|
+
const pm = PACKAGE_MANAGERS[pmName];
|
|
146
|
+
ok(`Detected package manager: ${pmName}`);
|
|
147
|
+
|
|
148
|
+
const devPackages = ["@biomejs/biome", `${KIT_NAME}@${KIT_VERSION}`];
|
|
149
|
+
if (!values["no-hooks"]) devPackages.push("husky");
|
|
150
|
+
const installArgv = pm.install(devPackages);
|
|
151
|
+
const installCmd = installArgv.join(" ");
|
|
152
|
+
|
|
153
|
+
if (values["skip-install"]) {
|
|
154
|
+
warn(`Skipped install. Run: ${installCmd}`);
|
|
155
|
+
} else {
|
|
156
|
+
try {
|
|
157
|
+
await $`${installArgv}`.cwd(cwd).quiet();
|
|
158
|
+
ok(`Installed ${devPackages.join(", ")}`);
|
|
159
|
+
} catch (error) {
|
|
160
|
+
fail(`Install failed: ${error.message}`);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
const biomeJsonPath = join(cwd, "biome.json");
|
|
165
|
+
const biomeJsoncPath = join(cwd, "biome.jsonc");
|
|
166
|
+
const extendsSpecifier = `${KIT_NAME}/${PRESET_PATHS[values.preset]}`;
|
|
167
|
+
|
|
168
|
+
if (existsSync(biomeJsonPath) || existsSync(biomeJsoncPath)) {
|
|
169
|
+
warn(`biome.json already exists — add this to its "extends": "${extendsSpecifier}"`);
|
|
170
|
+
} else {
|
|
171
|
+
const config = {
|
|
172
|
+
$schema: "./node_modules/@biomejs/biome/configuration_schema.json",
|
|
173
|
+
extends: [extendsSpecifier],
|
|
174
|
+
};
|
|
175
|
+
if (values.preset === "next") {
|
|
176
|
+
config.files = { includes: ["**", "!**/.next", "!**/out", "!**/next-env.d.ts"] };
|
|
177
|
+
}
|
|
178
|
+
await Bun.write(biomeJsonPath, `${JSON.stringify(config, null, 2)}\n`);
|
|
179
|
+
ok(`Wrote biome.json (extends ${extendsSpecifier})`);
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
pkg.scripts ??= {};
|
|
183
|
+
let pkgChanged = false;
|
|
184
|
+
|
|
185
|
+
if (!pkg.scripts.check) {
|
|
186
|
+
pkg.scripts.check = "biome check .";
|
|
187
|
+
pkgChanged = true;
|
|
188
|
+
ok('Added script "check"');
|
|
189
|
+
} else {
|
|
190
|
+
warn('Script "check" already exists — left untouched');
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
if (!pkg.scripts["check:fix"]) {
|
|
194
|
+
pkg.scripts["check:fix"] = "biome check --write .";
|
|
195
|
+
pkgChanged = true;
|
|
196
|
+
ok('Added script "check:fix"');
|
|
197
|
+
} else {
|
|
198
|
+
warn('Script "check:fix" already exists — left untouched');
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
if (!values["no-hooks"]) {
|
|
202
|
+
if (!pkg.scripts.prepare) {
|
|
203
|
+
pkg.scripts.prepare = "husky";
|
|
204
|
+
pkgChanged = true;
|
|
205
|
+
ok('Added script "prepare"');
|
|
206
|
+
} else if (!pkg.scripts.prepare.includes("husky")) {
|
|
207
|
+
pkg.scripts.prepare = `${pkg.scripts.prepare} && husky`;
|
|
208
|
+
pkgChanged = true;
|
|
209
|
+
ok('Appended husky to existing "prepare" script');
|
|
210
|
+
} else {
|
|
211
|
+
warn('Script "prepare" already runs husky — left untouched');
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
if (pkgChanged) {
|
|
216
|
+
await Bun.write(pkgPath, `${JSON.stringify(pkg, null, 2)}\n`);
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
if (!values["no-hooks"]) {
|
|
220
|
+
const gitDir = join(cwd, ".git");
|
|
221
|
+
if (!existsSync(gitDir)) {
|
|
222
|
+
warn("No .git directory found — skipping husky hook setup");
|
|
223
|
+
} else {
|
|
224
|
+
const huskyDir = join(cwd, ".husky");
|
|
225
|
+
const hookPath = join(huskyDir, "pre-commit");
|
|
226
|
+
if (existsSync(hookPath)) {
|
|
227
|
+
warn(".husky/pre-commit already exists — left untouched");
|
|
228
|
+
} else {
|
|
229
|
+
await $`mkdir -p ${huskyDir}`.quiet();
|
|
230
|
+
await Bun.write(hookPath, await Bun.file(join(KIT_DIR, "templates", "pre-commit")).text());
|
|
231
|
+
await $`chmod 755 ${hookPath}`.quiet();
|
|
232
|
+
ok("Wrote .husky/pre-commit");
|
|
233
|
+
if (values["skip-install"]) {
|
|
234
|
+
warn("Skipped: run `node_modules/.bin/husky` to finish git hooks setup");
|
|
235
|
+
} else {
|
|
236
|
+
const husky = binPath(cwd, "husky");
|
|
237
|
+
if (existsSync(husky)) {
|
|
238
|
+
try {
|
|
239
|
+
await $`${husky}`.cwd(cwd).quiet();
|
|
240
|
+
ok("Ran husky");
|
|
241
|
+
} catch (error) {
|
|
242
|
+
warn(`husky failed: ${error.message}`);
|
|
243
|
+
}
|
|
244
|
+
} else {
|
|
245
|
+
warn(`husky binary not found at ${husky} — run it manually once installed`);
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
if (!values["no-ci"]) {
|
|
253
|
+
const workflowsDir = join(cwd, ".github", "workflows");
|
|
254
|
+
const ciPath = join(workflowsDir, "biome.yml");
|
|
255
|
+
if (existsSync(ciPath)) {
|
|
256
|
+
warn(".github/workflows/biome.yml already exists — left untouched");
|
|
257
|
+
} else {
|
|
258
|
+
const workflow = `name: Biome
|
|
259
|
+
|
|
260
|
+
on:
|
|
261
|
+
pull_request:
|
|
262
|
+
push:
|
|
263
|
+
branches:
|
|
264
|
+
- main
|
|
265
|
+
|
|
266
|
+
jobs:
|
|
267
|
+
biome:
|
|
268
|
+
runs-on: ubuntu-latest
|
|
269
|
+
steps:
|
|
270
|
+
- uses: actions/checkout@v4
|
|
271
|
+
${pm.setupSteps.join("\n")}
|
|
272
|
+
- run: ${pm.runCheckCi}
|
|
273
|
+
`;
|
|
274
|
+
await $`mkdir -p ${workflowsDir}`.quiet();
|
|
275
|
+
await Bun.write(ciPath, workflow);
|
|
276
|
+
ok("Wrote .github/workflows/biome.yml");
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
console.log(`\nRun: ${pmName} run check:fix`);
|
package/package.json
CHANGED
|
@@ -1,6 +1,45 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ovt2/biome-react-kit",
|
|
3
|
-
"version": "
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
|
|
3
|
+
"version": "2.1.0",
|
|
4
|
+
"description": "Shared Biome lint/format/check preset for React apps",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"bin": {
|
|
8
|
+
"biome-react-kit": "./bin/cli.mjs"
|
|
9
|
+
},
|
|
10
|
+
"exports": {
|
|
11
|
+
"./biome": "./presets/base.json",
|
|
12
|
+
"./biome/strict": "./presets/strict.json",
|
|
13
|
+
"./biome/next": "./presets/next.json",
|
|
14
|
+
"./package.json": "./package.json"
|
|
15
|
+
},
|
|
16
|
+
"files": [
|
|
17
|
+
"bin",
|
|
18
|
+
"presets",
|
|
19
|
+
"templates",
|
|
20
|
+
"README.md"
|
|
21
|
+
],
|
|
22
|
+
"scripts": {
|
|
23
|
+
"check": "biome check .",
|
|
24
|
+
"check:fix": "biome check --write ."
|
|
25
|
+
},
|
|
26
|
+
"peerDependencies": {
|
|
27
|
+
"@biomejs/biome": ">=2.2.0 <3"
|
|
28
|
+
},
|
|
29
|
+
"devDependencies": {
|
|
30
|
+
"@biomejs/biome": "2.6.4"
|
|
31
|
+
},
|
|
32
|
+
"publishConfig": {
|
|
33
|
+
"access": "public"
|
|
34
|
+
},
|
|
35
|
+
"engines": {
|
|
36
|
+
"bun": ">=1.2"
|
|
37
|
+
},
|
|
38
|
+
"keywords": [
|
|
39
|
+
"biome",
|
|
40
|
+
"react",
|
|
41
|
+
"lint",
|
|
42
|
+
"format"
|
|
43
|
+
],
|
|
44
|
+
"author": "Expo2Dev"
|
|
45
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://biomejs.dev/schemas/2.6.4/schema.json",
|
|
3
|
+
"vcs": {
|
|
4
|
+
"enabled": true,
|
|
5
|
+
"clientKind": "git",
|
|
6
|
+
"useIgnoreFile": true
|
|
7
|
+
},
|
|
8
|
+
"formatter": {
|
|
9
|
+
"enabled": true,
|
|
10
|
+
"indentStyle": "space",
|
|
11
|
+
"indentWidth": 2,
|
|
12
|
+
"lineWidth": 100
|
|
13
|
+
},
|
|
14
|
+
"javascript": {
|
|
15
|
+
"formatter": {
|
|
16
|
+
"quoteStyle": "double",
|
|
17
|
+
"semicolons": "always",
|
|
18
|
+
"trailingCommas": "all"
|
|
19
|
+
}
|
|
20
|
+
},
|
|
21
|
+
"assist": {
|
|
22
|
+
"actions": {
|
|
23
|
+
"source": { "organizeImports": "on" }
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
"linter": {
|
|
27
|
+
"enabled": true,
|
|
28
|
+
"domains": {
|
|
29
|
+
"react": "recommended"
|
|
30
|
+
},
|
|
31
|
+
"rules": {
|
|
32
|
+
"preset": "recommended",
|
|
33
|
+
"correctness": {
|
|
34
|
+
"noUnusedImports": "warn",
|
|
35
|
+
"noUnusedVariables": "warn"
|
|
36
|
+
},
|
|
37
|
+
"suspicious": {
|
|
38
|
+
"noConsole": {
|
|
39
|
+
"level": "warn",
|
|
40
|
+
"options": { "allow": ["error", "warn"] }
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://biomejs.dev/schemas/2.6.4/schema.json",
|
|
3
|
+
"extends": ["./base.json"],
|
|
4
|
+
"linter": {
|
|
5
|
+
"rules": {
|
|
6
|
+
"correctness": {
|
|
7
|
+
"noUnusedImports": "error",
|
|
8
|
+
"noUnusedVariables": "error",
|
|
9
|
+
"useExhaustiveDependencies": "error"
|
|
10
|
+
},
|
|
11
|
+
"suspicious": {
|
|
12
|
+
"noExplicitAny": "error",
|
|
13
|
+
"noConsole": {
|
|
14
|
+
"level": "error",
|
|
15
|
+
"options": { "allow": ["error", "warn"] }
|
|
16
|
+
}
|
|
17
|
+
},
|
|
18
|
+
"style": {
|
|
19
|
+
"noNonNullAssertion": "error"
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|