Skip to content

chore: replace Biome with oxlint, oxfmt and Knip - #14

Open
Thomasims wants to merge 4 commits into
mainfrom
chore/oxc-tooling
Open

chore: replace Biome with oxlint, oxfmt and Knip#14
Thomasims wants to merge 4 commits into
mainfrom
chore/oxc-tooling

Conversation

@Thomasims

@Thomasims Thomasims commented Sep 7, 2026

Copy link
Copy Markdown
Contributor

Replaces Biome with the shared @antelopejs/tooling-configs presets: oxlint
(type-aware, with the vendored anti-slop rules), oxfmt for formatting and Knip
for dead-code detection. oxlint is pinned to 1.81.0 because the JS plugin API
is still alpha and has to match the version tooling-configs builds against.

tsconfig

Type-aware linting runs through tsgolint, which rejects options TypeScript 7
removed, so moduleResolution: "node" and baseUrl are gone and the
self-referential @antelopejs/interface-database path mapping the suites use is
now written relative (./src/index.ts), which is what the compiler wants once
baseUrl is absent.

module stays commonjs on purpose. Raising it to node16 would look like the
tidier fix and is a runtime break: tsc stops downlevelling dynamic imports and
emits native ESM ones, which bypass the CommonJS resolver detour the ajs
runtime installs.

pnpm build succeeds with no source change.

Code changes the linter forced

  • perfectionist(sort-imports): import ordering across the source and the
    suites, all applied by oxlint --fix.

  • unicorn(no-thenable) on Query.then. This is the only waiver this migration
    adds, and it replaces the biome-ignore that was already there:

    // oxlint-disable-next-line unicorn/no-thenable -- Query is deliberately PromiseLike so `await query` runs it; the contract requires this method.

    Query<T> implements PromiseLike<T> is how await query executes a query, so
    the method cannot go away — and removing it would be a breaking change to the
    interface anyway.

One suppression predates this branch and is carried over unchanged: the file-wide
/* eslint-disable @typescript-eslint/no-unused-expressions */ at the top of
src/tests/merge_operations.test.ts. oxlint honours eslint-flavoured directives,
so it is still load-bearing — removing it surfaces four
eslint(no-unused-expressions) errors from that file's chai property assertions
(expect(order).to.not.be.undefined). Narrowing it to per-line oxlint-disable-next-line
comments is left for a follow-up rather than smuggled into a tooling swap.

No public export was touched. Object.keys(require(...)) is identical before and
after for all eight published subpaths (., common, datum, query,
schema, selection, stream, valueproxy).

The remaining oxlint output is warnings only, which are a deliberate backlog and
are left as they are. pnpm lint exits 0.

Knip

Nothing was deleted. Two things had to be declared instead:

  • The suites live in src/tests/ (the preset only knows src/test/) and
    src/antelope.test.ts is read by ajs module test from
    package.json#antelopeJs.test. The whole compiled tree ships in the package
    and the modules implementing this interface run it as their conformance suite,
    which is why the suites are entry points rather than dead code.
  • src/tests/datasets/** is the fixture surface for those suites.
    datasets/index.ts is the barrel a suite can pull the whole set from, and
    datasets/codec_fields.ts is the type-level regression test added with the
    io-ts field codecs in feat: accept io-ts codecs as table field types #8 — its only job is to keep type-checking, so nothing
    will ever import it. Declaring the directory keeps io-ts/fp-ts honestly
    accounted for instead of dropping a fixture that guards a shipped feature.
  • ajs is ignored as a binary because CI installs @antelopejs/core globally
    instead of adding the CLI to every package.

Verification

pnpm build, pnpm lint, pnpm knip, pnpm format:check all exit 0.
pnpm test: 161 passing, identical to the baseline measured on an untouched
main worktree.

The oxfmt pass is a separate commit and is recorded in .git-blame-ignore-revs
so git blame stays readable. It also normalizes Markdown, YAML and the
package.json key order, which accounts for most of the diff.

Adopts the shared @antelopejs/tooling-configs presets: oxlint with the
vendored anti-slop rules, oxfmt for formatting and Knip for dead code.

Type-aware linting needs a tsconfig tsgolint accepts, so the removed
moduleResolution node10 and baseUrl options go away and the self-referential
path mapping the suites use becomes relative. The module stays on commonjs so
the emit keeps using require, which is what the AntelopeJS resolver hooks.

The one biome-ignore in the tree becomes an oxlint disable: Query is
deliberately thenable because it implements PromiseLike, so `await query` runs
it, and unicorn/no-thenable has to be waived on that method alone.

Knip needs the suites and their fixtures declared as entry points: the whole
compiled tree ships in the package and the implementing modules run it as
their conformance suite, which is not an edge Knip can follow. No export
changes: this package is a contract, so its surface is reachable only from
consumers Knip cannot see.
@Thomasims
Thomasims marked this pull request as draft September 7, 2026 10:37
@Thomasims
Thomasims marked this pull request as ready for review September 7, 2026 16:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant