Skip to content

Commit 15ca045

Browse files
authored
feat(toolchain): adopt Biome, oxlint, attw; keep eslint-config-next + knip (#98)
Five-tool toolchain adoption ported from libredb-database and adapted to Studio: Biome (formatter-only, lineWidth 120, CSS/JSON excluded), oxlint (fast syntactic linter in front of ESLint), a narrow type-aware ESLint layer over eslint-config-next (Strategy A) scoped to api+db, knip (verified), and @arethetypeswrong/cli (--profile node16). Fixes 5 floating-promise bugs plus a dead-fallback, a dropped error cause, and a useless regex escape surfaced by the new linters. CI lint-and-build now also runs Biome format, build:lib, and attw. Follow-ups (accessibility pass, pre-existing CodeQL/Sonar findings) tracked in #100. Rationale: docs/TOOLCHAIN.md.
1 parent 6f2bc63 commit 15ca045

470 files changed

Lines changed: 33449 additions & 31513 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.editorconfig

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# EditorConfig (https://editorconfig.org) - matches the Biome formatter settings
2+
# so editors agree before Biome ever runs.
3+
root = true
4+
5+
[*]
6+
charset = utf-8
7+
end_of_line = lf
8+
indent_style = space
9+
indent_size = 2
10+
insert_final_newline = true
11+
trim_trailing_whitespace = true
12+
13+
[*.md]
14+
# Markdown hard line breaks are two trailing spaces; do not strip them.
15+
trim_trailing_whitespace = false

.github/workflows/ci.yml

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,10 @@ jobs:
2929
- name: Install dependencies
3030
run: bun install --frozen-lockfile
3131

32-
- name: Run ESLint
32+
- name: Check formatting (Biome)
33+
run: bun run format
34+
35+
- name: Run linters (oxlint + ESLint)
3336
run: bun run lint
3437

3538
- name: Run TypeScript type check
@@ -48,6 +51,12 @@ jobs:
4851
USER_EMAIL: user@libredb.org
4952
USER_PASSWORD: test-user
5053

54+
- name: Build library package (tsup)
55+
run: bun run build:lib
56+
57+
- name: Check package types resolution (attw)
58+
run: bun run attw
59+
5160
test:
5261
name: Unit & Integration Tests
5362
runs-on: ubuntu-latest

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,3 +111,7 @@ data/
111111

112112
docs/superpowers/
113113

114+
# attw packaging scratch (type-resolution check)
115+
.attw/
116+
*.tgz
117+

.oxlintrc.json

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
{
2+
"$schema": "https://raw.githubusercontent.com/oxc-project/oxc/main/npm/oxlint/configuration_schema.json",
3+
"plugins": ["typescript", "oxc", "react", "react-hooks", "jsx-a11y", "nextjs", "import"],
4+
"categories": {
5+
"correctness": "error",
6+
"suspicious": "error",
7+
"perf": "warn",
8+
"pedantic": "off",
9+
"style": "off"
10+
},
11+
"rules": {
12+
"react/react-in-jsx-scope": "off",
13+
"react/no-unstable-nested-components": "off",
14+
"import/no-unassigned-import": "off",
15+
"import/no-named-as-default": "off",
16+
"react-hooks/exhaustive-deps": "off",
17+
"no-unused-vars": "off",
18+
"no-underscore-dangle": "off",
19+
"no-shadow": "off",
20+
"no-control-regex": "off",
21+
"jsx-a11y/no-static-element-interactions": "warn",
22+
"jsx-a11y/click-events-have-key-events": "warn",
23+
"jsx-a11y/label-has-associated-control": "warn",
24+
"jsx-a11y/prefer-tag-over-role": "warn",
25+
"jsx-a11y/no-autofocus": "warn",
26+
"jsx-a11y/control-has-associated-label": "warn",
27+
"jsx-a11y/no-noninteractive-element-interactions": "warn",
28+
"jsx-a11y/anchor-has-content": "warn"
29+
},
30+
"overrides": [
31+
{
32+
"files": ["tests/**", "**/*.test.ts", "**/*.test.tsx"],
33+
"rules": {
34+
"typescript/no-extraneous-class": "off",
35+
"no-useless-constructor": "off",
36+
"no-new": "off",
37+
"no-constant-binary-expression": "off"
38+
}
39+
}
40+
],
41+
"ignorePatterns": ["dist/**", ".next/**", "out/**", "build/**", "coverage/**", "node_modules/**", "next-env.d.ts"]
42+
}

CLAUDE.md

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,14 +24,19 @@ Web-based SQL IDE for cloud-native teams: PostgreSQL, MySQL, SQLite, Oracle, SQL
2424
bun install # deps (Bun preferred)
2525
bun dev # dev server (Turbopack)
2626
bun run build # production build
27-
bun run lint # ESLint 9
27+
bun run format # Biome formatter check (format:fix to write); CSS/JSON excluded
28+
bun run lint # oxlint (fast, syntactic) then ESLint 9 (eslint-config-next + narrow type-aware layer)
29+
bun run lint:oxc # oxlint only
2830
bun run typecheck # TypeScript strict
2931
bun run test # all layers: unit + api + integration + hooks + components
3032
bun run test:e2e # Playwright (requires build)
3133
bun run test:coverage # coverage report
3234
bun run build:lib # tsup → @libredb/studio package dist (see rule below)
35+
bun run attw # validate published type-resolution against the packed tarball (needs build:lib first)
3336
```
3437

38+
> **Toolchain rationale (Biome formatter, oxlint, type-aware ESLint layer, attw) lives in [`docs/TOOLCHAIN.md`](docs/TOOLCHAIN.md).** Biome is formatter-only (lineWidth 120); oxlint is the fast syntactic layer in front of ESLint; `eslint-config-next` still owns React/Next/hooks; a narrow `typescript-eslint` type-aware layer guards `src/app/api` + `src/lib/db` against floating promises; attw uses `--profile node16` (the package targets Node >=24 + modern bundlers, so node10 is ignored).
39+
3540
> **`build:lib` after platform-facing changes:** after changing any component used by platform (workspace, providers, …), run `build:lib``bun run build` (Next.js) does NOT update the package dist.
3641
3742
> **Tests — always `bun run test`, never bare `bun test`.** Component tests need isolated execution groups (`tests/run-components.sh`) to avoid `mock.module()` cross-contamination.
@@ -40,7 +45,7 @@ bun run build:lib # tsup → @libredb/studio package dist (see rule below
4045
4146
## Pre-Commit Verification (MANDATORY)
4247

43-
After every code change, run all four locally before claiming done — they match CI (`ci.yml`, `docker-build-push.yml`): `bun run lint` · `bun run typecheck` · `bun run test` · `bun run build`. A local pass on all four guarantees CI passes; do not skip any.
48+
After every code change, run all five locally before claiming done — they match CI (`ci.yml`, `docker-build-push.yml`): `bun run format` · `bun run lint` · `bun run typecheck` · `bun run test` · `bun run build`. A local pass guarantees CI passes; do not skip any. (`bun run lint` runs oxlint then ESLint; the CI `lint-and-build` job additionally runs `build:lib` + `attw`.)
4449

4550
## Architecture
4651

biome.json

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
{
2+
"$schema": "https://biomejs.dev/schemas/2.5.1/schema.json",
3+
"vcs": { "enabled": true, "clientKind": "git", "useIgnoreFile": true },
4+
"files": {
5+
"includes": ["src/**", "tests/**", "e2e/**", "scripts/**", "*.ts", "*.mts", "*.mjs"]
6+
},
7+
"formatter": {
8+
"enabled": true,
9+
"indentStyle": "space",
10+
"indentWidth": 2,
11+
"lineWidth": 120
12+
},
13+
"javascript": {
14+
"formatter": {
15+
"quoteStyle": "double",
16+
"semicolons": "always"
17+
}
18+
},
19+
"css": { "formatter": { "enabled": false } },
20+
"json": { "formatter": { "enabled": false } },
21+
"linter": { "enabled": false },
22+
"assist": { "enabled": false }
23+
}

0 commit comments

Comments
 (0)