@ovt2/biome-react-kit 0.0.0-stage → 2.3.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 +200 -2
- package/bin/cli.mjs +313 -0
- package/package.json +44 -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,201 @@
|
|
|
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
|
+
## CLI commands
|
|
38
|
+
|
|
39
|
+
Beyond `init`, the kit's own CLI wraps the Biome binary it already installed
|
|
40
|
+
in your project, so you never have to know Biome's own flags. Once it's
|
|
41
|
+
installed, use the short `biome-kit` alias instead of the full package name
|
|
42
|
+
— `bunx` resolves it from `node_modules/.bin` without touching the network:
|
|
43
|
+
|
|
44
|
+
```sh
|
|
45
|
+
bunx biome-kit check # biome check .
|
|
46
|
+
bunx biome-kit check:fix # biome check --write .
|
|
47
|
+
bunx biome-kit ci # biome ci --reporter=github .
|
|
48
|
+
bunx biome-kit check src/foo.ts # pass specific paths through
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
(The full name `@ovt2/biome-react-kit` still works everywhere `biome-kit`
|
|
52
|
+
does — it's the same binary under two names. You only _need_ the full name
|
|
53
|
+
once, for the very first `init`, since `bunx` has to resolve that from the
|
|
54
|
+
registry before anything is installed locally.)
|
|
55
|
+
|
|
56
|
+
These require Bun to invoke (same as `init`), since the CLI itself is a Bun
|
|
57
|
+
script. The `check`/`check:fix` scripts that `init` writes into your
|
|
58
|
+
`package.json` call `biome` directly instead, so `npm run check` (or
|
|
59
|
+
`pnpm`/`yarn run check`) stays Bun-free for everyday use — the CLI commands
|
|
60
|
+
above are a convenience for anyone who already has Bun and wants one
|
|
61
|
+
consistent command across projects.
|
|
62
|
+
|
|
63
|
+
See the [Command reference](#command-reference) below for every flag and
|
|
64
|
+
manual (non-CLI) setup path.
|
|
65
|
+
|
|
66
|
+
## Presets
|
|
67
|
+
|
|
68
|
+
| Name | Extends path | Use case |
|
|
69
|
+
| ------------------------------------ | ----------------------- | ------------------------------------------------------------------------------------------------ |
|
|
70
|
+
| `@ovt2/biome-react-kit/biome` | `./presets/base.json` | Default: recommended rules + React domain, warns on unused code/console. |
|
|
71
|
+
| `@ovt2/biome-react-kit/biome/strict` | `./presets/strict.json` | Base rules raised to errors (unused code, `any`, non-null assertions, console, exhaustive deps). |
|
|
72
|
+
| `@ovt2/biome-react-kit/biome/next` | `./presets/next.json` | Base preset plus the Next.js lint domain. |
|
|
73
|
+
|
|
74
|
+
Presets intentionally don't set `files.includes` — setting it in your own
|
|
75
|
+
`biome.json` would _replace_ the kit's, not merge with it. For Next.js apps,
|
|
76
|
+
add your own ignores:
|
|
77
|
+
|
|
78
|
+
```json
|
|
79
|
+
{
|
|
80
|
+
"extends": ["@ovt2/biome-react-kit/biome/next"],
|
|
81
|
+
"files": { "includes": ["**", "!**/.next", "!**/out", "!**/next-env.d.ts"] }
|
|
82
|
+
}
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
Add scripts:
|
|
86
|
+
|
|
87
|
+
```json
|
|
88
|
+
"check": "biome check .",
|
|
89
|
+
"check:fix": "biome check --write ."
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
## Command reference
|
|
93
|
+
|
|
94
|
+
Every command this kit provides, for every case.
|
|
95
|
+
|
|
96
|
+
### `init` — one-time project setup
|
|
97
|
+
|
|
98
|
+
```sh
|
|
99
|
+
# Default: base preset, installs husky + CI workflow
|
|
100
|
+
bunx @ovt2/biome-react-kit init
|
|
101
|
+
|
|
102
|
+
# Pick a different preset
|
|
103
|
+
bunx @ovt2/biome-react-kit init --preset strict
|
|
104
|
+
bunx @ovt2/biome-react-kit init --preset next
|
|
105
|
+
|
|
106
|
+
# Skip the pre-commit hook (no husky install, no .husky/pre-commit, no "prepare" script)
|
|
107
|
+
bunx @ovt2/biome-react-kit init --no-hooks
|
|
108
|
+
|
|
109
|
+
# Skip the GitHub Actions workflow (no .github/workflows/biome.yml)
|
|
110
|
+
bunx @ovt2/biome-react-kit init --no-ci
|
|
111
|
+
|
|
112
|
+
# Don't install anything — just print the install command and write the
|
|
113
|
+
# files that don't depend on packages being present yet
|
|
114
|
+
bunx @ovt2/biome-react-kit init --skip-install
|
|
115
|
+
|
|
116
|
+
# Combine flags freely
|
|
117
|
+
bunx @ovt2/biome-react-kit init --preset next --no-ci
|
|
118
|
+
bunx @ovt2/biome-react-kit init --preset strict --no-hooks --no-ci --skip-install
|
|
119
|
+
|
|
120
|
+
# Show usage
|
|
121
|
+
bunx @ovt2/biome-react-kit -h
|
|
122
|
+
bunx @ovt2/biome-react-kit --help
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
`init` is always safe to re-run: it never overwrites an existing
|
|
126
|
+
`biome.json`/`biome.jsonc`, script, `.husky/pre-commit`, or
|
|
127
|
+
`.github/workflows/biome.yml` — it just prints `!` warnings for whatever
|
|
128
|
+
already exists.
|
|
129
|
+
|
|
130
|
+
### `check` / `check:fix` / `ci` — run Biome without calling it directly
|
|
131
|
+
|
|
132
|
+
`biome-kit` is the short alias for `@ovt2/biome-react-kit`, installed
|
|
133
|
+
alongside the full name — use whichever you prefer:
|
|
134
|
+
|
|
135
|
+
```sh
|
|
136
|
+
# Lint/format-check the whole project
|
|
137
|
+
bunx biome-kit check
|
|
138
|
+
|
|
139
|
+
# Auto-fix what's fixable
|
|
140
|
+
bunx biome-kit check:fix
|
|
141
|
+
|
|
142
|
+
# CI-formatted output (GitHub Actions annotations), used by the generated workflow
|
|
143
|
+
bunx biome-kit ci
|
|
144
|
+
|
|
145
|
+
# Any of the three accept specific paths instead of defaulting to "."
|
|
146
|
+
bunx biome-kit check src/
|
|
147
|
+
bunx biome-kit check:fix src/components/Button.tsx
|
|
148
|
+
bunx biome-kit ci src/ tests/
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
These fail with a clear message instead of a stack trace if Biome isn't
|
|
152
|
+
installed yet in the current project (run `init` first).
|
|
153
|
+
|
|
154
|
+
### Scripts `init` writes into your `package.json`
|
|
155
|
+
|
|
156
|
+
```sh
|
|
157
|
+
npm run check # or: pnpm check / yarn check / bun run check
|
|
158
|
+
npm run check:fix # or: pnpm check:fix / yarn check:fix / bun run check:fix
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
These call the locally installed `biome` binary directly — no Bun required,
|
|
162
|
+
regardless of which package manager your project uses.
|
|
163
|
+
|
|
164
|
+
### Manual setup (without the CLI)
|
|
165
|
+
|
|
166
|
+
```sh
|
|
167
|
+
# Install Biome + the kit yourself
|
|
168
|
+
bun add -d -E @biomejs/biome @ovt2/biome-react-kit
|
|
169
|
+
npm install --save-dev --save-exact @biomejs/biome @ovt2/biome-react-kit
|
|
170
|
+
pnpm add --save-dev --save-exact @biomejs/biome @ovt2/biome-react-kit
|
|
171
|
+
yarn add --dev --exact @biomejs/biome @ovt2/biome-react-kit
|
|
172
|
+
|
|
173
|
+
# Then create biome.json by hand, extending whichever preset you want:
|
|
174
|
+
# { "extends": ["@ovt2/biome-react-kit/biome"] } — base
|
|
175
|
+
# { "extends": ["@ovt2/biome-react-kit/biome/strict"] } — strict
|
|
176
|
+
# { "extends": ["@ovt2/biome-react-kit/biome/next"] } — next
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
### Manual pre-commit hook (without `init`)
|
|
180
|
+
|
|
181
|
+
```sh
|
|
182
|
+
bun add -d husky
|
|
183
|
+
bunx husky init
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
Replace the contents of `.husky/pre-commit` with:
|
|
187
|
+
|
|
188
|
+
```sh
|
|
189
|
+
./node_modules/.bin/biome check --write --staged --no-errors-on-unmatched --files-ignore-unknown=true
|
|
190
|
+
git update-index --again
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
Commits with unfixable errors (e.g. an unsafe-fix-only rule set to error)
|
|
194
|
+
will be blocked until you resolve them.
|
|
195
|
+
|
|
196
|
+
### Migrating an existing config
|
|
197
|
+
|
|
198
|
+
```sh
|
|
199
|
+
bunx biome migrate eslint --write
|
|
200
|
+
bunx biome migrate prettier --write
|
|
201
|
+
```
|
package/bin/cli.mjs
ADDED
|
@@ -0,0 +1,313 @@
|
|
|
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 BIOME_SUBCOMMANDS = {
|
|
68
|
+
check: (paths) => ["check", ...paths],
|
|
69
|
+
"check:fix": (paths) => ["check", "--write", ...paths],
|
|
70
|
+
ci: (paths) => ["ci", "--reporter=github", ...paths],
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
const HELP = `Usage: bunx ${KIT_NAME} <command> [options]
|
|
74
|
+
|
|
75
|
+
Commands:
|
|
76
|
+
init [options] Set up Biome, scripts, hooks, and CI in the current project
|
|
77
|
+
check [paths] Run biome check (defaults to .)
|
|
78
|
+
check:fix [paths] Run biome check --write (defaults to .)
|
|
79
|
+
ci [paths] Run biome ci --reporter=github (defaults to .)
|
|
80
|
+
|
|
81
|
+
init options:
|
|
82
|
+
--preset <base|strict|next> Which preset to extend (default: base)
|
|
83
|
+
--no-hooks Skip husky + pre-commit hook setup
|
|
84
|
+
--no-ci Skip the GitHub Actions workflow
|
|
85
|
+
--skip-install Print install commands instead of running them
|
|
86
|
+
-h, --help Show this help
|
|
87
|
+
|
|
88
|
+
check / check:fix / ci run the Biome binary already installed in this
|
|
89
|
+
project's node_modules — you never need to call biome yourself. The
|
|
90
|
+
package manager (bun, npm, pnpm, or yarn) used by \`init\` is detected
|
|
91
|
+
from the "packageManager" field in package.json or from whichever
|
|
92
|
+
lockfile is present. Bun is used as the fallback when neither is found.
|
|
93
|
+
|
|
94
|
+
Once installed (after \`init\`), use the shorter alias for every command
|
|
95
|
+
except the first install: \`bunx biome-kit check\`, \`bunx biome-kit
|
|
96
|
+
check:fix\`, \`bunx biome-kit ci\`.
|
|
97
|
+
`;
|
|
98
|
+
|
|
99
|
+
function fail(message) {
|
|
100
|
+
console.error(`✘ ${message}`);
|
|
101
|
+
process.exit(1);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
function ok(message) {
|
|
105
|
+
console.log(`✔ ${message}`);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
function warn(message) {
|
|
109
|
+
console.log(`! ${message}`);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
function detectPackageManager(cwd, pkg) {
|
|
113
|
+
const declared = pkg.packageManager?.split("@")[0];
|
|
114
|
+
if (declared && declared in PACKAGE_MANAGERS) return declared;
|
|
115
|
+
for (const [name, pm] of Object.entries(PACKAGE_MANAGERS)) {
|
|
116
|
+
if (existsSync(join(cwd, pm.lockfile))) return name;
|
|
117
|
+
}
|
|
118
|
+
return "bun";
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
function binPath(cwd, name) {
|
|
122
|
+
return join(cwd, "node_modules", ".bin", name);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
const { values, positionals } = parseArgs({
|
|
126
|
+
args: Bun.argv.slice(2),
|
|
127
|
+
options: {
|
|
128
|
+
preset: { type: "string", default: "base" },
|
|
129
|
+
"no-hooks": { type: "boolean", default: false },
|
|
130
|
+
"no-ci": { type: "boolean", default: false },
|
|
131
|
+
"skip-install": { type: "boolean", default: false },
|
|
132
|
+
help: { type: "boolean", short: "h", default: false },
|
|
133
|
+
},
|
|
134
|
+
allowPositionals: true,
|
|
135
|
+
strict: false,
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
if (values.help) {
|
|
139
|
+
console.log(HELP);
|
|
140
|
+
process.exit(0);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
const command = positionals[0] ?? "init";
|
|
144
|
+
const cwd = process.cwd();
|
|
145
|
+
|
|
146
|
+
if (command in BIOME_SUBCOMMANDS) {
|
|
147
|
+
const biome = binPath(cwd, "biome");
|
|
148
|
+
if (!existsSync(biome)) {
|
|
149
|
+
fail(`Biome isn't installed in this project. Run: bunx ${KIT_NAME} init`);
|
|
150
|
+
}
|
|
151
|
+
const extraPaths = positionals.slice(1);
|
|
152
|
+
const biomeArgs = BIOME_SUBCOMMANDS[command](extraPaths.length ? extraPaths : ["."]);
|
|
153
|
+
try {
|
|
154
|
+
await $`${biome} ${biomeArgs}`.cwd(cwd);
|
|
155
|
+
} catch (error) {
|
|
156
|
+
process.exit(error.exitCode ?? 1);
|
|
157
|
+
}
|
|
158
|
+
process.exit(0);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
if (command !== "init") {
|
|
162
|
+
fail(`Unknown command "${command}". Usage: bunx ${KIT_NAME} <init|check|check:fix|ci> [options]`);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
if (!(values.preset in PRESET_PATHS)) {
|
|
166
|
+
fail(
|
|
167
|
+
`Invalid preset "${values.preset}". Valid presets: ${Object.keys(PRESET_PATHS).join(", ")}.`,
|
|
168
|
+
);
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
const pkgPath = join(cwd, "package.json");
|
|
172
|
+
if (!existsSync(pkgPath)) {
|
|
173
|
+
fail("No package.json found in the current directory.");
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
const pkg = await Bun.file(pkgPath).json();
|
|
177
|
+
const pmName = detectPackageManager(cwd, pkg);
|
|
178
|
+
const pm = PACKAGE_MANAGERS[pmName];
|
|
179
|
+
ok(`Detected package manager: ${pmName}`);
|
|
180
|
+
|
|
181
|
+
const devPackages = ["@biomejs/biome", `${KIT_NAME}@${KIT_VERSION}`];
|
|
182
|
+
if (!values["no-hooks"]) devPackages.push("husky");
|
|
183
|
+
const installArgv = pm.install(devPackages);
|
|
184
|
+
const installCmd = installArgv.join(" ");
|
|
185
|
+
|
|
186
|
+
if (values["skip-install"]) {
|
|
187
|
+
warn(`Skipped install. Run: ${installCmd}`);
|
|
188
|
+
} else {
|
|
189
|
+
try {
|
|
190
|
+
await $`${installArgv}`.cwd(cwd).quiet();
|
|
191
|
+
ok(`Installed ${devPackages.join(", ")}`);
|
|
192
|
+
} catch (error) {
|
|
193
|
+
fail(`Install failed: ${error.message}`);
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
const biomeJsonPath = join(cwd, "biome.json");
|
|
198
|
+
const biomeJsoncPath = join(cwd, "biome.jsonc");
|
|
199
|
+
const extendsSpecifier = `${KIT_NAME}/${PRESET_PATHS[values.preset]}`;
|
|
200
|
+
|
|
201
|
+
if (existsSync(biomeJsonPath) || existsSync(biomeJsoncPath)) {
|
|
202
|
+
warn(`biome.json already exists — add this to its "extends": "${extendsSpecifier}"`);
|
|
203
|
+
} else {
|
|
204
|
+
const config = {
|
|
205
|
+
$schema: "./node_modules/@biomejs/biome/configuration_schema.json",
|
|
206
|
+
extends: [extendsSpecifier],
|
|
207
|
+
};
|
|
208
|
+
if (values.preset === "next") {
|
|
209
|
+
config.files = { includes: ["**", "!**/.next", "!**/out", "!**/next-env.d.ts"] };
|
|
210
|
+
}
|
|
211
|
+
await Bun.write(biomeJsonPath, `${JSON.stringify(config, null, 2)}\n`);
|
|
212
|
+
ok(`Wrote biome.json (extends ${extendsSpecifier})`);
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
pkg.scripts ??= {};
|
|
216
|
+
let pkgChanged = false;
|
|
217
|
+
|
|
218
|
+
if (!pkg.scripts.check) {
|
|
219
|
+
pkg.scripts.check = "biome check .";
|
|
220
|
+
pkgChanged = true;
|
|
221
|
+
ok('Added script "check"');
|
|
222
|
+
} else {
|
|
223
|
+
warn('Script "check" already exists — left untouched');
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
if (!pkg.scripts["check:fix"]) {
|
|
227
|
+
pkg.scripts["check:fix"] = "biome check --write .";
|
|
228
|
+
pkgChanged = true;
|
|
229
|
+
ok('Added script "check:fix"');
|
|
230
|
+
} else {
|
|
231
|
+
warn('Script "check:fix" already exists — left untouched');
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
if (!values["no-hooks"]) {
|
|
235
|
+
if (!pkg.scripts.prepare) {
|
|
236
|
+
pkg.scripts.prepare = "husky";
|
|
237
|
+
pkgChanged = true;
|
|
238
|
+
ok('Added script "prepare"');
|
|
239
|
+
} else if (!pkg.scripts.prepare.includes("husky")) {
|
|
240
|
+
pkg.scripts.prepare = `${pkg.scripts.prepare} && husky`;
|
|
241
|
+
pkgChanged = true;
|
|
242
|
+
ok('Appended husky to existing "prepare" script');
|
|
243
|
+
} else {
|
|
244
|
+
warn('Script "prepare" already runs husky — left untouched');
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
if (pkgChanged) {
|
|
249
|
+
await Bun.write(pkgPath, `${JSON.stringify(pkg, null, 2)}\n`);
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
if (!values["no-hooks"]) {
|
|
253
|
+
const gitDir = join(cwd, ".git");
|
|
254
|
+
if (!existsSync(gitDir)) {
|
|
255
|
+
warn("No .git directory found — skipping husky hook setup");
|
|
256
|
+
} else {
|
|
257
|
+
const huskyDir = join(cwd, ".husky");
|
|
258
|
+
const hookPath = join(huskyDir, "pre-commit");
|
|
259
|
+
if (existsSync(hookPath)) {
|
|
260
|
+
warn(".husky/pre-commit already exists — left untouched");
|
|
261
|
+
} else {
|
|
262
|
+
await $`mkdir -p ${huskyDir}`.quiet();
|
|
263
|
+
await Bun.write(hookPath, await Bun.file(join(KIT_DIR, "templates", "pre-commit")).text());
|
|
264
|
+
await $`chmod 755 ${hookPath}`.quiet();
|
|
265
|
+
ok("Wrote .husky/pre-commit");
|
|
266
|
+
if (values["skip-install"]) {
|
|
267
|
+
warn("Skipped: run `node_modules/.bin/husky` to finish git hooks setup");
|
|
268
|
+
} else {
|
|
269
|
+
const husky = binPath(cwd, "husky");
|
|
270
|
+
if (existsSync(husky)) {
|
|
271
|
+
try {
|
|
272
|
+
await $`${husky}`.cwd(cwd).quiet();
|
|
273
|
+
ok("Ran husky");
|
|
274
|
+
} catch (error) {
|
|
275
|
+
warn(`husky failed: ${error.message}`);
|
|
276
|
+
}
|
|
277
|
+
} else {
|
|
278
|
+
warn(`husky binary not found at ${husky} — run it manually once installed`);
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
if (!values["no-ci"]) {
|
|
286
|
+
const workflowsDir = join(cwd, ".github", "workflows");
|
|
287
|
+
const ciPath = join(workflowsDir, "biome.yml");
|
|
288
|
+
if (existsSync(ciPath)) {
|
|
289
|
+
warn(".github/workflows/biome.yml already exists — left untouched");
|
|
290
|
+
} else {
|
|
291
|
+
const workflow = `name: Biome
|
|
292
|
+
|
|
293
|
+
on:
|
|
294
|
+
pull_request:
|
|
295
|
+
push:
|
|
296
|
+
branches:
|
|
297
|
+
- main
|
|
298
|
+
|
|
299
|
+
jobs:
|
|
300
|
+
biome:
|
|
301
|
+
runs-on: ubuntu-latest
|
|
302
|
+
steps:
|
|
303
|
+
- uses: actions/checkout@v4
|
|
304
|
+
${pm.setupSteps.join("\n")}
|
|
305
|
+
- run: ${pm.runCheckCi}
|
|
306
|
+
`;
|
|
307
|
+
await $`mkdir -p ${workflowsDir}`.quiet();
|
|
308
|
+
await Bun.write(ciPath, workflow);
|
|
309
|
+
ok("Wrote .github/workflows/biome.yml");
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
console.log(`\nRun: ${pmName} run check:fix`);
|
package/package.json
CHANGED
|
@@ -1,6 +1,46 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ovt2/biome-react-kit",
|
|
3
|
-
"version": "
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
|
|
3
|
+
"version": "2.3.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
|
+
"biome-kit": "bin/cli.mjs"
|
|
10
|
+
},
|
|
11
|
+
"exports": {
|
|
12
|
+
"./biome": "./presets/base.json",
|
|
13
|
+
"./biome/strict": "./presets/strict.json",
|
|
14
|
+
"./biome/next": "./presets/next.json",
|
|
15
|
+
"./package.json": "./package.json"
|
|
16
|
+
},
|
|
17
|
+
"files": [
|
|
18
|
+
"bin",
|
|
19
|
+
"presets",
|
|
20
|
+
"templates",
|
|
21
|
+
"README.md"
|
|
22
|
+
],
|
|
23
|
+
"scripts": {
|
|
24
|
+
"check": "biome check .",
|
|
25
|
+
"check:fix": "biome check --write ."
|
|
26
|
+
},
|
|
27
|
+
"peerDependencies": {
|
|
28
|
+
"@biomejs/biome": ">=2.2.0 <3"
|
|
29
|
+
},
|
|
30
|
+
"devDependencies": {
|
|
31
|
+
"@biomejs/biome": "2.6.4"
|
|
32
|
+
},
|
|
33
|
+
"publishConfig": {
|
|
34
|
+
"access": "public"
|
|
35
|
+
},
|
|
36
|
+
"engines": {
|
|
37
|
+
"bun": ">=1.2"
|
|
38
|
+
},
|
|
39
|
+
"keywords": [
|
|
40
|
+
"biome",
|
|
41
|
+
"react",
|
|
42
|
+
"lint",
|
|
43
|
+
"format"
|
|
44
|
+
],
|
|
45
|
+
"author": "Expo2Dev"
|
|
46
|
+
}
|
|
@@ -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
|
+
}
|