Skip to content

Modernize toolchain: TypeScript 7, oxlint, oxfmt#5

Merged
linyiru merged 6 commits into
mainfrom
chore/ts7-oxc-toolchain
Jul 21, 2026
Merged

Modernize toolchain: TypeScript 7, oxlint, oxfmt#5
linyiru merged 6 commits into
mainfrom
chore/ts7-oxc-toolchain

Conversation

@linyiru

@linyiru linyiru commented Jul 21, 2026

Copy link
Copy Markdown
Collaborator

Summary

Migrates the toolchain to the native-compiler era in four atomic commits:

  1. Upgrade TypeScript to 7.0 — the Go-native tsc, tsc --noEmit drops from ~4.7s to ~1.4s. Two compiler-driven adjustments: a matchesSelector() helper works around TS7 lib.dom's new this is narrowing on Element.matches("<tag>") (which collapses HTMLElement to never for tags like section/dt/figcaption), and a vite-env.d.ts covers side-effect CSS imports (new TS2882).
  2. Replace ESLint with oxlint — typescript-eslint does not support TS7, so lint moves to oxlint with type-aware rules via oxlint-tsgolint (built on typescript-go). Same rule set preserved (no-floating-promises, no-misused-promises, no-unsafe-*, consistent-type-imports); lint drops from ~9.2s to ~1s. Includes four small fixes for real findings the new linter surfaced.
  3. Adopt oxfmt as the repository formatter — the repo previously had no formatter. Prettier-compatible, configured to match existing style (printWidth: 100, no trailing commas). Markdown (translated READMEs/docs) and golden extraction fixtures are deliberately excluded. CI gains a Format check step.
  4. git blame hygiene.git-blame-ignore-revs points at the reformat commit.

The website workspace keeps its own TypeScript 5.x: astro check needs the stable compiler API that only lands in TS 7.1.

Notes for review

  • Commits 1 and 2 are a paired transition: at commit 1 the old ESLint setup cannot run against TS7 (typescript-eslint has no TS7 support). Type check, tests, and build pass at every commit; lint is green again from commit 2.
  • The bulk of the diff is the one-time reformat in commit 3; commits 1–2 carry the semantic changes and are small.
  • oxlint's type-aware mode is alpha; tsc --noEmit (strict) remains the type-safety gate in CI.

Testing

  • pnpm check / pnpm lint / pnpm fmt:check all green
  • pnpm test — 472 tests in 42 files pass
  • pnpm check:extension, pnpm build (extension + website) pass

linyiru added 4 commits July 22, 2026 06:53
TypeScript 7.0 ships the native Go compiler as the standard tsc, cutting
tsc --noEmit on the extension from ~4.7s to ~1.4s.

Two adjustments the new compiler required:

- TS7's lib.dom types Element.matches("<tag>") as a `this is` guard.
  For tags that map to HTMLElement itself (section, dt, figcaption) the
  false branch collapses HTMLElement to `never`, breaking every check
  after it. A matchesSelector() helper routes the selector through a
  plain string parameter to keep matches a boolean test.
- Side-effect CSS imports now fail with TS2882; a vite-env.d.ts with
  vite/client types covers them.

The website keeps its own TypeScript 5.x: astro check depends on the
stable compiler API that only lands in TS 7.1.
typescript-eslint does not support TypeScript 7, so the previous lint
setup cannot run against the new compiler. oxlint's type-aware mode
(via oxlint-tsgolint, built on typescript-go) covers the same rules —
consistent-type-imports, no-floating-promises, no-misused-promises,
no-unnecessary-type-assertion and the no-unsafe-* family — and runs the
whole lint in about a second instead of nine.

The .oxlintrc.json mirrors the old eslint.config.mjs: correctness
category as errors, the same type-aware rules opted in, node overrides
for config/scripts .mjs files, and type-aware rules kept off for them.

Small code fixes for findings the new linter surfaced:
- drop meaningless `void` on the synchronous #drain() calls
- drop an unnecessary `?? {}` fallback in an object spread
- count code points via Array.from instead of string spread
- remove unsafe optional chaining before property access in a test
The repo previously had no formatter. oxfmt is Prettier-compatible and
formats the whole tree in about a second, so CI can enforce it cheaply
(new Format check step runs oxfmt --check).

Configuration follows the existing code style to keep this reformat
minimal: printWidth 100 (also oxfmt's default) and no trailing commas.
Two file groups are excluded on purpose:

- **/*.md — prose, much of it translated READMEs; rewrapping would
  churn every locale for no benefit
- apps/extension/test/fixtures/** — golden extraction fixtures whose
  whitespace is part of what the tests assert

Everything else (source, scripts, JSON, CSS, HTML, YAML) is formatted
in this commit; root scripts fmt / fmt:check are the entry points.
Comment thread apps/extension/scripts/capture-fixture.mjs Fixed
Comment thread apps/extension/scripts/capture-fixture.mjs Fixed

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR modernizes the repository’s TypeScript/tooling stack by upgrading to TypeScript 7, replacing ESLint with oxlint (type-aware), and introducing oxfmt as a formatter with CI enforcement—alongside the associated one-time reformat and a blame-ignore entry to preserve git blame usefulness.

Changes:

  • Upgrade toolchain to TypeScript 7 and apply small code adjustments required by updated lib.dom typings.
  • Replace ESLint/typescript-eslint with oxlint (+ type-aware mode via oxlint-tsgolint).
  • Adopt oxfmt repo-wide (plus CI fmt:check) and add .git-blame-ignore-revs for the reformat commit.

Reviewed changes

Copilot reviewed 97 out of 99 changed files in this pull request and generated no comments.

Show a summary per file
File Description
package.json Adds TS7 + oxlint/oxfmt tooling and formatter scripts at the repo root.
CHANGELOG.md Documents the TypeScript/oxlint/oxfmt toolchain changes.
apps/website/src/scripts/site.ts Formatter-driven style changes in website demo script.
apps/website/src/i18n/ui.ts Formatter-driven reflow of website i18n strings.
apps/website/scripts/build-og.mjs Formatter-driven reflow of OG image build script.
apps/website/package.json Minor formatting-only adjustment.
apps/website/astro.config.mjs Minor formatting-only adjustment.
apps/extension/vite.config.ts Formatting-only changes in Vite config parsing.
apps/extension/test/chromeI18n.ts Formatting-only changes in test mock typing and formatting.
apps/extension/src/vite-env.d.ts Adds Vite client type reference to satisfy TS side-effect CSS import typing.
apps/extension/src/shared/types.ts Formatting-only change to union type layout.
apps/extension/src/shared/translationLabel.ts Formatting-only changes for readability.
apps/extension/src/shared/text.ts Adjusts codepoint counting implementation + formatting.
apps/extension/src/shared/storage.ts Formatting-only changes to typed storage read.
apps/extension/src/shared/migrations/versions/v0.ts Formatting-only changes to provider list literal.
apps/extension/src/shared/migrations/index.ts Small change to how adapter defaults are merged during settings parse.
apps/extension/src/shared/json.test.ts Formatting-only changes to test expectation layout.
apps/extension/src/shared/defaults.test.ts Formatting-only changes to test expectation layout.
apps/extension/src/popup/popup.css Formatter-driven wrapping of long font-family/font declarations.
apps/extension/src/options/settingsForm.ts Formatting-only changes to query/trim expression layout.
apps/extension/src/options/settingsForm.test.ts Formatting-only changes to assertion layout.
apps/extension/src/options/providerSettings.ts Formatting-only changes to option rendering logic layout.
apps/extension/src/options/providerSettings.test.ts Formatting-only changes to test layout.
apps/extension/src/options/optionsLayout.test.ts Formatting-only changes to test layout.
apps/extension/src/options/options.ts Formatting-only changes to initializer call layout.
apps/extension/src/options/options.css Formatter-driven wrapping of long font-family declaration.
apps/extension/src/options/languageSelect.ts Formatting-only changes to function signature and attribute set layout.
apps/extension/src/options/languageSelect.test.ts Formatting-only changes to assertion layout.
apps/extension/src/options/languages.ts Formatter-driven multi-line layout of the language options table + signatures.
apps/extension/src/options/languages.test.ts Formatting-only changes to imports and expectations.
apps/extension/src/options/displayPreview.ts Formatting-only changes to object literal layout.
apps/extension/src/options/displayPreview.test.ts Formatting-only changes to test layout.
apps/extension/src/options/cachePrivacy.ts Formatting-only changes to function signature layout.
apps/extension/src/content/translationRenderer.ts Formatting-only changes (plus minor line wrapping) in renderer helpers.
apps/extension/src/content/translationRenderer.test.ts Formatting-only changes to test layout.
apps/extension/src/content/translationQueue.ts Removes void call-site now that drain is synchronous + formatting.
apps/extension/src/content/translationQueue.test.ts Formatting-only changes to test literal layout.
apps/extension/src/content/textBlocks.test.ts Formatting-only changes to test layout.
apps/extension/src/content/siteAdapters/youtube/controls.ts Formatting-only changes to YouTube adapter control logic layout.
apps/extension/src/content/siteAdapters/youtube/controls.test.ts Formatting-only changes to YouTube adapter test layout.
apps/extension/src/content/siteAdapters/youtube/captionTracks.ts Formatting-only changes + minor wrapping in caption track parsing helpers.
apps/extension/src/content/siteAdapters/youtube/captionTracks.test.ts Formatting-only changes to caption track tests.
apps/extension/src/content/siteAdapters/xFixtures.test.ts Formatting-only changes to fixture test imports/signatures.
apps/extension/src/content/siteAdapters/x.ts Uses matchesSelector() helper to avoid TS7 Element.matches() narrowing pitfalls + formatting.
apps/extension/src/content/siteAdapters/x.test.ts Formatting-only changes to tests.
apps/extension/src/content/siteAdapters/index.ts Formatting-only changes to function signature layout.
apps/extension/src/content/readingVisibility.ts Formatting-only changes to boolean expression layout.
apps/extension/src/content/readingVisibility.test.ts Formatting-only changes to tests.
apps/extension/src/content/orchestrator.ts Formatting-only changes to imports and long expressions.
apps/extension/src/content/orchestrator.test.ts Formatting-only changes to tests.
apps/extension/src/content/layoutStrategy.ts Formatting-only changes to Pick<> type layout.
apps/extension/src/content/layoutStrategy.test.ts Formatting-only changes to tests and literals.
apps/extension/src/content/floatingButton.ts Formatting-only changes to DOM setup and query layout.
apps/extension/src/content/floatingButton.test.ts Formatting-only changes to tests.
apps/extension/src/content/extractionFixtures.test.ts Formatting-only changes to fixture test imports and object literal layout.
apps/extension/src/content/extraction/universal.ts Formatting-only changes to function signature and loop layout.
apps/extension/src/content/extraction/shared.ts Uses matchesSelector() for TS7-safe tag checks + formatting.
apps/extension/src/content/extraction/legacy.ts Formatting-only changes to helper signatures.
apps/extension/src/content/extraction/inlineText.ts Formatting-only changes to signature and condition layout.
apps/extension/src/content/extraction/cascade.ts Formatting-only changes to imports and signature.
apps/extension/src/content/extraction/archetypes/docs.ts Formatting-only changes to selector lists and confidence checks.
apps/extension/src/content/extraction/archetypes/docs.test.ts Formatting-only changes to tests.
apps/extension/src/content/extraction/archetypes/article.ts Formatting-only changes to selector lists and confidence checks.
apps/extension/src/content/extraction/archetypes/article.test.ts Formatting-only changes to tests.
apps/extension/src/content/dom.ts Adds matchesSelector() helper to avoid TS7 Element.matches() narrowing edge cases.
apps/extension/src/content/displayStyle.ts Formatting-only changes to long argument lists and font-family strings.
apps/extension/src/content/displayStyle.test.ts Formatting-only changes to tests.
apps/extension/src/content/contentScript.ts Formatting-only changes to message responses and event listener options.
apps/extension/src/content/blockCandidates.ts Uses matchesSelector() helper for TS7-safe tag checks + formatting.
apps/extension/src/content/blockCandidates.test.ts Formatting-only changes to tests.
apps/extension/src/background/serviceWorker.ts Formatting-only changes to imports and object construction; no behavior change intended.
apps/extension/src/background/serviceWorker.test.ts Formatting-only changes to tests and helper setup.
apps/extension/src/background/providers/shared.ts Formatting-only changes to function signatures and boolean checks.
apps/extension/src/background/providers/shared.test.ts Formatting-only changes to tests.
apps/extension/src/background/providers/openai.ts Formatting-only changes to type imports and helper signature layout.
apps/extension/src/background/providers/openai.test.ts Formatting-only changes to tests.
apps/extension/src/background/providers/index.test.ts Formatting-only changes to table-driven test layout.
apps/extension/src/background/providers/google.ts Formatting-only changes to type imports and predicate formatting.
apps/extension/src/background/providers/google.test.ts Formatting-only changes to tests and fixtures.
apps/extension/src/background/providers/anthropic.ts Formatting-only changes to type imports and map return object layout.
apps/extension/src/background/providers/anthropic.test.ts Formatting-only changes to tests.
apps/extension/scripts/package-extension.mjs Formatting-only changes to long calls and assertions.
apps/extension/scripts/check-release-version.mjs Formatting-only changes to assertions.
apps/extension/scripts/check-release-readiness.mjs Formatting-only changes to assertions and long expressions.
apps/extension/scripts/check-extension.mjs Formatting-only changes to assertions and helper formatting.
apps/extension/scripts/capture-fixture.mjs Formatting-only changes to long strings/regex calls and helper formatting.
apps/extension/package.json Switches extension lint script from ESLint to oxlint.
apps/extension/options.html Formatter-driven HTML reflow; no semantic changes intended.
apps/extension/eslint.config.mjs Removes ESLint configuration (migration to oxlint).
apps/extension/.oxlintrc.json Adds oxlint configuration (type-aware + rule parity with prior setup).
.oxfmtrc.json Adds repository formatter configuration and ignore patterns.
.github/workflows/ci.yml Adds CI format check step (pnpm fmt:check).
.github/ISSUE_TEMPLATE/youtube-captions.yml Whitespace-only template cleanup.
.github/ISSUE_TEMPLATE/website-translation.yml Whitespace-only template cleanup.
.github/ISSUE_TEMPLATE/provider-options.yml Whitespace-only template cleanup.
.github/ISSUE_TEMPLATE/beta-feedback.yml Whitespace-only template cleanup.
.git-blame-ignore-revs Adds ignore-revs entry for the formatting commit to keep blame usable.
Files not reviewed (1)
  • pnpm-lock.yaml: Generated file

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

CodeQL flagged the single-pass on*/style/nonce attribute removal in the
fixture capture script (js/incomplete-multi-character-sanitization):
removing one attribute can splice the surrounding text into a new
strippable attribute, which one pass leaves behind. Repeat the strip
passes until the output stops changing; the idempotent href/src URL
rewrite stays outside the loop.
Comment thread apps/extension/scripts/capture-fixture.mjs Fixed
Comment thread apps/extension/scripts/capture-fixture.mjs Fixed
CodeQL's js/incomplete-multi-character-sanitization is a per-call-site
check and does not credit the previous fix-point loop, so the alert
survived. Replace the substring-deletion approach entirely: parse each
opening tag, tokenize its attributes, and drop volatile ones by exact
name match, then reassemble the tag. Spliced text can no longer form a
surviving on* handler because filtering happens on parsed tokens, not
on the raw document string.
@linyiru
linyiru merged commit 85d964b into main Jul 21, 2026
4 checks passed
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.

3 participants