Skip to content

build: unify TypeScript on 5.9 and @types/node on 22 - #1150

Merged
vezwork merged 1 commit into
quarto-dev:mainfrom
nealrichardson:build/typescript-5.9
Sep 25, 2026
Merged

vezwork merged 1 commit into
quarto-dev:mainfrom
nealrichardson:build/typescript-5.9

Conversation

@nealrichardson

Copy link
Copy Markdown
Contributor

Phase 0.2 of the dependency upgrade. This is independent of #1149 (Node 24), and either can merge first.

TypeScript was split: 4.9.4 was hoisted and used by most tsc runs, while 5.8.3 was nested under the @quarto/* packages. @types/node was on four different majors (16.x, 18, 20, 20).

Changes

TypeScript ^5.9.3

  • It's now a devDependency only in the workspaces that actually run tsc (apps/{lsp,vscode,vscode-editor,vscode-markdownit,panmirror} and the four published @quarto/* packages), plus the root, so there's one hoisted copy for typescript-eslint and typescript.tsdk.
  • It was removed from about 20 source-only workspaces that listed it as a runtime dependency but never import it.
  • yarn.lock now has exactly one typescript entry.

Published @quarto/* manifests. typescript, tsconfig and build moved from dependencies to devDependencies. Today, anyone who installs @quarto/json-validator from npm also gets TypeScript and the unrelated public npm packages named tsconfig and build. The fix only takes effect on npm after the next patch release of those packages.

@types/node ^22.15.0 everywhere. I originally planned this for the engine-floor PR, but it can't be split out:

  • TS 5.9's Buffer/ArrayBufferView typings fail against the old @types/node (errors in hover-image.ts and zotero/local/db.ts).
  • Every @types/node@22 release needs TS ≥ 5.6.

22 matches the engines.vscode: ^1.101 floor we decided on (VS Code 1.101 ships Node 22). The engines.vscode and @types/vscode bump itself is still a separate PR. I also hand-merged the transitive @types/node@* lock entry into the 22 entry, so only one copy gets hoisted. yarn why @types/node now shows 22.20.4 at the root, plus the nested jayson (12) and @fast-csv (14) copies, which are unavoidable.

One real bug caught by TS 5.5 regex checking. In rmd_chunk-image.ts, [^\2] doesn't mean "not the opening quote": inside a character class, \2 is the octal escape \x02. So the include_graphics() path match ran greedily past the closing quote. For example, include_graphics("a.png"); x <- "b" captured a.png"); x <- "b. I changed it to (.+?)\2.

Verification

  • yarn build --force: 14/14 tasks. This includes tsc --noEmit for apps/vscode, apps/lsp, vscode-editor, vscode-markdownit and panmirror.
  • The published packages' dist/cjs output (JS and .d.ts) is byte-identical to the 5.8.3 build.
  • yarn install leaves the lockfile unchanged.
  • yarn test-packages: 8/8 tasks.
  • yarn test-vscode (VS Code 1.109, Quarto CLI on PATH): main label 150 passing, 0 failing; r-project label 3/3.
  • yarn lint --continue: same result as main. The 6 no-unused-vars errors in quarto-lsp are pre-existing. There are no typescript-eslint "unsupported TypeScript version" warnings, but typescript-eslint 5 officially supports only TS < 5.1. That gets resolved in the ESLint 10 / typescript-eslint 8 step.

🤖 Generated with Claude Code

TypeScript was split between 4.9.4 (hoisted, used by most tsc runs) and
5.8.3 (nested under the @quarto/* packages).

- typescript ^5.9.3 as a devDependency only in workspaces that run tsc,
  plus the root (one hoisted copy for typescript-eslint and tsdk). It was
  a runtime `dependency` in ~20 source-only workspaces that never import it.
- The published @quarto/* packages no longer list typescript, tsconfig or
  build as runtime dependencies (npm consumers were installing TypeScript
  and the unrelated public `tsconfig` and `build` packages).
- @types/node ^22.15.0 everywhere (was 16.x / 18 / 20). This matches the
  decided engines.vscode ^1.101 floor (Node 22), and is required: TS 5.9's
  Buffer/ArrayBufferView typings break against the old @types/node, and
  @types/node 22 needs TS >= 5.6, so the two have to move together.
  yarn.lock merges the transitive @types/node@* into the 22 entry so a
  single copy is hoisted.
- Fix a regex TS 5.5 now rejects: in `[^\2]`, `\2` is the octal escape
  \x02, not a backreference, so the include_graphics() path match ran
  greedily past the closing quote (and across lines).

Emitted dist/cjs for the four published packages is byte-identical.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@posit-snyk-bot

posit-snyk-bot commented Sep 25, 2026 •

Copy link
Copy Markdown
Contributor

✅ Snyk checks have passed. No issues have been found so far.

Status Scan Engine Critical High Medium Low Total (0)
✅ Open Source Security 0 0 0 0 0 issues
✅ Licenses 0 0 0 0 0 issues

💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse.

@vezwork vezwork left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I also hand-merged the transitive @types/node@* lock entry

😳.

Continued thanks for simple PRs with nice writeup.

@vezwork
vezwork merged commit af9e83c into quarto-dev:main Sep 25, 2026
7 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