From aabddc3adc007b704d0839920ed4466fb5788a47 Mon Sep 17 00:00:00 2001 From: cliffhall Date: Sat, 24 Oct 2026 23:23:30 -0400 Subject: [PATCH 1/2] chore(cli): migrate the CLI bundle from tsup to tsdown (#1492) tsup is unmaintained and points users at tsdown. Move clients/cli as the prototype the issue asks for, and record the findings and the path for the remaining three builds in docs/tsdown-migration.md. - clients/cli/tsdown.config.ts replaces tsup.config.ts. Externals live in a hoisted EXTERNALS array expanded with subpath patterns, because a bare string in deps.neverBundle matches the exact specifier only and subpaths would otherwise be inlined silently. - fixedExtension: false keeps build/index.js; comments.jsdoc: false keeps the bundle at 681 KB against tsup's 844 KB. - Drop the CLI's esbuild override and allowScripts entries: neither esbuild nor fsevents is in its install without tsup. - verify:bundle-externals reads the EXTERNALS array, accepts Rolldown's //#region banners as well as the plain form, and discovers tsdown configs. - Docs and references updated; remaining clients tracked in #2797. Co-Authored-By: Claude Opus 5.5 Signed-off-by: cliffhall --- .claude/skills/local-dev/SKILL.md | 10 +- .claude/skills/project-structure/SKILL.md | 2 +- AGENTS.md | 8 +- README.md | 3 +- clients/cli/README.md | 2 +- clients/cli/package-lock.json | 1589 +++++++-------------- clients/cli/package.json | 11 +- clients/cli/tsconfig.json | 2 +- clients/cli/tsdown.config.ts | 105 ++ clients/cli/tsup.config.ts | 80 -- core/auth/node/file-lock.ts | 6 +- docs/architecture.md | 3 +- docs/publishing.md | 2 +- docs/quality-gate.md | 2 +- docs/tsdown-migration.md | 108 ++ scripts/sdk-watch.mjs | 2 +- scripts/verify-bundle-externals.mjs | 59 +- scripts/verify-bundle-externals.test.mjs | 51 +- specification/v2_cli_tui_launcher.md | 2 +- 19 files changed, 857 insertions(+), 1190 deletions(-) create mode 100644 clients/cli/tsdown.config.ts delete mode 100644 clients/cli/tsup.config.ts create mode 100644 docs/tsdown-migration.md diff --git a/.claude/skills/local-dev/SKILL.md b/.claude/skills/local-dev/SKILL.md index 707d3d108b..b4a7bec18d 100644 --- a/.claude/skills/local-dev/SKILL.md +++ b/.claude/skills/local-dev/SKILL.md @@ -73,9 +73,13 @@ To run the CLI or TUI: `node clients/launcher/build/index.js --cli …` / `package.json`** — it is not published on its own. Each client bundles it via a build-time alias: -- **CLI / TUI** — `esbuildOptions.alias` in `tsup.config.ts` maps +- **TUI / mcpdo** — `esbuildOptions.alias` in `tsup.config.ts` maps `@inspector/core` → the repo `core/` directory, with `noExternal: [/^@inspector\/core/]` inlining it. +- **CLI** — the same two settings under their tsdown names in + `tsdown.config.ts`: a top-level `alias`, and `deps.alwaysBundle` (#1492). + Its externals are `deps.neverBundle`, where a bare string matches the exact + specifier only — the config expands each name to cover its subpaths. - **Web** — **two** configs, because the client is two builds: `clients/web/vite.config.ts` for the browser app, and `clients/web/tsup.runner.config.ts` for the Node backend runner, which @@ -178,7 +182,7 @@ toolchain". `tsx`, `playwright`, `storybook`, `happy-dom`, `ink-testing-library` `vite-node` and each client's own `@types/*` are toolchain too and stay where they are — hoisting them would make every client install the union of all five. So do the ones **more than one** client declares without all of them doing so: -`tsup` sits in web, cli and tui, and `vite` in web and tui on top of the root +`tsup` sits in web, mcpdo and tui, and `vite` in web and tui on top of the root _runtime_ `dependency` that `--web --dev` needs. Neither is in scope here; whether to consolidate them is a separate call with a separate rationale (`vite` especially, since its root declaration is a `dependency`, not a @@ -270,7 +274,7 @@ Two live examples worth knowing: ### Why a root dependency must also be externalised -tsup and Vite externalise what the **client's** `package.json` declares, and a +tsup, tsdown and Vite externalise what the **client's** `package.json` declares, and a root-only dependency is in none of them — so it is **bundled**, silently. For a CJS package inlined into an ESM bundle that is fatal: esbuild leaves a `Dynamic require of "path" is not supported` shim that throws at _import_ time, diff --git a/.claude/skills/project-structure/SKILL.md b/.claude/skills/project-structure/SKILL.md index 8928a71a65..f87fa8ecea 100644 --- a/.claude/skills/project-structure/SKILL.md +++ b/.claude/skills/project-structure/SKILL.md @@ -19,7 +19,7 @@ inspector/ │ │ ├── src/ Browser app: components, hooks, lib/, utils/, theme/ │ │ ├── server/ Node-only dev/prod backend wiring (see below) │ │ └── static/ sandbox_proxy.html — served for the MCP Apps tab -│ ├── cli/ Scriptable CLI (tsup bundle, @inspector/core alias) +│ ├── cli/ Scriptable CLI (tsdown bundle, @inspector/core alias) │ ├── tui/ Ink + React terminal UI (tsup bundle) │ └── launcher/ The `mcp-inspector` bin; dispatches to web/cli/tui in-process ├── core/ Shared code, consumed via the `@inspector/core` alias (no package.json) diff --git a/AGENTS.md b/AGENTS.md index aad77a1906..57b9be5a41 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -41,7 +41,7 @@ inspector/ │ │ ├── src/ Browser app: components, hooks, lib/, utils/, theme/ │ │ ├── server/ Node-only dev/prod backend wiring │ │ └── static/ sandbox_proxy.html — served for the MCP Apps tab -│ ├── cli/ Scriptable CLI (tsup bundle, @inspector/core alias) +│ ├── cli/ Scriptable CLI (tsdown bundle, @inspector/core alias) │ ├── mcpdo/ Experimental connection CLI (`mcpdo` bin — connect once, many │ │ commands; implicit Unix-socket connection daemon). Bundled │ │ into the published package — see clients/mcpdo/README.md @@ -107,10 +107,10 @@ The reasoning behind each of these, and what breaks when it is ignored, is the - **A client declares only what that client alone consumes** — its own UI stack, its bundler-inlined packages, its dev tooling. `clients/cli`, `clients/mcpdo` and `clients/launcher` therefore declare **no** runtime dependencies at all, and that is the expected steady state, not an omission: everything they run on is root-declared and resolves by walk-up from the client directory. Re-adding a root-declared package to a client manifest re-creates the second copy this rule exists to make impossible (#1896), so a missing module at runtime is a signal to check the **root** manifest and the client's `external` list, never to add it back. - **A package that moves to the root moves its `vitest.shared.mts` pin with it.** Left pointing at `/node_modules` a pin resolves to a directory that no longer exists — or, where a transitive copy happens to sit there (`chokidar` under `vite`, `react` as a peer of `react-dom` and `ink`), to the very duplicate the pin list exists to prevent. **`react` and `react-dom` are the deliberate exception** and stay pinned per client, so a client's renderer and the React it calls into come from one install; every other root-owned pin resolves from the repo root. - **`dependencies` vs `devDependencies` follows from who consumes it at runtime**, not from where it is declared. Anything `core/` imports at runtime must be a root **`dependency`** — the client builds externalize npm packages and a published install resolves them from the root manifest, where devDependencies are absent. -- **The shared toolchain is declared once, at the repo root, and in no client manifest.** `eslint`, `@eslint/js`, `typescript-eslint`, `globals`, `prettier`, `typescript`, `vitest`, `@vitest/coverage-v8` and `@types/node` are used by every client's own scripts, and a client that declares none of them still resolves the root copy by walk-up — `npm run` puts each ancestor `node_modules/.bin` on `PATH`, and Node and TypeScript walk parent `node_modules` / `node_modules/@types` the same way. `clients/launcher` declares no `devDependencies` at all and its `validate` is unchanged. A client-side declaration buys nothing and installs a second copy free to drift, as `globals` (`^17.7.0` root / `^17.4.0` clients) and `typescript-eslint` (`^8.65.0` / `^8.56.1`) had before #2196. These stay **`devDependencies`** — none is consumed at runtime and the tarball ships only each client's `build/`. The boundary is **used by every client**, not "used by one": anything narrower stays where it is, whether one client declares it (`tsx`, `playwright`, `storybook`, `happy-dom`, `ink-testing-library`, `vite-node`, each client's own `@types/*`) or several do — `tsup` is declared in web, cli and tui, and `vite` in web and tui on top of the root **runtime** `dependency` that `--web --dev` needs. Those are out of scope here; consolidating them is a different call with a different rationale. +- **The shared toolchain is declared once, at the repo root, and in no client manifest.** `eslint`, `@eslint/js`, `typescript-eslint`, `globals`, `prettier`, `typescript`, `vitest`, `@vitest/coverage-v8` and `@types/node` are used by every client's own scripts, and a client that declares none of them still resolves the root copy by walk-up — `npm run` puts each ancestor `node_modules/.bin` on `PATH`, and Node and TypeScript walk parent `node_modules` / `node_modules/@types` the same way. `clients/launcher` declares no `devDependencies` at all and its `validate` is unchanged. A client-side declaration buys nothing and installs a second copy free to drift, as `globals` (`^17.7.0` root / `^17.4.0` clients) and `typescript-eslint` (`^8.65.0` / `^8.56.1`) had before #2196. These stay **`devDependencies`** — none is consumed at runtime and the tarball ships only each client's `build/`. The boundary is **used by every client**, not "used by one": anything narrower stays where it is, whether one client declares it (`tsx`, `playwright`, `storybook`, `happy-dom`, `ink-testing-library`, `vite-node`, each client's own `@types/*`) or several do — `tsup` is declared in web, mcpdo and tui (`tsdown` in cli, #1492), and `vite` in web and tui on top of the root **runtime** `dependency` that `--web --dev` needs. Those are out of scope here; consolidating them is a different call with a different rationale. - ⚠️ **Deleting the declaration does not always delete the copy, and the local copy still wins.** npm auto-installs an unmet **peer** into the install that needs it, and it has no visibility into the root's tree — so a client-only ESLint plugin drags a client-local `eslint` in (`eslint-plugin-react-refresh`/`-storybook` in web, `eslint-plugin-react-hooks` in tui), and web's Storybook/Vitest stack drags in a local `typescript` and `vitest`. A hoisted transitive does the same: `@types/express` puts an `@types/node` in web and cli. Those copies sit _nearer_ than the root's and take precedence. The consolidation is therefore about **one declaration and one place to bump**, not about a single copy on disk. ⚠️ **Nothing keeps the surviving copies aligned automatically — but since #2226 the guard rejects the drift.** A **peer** copy is at least constrained by its holder's peer range — tightly for `vitest` (an exact peer, hence the pin below), loosely for `eslint` (`^9 || ^10`), where the copies agree only because npm resolves the same latest in both installs. A **transitive** copy is constrained by nothing of ours at all, and cli's `@types/node` (`24.13.1` against the root's `24.13.3`) diverged on exactly that. **That is detection, not alignment: `verify:dep-lockstep` fails on this class since #2226, and you still do the bump by hand.** Its second tier compares every package any install _declares_ (`dependencies`, `devDependencies`, `optionalDependencies`; not peers) against every top-level copy across all five installs, independent of what a `tsc` program loads, so a transitive drift and a peer shadow (`eslint`, `typescript`, `vitest`) are both in scope now. Two limits remain: the tier reads lockfiles, so a tool binary you installed by hand and never committed is still invisible; and it only compares names some manifest declares, so a purely transitive package no manifest names is out of scope in both tiers unless a `tsc` program loads both copies. Aligning a stale install is `npm update ` there; a transitive copy that will not move takes an `overrides` entry in that install (`clients/cli` pins `@types/node` this way). - ⚠️ **`vitest`, `@vitest/coverage-v8` and web's `@vitest/browser-playwright` are pinned exactly, and move together.** `@vitest/browser-playwright` declares an **exact** peer on `vitest`, so it — not the root range — decides which `vitest` web installs. Left to float, the root resolves a newer patch and web's tests then run on one `vitest` while loading a coverage provider built against another. Bumping means editing all three in one change, the same discipline the exact `prettier` pin (#1790) exists for. ⚠️ **Editing the three is necessary but not sufficient — `clients/web` also carries a `vitest` `overrides` entry that has to move with them.** Web does not declare `vitest`, so its copy is the peer shadow above; its lockfile pins that copy at the old patch, and the exact peer plus the lockfile form a knot `npm install` resolves by refusing outright (`Conflicting peer dependency: vitest@`), while `npm update` will not move it either. Deleting web's lockfile clears the error and re-resolves every caret range in the tree at once — an uncontrolled dependency update wearing a security patch's clothes. The `overrides` entry is the controlled alternative, the same mechanism `clients/cli` uses for `@types/node`: it moves the shadowed copy and nothing else, keeping the churn inside the vitest constellation. So a vitest bump is **four** edits, and the override's version is an exact pin like the other three (#2301). -- **A root-declared package that `core/` imports at runtime must also be named in all four bundler `external` lists** (`clients/{cli,mcpdo,tui}/tsup.config.ts`, `clients/web/tsup.runner.config.ts`), since which client reaches it is a function of what `core/` imports rather than of what the client's own code names. `npm run verify:bundle-externals` enforces this against the **built output**. +- **A root-declared package that `core/` imports at runtime must also be named in all four bundler `external` lists** (`clients/cli/tsdown.config.ts`, `clients/{mcpdo,tui}/tsup.config.ts`, `clients/web/tsup.runner.config.ts`), since which client reaches it is a function of what `core/` imports rather than of what the client's own code names. `npm run verify:bundle-externals` enforces this against the **built output**. - **A dependency that renders React components must be bundled** into the client that uses it (`noExternal`) and declared only there — an externalized one resolves its own `react` and splits the tree. `ink` is the single exemption, on cost, and it is only safe while the root `react` range stays open to the whole major (`^19.0.0`). - **One version per install-crossing dependency.** When bumping a dependency the shared sources pull in, bump it in every install that declares it. Consolidating to the root is what makes most of these unbumpable in two places at once, but it does not retire the rule — a client's `devDependencies`, and any package that arrives transitively into a client install, can still skew against the root. Never raise the tsc heap to work around one. `npm run verify:dep-lockstep` enforces this in two tiers: packages that reach one `tsc` **program** from two installs (the #1896 heap-exhaustion class), and — since #2226 — every package any install **declares** that more than one install holds a top-level copy of, whether or not a program ever sees both. - **Pin a transitive dependency with an `overrides` entry**, not with `npm audit fix` — which "resolves" an advisory with no upward escape by silently downgrading. @@ -551,7 +551,7 @@ Pick by how many notifications the wait needs: ## Build output is never a gate target -**No gate — lint, format, or typecheck — may read generated output.** The gated surface is first-party source only: `clients/*/src`, `clients/*/__tests__`, `clients/web/{server,.storybook}`, each client's top-level configs, `core/`, `test-servers/src`, `scripts/`, and the root shared files. Everything a build writes is out of scope: `clients/*/build` (the tsup/tsc bundles), `clients/web/dist` (the Vite SPA), `clients/web/storybook-static`, `clients/*/coverage`, `test-servers/build`, `core/**/{build,dist}`, and any `*.tsbuildinfo`. Each scope states this itself — `globalIgnores([...])` in every `eslint.config.js`, the `format`/`format:check` globs in each `package.json`, and a tsconfig `include` that names source directories rather than the package root. +**No gate — lint, format, or typecheck — may read generated output.** The gated surface is first-party source only: `clients/*/src`, `clients/*/__tests__`, `clients/web/{server,.storybook}`, each client's top-level configs, `core/`, `test-servers/src`, `scripts/`, and the root shared files. Everything a build writes is out of scope: `clients/*/build` (the tsup/tsdown/tsc bundles), `clients/web/dist` (the Vite SPA), `clients/web/storybook-static`, `clients/*/coverage`, `test-servers/build`, `core/**/{build,dist}`, and any `*.tsbuildinfo`. Each scope states this itself — `globalIgnores([...])` in every `eslint.config.js`, the `format`/`format:check` globs in each `package.json`, and a tsconfig `include` that names source directories rather than the package root. Why it matters, given that these paths are all gitignored and the findings are usually warnings: diff --git a/README.md b/README.md index 39fbb90ae7..cee3ecfea8 100644 --- a/README.md +++ b/README.md @@ -53,7 +53,7 @@ v2 is **not** an npm workspace — each client under `clients/*` keeps its own ` inspector/ ├── clients/ │ ├── web/ Web client (Vite + React + Mantine). src/ = browser app; server/ = Node backend -│ ├── cli/ CLI client (tsup bundle, @inspector/core alias) +│ ├── cli/ CLI client (tsdown bundle, @inspector/core alias) │ ├── mcpdo/ Experimental connection CLI (`mcpdo` bin) — bundled into the │ │ published package; see clients/mcpdo/README.md │ ├── tui/ TUI client (Ink + React, tsup bundle) @@ -87,6 +87,7 @@ Each client has its own README with client-specific detail: | [Writing a skill](./docs/skill-authoring.md) | How to write a skill description that actually fires, and eval cases that measure it — the case shapes that work, and the tuning loop | | [Test servers](./docs/test-servers.md) | The composable test servers and the showcase config for every feature — what to run, what to click, and what the broken build did | | [Publishing](./docs/publishing.md) | What ships in the tarball, the packaging invariants, and `pack:verify` | +| [Migrating from tsup to tsdown](./docs/tsdown-migration.md) | Why the client bundles are moving to tsdown, the option mapping, the gotchas that don't fail a build, and the order for the remaining clients | | [Serving the web UI over HTTPS](./docs/tls.md) | `INSPECTOR_TLS_KEY_PATH` / `INSPECTOR_TLS_CERT_PATH`, a trusted local mkcert setup, custom hostnames and `ALLOWED_ORIGINS`, and `NODE_EXTRA_CA_CERTS` for outbound private-CA servers | | [Docker](./docs/docker.md) | Running the container image — ports, volumes, and making secrets durable in a container | | [Where secrets are stored](./docs/secret-storage.md) | How the secret store is chosen on every runtime — OS keychain, `secrets.json` or memory — plus file encryption, locking, and moving back to a keychain | diff --git a/clients/cli/README.md b/clients/cli/README.md index 8db062f498..5374ab84b5 100644 --- a/clients/cli/README.md +++ b/clients/cli/README.md @@ -98,7 +98,7 @@ Proxy routing is powered by the [`undici`](https://www.npmjs.com/package/undici) Because undici's `Response` is a different class from `globalThis.Response`, the proxied fetch re-wraps each response as a genuine global `Response`, streaming preserved. Without that, `res instanceof Response` is `false` for callers that test it — including the MCP SDK, whose OAuth error formatter would degrade every message to `Raw body: [object Response]`. -`undici` is declared **only** in the root `package.json`, and every client's tsup config lists it as `external`. Both halves matter: tsup auto-externalizes what the _nearest_ manifest declares, so without the explicit entry the web and TUI bundles inlined it — and a CommonJS package inlined into an ESM bundle throws `Dynamic require of "assert" is not supported` the first time it is used. `npm run verify:bundle-externals` is the durable guard. +`undici` is declared **only** in the root `package.json`, and every client's bundler config lists it as `external` (this client's is `clients/cli/tsdown.config.ts`). Both halves matter: the bundler auto-externalizes what the _nearest_ manifest declares, so without the explicit entry the web and TUI bundles inlined it — and a CommonJS package inlined into an ESM bundle throws `Dynamic require of "assert" is not supported` the first time it is used. `npm run verify:bundle-externals` is the durable guard. ### Shell completion diff --git a/clients/cli/package-lock.json b/clients/cli/package-lock.json index 8016d0d25c..b95ddd3dad 100644 --- a/clients/cli/package-lock.json +++ b/clients/cli/package-lock.json @@ -12,49 +12,38 @@ }, "devDependencies": { "@types/express": "^5.0.6", - "tsup": "^8.5.0" + "tsdown": "^0.23.1" } }, - "node_modules/@esbuild/aix-ppc64": { - "version": "0.28.2", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.28.2.tgz", - "integrity": "sha512-XExcO+dvLKvVtNTibSTBej1NCAbaGhWn9Ww1ZPx80qsahhPFe/8jgWP0IchNe0F3HwkU7n8ejhH8bjonqht8mQ==", - "cpu": [ - "ppc64" - ], + "node_modules/@oxc-project/types": { + "version": "0.155.0", + "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.155.0.tgz", + "integrity": "sha512-SeE8JPwW1xs1tHeNycjUtUBdhorRa8o4jlvjwk49R7/Z291i+4DQa7JJIgOm/TaYQZx+QrPQbVJ/9c8dMIZN8Q==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "aix" - ], - "engines": { - "node": ">=18" + "funding": { + "url": "https://github.com/sponsors/oxc-project" } }, - "node_modules/@esbuild/android-arm": { - "version": "0.28.2", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.28.2.tgz", - "integrity": "sha512-kXXoiPVVGQcnIYGOeaovwOURpniDBpSq4A03qkQ+BMQqtGG6HYap3xne9C1O1yo4TR3qxlCX5IqqmX6fFo2Lqg==", - "cpu": [ - "arm" - ], + "node_modules/@quansync/fs": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@quansync/fs/-/fs-1.1.0.tgz", + "integrity": "sha512-qAPG/t3HqML1TlN7sY/pTbEjzFVAKsMjNNMGheyDosro+kT4iw2KCUoHcVdmliwWjorm4elZbgNQyU2eD97eDg==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" + "dependencies": { + "quansync": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sxzz" } }, - "node_modules/@esbuild/android-arm64": { - "version": "0.28.2", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.28.2.tgz", - "integrity": "sha512-5YfKeeI8qWfBZIX+u2xZC3Zlb3Os/gLS2sbEKM+I4ZOcsWmHS2WLysCcQZDAFRslDUU5Oiq44gf6PYN1vGwG5A==", + "node_modules/@rolldown/binding-android-arm-eabi": { + "version": "1.2.15", + "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm-eabi/-/binding-android-arm-eabi-1.2.15.tgz", + "integrity": "sha512-aLcgK9gIJ3YRvrrtfSBbRa27F5WrpiTaPulnFpsHPxpUHgFlSgnU4854MHwoRGEBhfRJDWCS2WQ7lIjskE9Olw==", "cpu": [ - "arm64" + "arm" ], "dev": true, "license": "MIT", @@ -63,15 +52,15 @@ "android" ], "engines": { - "node": ">=18" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@esbuild/android-x64": { - "version": "0.28.2", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.28.2.tgz", - "integrity": "sha512-O387ite7SzUyCcy3JQX4P4bLtEA7bLLkx+esve5JHnyYfNTxcVpXZo9jhdB0lTKN44gztELTdU7nS8Nr16Fs1Q==", + "node_modules/@rolldown/binding-android-arm64": { + "version": "1.2.15", + "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.2.15.tgz", + "integrity": "sha512-xD7DdZCrbThKuxNg7ooQmvp07ys4J/pnSEMTG3/OdOWl6daC67m/Q4fL78sRHMxTH/N4fGUbYhcPM0MF5WFHkg==", "cpu": [ - "x64" + "arm64" ], "dev": true, "license": "MIT", @@ -80,13 +69,13 @@ "android" ], "engines": { - "node": ">=18" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@esbuild/darwin-arm64": { - "version": "0.28.2", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.28.2.tgz", - "integrity": "sha512-n4KqkOQrraxHJcgjM1RvwbigfQKIKJVpM7xp+KsxiyUSrRdIXnt73VhrPAx0fV44hgfmIVKjxMN9J1t5jySVkw==", + "node_modules/@rolldown/binding-darwin-arm64": { + "version": "1.2.15", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.2.15.tgz", + "integrity": "sha512-m2WuQ6r0B4OTYxyPpNLtXaMRbRDUbG8YQV2Q3KTdSSK8Th6KHCnC8jVCJt8bvYeSB5WivkkNbc85mKadaSdOxA==", "cpu": [ "arm64" ], @@ -97,13 +86,13 @@ "darwin" ], "engines": { - "node": ">=18" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@esbuild/darwin-x64": { - "version": "0.28.2", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.28.2.tgz", - "integrity": "sha512-uq6suIWYP37qzGddBKPw5QEQPi6HiLGsO7UmkpfyaYNQ3D+rN6w6WfwH+nuqcGXWvawGwxOEroO4YGnFh95azw==", + "node_modules/@rolldown/binding-darwin-x64": { + "version": "1.2.15", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.2.15.tgz", + "integrity": "sha512-5RtnsHM36nodM9WbMy+zip0LGS/G+y5wro5RHrpOlr4ac24+1zSi9kiV2MP1myZeZ/ifEHfulQcWjnAXzc2C2A==", "cpu": [ "x64" ], @@ -114,30 +103,13 @@ "darwin" ], "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/freebsd-arm64": { - "version": "0.28.2", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.28.2.tgz", - "integrity": "sha512-n+I0BTSRIoy+d6RPKnEVwql5UwBJolytvY4mAOIEJorKlqgPII8ix6slVVrfZ5Tnj7glIZvloylbB/EJPMWEXw==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=18" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@esbuild/freebsd-x64": { - "version": "0.28.2", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.28.2.tgz", - "integrity": "sha512-78XJTJkvPs0kz2w61301PJjXl4g7q3JqiYMZ/M/yVI73EHBrCRTgkhu9oqG7vPqq+a/yadEW8aD+agKlk5xrmg==", + "node_modules/@rolldown/binding-freebsd-x64": { + "version": "1.2.15", + "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.2.15.tgz", + "integrity": "sha512-g3l09pyFqhu+135JKkbkwiKGQmwU5hUMUPJ4VdBADvuqR8d33L6H578rh8m7rtxbdp+VmX/+nzI7nvhSZlzpUQ==", "cpu": [ "x64" ], @@ -148,13 +120,13 @@ "freebsd" ], "engines": { - "node": ">=18" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@esbuild/linux-arm": { - "version": "0.28.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.28.2.tgz", - "integrity": "sha512-XlDnu2q5yoqems+xay6wSAcg9DDD7K9RLKZEBOMZm3ckNpJBvOX20tSfby8KfrrhINDyv9V2YVZKY/SpoGJI8w==", + "node_modules/@rolldown/binding-linux-arm-gnueabihf": { + "version": "1.2.15", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.2.15.tgz", + "integrity": "sha512-nIe3VugI97nGQtspPxDqA4sXMUpeiocKIP/CqpY/u/vgbT+alX+cVxu1C/oVBPKg4feNTmYovE91v4DgXvXNwQ==", "cpu": [ "arm" ], @@ -165,183 +137,150 @@ "linux" ], "engines": { - "node": ">=18" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@esbuild/linux-arm64": { - "version": "0.28.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.28.2.tgz", - "integrity": "sha512-pW4AC0P3it8c7do9MVM4p51FzHzdM/TZrerurgRcHJ2WTa1VQ1CIq18xncfpBJw4ojkiZZrKW2yIBWBP92j6Ug==", + "node_modules/@rolldown/binding-linux-arm64-gnu": { + "version": "1.2.15", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.2.15.tgz", + "integrity": "sha512-iTBjXx+B5QSvgI89lJfmqh4wTh8NabR1YZIIN3hNx4zSG0EVfVqkOvLulNpG4251pbd6/IAmZ/LefVk1Y4rPhw==", "cpu": [ "arm64" ], "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" + "libc": [ + "glibc" ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-ia32": { - "version": "0.28.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.28.2.tgz", - "integrity": "sha512-CYbnj78HsIeA+DhgUKgFCfvNsTHFhMMrinUrMZpDXJXKN8T3XViTZ/+wtHeVxEWY8ewSzTFN+nRmSwO2tZaLUQ==", - "cpu": [ - "ia32" - ], - "dev": true, "license": "MIT", "optional": true, "os": [ "linux" ], "engines": { - "node": ">=18" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@esbuild/linux-loong64": { - "version": "0.28.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.28.2.tgz", - "integrity": "sha512-buwkd8nsph4R+ajRvw0qM5Hja/TXQow3ptzWO2EbG/cqcIkHloRrdlBtQlshyYGTNFvfkfJ5tpPLVkY4DtsPfQ==", + "node_modules/@rolldown/binding-linux-arm64-musl": { + "version": "1.2.15", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.2.15.tgz", + "integrity": "sha512-uN26XOnVR7rqQupG3V9oAG2EGGatWjcJHOeDOHUFCh4TBWmP2tHTFoVN13aYbwfm0aHqJAEmcwhAu6sooIjfqQ==", "cpu": [ - "loong64" + "arm64" ], "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-mips64el": { - "version": "0.28.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.28.2.tgz", - "integrity": "sha512-ZVykbDyk7519VwiNb9Lcj9m8XM6v5V9uKPvrEMkkEedVewf+0itkhahp4HDpgERXhwLRpWFypsGbG/J8s0QjJA==", - "cpu": [ - "mips64el" + "libc": [ + "musl" ], - "dev": true, "license": "MIT", "optional": true, "os": [ "linux" ], "engines": { - "node": ">=18" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@esbuild/linux-ppc64": { - "version": "0.28.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.28.2.tgz", - "integrity": "sha512-CAXl+Dtd9UUuJd8pKKdwh6MLm3MUMiqMPmhZ3tTSXPqfyQ3vDl6R5hZdZ/kYojK4ofXtdfSv1tFq8XzWx3heNQ==", + "node_modules/@rolldown/binding-linux-ppc64-gnu": { + "version": "1.2.15", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.2.15.tgz", + "integrity": "sha512-9nWkcdd+H+XhaA3fQIwpHnKIrfx/PQ6rO0pivr78Og07tXlUlctBBJoEYLPfhTmCR/QxEVdn6uPjHV5SymPhdw==", "cpu": [ "ppc64" ], "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-riscv64": { - "version": "0.28.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.28.2.tgz", - "integrity": "sha512-GeXCej4IQtU1B+QlDV8W/RRvbzI3O/Stss+/bCXv4lZls5WGRtu2a+3JkA3i4qIUlMXpcHebWpF8AkJhATowuA==", - "cpu": [ - "riscv64" + "libc": [ + "glibc" ], - "dev": true, "license": "MIT", "optional": true, "os": [ "linux" ], "engines": { - "node": ">=18" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@esbuild/linux-s390x": { - "version": "0.28.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.28.2.tgz", - "integrity": "sha512-3H1weTYZPxt/WOhByszQZybS9w5lKzUn1FDMsgEChbHWQwHYQQRfBxgCcZvPhjHfKyJjIievvMmEUawJrdY9Dg==", + "node_modules/@rolldown/binding-linux-s390x-gnu": { + "version": "1.2.15", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.2.15.tgz", + "integrity": "sha512-Ggh0ciFjLwIusLSLz7LZYEaGdxOAUJXI+Qu5JCbhPJJHEt8vP+IjRATTJheiJsdzzTYgUiHUiw3X1Ea3ZpMBdA==", "cpu": [ "s390x" ], "dev": true, + "libc": [ + "glibc" + ], "license": "MIT", "optional": true, "os": [ "linux" ], "engines": { - "node": ">=18" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@esbuild/linux-x64": { - "version": "0.28.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.28.2.tgz", - "integrity": "sha512-4xTZr1FUmSoQW4XIWmit3tzQrUTZM+N3P0XV8xROKYF50XfI7xeO90+1bZvNwxIufQ9hDQVRJH5YhgPVF8A/HQ==", + "node_modules/@rolldown/binding-linux-x64-gnu": { + "version": "1.2.15", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.2.15.tgz", + "integrity": "sha512-FHg60rS6DBePAYZ9X9F67x+JObFdmgn6tupA1C/a3B+CufFmTD4mX+e8M75tCiAO3foR/6xwVBI0KQiI7sn/rw==", "cpu": [ "x64" ], "dev": true, + "libc": [ + "glibc" + ], "license": "MIT", "optional": true, "os": [ "linux" ], "engines": { - "node": ">=18" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@esbuild/netbsd-arm64": { - "version": "0.28.2", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.28.2.tgz", - "integrity": "sha512-sSATRjPeDBg3pdgHoQfoYBob11Kk1FGa9lui5RIHZCoCkJa9QKlvl3/vKz2usCmYYjs7ymJR/2Nnsqe+Hjt5nw==", + "node_modules/@rolldown/binding-linux-x64-musl": { + "version": "1.2.15", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.2.15.tgz", + "integrity": "sha512-/cvV/7v5VGz/moiz0XKRj2dE8DzsKyhIu1KpOvJGPjRywg3yscON889UGvAe8zfiJLHup7VLjBduoGWi3HusWQ==", "cpu": [ - "arm64" + "x64" ], "dev": true, + "libc": [ + "musl" + ], "license": "MIT", "optional": true, "os": [ - "netbsd" + "linux" ], "engines": { - "node": ">=18" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@esbuild/netbsd-x64": { - "version": "0.28.2", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.28.2.tgz", - "integrity": "sha512-lqnzCV+mM0gIADaKihiCg6ifgfU2L3h5E33rNQBN1Y4MaVGnzryzmvvf7UHxprpQdE8hpqLolJ9Rl+SkIRDpyw==", + "node_modules/@rolldown/binding-openharmony-arm64": { + "version": "1.2.15", + "resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.2.15.tgz", + "integrity": "sha512-MyzC5Hrv/sm+Z7TSGKP/j8001RO2xQm1zOpCNVL4j0cY/VhBZviludA2YFQ7i4lH6ZAXxQm0lcMdBzM+99mE7w==", "cpu": [ - "x64" + "arm64" ], "dev": true, "license": "MIT", "optional": true, "os": [ - "netbsd" + "openharmony" ], "engines": { - "node": ">=18" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@esbuild/openbsd-arm64": { - "version": "0.28.2", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.28.2.tgz", - "integrity": "sha512-AL2qJILH7lNjrDmCQDvdxMfAUIv8KMNZOvrwAQ8i8//ntL9FflhOyMJ8OZSMBb8/AWXe3/5v5S20y3zCoZWKoQ==", + "node_modules/@rolldown/binding-win32-arm64-msvc": { + "version": "1.2.15", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.2.15.tgz", + "integrity": "sha512-+PgYiS+AH5omy6L45ZLxybasauJaj3M8buoT83D+nzPmCayXlxUV9hydhciCKVyIg0B/v0BtXPDE1uGqNwCPpg==", "cpu": [ "arm64" ], @@ -349,16 +288,16 @@ "license": "MIT", "optional": true, "os": [ - "openbsd" + "win32" ], "engines": { - "node": ">=18" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@esbuild/openbsd-x64": { - "version": "0.28.2", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.28.2.tgz", - "integrity": "sha512-QtiuPytchRyC4rwUKhexJdQKvDuZ6hWloi3igqPQNUJCS1/v9EiO3UTOXR6A3FoMo4fnAKbWJdqaIwhOzh8qEw==", + "node_modules/@rolldown/binding-win32-x64-msvc": { + "version": "1.2.15", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.2.15.tgz", + "integrity": "sha512-HFZd2QNQYn1JbIi+Hpd7H+r/lkWxcfIu28nirZ6eCn2LafuvmExMlb/P96Sfx5tf7pPArw39IdhmCF8vmV+NhQ==", "cpu": [ "x64" ], @@ -366,154 +305,121 @@ "license": "MIT", "optional": true, "os": [ - "openbsd" + "win32" ], "engines": { - "node": ">=18" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@esbuild/openharmony-arm64": { - "version": "0.28.2", - "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.28.2.tgz", - "integrity": "sha512-WkhYDmpTjLvGlScA1rwjRUmhl4k8oXR3cIbtqWmELgU/dFeHHlEllxDvdWcNJV9rbzCexB5vz8gtNewWLgCT7Q==", - "cpu": [ - "arm64" - ], + "node_modules/@rolldown/pluginutils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.1.tgz", + "integrity": "sha512-2j9bGt5Jh8hj+vPtgzPtl72j0yRxHAyumoo6TNfAjsLB04UtpSvPbPcDcBMxz7n+9CYB0c1GxQFxYRg2jimqGw==", "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openharmony" - ], - "engines": { - "node": ">=18" - } + "license": "MIT" }, - "node_modules/@esbuild/sunos-x64": { - "version": "0.28.2", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.28.2.tgz", - "integrity": "sha512-GPMSkTOtMnv2U2F8gxe4Io6qmVs+YKyp832Etqqxr0hFngmXQ3rzwytelm3GIn7T4VviRUlf3sOgBOiTdvaf7g==", - "cpu": [ - "x64" - ], + "node_modules/@types/body-parser": { + "version": "1.19.6", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.6.tgz", + "integrity": "sha512-HLFeCYgz89uk22N5Qg3dvGvsv46B8GLvKKo1zKG4NybA8U2DiEO3w9lqGg29t/tfLRJpJ6iQxnVw4OnB7MoM9g==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "sunos" - ], - "engines": { - "node": ">=18" + "dependencies": { + "@types/connect": "*", + "@types/node": "*" } }, - "node_modules/@esbuild/win32-arm64": { - "version": "0.28.2", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.28.2.tgz", - "integrity": "sha512-PIhhEkE9uPBleRBrQEJpUn7MBnibZzbGzYWPmY3x+YoVg/95zbjB4CxPPOQ8l5tYYM4mMaCthF8/1DIfBQQyWQ==", - "cpu": [ - "arm64" - ], + "node_modules/@types/connect": { + "version": "3.4.38", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", + "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" + "dependencies": { + "@types/node": "*" } }, - "node_modules/@esbuild/win32-ia32": { - "version": "0.28.2", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.28.2.tgz", - "integrity": "sha512-YmJbfTlvU7Sdn9BB+4PRES4oB6pxgS37MAONj+hBr/cpXS1aBPKXxNnDbu+QCWPj0o9dgyxeq79g6c5P8KeuYA==", - "cpu": [ - "ia32" - ], + "node_modules/@types/express": { + "version": "5.0.6", + "resolved": "https://registry.npmjs.org/@types/express/-/express-5.0.6.tgz", + "integrity": "sha512-sKYVuV7Sv9fbPIt/442koC7+IIwK5olP1KWeD88e/idgoJqDm3JV/YUiPwkoKK92ylff2MGxSz1CSjsXelx0YA==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" + "dependencies": { + "@types/body-parser": "*", + "@types/express-serve-static-core": "^5.0.0", + "@types/serve-static": "^2" } }, - "node_modules/@esbuild/win32-x64": { - "version": "0.28.2", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.28.2.tgz", - "integrity": "sha512-5ebpxr3nWMzrL/rnUI755Jkuee0bHL/Gq0WTF9lvcpv73wAp5eu8MfBUgWK9bhWvZjj7yX8etf/8tI8Ney695g==", - "cpu": [ - "x64" - ], + "node_modules/@types/express-serve-static-core": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-5.1.2.tgz", + "integrity": "sha512-d3KvEXBSo/lOAMc2u6fkyDHBvetBHeqD7wm/AcXfLpSOQwlmG9D/aQ0SFswVjv05p7ullQS7Mjohj6/VdbZuTg==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" + "dependencies": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*", + "@types/send": "*" } }, - "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.13", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", - "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", + "node_modules/@types/http-errors": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.5.tgz", + "integrity": "sha512-r8Tayk8HJnX0FztbZN7oVqGccWgw98T/0neJphO91KkmOzug1KkofZURD4UaD5uH8AqcFLfdPErnBod0u71/qg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/node": { + "version": "24.19.2", + "resolved": "https://registry.npmjs.org/@types/node/-/node-24.19.2.tgz", + "integrity": "sha512-93d49wCWJkCyN87MxLpNN6KXPCwFw7bVUg79mGUV1OS40JGWwVCr8n61DXCSqz7CV6/VfPkb7xec7uP2M+QHWQ==", "dev": true, "license": "MIT", "dependencies": { - "@jridgewell/sourcemap-codec": "^1.5.0", - "@jridgewell/trace-mapping": "^0.3.24" + "undici-types": ">=7.24.0 <7.24.7" } }, - "node_modules/@jridgewell/resolve-uri": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", - "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "node_modules/@types/qs": { + "version": "6.15.1", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.15.1.tgz", + "integrity": "sha512-GZHUBZR9hckSUhrxmp1nG6NwdpM9fCunJwyThLW1X3AyHgd9IlHb6VANpQQqDr2o/qQp6McZ3y/IA2rVzKzSbw==", "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.0.0" - } + "license": "MIT" }, - "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.5.5", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", - "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "node_modules/@types/range-parser": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz", + "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==", "dev": true, "license": "MIT" }, - "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.31", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", - "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", + "node_modules/@types/send": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@types/send/-/send-1.2.1.tgz", + "integrity": "sha512-arsCikDvlU99zl1g69TcAB3mzZPpxgw0UQnaHeC1Nwb015xp8bknZv5rIfri9xTOcMuaVgvabfIRA7PSZVuZIQ==", "dev": true, "license": "MIT", "dependencies": { - "@jridgewell/resolve-uri": "^3.1.0", - "@jridgewell/sourcemap-codec": "^1.4.14" + "@types/node": "*" } }, - "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.61.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.61.1.tgz", - "integrity": "sha512-JnBB8MdXj45cajvTuO5FmPlvFVJRQgvrz1uSEl3NwqFnReAPGwb8EanbGi4z2nRaqLzjJSv5/JmycoTKlRZxHA==", - "cpu": [ - "arm" - ], + "node_modules/@types/serve-static": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-2.2.0.tgz", + "integrity": "sha512-8mam4H1NHLtu7nmtalF7eyBH14QyOASmcxHhSfEoRyr0nP/YdoesEtU+uSRvMe96TW/HPTtkoKqQLl53N7UXMQ==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "android" - ] + "dependencies": { + "@types/http-errors": "*", + "@types/node": "*" + } }, - "node_modules/@rollup/rollup-android-arm64": { - "version": "4.61.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.61.1.tgz", - "integrity": "sha512-Jx2g7iSjw4AOT0HDPHM9RV3GNjRXwybWtSFZiZAYUTjUwjVrYIwq3kBf+LnhqJlzXFAqTAh2F7IGI+O568exPw==", + "node_modules/@yuku-core/binding-android-arm64": { + "version": "0.19.0", + "resolved": "https://registry.npmjs.org/@yuku-core/binding-android-arm64/-/binding-android-arm64-0.19.0.tgz", + "integrity": "sha512-wdL2XmTiZixAOaHk9Z0JJZ8u9Qm8d333Zjpc6gaxXFX+UR5BlsfxZ7a2+2Rm71pamppsPYGUGFq2oVLbh6DISw==", "cpu": [ "arm64" ], @@ -524,10 +430,10 @@ "android" ] }, - "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.61.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.61.1.tgz", - "integrity": "sha512-0F1L/Z3Eqv8mT2n3dCpeO8GcTvHvVqkP5/t6DMsn0KzhYVcg+s7Ncl5DS8qjKYEeio6Az0Gt6nyBORay5qIlCA==", + "node_modules/@yuku-core/binding-darwin-arm64": { + "version": "0.19.0", + "resolved": "https://registry.npmjs.org/@yuku-core/binding-darwin-arm64/-/binding-darwin-arm64-0.19.0.tgz", + "integrity": "sha512-7sNJa6XJhyetnTy64jw3NEi4YgUcezHk1G5GH9FSvXAuC8wIlbaOwT9lgq5qo5sspjrZJQlBR1TWflP49uRpMw==", "cpu": [ "arm64" ], @@ -538,10 +444,10 @@ "darwin" ] }, - "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.61.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.61.1.tgz", - "integrity": "sha512-qLttcH871ujY4YcVfUSShhOw+CsoTatYz8gRbHO7Bb92QH059/P0y5do1KMs41fY0BpD2x4AJH/gID0zFiqVKQ==", + "node_modules/@yuku-core/binding-darwin-x64": { + "version": "0.19.0", + "resolved": "https://registry.npmjs.org/@yuku-core/binding-darwin-x64/-/binding-darwin-x64-0.19.0.tgz", + "integrity": "sha512-pTC7dYEc59isdyizc3nsuyFNBu2LU5wMYZ1be6UMr59PY/AJNtO1aBLWV0MgL/z7C1nv/2sX4TNjGgKLoeevJw==", "cpu": [ "x64" ], @@ -552,24 +458,10 @@ "darwin" ] }, - "node_modules/@rollup/rollup-freebsd-arm64": { - "version": "4.61.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.61.1.tgz", - "integrity": "sha512-fUI4RapGE0Oh3mb8mgfvC1O2nU1RpDZUKnDQm3xB1Ipg7C2wTs5Kstz7G2uWK99a8S2yTMq8/P4uycwNa0nJyw==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ] - }, - "node_modules/@rollup/rollup-freebsd-x64": { - "version": "4.61.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.61.1.tgz", - "integrity": "sha512-H5YrdvJaDtI/U9/emrD4b++xkvp3y/JvOe4rizHbxvkyMfRS/CiRYdji+Pl8D0brEaNFWUh1drQxgAGIl6Xudw==", + "node_modules/@yuku-core/binding-freebsd-x64": { + "version": "0.19.0", + "resolved": "https://registry.npmjs.org/@yuku-core/binding-freebsd-x64/-/binding-freebsd-x64-0.19.0.tgz", + "integrity": "sha512-xrZjF6XOEwyLOiDIfrwDdRCS6ghxcJeirNC1KivQhVcUwlRonaU79S3/Uiyx3lBylPnT8qKJ3/aMT+H52nGTJQ==", "cpu": [ "x64" ], @@ -580,514 +472,189 @@ "freebsd" ] }, - "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.61.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.61.1.tgz", - "integrity": "sha512-Q8CBCCQtDFrYtXoeUXSrnFXKOnyUhx6bz+SkL6A0E7V8kAiCJ5pamq1WtbfpVGhR5TSpXY6ak3avmDc5fHTyJA==", + "node_modules/@yuku-core/binding-linux-arm-gnu": { + "version": "0.19.0", + "resolved": "https://registry.npmjs.org/@yuku-core/binding-linux-arm-gnu/-/binding-linux-arm-gnu-0.19.0.tgz", + "integrity": "sha512-0OyIH53C0I1CbADHn9FSdCfX5qbpeLwJhmOVhonFJNYheybOnkSJ50qGMfTJIb8y5zrwqvLs7FVBvz6Fk8maZg==", "cpu": [ "arm" ], "dev": true, + "libc": [ + "glibc" + ], "license": "MIT", "optional": true, "os": [ "linux" ] }, - "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.61.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.61.1.tgz", - "integrity": "sha512-nwnhk1581l0FBVellGcVCAT0Oi06onEA3WB53sf01VO3I0UPBkMH9sXONYME2K0ovXcNayJfNtHfm6mpJElatQ==", + "node_modules/@yuku-core/binding-linux-arm-musl": { + "version": "0.19.0", + "resolved": "https://registry.npmjs.org/@yuku-core/binding-linux-arm-musl/-/binding-linux-arm-musl-0.19.0.tgz", + "integrity": "sha512-z/iPfkCOCSXE34VXNt0uP1ORSW+4mEa9b5CiJcWZeqZH08g49bFU/jRM2T04f+Wpw5mJ6HIzNBiojxeAbrHjeg==", "cpu": [ "arm" ], "dev": true, + "libc": [ + "musl" + ], "license": "MIT", "optional": true, "os": [ "linux" ] }, - "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.61.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.61.1.tgz", - "integrity": "sha512-x5Xr49hwt3hdW75UOZm3395YwwzPyauktslv29KpWL/T+vVAzoT3azLcTWv0eMciBNrx+DYjH4paehHoLpPvpg==", + "node_modules/@yuku-core/binding-linux-arm64-gnu": { + "version": "0.19.0", + "resolved": "https://registry.npmjs.org/@yuku-core/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-0.19.0.tgz", + "integrity": "sha512-jLNTi+gzaRwBJ+gwhCJ+rDb5dmx/8hEBx93UWd7hjMSqPTL1D1wvVSvXVAldV5kALvju7b0/m51EHEhs4+I1fA==", "cpu": [ "arm64" ], "dev": true, + "libc": [ + "glibc" + ], "license": "MIT", "optional": true, "os": [ "linux" ] }, - "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.61.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.61.1.tgz", - "integrity": "sha512-unMS3H73DpaoPyyEVPjGKleM/s0mkmsauTENpw4INQY8y4+IuLNjkueQ5QCtC0D3N38Y38yhAU8OoZ20S2Tm6w==", + "node_modules/@yuku-core/binding-linux-arm64-musl": { + "version": "0.19.0", + "resolved": "https://registry.npmjs.org/@yuku-core/binding-linux-arm64-musl/-/binding-linux-arm64-musl-0.19.0.tgz", + "integrity": "sha512-YwyPIdW/rN2Fmv0MTFWi47FaB3F9g+2b+sJISyAw83Yd60RWH4T3Nx6XkAHHVN+uKJNBAd6So7/BVihSiFYvuQ==", "cpu": [ "arm64" ], "dev": true, + "libc": [ + "musl" + ], "license": "MIT", "optional": true, "os": [ "linux" ] }, - "node_modules/@rollup/rollup-linux-loong64-gnu": { - "version": "4.61.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.61.1.tgz", - "integrity": "sha512-zNZzGRnAhwjFEYmvphJRV5XaQGjs62cCmeYYHUT//NbvEnHauw+I85nGG+SiVg5ld4GX8D1IbKIX+ozITQnhMQ==", + "node_modules/@yuku-core/binding-linux-x64-gnu": { + "version": "0.19.0", + "resolved": "https://registry.npmjs.org/@yuku-core/binding-linux-x64-gnu/-/binding-linux-x64-gnu-0.19.0.tgz", + "integrity": "sha512-/vskaAXVX3ESR43FiTdfiYS7z1b9uoQJwVQ/0RgUHgN2sWoAyCZs+aX4CgU7eKGIHTVfp9VFwv+c+2XchYiEtQ==", "cpu": [ - "loong64" + "x64" ], "dev": true, + "libc": [ + "glibc" + ], "license": "MIT", "optional": true, "os": [ "linux" ] }, - "node_modules/@rollup/rollup-linux-loong64-musl": { - "version": "4.61.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.61.1.tgz", - "integrity": "sha512-LdpWGL8X209B2SIvWjqlc8VZgM6PKfontSerGepuldQmHYrAOtnMCXeJkxXGbC+PPZVOuu5czJo7fNV6aeW8rQ==", + "node_modules/@yuku-core/binding-linux-x64-musl": { + "version": "0.19.0", + "resolved": "https://registry.npmjs.org/@yuku-core/binding-linux-x64-musl/-/binding-linux-x64-musl-0.19.0.tgz", + "integrity": "sha512-FuXL5igeSKib9Rye02TdH+D6SQezTyGxIATMu1Qsn/QywrzwpGl35OLpS2C1x5vpGLeVE2XgiLd5mVPFHmIglQ==", "cpu": [ - "loong64" + "x64" ], "dev": true, + "libc": [ + "musl" + ], "license": "MIT", "optional": true, "os": [ "linux" ] }, - "node_modules/@rollup/rollup-linux-ppc64-gnu": { - "version": "4.61.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.61.1.tgz", - "integrity": "sha512-EC5kTtNaNGOmbMGqar8dvJy6y/hg99GAwjfBz++pxZhQATXGcRjd6c5en5wcbru0vkRmiMGsQKdMJOOf6sza4g==", + "node_modules/@yuku-core/binding-win32-arm64": { + "version": "0.19.0", + "resolved": "https://registry.npmjs.org/@yuku-core/binding-win32-arm64/-/binding-win32-arm64-0.19.0.tgz", + "integrity": "sha512-YuJAe7zEKT1Xa7LuHlhGJpPnYQeVtvo0rZvNjJRqkH0hQGOw4C8QeP30Tg5VKGzZfo2x8CjhjEhKt4TmLwfmdg==", "cpu": [ - "ppc64" + "arm64" ], "dev": true, "license": "MIT", "optional": true, "os": [ - "linux" + "win32" ] }, - "node_modules/@rollup/rollup-linux-ppc64-musl": { - "version": "4.61.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.61.1.tgz", - "integrity": "sha512-8hiwp6D4acEcNK78I4rP0/XtS1sknWIAMJBPdR4l6zUtyTm5KiTDr5bXmWt4foY7nAN7AThDHgkLIEZOWKbzWw==", + "node_modules/@yuku-core/binding-win32-x64": { + "version": "0.19.0", + "resolved": "https://registry.npmjs.org/@yuku-core/binding-win32-x64/-/binding-win32-x64-0.19.0.tgz", + "integrity": "sha512-o8iY/mXwlRkedp0LNTr4+TEfXTPQwoNZmv6k+1WIAd1ZXEn8xJJTBCtB0osaVvdZo/x/cNmV16UrWrrGpM5Mvw==", "cpu": [ - "ppc64" + "x64" ], "dev": true, "license": "MIT", "optional": true, "os": [ - "linux" + "win32" ] }, - "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.61.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.61.1.tgz", - "integrity": "sha512-10dh/h/BqA7DuMPWSxkR8uks18FRwnwOEqr5zOTEl+NOwP/OMzKX8OFR/Of9xxDA7D5qef1Nzar5WDD2kCCr1g==", - "cpu": [ - "riscv64" - ], + "node_modules/@yuku-toolchain/types": { + "version": "0.19.0", + "resolved": "https://registry.npmjs.org/@yuku-toolchain/types/-/types-0.19.0.tgz", + "integrity": "sha512-tFkNbsP4WXX9UMUC5syJGdK9dPMLK0PPaIuXCcCYH75sZ8MrebfBZ2XvCILRTw8AgLivSSCfDa4R67iYBDa4Kg==", "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] + "license": "MIT" }, - "node_modules/@rollup/rollup-linux-riscv64-musl": { - "version": "4.61.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.61.1.tgz", - "integrity": "sha512-YKJ5lg35DP17gcAOggnihe+APw9HLyj1Xn7gsmGumBJAUDa6NGXNixJzmkWLhcK9TOuuyQjdamzvJefkO7qHZQ==", - "cpu": [ - "riscv64" - ], + "node_modules/cac": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/cac/-/cac-7.1.0.tgz", + "integrity": "sha512-LMDU/U2yA4IPIY8KT0NsNPWEYZvAMkbgyspxJ6btJaYV+WMDOHAZCmB0lsTObiHaRS1V/ztKAl7+TSkTqXyeoA==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.61.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.61.1.tgz", - "integrity": "sha512-Mlil5G2Jj6a7B3LWGctg+XPL9vdXYuzCtNXfxOQ0nPjc2m6ueUktocPGH9bnAM0bNRKb/bAWTujUU7IJQdQA+g==", - "cpu": [ - "s390x" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.61.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.61.1.tgz", - "integrity": "sha512-bVWIOIk6pV01p4CdUbPP7CJ/434z+OooYjDuFcR+44N35YvKUC66G8MGnvcWx5mWKW3g61J+t74l3Kj15Kwn2Q==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.61.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.61.1.tgz", - "integrity": "sha512-qy5pBvZbqNFheBz61R1rzsezjm0J7O2oNGoWtGoY89SZYLUfxAJTBAqDChqAIdB4rCiIbi9nF7yZ83GnNiLwSw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-openbsd-x64": { - "version": "4.61.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.61.1.tgz", - "integrity": "sha512-E83TXjI4zm0+5f2qO+UOudaCYIhYwpJ5jq6YCZNIZ+6CbfhKrkAGezeiASBL9ElxAxFsRS9ZhESv8mfnj6TKeg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ] - }, - "node_modules/@rollup/rollup-openharmony-arm64": { - "version": "4.61.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.61.1.tgz", - "integrity": "sha512-fbWnKqVkjrJN38vNe3ahkbk6iejS/3b0Nt7EEtPpE6RBacZcGXNKbzfHN3GUUlXOPghUg0j6XUGrtjX9z1sIvA==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openharmony" - ] - }, - "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.61.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.61.1.tgz", - "integrity": "sha512-ArMl38iVAbk0New1ogihQNY6iphLi4ZaRsa037gUzv5yeKPY8TD3Dmy4x2RNC1VztU/uqm+G+/RwFrSka3Oy2g==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.61.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.61.1.tgz", - "integrity": "sha512-0mYtjHS9ucAbcATycCNK9IGBk/cCe/ma7EmSLGZdsxnOA8cjRIyU04wDpVAD9NiOfLUR9KTxdiO53uOkherqjQ==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@rollup/rollup-win32-x64-gnu": { - "version": "4.61.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.61.1.tgz", - "integrity": "sha512-gK1iCEPfpoSG9wfBihXxvBMi8ZfcWffYkEsC/Eih+iFENTaewvNcrEQ69lIOWYO5pePHKLHHO7nq5AILGO/HQQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.61.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.61.1.tgz", - "integrity": "sha512-X+zaP2x+j4RXGfbp/seSoRHWnPxzApilDszisZxbYH5C/jTxFhCtDNdPGZb9lJyYPs24wGxruPF7Y+sIXt9Gzw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@types/body-parser": { - "version": "1.19.6", - "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.6.tgz", - "integrity": "sha512-HLFeCYgz89uk22N5Qg3dvGvsv46B8GLvKKo1zKG4NybA8U2DiEO3w9lqGg29t/tfLRJpJ6iQxnVw4OnB7MoM9g==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/connect": "*", - "@types/node": "*" - } - }, - "node_modules/@types/connect": { - "version": "3.4.38", - "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", - "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/estree": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.9.tgz", - "integrity": "sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/express": { - "version": "5.0.6", - "resolved": "https://registry.npmjs.org/@types/express/-/express-5.0.6.tgz", - "integrity": "sha512-sKYVuV7Sv9fbPIt/442koC7+IIwK5olP1KWeD88e/idgoJqDm3JV/YUiPwkoKK92ylff2MGxSz1CSjsXelx0YA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/body-parser": "*", - "@types/express-serve-static-core": "^5.0.0", - "@types/serve-static": "^2" - } - }, - "node_modules/@types/express-serve-static-core": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-5.1.2.tgz", - "integrity": "sha512-d3KvEXBSo/lOAMc2u6fkyDHBvetBHeqD7wm/AcXfLpSOQwlmG9D/aQ0SFswVjv05p7ullQS7Mjohj6/VdbZuTg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "*", - "@types/qs": "*", - "@types/range-parser": "*", - "@types/send": "*" - } - }, - "node_modules/@types/http-errors": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.5.tgz", - "integrity": "sha512-r8Tayk8HJnX0FztbZN7oVqGccWgw98T/0neJphO91KkmOzug1KkofZURD4UaD5uH8AqcFLfdPErnBod0u71/qg==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/node": { - "version": "24.19.2", - "resolved": "https://registry.npmjs.org/@types/node/-/node-24.19.2.tgz", - "integrity": "sha512-93d49wCWJkCyN87MxLpNN6KXPCwFw7bVUg79mGUV1OS40JGWwVCr8n61DXCSqz7CV6/VfPkb7xec7uP2M+QHWQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "undici-types": ">=7.24.0 <7.24.7" - } - }, - "node_modules/@types/qs": { - "version": "6.15.1", - "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.15.1.tgz", - "integrity": "sha512-GZHUBZR9hckSUhrxmp1nG6NwdpM9fCunJwyThLW1X3AyHgd9IlHb6VANpQQqDr2o/qQp6McZ3y/IA2rVzKzSbw==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/range-parser": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz", - "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/send": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@types/send/-/send-1.2.1.tgz", - "integrity": "sha512-arsCikDvlU99zl1g69TcAB3mzZPpxgw0UQnaHeC1Nwb015xp8bknZv5rIfri9xTOcMuaVgvabfIRA7PSZVuZIQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/serve-static": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-2.2.0.tgz", - "integrity": "sha512-8mam4H1NHLtu7nmtalF7eyBH14QyOASmcxHhSfEoRyr0nP/YdoesEtU+uSRvMe96TW/HPTtkoKqQLl53N7UXMQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/http-errors": "*", - "@types/node": "*" - } - }, - "node_modules/acorn": { - "version": "8.16.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz", - "integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==", - "dev": true, - "license": "MIT", - "bin": { - "acorn": "bin/acorn" - }, "engines": { - "node": ">=0.4.0" + "node": ">=20.19.0" } }, - "node_modules/any-promise": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", - "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==", + "node_modules/defu": { + "version": "6.1.7", + "resolved": "https://registry.npmjs.org/defu/-/defu-6.1.7.tgz", + "integrity": "sha512-7z22QmUWiQ/2d0KkdYmANbRUVABpZ9SNYyH5vx6PZ+nE5bcC0l7uFvEfHlyld/HcGBFTL536ClDt3DEcSlEJAQ==", "dev": true, "license": "MIT" }, - "node_modules/bundle-require": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/bundle-require/-/bundle-require-5.1.0.tgz", - "integrity": "sha512-3WrrOuZiyaaZPWiEt4G3+IffISVC9HYlWueJEBWED4ZH4aIAC2PnkdnuRrR94M+w6yGWn4AglWtJtBI8YqvgoA==", - "dev": true, - "license": "MIT", - "dependencies": { - "load-tsconfig": "^0.2.3" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "peerDependencies": { - "esbuild": ">=0.18" - } - }, - "node_modules/cac": { - "version": "6.7.14", - "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz", - "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/chokidar": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", - "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", + "node_modules/dts-resolver": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/dts-resolver/-/dts-resolver-3.0.0.tgz", + "integrity": "sha512-1T1f+z+4tl9XD+m+0HBgWoL/nm0bOIffyWaUuUSBlFg/86IWvfx+wjNaO/ybU0AJzG9/Mi5hBUgGV6zCmWEN7Q==", "dev": true, "license": "MIT", - "dependencies": { - "readdirp": "^4.0.1" - }, "engines": { - "node": ">= 14.16.0" + "node": "^22.18.0 || >=24.0.0" }, "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/confbox": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/confbox/-/confbox-0.1.8.tgz", - "integrity": "sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==", - "dev": true, - "license": "MIT" - }, - "node_modules/consola": { - "version": "3.4.2", - "resolved": "https://registry.npmjs.org/consola/-/consola-3.4.2.tgz", - "integrity": "sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^14.18.0 || >=16.10.0" - } - }, - "node_modules/debug": { - "version": "4.4.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", - "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", - "dev": true, - "license": "MIT", - "dependencies": { - "ms": "^2.1.3" + "url": "https://github.com/sponsors/sxzz" }, - "engines": { - "node": ">=6.0" + "peerDependencies": { + "oxc-resolver": ">=11.0.0" }, "peerDependenciesMeta": { - "supports-color": { + "oxc-resolver": { "optional": true } } }, - "node_modules/esbuild": { - "version": "0.28.2", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.28.2.tgz", - "integrity": "sha512-HKVLS8dvII+xoKW9kmqxbRKrnWEXfJJr/FZhhJmiqIB0e053QNYFqOBouTMO/k5sID4MvCiUCvv8b9M4h32wIA==", + "node_modules/empathic": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/empathic/-/empathic-2.1.0.tgz", + "integrity": "sha512-AnfC1ATldl49/cvZdLPDjBfrRNwbDO05aibiOtzQu3qtlbJtomNLhF30HEtn/7iBz50dlMECqATo3fG0LrdEgw==", "dev": true, - "hasInstallScript": true, "license": "MIT", - "bin": { - "esbuild": "bin/esbuild" - }, "engines": { - "node": ">=18" - }, - "optionalDependencies": { - "@esbuild/aix-ppc64": "0.28.2", - "@esbuild/android-arm": "0.28.2", - "@esbuild/android-arm64": "0.28.2", - "@esbuild/android-x64": "0.28.2", - "@esbuild/darwin-arm64": "0.28.2", - "@esbuild/darwin-x64": "0.28.2", - "@esbuild/freebsd-arm64": "0.28.2", - "@esbuild/freebsd-x64": "0.28.2", - "@esbuild/linux-arm": "0.28.2", - "@esbuild/linux-arm64": "0.28.2", - "@esbuild/linux-ia32": "0.28.2", - "@esbuild/linux-loong64": "0.28.2", - "@esbuild/linux-mips64el": "0.28.2", - "@esbuild/linux-ppc64": "0.28.2", - "@esbuild/linux-riscv64": "0.28.2", - "@esbuild/linux-s390x": "0.28.2", - "@esbuild/linux-x64": "0.28.2", - "@esbuild/netbsd-arm64": "0.28.2", - "@esbuild/netbsd-x64": "0.28.2", - "@esbuild/openbsd-arm64": "0.28.2", - "@esbuild/openbsd-x64": "0.28.2", - "@esbuild/openharmony-arm64": "0.28.2", - "@esbuild/sunos-x64": "0.28.2", - "@esbuild/win32-arm64": "0.28.2", - "@esbuild/win32-ia32": "0.28.2", - "@esbuild/win32-x64": "0.28.2" + "node": ">=14" } }, "node_modules/fdir": { @@ -1108,143 +675,60 @@ } } }, - "node_modules/fix-dts-default-cjs-exports": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/fix-dts-default-cjs-exports/-/fix-dts-default-cjs-exports-1.0.1.tgz", - "integrity": "sha512-pVIECanWFC61Hzl2+oOCtoJ3F17kglZC/6N94eRWycFgBH35hHx0Li604ZIzhseh97mf2p0cv7vVrOZGoqhlEg==", + "node_modules/get-tsconfig": { + "version": "5.0.0-beta.6", + "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-5.0.0-beta.6.tgz", + "integrity": "sha512-X6fBC0pmImC70gvX2zm56go9hx0MyoGVdG0tUCkg/D+Xnh5TJsOZ7iDbOdI3PvmtrDxnu1YdDufpK2QJX1Meqw==", "dev": true, "license": "MIT", "dependencies": { - "magic-string": "^0.30.17", - "mlly": "^1.7.4", - "rollup": "^4.34.8" - } - }, - "node_modules/fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, - "node_modules/joycon": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/joycon/-/joycon-3.1.1.tgz", - "integrity": "sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - } - }, - "node_modules/lilconfig": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.3.tgz", - "integrity": "sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==", - "dev": true, - "license": "MIT", + "resolve-pkg-maps": "^1.0.0" + }, "engines": { - "node": ">=14" + "node": ">=20.20.0" }, "funding": { - "url": "https://github.com/sponsors/antonk52" + "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" } }, - "node_modules/lines-and-columns": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", - "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "node_modules/hookable": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/hookable/-/hookable-6.1.2.tgz", + "integrity": "sha512-+abwxtiEA52GCVIsQqut3S/uKTbUwYIp4Pe/vv+6py5XiXBCqMZHg6pA6Y5qhgLSEys0/cYuPbO0z1QFj5ZCmg==", "dev": true, "license": "MIT" }, - "node_modules/load-tsconfig": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/load-tsconfig/-/load-tsconfig-0.2.5.tgz", - "integrity": "sha512-IXO6OCs9yg8tMKzfPZ1YmheJbZCiEsnBdcB03l0OcfK9prKnJb96siuHCr5Fl37/yo9DnKU+TLpxzTUspw9shg==", + "node_modules/import-without-cache": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/import-without-cache/-/import-without-cache-0.4.1.tgz", + "integrity": "sha512-vXoV9PjKHEednCUu01e98TkImxy67e3BJXbTIOmIq4Hyzw3IAwYRcuPkfeTzJzwyyts4kjuA73x+pWJLc4f86A==", "dev": true, "license": "MIT", "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - } - }, - "node_modules/magic-string": { - "version": "0.30.21", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz", - "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jridgewell/sourcemap-codec": "^1.5.5" - } - }, - "node_modules/mlly": { - "version": "1.8.2", - "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.8.2.tgz", - "integrity": "sha512-d+ObxMQFmbt10sretNDytwt85VrbkhhUA/JBGm1MPaWJ65Cl4wOgLaB1NYvJSZ0Ef03MMEU/0xpPMXUIQ29UfA==", - "dev": true, - "license": "MIT", - "dependencies": { - "acorn": "^8.16.0", - "pathe": "^2.0.3", - "pkg-types": "^1.3.1", - "ufo": "^1.6.3" - } - }, - "node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true, - "license": "MIT" - }, - "node_modules/mz": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", - "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "any-promise": "^1.0.0", - "object-assign": "^4.0.1", - "thenify-all": "^1.0.0" + "node": "^22.18.0 || >=24.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sxzz" } }, - "node_modules/object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "node_modules/obug": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/obug/-/obug-3.0.0.tgz", + "integrity": "sha512-5vvB5+W7ePv+p3uqxi+RcW1XAzLW0/hxt3/4X4Lc4qHudzOhmBiBwOY6DRob4WnanAEGvNcLjF+KNOufrUoEQw==", "dev": true, + "funding": [ + "https://github.com/sponsors/sxzz", + "https://opencollective.com/debug" + ], "license": "MIT", "engines": { - "node": ">=0.10.0" + "node": ">=12.20.0" } }, - "node_modules/pathe": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", - "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", - "dev": true, - "license": "MIT" - }, - "node_modules/picocolors": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", - "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", - "dev": true, - "license": "ISC" - }, "node_modules/picomatch": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.5.tgz", - "integrity": "sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A==", + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.7.tgz", + "integrity": "sha512-qcJu88Q2IWqJsDD529JKMdwGm/dvInW4HvQnRwiH9JtihJvzGOscDtHE3x1pBKeUOTysQ8kVmLnJ2kJu7yhcGA==", "dev": true, "license": "MIT", "engines": { @@ -1254,213 +738,123 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, - "node_modules/pirates": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.7.tgz", - "integrity": "sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 6" - } - }, - "node_modules/pkg-types": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-1.3.1.tgz", - "integrity": "sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "confbox": "^0.1.8", - "mlly": "^1.7.4", - "pathe": "^2.0.1" - } - }, - "node_modules/postcss-load-config": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-6.0.1.tgz", - "integrity": "sha512-oPtTM4oerL+UXmx+93ytZVN82RrlY/wPUV8IeDxFrzIjXOLF1pN+EmKPLbubvKHT2HC20xXsCAH2Z+CKV6Oz/g==", + "node_modules/quansync": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/quansync/-/quansync-1.0.0.tgz", + "integrity": "sha512-5xZacEEufv3HSTPQuchrvV6soaiACMFnq1H8wkVioctoH3TRha9Sz66lOxRwPK/qZj7HPiSveih9yAyh98gvqA==", "dev": true, "funding": [ { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" + "type": "individual", + "url": "https://github.com/sponsors/antfu" }, { - "type": "github", - "url": "https://github.com/sponsors/ai" + "type": "individual", + "url": "https://github.com/sponsors/sxzz" } ], - "license": "MIT", - "dependencies": { - "lilconfig": "^3.1.1" - }, - "engines": { - "node": ">= 18" - }, - "peerDependencies": { - "jiti": ">=1.21.0", - "postcss": ">=8.0.9", - "tsx": "^4.8.1", - "yaml": "^2.4.2" - }, - "peerDependenciesMeta": { - "jiti": { - "optional": true - }, - "postcss": { - "optional": true - }, - "tsx": { - "optional": true - }, - "yaml": { - "optional": true - } - } + "license": "MIT" }, - "node_modules/readdirp": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", - "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", + "node_modules/resolve-pkg-maps": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", + "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", "dev": true, "license": "MIT", - "engines": { - "node": ">= 14.18.0" - }, "funding": { - "type": "individual", - "url": "https://paulmillr.com/funding/" + "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" } }, - "node_modules/resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/rollup": { - "version": "4.61.1", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.61.1.tgz", - "integrity": "sha512-I4KW6iuRpuu2uHBLraZ1wNZe0DP7lnRha+VJ9tNaYVaVgKhW0aI3h4RYnoRPeql0flHm/Co55b7snEDcOfOJrA==", + "node_modules/rolldown": { + "version": "1.2.15", + "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.2.15.tgz", + "integrity": "sha512-6odND+fel5zVw3I4Yc2e69gvguDnX0CAAGiNDZSq4ik5WUcaLrkD2GLuog0XcODbor31hZ5ayEMgVDno+KPV5g==", "dev": true, "license": "MIT", "dependencies": { - "@types/estree": "1.0.9" + "@oxc-project/types": "=0.155.0", + "@rolldown/pluginutils": "^1.0.0" }, "bin": { - "rollup": "dist/bin/rollup" + "rolldown": "bin/cli.mjs" }, "engines": { - "node": ">=18.0.0", - "npm": ">=8.0.0" + "node": "^20.19.0 || >=22.12.0" }, "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.61.1", - "@rollup/rollup-android-arm64": "4.61.1", - "@rollup/rollup-darwin-arm64": "4.61.1", - "@rollup/rollup-darwin-x64": "4.61.1", - "@rollup/rollup-freebsd-arm64": "4.61.1", - "@rollup/rollup-freebsd-x64": "4.61.1", - "@rollup/rollup-linux-arm-gnueabihf": "4.61.1", - "@rollup/rollup-linux-arm-musleabihf": "4.61.1", - "@rollup/rollup-linux-arm64-gnu": "4.61.1", - "@rollup/rollup-linux-arm64-musl": "4.61.1", - "@rollup/rollup-linux-loong64-gnu": "4.61.1", - "@rollup/rollup-linux-loong64-musl": "4.61.1", - "@rollup/rollup-linux-ppc64-gnu": "4.61.1", - "@rollup/rollup-linux-ppc64-musl": "4.61.1", - "@rollup/rollup-linux-riscv64-gnu": "4.61.1", - "@rollup/rollup-linux-riscv64-musl": "4.61.1", - "@rollup/rollup-linux-s390x-gnu": "4.61.1", - "@rollup/rollup-linux-x64-gnu": "4.61.1", - "@rollup/rollup-linux-x64-musl": "4.61.1", - "@rollup/rollup-openbsd-x64": "4.61.1", - "@rollup/rollup-openharmony-arm64": "4.61.1", - "@rollup/rollup-win32-arm64-msvc": "4.61.1", - "@rollup/rollup-win32-ia32-msvc": "4.61.1", - "@rollup/rollup-win32-x64-gnu": "4.61.1", - "@rollup/rollup-win32-x64-msvc": "4.61.1", - "fsevents": "~2.3.2" - } - }, - "node_modules/source-map": { - "version": "0.7.6", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.6.tgz", - "integrity": "sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ==", - "dev": true, - "license": "BSD-3-Clause", - "engines": { - "node": ">= 12" - } - }, - "node_modules/sucrase": { - "version": "3.35.1", - "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.35.1.tgz", - "integrity": "sha512-DhuTmvZWux4H1UOnWMB3sk0sbaCVOoQZjv8u1rDoTV0HTdGem9hkAZtl4JZy8P2z4Bg0nT+YMeOFyVr4zcG5Tw==", + "@rolldown/binding-android-arm-eabi": "1.2.15", + "@rolldown/binding-android-arm64": "1.2.15", + "@rolldown/binding-darwin-arm64": "1.2.15", + "@rolldown/binding-darwin-x64": "1.2.15", + "@rolldown/binding-freebsd-x64": "1.2.15", + "@rolldown/binding-linux-arm-gnueabihf": "1.2.15", + "@rolldown/binding-linux-arm64-gnu": "1.2.15", + "@rolldown/binding-linux-arm64-musl": "1.2.15", + "@rolldown/binding-linux-ppc64-gnu": "1.2.15", + "@rolldown/binding-linux-s390x-gnu": "1.2.15", + "@rolldown/binding-linux-x64-gnu": "1.2.15", + "@rolldown/binding-linux-x64-musl": "1.2.15", + "@rolldown/binding-openharmony-arm64": "1.2.15", + "@rolldown/binding-win32-arm64-msvc": "1.2.15", + "@rolldown/binding-win32-x64-msvc": "1.2.15" + } + }, + "node_modules/rolldown-plugin-dts": { + "version": "0.28.8", + "resolved": "https://registry.npmjs.org/rolldown-plugin-dts/-/rolldown-plugin-dts-0.28.8.tgz", + "integrity": "sha512-FVhfqxorCWcc20BVT5eVRfRjzLLl6mgzjcMR4gSBf0K4oQMXT0qoHhhzfXy0L7y83fQy7Ug5ZDNk90xM3/LiCQ==", "dev": true, "license": "MIT", "dependencies": { - "@jridgewell/gen-mapping": "^0.3.2", - "commander": "^4.0.0", - "lines-and-columns": "^1.1.6", - "mz": "^2.7.0", - "pirates": "^4.0.1", - "tinyglobby": "^0.2.11", - "ts-interface-checker": "^0.1.9" - }, - "bin": { - "sucrase": "bin/sucrase", - "sucrase-node": "bin/sucrase-node" + "dts-resolver": "^3.0.0", + "get-tsconfig": "5.0.0-beta.6", + "obug": "^3.0.0", + "yuku-ast": "^0.19.0", + "yuku-codegen": "^0.19.0", + "yuku-parser": "^0.19.0" }, "engines": { - "node": ">=16 || 14 >=14.17" - } - }, - "node_modules/sucrase/node_modules/commander": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", - "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 6" - } - }, - "node_modules/thenify": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", - "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", - "dev": true, - "license": "MIT", - "dependencies": { - "any-promise": "^1.0.0" + "node": "^22.18.0 || ^24.11.0 || >=26.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sxzz" + }, + "peerDependencies": { + "@typescript/native-preview": "*", + "@volar/typescript": "~2.4.0", + "@vue/language-core": "~3.2.0 || ~3.3.0", + "rolldown": "^1.2.0", + "typescript": "^5.0.0 || ^6.0.0 || ~7.0.0", + "vue-tsc": "~3.2.0 || ~3.3.0" + }, + "peerDependenciesMeta": { + "@typescript/native-preview": { + "optional": true + }, + "@volar/typescript": { + "optional": true + }, + "@vue/language-core": { + "optional": true + }, + "typescript": { + "optional": true + }, + "vue-tsc": { + "optional": true + } } }, - "node_modules/thenify-all": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", - "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==", + "node_modules/tinyexec": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.3.1.tgz", + "integrity": "sha512-GCvB3aoys96IuDFBMcTB46JOR6mdMtAToqwiW8JlWhsoh1mhHi/xn9ss/Dg7N555GiJyEt2qzoG/NHCwM6h1EA==", "dev": true, "license": "MIT", - "dependencies": { - "thenify": ">= 3.1.0 < 4" - }, "engines": { - "node": ">=0.8" + "node": ">=18" } }, - "node_modules/tinyexec": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-0.3.2.tgz", - "integrity": "sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==", - "dev": true, - "license": "MIT" - }, "node_modules/tinyglobby": { "version": "0.2.17", "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.17.tgz", @@ -1488,72 +882,91 @@ "tree-kill": "cli.js" } }, - "node_modules/ts-interface-checker": { - "version": "0.1.13", - "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz", - "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==", - "dev": true, - "license": "Apache-2.0" - }, - "node_modules/tsup": { - "version": "8.5.1", - "resolved": "https://registry.npmjs.org/tsup/-/tsup-8.5.1.tgz", - "integrity": "sha512-xtgkqwdhpKWr3tKPmCkvYmS9xnQK3m3XgxZHwSUjvfTjp7YfXe5tT3GgWi0F2N+ZSMsOeWeZFh7ZZFg5iPhing==", + "node_modules/tsdown": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/tsdown/-/tsdown-0.23.1.tgz", + "integrity": "sha512-MSC2WSOts3in95J334/VIS7KPfor3eCSvndJ6KdoVj9Aak9Kh1aNfz9ws5owhdukuTNSXRdfkPEzA/ihpDD6SA==", "dev": true, "license": "MIT", "dependencies": { - "bundle-require": "^5.1.0", - "cac": "^6.7.14", - "chokidar": "^4.0.3", - "consola": "^3.4.0", - "debug": "^4.4.0", - "esbuild": "^0.27.0", - "fix-dts-default-cjs-exports": "^1.0.0", - "joycon": "^3.1.1", - "picocolors": "^1.1.1", - "postcss-load-config": "^6.0.1", - "resolve-from": "^5.0.0", - "rollup": "^4.34.8", - "source-map": "^0.7.6", - "sucrase": "^3.35.0", - "tinyexec": "^0.3.2", - "tinyglobby": "^0.2.11", - "tree-kill": "^1.2.2" + "cac": "^7.0.1", + "defu": "^6.1.7", + "empathic": "^2.1.0", + "hookable": "^6.1.2", + "import-without-cache": "^0.4.1", + "obug": "^3.0.0", + "picomatch": "^4.0.7", + "rolldown": "~1.2.13", + "rolldown-plugin-dts": "^0.28.7", + "tinyexec": "^1.3.1", + "tinyglobby": "^0.2.17", + "tree-kill": "^1.2.2", + "unconfig-core": "^7.5.0", + "verkit": "^0.5.0" }, "bin": { - "tsup": "dist/cli-default.js", - "tsup-node": "dist/cli-node.js" + "tsdown": "dist/run.mjs" }, "engines": { - "node": ">=18" + "node": "^22.18.0 || ^24.11.0 || >=26.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sxzz" }, "peerDependencies": { - "@microsoft/api-extractor": "^7.36.0", - "@swc/core": "^1", - "postcss": "^8.4.12", - "typescript": ">=4.5.0" + "@arethetypeswrong/core": "^0.18.1", + "@tsdown/css": "0.23.1", + "@tsdown/exe": "0.23.1", + "@vitejs/devtools": "*", + "publint": "^0.3.8", + "tsx": "*", + "typescript": "^5.0.0 || ^6.0.0 || ^7.0.0", + "unplugin-unused": ">=0.5.0", + "unrun": "*" }, "peerDependenciesMeta": { - "@microsoft/api-extractor": { + "@arethetypeswrong/core": { + "optional": true + }, + "@tsdown/css": { + "optional": true + }, + "@tsdown/exe": { + "optional": true + }, + "@vitejs/devtools": { "optional": true }, - "@swc/core": { + "publint": { "optional": true }, - "postcss": { + "tsx": { "optional": true }, "typescript": { "optional": true + }, + "unplugin-unused": { + "optional": true + }, + "unrun": { + "optional": true } } }, - "node_modules/ufo": { - "version": "1.6.4", - "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.6.4.tgz", - "integrity": "sha512-JFNbkD1Svwe0KvGi8GOeLcP4kAWQ609twvCdcHxq1oSL8svv39ZuSvajcD8B+5D0eL4+s1Is2D/O6KN3qcTeRA==", + "node_modules/unconfig-core": { + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/unconfig-core/-/unconfig-core-7.5.0.tgz", + "integrity": "sha512-Su3FauozOGP44ZmKdHy2oE6LPjk51M/TRRjHv2HNCWiDvfvCoxC2lno6jevMA91MYAdCdwP05QnWdWpSbncX/w==", "dev": true, - "license": "MIT" + "license": "MIT", + "dependencies": { + "@quansync/fs": "^1.0.0", + "quansync": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } }, "node_modules/undici-types": { "version": "7.24.6", @@ -1561,6 +974,86 @@ "integrity": "sha512-WRNW+sJgj5OBN4/0JpHFqtqzhpbnV0GuB+OozA9gCL7a993SmU+1JBZCzLNxYsbMfIeDL+lTsphD5jN5N+n0zg==", "dev": true, "license": "MIT" + }, + "node_modules/verkit": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/verkit/-/verkit-0.5.0.tgz", + "integrity": "sha512-u4J1hr6Y+C/hit34GwL3eIcUf3wngT8TlYUjK7tk0jxydKLAq3sYvifjdTDA6U3KCKRcQCQDGf/srjxfZF3l7g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18.12.0" + }, + "funding": { + "url": "https://github.com/sponsors/sxzz" + } + }, + "node_modules/yuku-ast": { + "version": "0.19.0", + "resolved": "https://registry.npmjs.org/yuku-ast/-/yuku-ast-0.19.0.tgz", + "integrity": "sha512-PyCsiScaelhxBGzL8dyeJkLqvRZycoh78R31Vrt/WqYrm0hMFoKwIw/X7Dx5mBKLWAMlV9I9HEyBOHnj2gZVyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@yuku-toolchain/types": "^0.19.0" + }, + "engines": { + "node": ">=14.18.0" + } + }, + "node_modules/yuku-codegen": { + "version": "0.19.0", + "resolved": "https://registry.npmjs.org/yuku-codegen/-/yuku-codegen-0.19.0.tgz", + "integrity": "sha512-uymAKHjDuaP4BEpkXC/BSLz4DUEF5oArZ5AuD3888nb2miChjWSgpPdojEJxm3pjpXkgUaCRJQyNAbnMN33wHg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@yuku-toolchain/types": "^0.19.0" + }, + "engines": { + "node": ">=14.18.0" + } + }, + "node_modules/yuku-core": { + "version": "0.19.0", + "resolved": "https://registry.npmjs.org/yuku-core/-/yuku-core-0.19.0.tgz", + "integrity": "sha512-kYK9e1XdfirNhkipzW0wmMcSWcVF/CWnuugodfVYRCUwvoBefweL9HzB96OiKEhsx78V5WbUxbJqlizMX869Qg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@yuku-toolchain/types": "^0.19.0" + }, + "engines": { + "node": ">=14.18.0" + }, + "optionalDependencies": { + "@yuku-core/binding-android-arm64": "0.19.0", + "@yuku-core/binding-darwin-arm64": "0.19.0", + "@yuku-core/binding-darwin-x64": "0.19.0", + "@yuku-core/binding-freebsd-x64": "0.19.0", + "@yuku-core/binding-linux-arm-gnu": "0.19.0", + "@yuku-core/binding-linux-arm-musl": "0.19.0", + "@yuku-core/binding-linux-arm64-gnu": "0.19.0", + "@yuku-core/binding-linux-arm64-musl": "0.19.0", + "@yuku-core/binding-linux-x64-gnu": "0.19.0", + "@yuku-core/binding-linux-x64-musl": "0.19.0", + "@yuku-core/binding-win32-arm64": "0.19.0", + "@yuku-core/binding-win32-x64": "0.19.0" + } + }, + "node_modules/yuku-parser": { + "version": "0.19.0", + "resolved": "https://registry.npmjs.org/yuku-parser/-/yuku-parser-0.19.0.tgz", + "integrity": "sha512-XrBh9ZiQK5mJVRxZBAvD6LwRyAYrK3MFtH3+onyuxFL5hFD44EC3QOmIC1FjTj6H2MMwq46/NAI+NZxLZPZgxg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@yuku-toolchain/types": "^0.19.0", + "yuku-core": "0.19.0" + }, + "engines": { + "node": ">=14.18.0" + } } } } diff --git a/clients/cli/package.json b/clients/cli/package.json index 5f48bd335f..65585b04b6 100644 --- a/clients/cli/package.json +++ b/clients/cli/package.json @@ -15,7 +15,7 @@ "build" ], "scripts": { - "build": "tsup", + "build": "tsdown", "typecheck": "tsc --noEmit -p tsconfig.json && tsc --noEmit -p tsconfig.test.json", "check": "npm run format:check && npm run lint && npm run typecheck", "validate": "npm run check && npm run test", @@ -32,16 +32,11 @@ "format": "prettier --write src __tests__ \"*.{ts,tsx,mts,cts,js,jsx,mjs,cjs}\"", "format:check": "prettier --check src __tests__ \"*.{ts,tsx,mts,cts,js,jsx,mjs,cjs}\"" }, - "allowScripts": { - "esbuild": false, - "fsevents": false - }, "devDependencies": { "@types/express": "^5.0.6", - "tsup": "^8.5.0" + "tsdown": "^0.23.1" }, "overrides": { - "@types/node": "^24.12.4", - "esbuild": "^0.28.2" + "@types/node": "^24.12.4" } } diff --git a/clients/cli/tsconfig.json b/clients/cli/tsconfig.json index 31e268fdba..0dee8f7014 100644 --- a/clients/cli/tsconfig.json +++ b/clients/cli/tsconfig.json @@ -20,6 +20,6 @@ "@inspector/core/*": ["../../core/*"] } }, - "include": ["src/**/*", "vitest.config.ts", "tsup.config.ts"], + "include": ["src/**/*", "vitest.config.ts", "tsdown.config.ts"], "exclude": ["node_modules", "**/*.test.*", "build"] } diff --git a/clients/cli/tsdown.config.ts b/clients/cli/tsdown.config.ts new file mode 100644 index 0000000000..94f9b31fbb --- /dev/null +++ b/clients/cli/tsdown.config.ts @@ -0,0 +1,105 @@ +import { defineConfig } from "tsdown"; +import path from "node:path"; +import { fileURLToPath } from "node:url"; + +const dirname = path.dirname(fileURLToPath(import.meta.url)); +const repoRoot = path.resolve(dirname, "../.."); + +// Every npm package this bundle must leave external, as bare package names. +// `scripts/verify-bundle-externals.mjs` reads this array as text, so keep it a +// literal of plain strings; `neverBundle` below expands each name to cover its +// subpaths. +const EXTERNALS = [ + // `undici` MUST stay external. It is CommonJS, so inlining it rewrites + // `import("undici")` to a relative chunk whose CJS `require("assert")` has no + // ESM equivalent and throws at first use — and because the specifier was + // rewritten at build time, no user-side install can ever satisfy it (#2067). + // It is declared in the ROOT manifest only, so tsdown cannot infer this from + // a nearest-manifest lookup; the entry has to be explicit. + "undici", + "@napi-rs/keyring", + // Root-declared (see the repo's dependency-placement rule) and CJS, which + // is the combination that bites: tsdown externalizes what the *client's* + // package.json declares, so a root-only dependency is bundled unless named + // here — and inlining a CJS module into an ESM bundle leaves a + // `require("path")` shim that throws at import time and takes the whole + // binary down before it parses a flag. + "proper-lockfile", + "@modelcontextprotocol/client", + "@modelcontextprotocol/core", + // Root-declared and reached through `core/mcp/apps.ts`, so it must be + // external here like every other root runtime dependency (AGENTS.md). This + // client was actually inlining it — dragging the transitive v1 SDK and + // zod-to-json-schema in with it — which the #2067 guard surfaced. ESM, so it + // was not failing the way `undici` did; the rule is what it violated. + "@modelcontextprotocol/ext-apps", + "@modelcontextprotocol/ext-tasks", + "commander", + "pino", + // Consolidated to the ROOT manifest by #2195, along with every other + // runtime dependency `core/` imports. tsdown externalizes only what the + // *nearest* package.json declares, so once a client stops declaring one it + // must be named here or Rolldown inlines it — the #2067 failure class, now + // reached by a manifest edit rather than an omission. + "ajv", + "atomically", + "open", + "zod", + // Newly on `core/`'s runtime import graph as of #2248: + // `core/mcp/skillFile.ts` parses a served SKILL.md's YAML frontmatter to + // check it against the entry the listing advertised (SEP-2640). Already a + // root `dependency` — it was reached from `test-servers/src` — so this + // adds no package, but a root-declared dependency `core/` imports must be + // named in all four `external` lists or the bundler inlines it here. + "yaml", + // Reached through `core/` but not through this client's own code today. + // AGENTS.md requires every root-declared package `core/` imports at runtime + // in ALL four lists regardless, because which client reaches one is a + // function of what `core/` imports rather than of what the client names — + // so the list must not depend on today's reachability (Copilot). + "chokidar", + "hono", + "react", +]; + +/** + * A plain string in `neverBundle` matches only that exact specifier, unlike + * tsup's `external`, which also covered subpaths. Without the regex, + * `zod/v4`, `@modelcontextprotocol/client/stdio` and `react/jsx-runtime` are + * inlined while the bare names stay external — and the build still succeeds. + */ +function withSubpaths(name: string): (string | RegExp)[] { + const escaped = name.replace(/[.*+?^${}()|[\]\\/]/g, "\\$&"); + return [name, new RegExp(`^${escaped}/`)]; +} + +export default defineConfig({ + entry: { + index: "src/index.ts", + }, + format: ["esm"], + outDir: "build", + clean: true, + // No source maps in the published bundle — they roughly double the on-disk + // size and aren't needed at runtime (debug via `npm run dev` on the source). + sourcemap: false, + dts: false, + target: "node22", + platform: "node", + // tsdown defaults to `.mjs` on `platform: "node"`; `bin`, `main`, the e2e + // test and `scripts/pack-and-verify.mjs` all name `build/index.js`. + fixedExtension: false, + alias: { + "@inspector/core": path.join(repoRoot, "core"), + }, + deps: { + // Bundle core source; leave npm deps external. + alwaysBundle: [/^@inspector\/core/], + neverBundle: EXTERNALS.flatMap(withSubpaths), + }, + outputOptions: { + // Rolldown keeps JSDoc blocks by default, which nearly doubles the bundle + // against tsup's output. Nothing reads them at runtime. + comments: { jsdoc: false }, + }, +}); diff --git a/clients/cli/tsup.config.ts b/clients/cli/tsup.config.ts deleted file mode 100644 index 2d2cf61fe5..0000000000 --- a/clients/cli/tsup.config.ts +++ /dev/null @@ -1,80 +0,0 @@ -import { defineConfig } from "tsup"; -import path from "node:path"; -import { fileURLToPath } from "node:url"; - -const dirname = path.dirname(fileURLToPath(import.meta.url)); -const repoRoot = path.resolve(dirname, "../.."); - -export default defineConfig({ - entry: { - index: "src/index.ts", - }, - format: ["esm"], - outDir: "build", - clean: true, - // No source maps in the published bundle — they roughly double the on-disk - // size and aren't needed at runtime (debug via `npm run dev` on the source). - sourcemap: false, - target: "node22", - platform: "node", - // Bundle core source; leave npm deps external. - noExternal: [/^@inspector\/core/], - external: [ - // `undici` MUST stay external. It is CommonJS, so inlining it rewrites - // `import("undici")` to a relative chunk whose `require("assert")` hits - // esbuild's ESM `__require` shim and throws "Dynamic require of \"assert\" - // is not supported" — and because the specifier was rewritten at build time, - // no user-side install can ever satisfy it (#2067). It is declared in the - // ROOT manifest only, so tsup cannot infer this from a nearest-manifest - // lookup; the entry has to be explicit. - "undici", - "@napi-rs/keyring", - // Root-declared (see the repo's dependency-placement rule) and CJS, which - // is the combination that bites: tsup externalizes what the *client's* - // package.json declares, so a root-only dependency is bundled unless named - // here — and inlining a CJS module into an ESM bundle leaves esbuild's - // `Dynamic require of "path" is not supported` shim, which throws at - // import time and takes the whole binary down before it parses a flag. - "proper-lockfile", - "@modelcontextprotocol/client", - "@modelcontextprotocol/core", - // Root-declared and reached through `core/mcp/apps.ts`, so it must be - // external here like every other root runtime dependency (AGENTS.md). This - // client was actually inlining it — dragging the transitive v1 SDK and - // zod-to-json-schema in with it — which the #2067 guard surfaced. ESM, so it - // was not failing the way `undici` did; the rule is what it violated. - "@modelcontextprotocol/ext-apps", - "@modelcontextprotocol/ext-tasks", - "commander", - "pino", - // Consolidated to the ROOT manifest by #2195, along with every other - // runtime dependency `core/` imports. tsup externalizes only what the - // *nearest* package.json declares, so once a client stops declaring one it - // must be named here or esbuild inlines it — the #2067 failure class, now - // reached by a manifest edit rather than an omission. - "ajv", - "atomically", - "open", - "zod", - // Newly on `core/`'s runtime import graph as of #2248: - // `core/mcp/skillFile.ts` parses a served SKILL.md's YAML frontmatter to - // check it against the entry the listing advertised (SEP-2640). Already a - // root `dependency` — it was reached from `test-servers/src` — so this - // adds no package, but a root-declared dependency `core/` imports must be - // named in all three `external` lists or tsup inlines it here. - "yaml", - // Reached through `core/` but not through this client's own code today. - // AGENTS.md requires every root-declared package `core/` imports at runtime - // in ALL three lists regardless, because which client reaches one is a - // function of what `core/` imports rather than of what the client names — - // so the list must not depend on today's reachability (Copilot). - "chokidar", - "hono", - "react", - ], - esbuildOptions(options) { - options.alias = { - "@inspector/core": path.join(repoRoot, "core"), - }; - }, -}); diff --git a/core/auth/node/file-lock.ts b/core/auth/node/file-lock.ts index 295bb401b9..3cdcae3d18 100644 --- a/core/auth/node/file-lock.ts +++ b/core/auth/node/file-lock.ts @@ -79,9 +79,9 @@ import nodeFs, { statSync, rmdirSync } from "node:fs"; import * as fs from "node:fs/promises"; import * as path from "node:path"; // CJS-only package. A default import is the shape that survives every -// bundler this repo runs core/ through (tsup for cli/tui, vite's SSR/node -// graph for the web runner); named imports off a CJS module depend on -// lexer detection that esbuild and rollup disagree about. +// bundler this repo runs core/ through (tsdown for cli, tsup for tui/mcpdo, +// vite's SSR/node graph for the web runner); named imports off a CJS module +// depend on lexer detection that esbuild and rollup disagree about. import properLockfile from "proper-lockfile"; import { SecretFileLockHeldError } from "./secret-store.js"; diff --git a/docs/architecture.md b/docs/architecture.md index 0eb1c100e6..c3bc409974 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -8,7 +8,8 @@ `core/` intentionally has **no `package.json`** — it is not published on its own. Each client bundles it in via a `@inspector/core` alias: -- **CLI / TUI:** `esbuildOptions.alias` in their `tsup.config.ts` maps `@inspector/core` → the repo `core/` directory, and `noExternal: [/^@inspector\/core/]` inlines it into the bundle. +- **TUI / mcpdo:** `esbuildOptions.alias` in their `tsup.config.ts` maps `@inspector/core` → the repo `core/` directory, and `noExternal: [/^@inspector\/core/]` inlines it into the bundle. +- **CLI:** `clients/cli/tsdown.config.ts` does the same with tsdown's `alias` and `deps.alwaysBundle` ([tsdown migration](./tsdown-migration.md), #1492). - **Web:** two configs, because the client is two builds — `clients/web/vite.config.ts` for the browser app, and `clients/web/tsup.runner.config.ts` for the Node backend runner, which defines the alias itself. Publishing `core/` as its own package (e.g. for third parties to build on) is deliberately deferred — see issue [#1636](https://github.com/modelcontextprotocol/inspector/issues/1636). diff --git a/docs/publishing.md b/docs/publishing.md index 3adbd21304..0c52dde12d 100644 --- a/docs/publishing.md +++ b/docs/publishing.md @@ -7,7 +7,7 @@ The root `@modelcontextprotocol/inspector` package ships as **one tarball with a The root `package.json` `"files"` allowlist is the source of truth for the tarball. A few non-obvious entries exist because they are read **at runtime** or were silently dropped by npm's packlist — do not remove them without re-running `npm run pack:verify`: -- **No source maps.** The client bundlers set `sourcemap: false` (`clients/{cli,tui}/tsup.config.ts`, `clients/web/tsup.runner.config.ts`); Vite and the launcher's `tsc` already emit none. Maps are ~half the unpacked size and aren't needed at runtime — debug via `npm run dev` on the source. +- **No source maps.** The client bundlers set `sourcemap: false` (`clients/cli/tsdown.config.ts`, `clients/tui/tsup.config.ts`, `clients/web/tsup.runner.config.ts`); Vite and the launcher's `tsc` already emit none. Maps are ~half the unpacked size and aren't needed at runtime — debug via `npm run dev` on the source. - **`clients/web/build` ships via `clients/web/.npmignore`.** `clients/web/.gitignore` lists `build/`, and npm's packlist honors that nested `.gitignore` over the root `"files"` allowlist — so the prod web-server runner was silently missing from the tarball while `clients/web/dist` slipped through (its `.gitignore` only lists `dist-ssr`). `clients/web/.npmignore` overrides the `.gitignore` for publishing so both `build/` (runner) and `dist/` (SPA) ship. The other clients don't need this — none ship a nested `.gitignore`. - **`clients/web/static` ships the MCP Apps sandbox proxy.** `clients/web/static/sandbox_proxy.html` is a committed source file (not a build artifact), read from disk at runtime by `clients/web/server/sandbox-controller.ts` as `/../static/sandbox_proxy.html`. It was missing from the root `"files"` allowlist entirely, so every published build failed the Apps tab with **"Sandbox not loaded"** ([#1859](https://github.com/modelcontextprotocol/inspector/issues/1859)) while working fine in the repo. Because the path is resolved _relative to_ `clients/web/build`, the directory must ship at that exact location — `pack:verify` asserts the tarball entry, the installed-on-disk path, and (since [#2003](https://github.com/modelcontextprotocol/inspector/issues/2003)) that a widget actually *loads through* it on the installed bin. Presence and reachability are different properties: a rename with a stale reader ships a file that is there and unusable. - **A dependency that renders React is bundled, not externalized.** An externalized package resolves its own `react` from wherever npm placed **it** in the consumer's tree, which is not necessarily where the bundle resolves ours — npm places a package beside a React satisfying _its_ peer range, and those ranges are looser than ours. `ink-form` and `ink-scroll-view` declare `">=18"`, so a project holding React 18 satisfies them and gets them hoisted while the Inspector's React 19 nests underneath: two React copies, and the TUI dies with `TypeError: Cannot read properties of null (reading 'useState')` the moment a tool test form or a scroll view mounts ([#1952](https://github.com/modelcontextprotocol/inspector/issues/1952)). Both are therefore inlined by `clients/tui/tsup.config.ts` and are **not** root dependencies: the tarball ships their code inside `clients/tui/build/index.js` rather than having consumers install them. Bundling also pins their transitive deps to what this repo's install resolved (notably `ink-select-input@6` via `overrides`, which npm ignores for a package installed as a dependency). **`ink` is the one exception, on cost:** bundling it works but adds ~1.4 MB (`react-reconciler` and `yoga-layout` come along, plus a `createRequire` banner for the inlined CJS), so it stays external — _not_ because its `">=19"` peer makes it safe, which it does not. What keeps that tolerable is the root `react` range: `"^19.0.0"` is deliberately open to the whole major so npm can dedupe our React with whatever React 19 a consumer pins, leaving an external `ink` on the same copy the bundle uses. **Narrowing that range reopens the bug for the renderer itself** — `clients/tui/__tests__/tsupConfig.test.ts` pins it to `ink`'s peer floor, and guards the rest of the split; see the [TUI README](../clients/tui/README.md#bundling-react-rendering-dependencies-must-be-inlined-1952). diff --git a/docs/quality-gate.md b/docs/quality-gate.md index fa0e07737a..ccdb1be036 100644 --- a/docs/quality-gate.md +++ b/docs/quality-gate.md @@ -40,7 +40,7 @@ That is the readable half, and prose rots. The enforced half is `scripts/lib/wor | `npm run coverage` | The **per-file ≥90% gate** (lines/statements/functions/branches) under v8 instrumentation, per client. CI-enforced. For web this also runs the integration project and covers the shared `core/` runtime (including `core/json` and `core/client`). **`maxWorkers` is deliberately unset**, here and in every Vitest project ([#2336](https://github.com/modelcontextprotocol/inspector/issues/2336), PR [#2345](https://github.com/modelcontextprotocol/inspector/pull/2345)): the forks-pool projects inherit Vitest's `max(availableParallelism() - 1, 1)` — 7 on the eight-logical-core machine this team works on — and keeping it is a choice with a measurement, recorded beside `TIMEOUTS` in `vitest.shared.mts`: at the leased baseline, arms interleaved over three rounds, `maxWorkers: 4` cost +14% wall on web `unit` and +39% on `coverage:web` for zero fewer failures (0 across all 18 runs). See [Multi-agent testing](#multi-agent-testing-the-gate-lease) for why a cap was the wrong lever for the contention it was proposed against. Ends with `verify:coverage-scope` (below), which checks that each report measured the file set its client declares. | | `npm run smoke` | End-to-end smokes through the built launcher (`--help` dispatch + prod cli/tui/web — the TUI one runs under a **pseudoterminal** and asserts the Ink app is still running two seconds after its first frame, not merely that it painted one, [#2147](https://github.com/modelcontextprotocol/inspector/issues/2147)), plus three headless-browser smokes: a boot smoke that runs the prod web bundle and asserts a clean first render (no uncaught error — sync exception or unhandled rejection, how a Node built-in reaching the browser bundle manifests), and an **MCP Apps** smoke (`smoke:web:app`) that drives connect → open app → `data-app-status="ready"` against a composable App server, covering the sandbox proxy and UI-protocol bridge, and an **app-rendered elicitation** smoke (`smoke:web:elicit`) that drives one end to end — call the tool, answer inside the sandboxed app, see the app's `ElicitResult` reach the server — and then the same tool against a server that never advertised the capability, which must fall back to the native elicitation form. Those three take their engine from `SMOKE_BROWSER` — see [Supported browsers](#supported-browsers). A fourth, **`smoke:web:tabs`**, drives the core tabs against one server on one browser launch — Tools runs a tool and asserts its `structuredContent` section, Resources reads a resource with templates listed, Prompts fetches one ([#2148](https://github.com/modelcontextprotocol/inspector/issues/2148)) — asserting the `data-*` contract in [the web README](../clients/web/README.md#core-tab-automation-contract) rather than visible copy. It is **Chromium-only**: those tabs are ordinary React and Mantine, so unlike the sandbox they are not engine-sensitive. The Playwright budgets the browser smokes wait under are **named once**, in `scripts/lib/browser-timeouts.mjs` (`BROWSER_TIMEOUTS`: `ui` 30s, `roundTrip` 45s, `nested` 15s, `bestEffort` 5s — [#2323](https://github.com/modelcontextprotocol/inspector/issues/2323)); since [#2333](https://github.com/modelcontextprotocol/inspector/issues/2333) (PR [#2349](https://github.com/modelcontextprotocol/inspector/pull/2349)) the shared flow helpers `deep-link-connect.mjs` and `mcp-app-flow.mjs` default to those constants instead of carrying literals of their own, and the two helper budgets that stay put are **stated at the site with the measurement behind them**: `announced-child.mjs`'s `DEFAULTS` (a 30s readiness ceiling on a 250ms poll — boot-to-announce measured 135ms median through it at load average 15, so a passing start pays one poll interval, not the budget) and `pty.mjs`'s `SCRIPT_PROBE_TIMEOUT_MS` (5s for the `script --version` probe, measured at 1.3ms median). That probe's expiry is now a **failure, not a skip**: a timed-out `spawnSync` reports in the same `error` slot as `ENOENT`, and reading both as "no `script(1)` on PATH" had turned `smoke:tui` into an exit-0 skip on exactly the loaded machine the gate is meant to be believable on. | | `npm run verify:build-gate` | Runs a real `vite build` with a Node built-in forced into the browser graph and asserts the build **fails** via the #1769 gate (which turns Vite's browser-externalization warning into a hard error). Guards against the warning phrasing drifting in a Vite bump and silently disabling the gate. Part of `npm run local:gate` and of GitHub CI. | -| `npm run verify:bundle-externals` | Guards the must-not-bundle invariant (#2067): for each tsup-bundled client it reads the **built** `build/` output and fails if any package that must stay external was inlined anyway. Candidates are the union of the client's own `external` array **and the root manifest's `dependencies`** — the latter because #2067 was a *missing* `external` entry, which a self-referential check would have passed. Detection is via esbuild's `// ` module banners, so it covers both shapes — a separate `-HASH.js` chunk (what a dynamically `import()`ed CommonJS package produces) and a statically-imported package folded straight into `index.js`, which emits no chunk at all. A build with no banners fails as such rather than passing clean, so enabling `minify` cannot silently retire the check. `undici` was declared only in the root and `clients/cli` manifests, and tsup auto-externalizes only what the _nearest_ manifest declares, so the web and TUI bundles inlined 1.05MB of it — and CommonJS inlined into an ESM bundle throws `Dynamic require of "assert" is not supported` on first use, from a specifier no user-side install can satisfy. Reads the output rather than the config because those two disagreed for four releases. Part of `npm run local:gate` and of GitHub CI. | +| `npm run verify:bundle-externals` | Guards the must-not-bundle invariant (#2067): for each bundled client (tsup, or tsdown for the CLI) it reads the **built** `build/` output and fails if any package that must stay external was inlined anyway. Candidates are the union of the client's own `external` array **and the root manifest's `dependencies`** — the latter because #2067 was a *missing* `external` entry, which a self-referential check would have passed. Detection is via esbuild's `// ` module banners, so it covers both shapes — a separate `-HASH.js` chunk (what a dynamically `import()`ed CommonJS package produces) and a statically-imported package folded straight into `index.js`, which emits no chunk at all. A build with no banners fails as such rather than passing clean, so enabling `minify` cannot silently retire the check. `undici` was declared only in the root and `clients/cli` manifests, and tsup auto-externalizes only what the _nearest_ manifest declares, so the web and TUI bundles inlined 1.05MB of it — and CommonJS inlined into an ESM bundle throws `Dynamic require of "assert" is not supported` on first use, from a specifier no user-side install can satisfy. Reads the output rather than the config because those two disagreed for four releases. Part of `npm run local:gate` and of GitHub CI. | | `npm run verify:install-fresh` | Guards against a **stale install** ([#2494](https://github.com/modelcontextprotocol/inspector/issues/2494)). Every other dependency guard reads lockfiles, so none can see `node_modules` lagging the lockfile beside it — the ordinary state of a long-lived checkout after a `git pull` brings in a bump. When the MCP SDK moved 2.0.0 → 2.1.0, such a checkout passed every guard, lint and typecheck and failed only in `transportAuthorizationPrecedence.test.ts`, reporting the old SDK's behavior as a product defect. For the root and every `clients/*` install, compares each `package-lock.json` package entry against the installed copy's own `package.json` version (ground truth, not npm's hidden lockfile), exempting absent `optional`/`devOptional` entries (platform binaries), and fails naming each stale or missing package and `npm install`. Runs first in `validate:guards`; CI installs fresh, so it never fires there. | | `npm run verify:install-scripts` | Guards against an **unreviewed dependency install script** ([#2712](https://github.com/modelcontextprotocol/inspector/issues/2712)). npm 11.x still runs a script that `allowScripts` neither allows nor denies, so a new dependency's `postinstall` would otherwise run on every install unnoticed. For the root and every `clients/*` install, reads each `package-lock.json` entry flagged `hasInstallScript` and fails unless that install's **own** `package.json` `allowScripts` decides it (`true` or `false`), matched as npm 11.19 matches it: identity from the lockfile's `resolved` registry URL rather than the folder name, and only a bare name or exact versions joined by `||` as keys — npm ignores `^`/`~` ranges. It also reports a **non-registry** dependency (git, file, remote tarball) even when the lockfile does not flag a script, because npm runs `prepare` for those and the lockfile records only preinstall/install/postinstall; such an entry is cleared by a key equal to its exact `resolved` spec. A bundled dependency with a script is always reported, since no key can decide it. Reads the lockfile rather than `npm install-scripts ls` because Node 22's bundled npm 10.x has no such subcommand. It enforces the **decision**; the **blocking** is npm's, from 11.19 — which is why every CI job that installs dependencies first installs the exact npm pinned as `CI_NPM_VERSION` in `main.yml` ([#2715](https://github.com/modelcontextprotocol/inspector/issues/2715)). `esbuild` and `fsevents` are denied: neither script is needed (platform binaries arrive via `optionalDependencies` / prebuilt). | | `npm run verify:format-coverage` | Parses the `format:check` globs out of every `package.json` (only those reachable from `validate`), enumerates all tracked source files, and **fails** listing any not covered by a glob — the durable guard for the "every first-party source file is format-gated" invariant (#1792). Runs first in `validate`. | diff --git a/docs/tsdown-migration.md b/docs/tsdown-migration.md new file mode 100644 index 0000000000..79111bca50 --- /dev/null +++ b/docs/tsdown-migration.md @@ -0,0 +1,108 @@ +# Migrating from tsup to tsdown + +Findings and recommendation for [#1492](https://github.com/modelcontextprotocol/inspector/issues/1492). + +## Recommendation + +**Migrate, one client at a time.** The CLI moved first (this change) as the +prototype. It builds, passes its full suite including the e2e tests that spawn +the built binary, keeps exactly the same set of bare imports as the tsup +bundle, and passes `verify:bundle-externals`. Nothing blocks the other three. +What's left is a set of gotchas, all listed below, and each one now has a guard +or a test. + +Why move at all: [tsup](https://github.com/egoist/tsup) is effectively +unmaintained, and its README points users to +[tsdown](https://tsdown.dev/). It also pins an esbuild range with no upward +escape from a past advisory, which is why every client that builds with tsup +carries an `esbuild` `overrides` entry. Moving the CLI deleted that override and its +`allowScripts` entries along with tsup: neither `esbuild` nor `fsevents` (from +tsup's rollup) is in the CLI's install any more. + +## Inventory + +| Build | Config | Entries | Relies on | +| ---------- | ----------------------------------- | ------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| CLI | `clients/cli/tsdown.config.ts` | `index` | **Migrated.** | +| Web runner | `clients/web/tsup.runner.config.ts` | `src/index.ts` | `@inspector/core` alias, `noExternal`, `external` | +| mcpdo | `clients/mcpdo/tsup.config.ts` | `mcp-bin`, `mcpdod` | The same, plus two entries (and therefore shared chunks); `src/daemon/ensure.ts` locates `mcpdod.js` relative to the running chunk | +| TUI | `clients/tui/tsup.config.ts` | `index.ts` | The same, plus `jsx: "automatic"`, and `ink-form` / `ink-scroll-view` in `noExternal`. `__tests__/tsupConfig.test.ts` imports the config and tsup's `Options` type | + +`test-servers` is built with plain `tsc`, not tsup, and `clients/launcher` is +also `tsc`. Neither is in scope. + +## Option mapping + +| tsup | tsdown | +| ------------------------------------- | ------------------------------------------------------------ | +| `esbuildOptions(o) { o.alias = … }` | top-level `alias` | +| `noExternal` | `deps.alwaysBundle` | +| `external` | `deps.neverBundle` (see gotcha 1) | +| `esbuildOptions(o) { o.jsx = … }` | `inputOptions.transform.jsx` (for the TUI, not yet tried here) | +| `format`, `target`, `platform`, `outDir`, `clean`, `sourcemap` | unchanged | +| shebang preserved, exec bit set | unchanged; tsdown sets the exec bit itself | + +`external` and `noExternal` still work in tsdown, but they're deprecated +aliases, so the CLI config uses the `deps.*` names. + +## Gotchas + +None of these fails the build, so each one needs a guard or a test to catch it. + +1. **`neverBundle` strings match the exact specifier only.** tsup's `external: + ["zod"]` also covered `zod/v4`; tsdown's doesn't. Listing bare names silently + inlined subpath imports of six packages (`@modelcontextprotocol/client`, + `core`, `ext-apps` and `ext-tasks`, plus `zod` and `hono`), and the bundle + grew to 1.36 MB. tsdown prints + a "Detected dependencies in bundle" hint and the build still succeeds. The + config keeps a `const EXTERNALS = [...]` of bare names and expands each one + to the name plus a `^name/` pattern. `verify:bundle-externals` caught all six + inlined packages when the expansion was removed. +2. **Output defaults to `.mjs` on `platform: "node"`.** `fixedExtension: false` + keeps `build/index.js`, which `bin`, `main`, the e2e test and + `scripts/pack-and-verify.mjs` all name. +3. **Rolldown keeps JSDoc comments.** That produced a 1.22 MB CLI bundle. + `outputOptions.comments: { jsdoc: false }` brings it to 681 KB, against + tsup's 844 KB. +4. **Module banners vary by Rolldown release.** Rolldown 1.2.15 (the version + tsdown 0.23.1 resolves here) writes the same `// ` banner as esbuild. + An earlier prototype on Rolldown 1.2.13 saw `//#region `. + `verify:bundle-externals` reads banners to find inlined packages, so it now + accepts both forms. A bundle with neither still fails loudly as banner-less. +5. **The guard parsed only `external: [`.** It now also reads the + `const EXTERNALS = [` array, and its enrolment test discovers + `tsdown*.config.ts` as well as `tsup*.config.ts`. + +## Measurements (CLI) + +| | tsup 8.5.1 | tsdown 0.23.1 (Rolldown 1.2.15) | +| ----------------- | ---------- | ------------------------------- | +| `build/index.js` | 844 KB | 681 KB | +| Build time | ~110 ms | ~45 ms | +| Bare imports | 31 | 31, the identical set | + +## Path for the remaining clients + +Tracked in [#2797](https://github.com/modelcontextprotocol/inspector/issues/2797). Suggested order: **web runner**, then **mcpdo**, then the **TUI**. + +- **Web runner.** A single entry with no JSX: the CLI change applied to a + different file. `clients/web` also builds with Vite, so check that + `vite.config.ts` doesn't share anything with the runner config. +- **mcpdo.** Two entries produce shared chunks, so check how + `src/daemon/ensure.ts` resolves `mcpdod.js` relative to the running chunk + against Rolldown's chunk naming (`hash` defaults to `true`). The + `stop-dev-daemon` step in `build:dev` is unaffected. +- **TUI.** JSX moves to `inputOptions.transform.jsx`, and `ink-form` / + `ink-scroll-view` move to `deps.alwaysBundle`. `tsupConfig.test.ts` imports + the config and tsup's `Options` type, so it needs rewriting against tsdown's + `UserConfig`. Its React-externals policy assertions must keep holding, since + `react` must stay external while every React-rendering dependency is bundled + (AGENTS.md). + +Each step drops that client's `tsup` devDependency and, once `npm ls esbuild` +shows nothing left in that install, its `esbuild` override and `allowScripts` +entries. Web keeps esbuild through Vite, so its entries probably stay. Each step +also updates `BUNDLED_CLIENTS` in +`scripts/verify-bundle-externals.mjs`, the bundler `external` list paths in +AGENTS.md and `scripts/sdk-watch.mjs`, and the config name in that client's +`tsconfig.json` `include`. diff --git a/scripts/sdk-watch.mjs b/scripts/sdk-watch.mjs index ae7d68515c..99d3439f82 100644 --- a/scripts/sdk-watch.mjs +++ b/scripts/sdk-watch.mjs @@ -534,7 +534,7 @@ export function buildIssueBody(state) { "### Upgrade checklist", "", ...manifestChecklist(rows, target), - "- [ ] Re-check the bundler `external` lists (`clients/{cli,mcpdo,tui}/tsup.config.ts`, `clients/web/tsup.runner.config.ts`) if the release adds or renames an entry point; `npm run verify:bundle-externals` enforces this against the built output.", + "- [ ] Re-check the bundler `external` lists (`clients/cli/tsdown.config.ts`, `clients/{mcpdo,tui}/tsup.config.ts`, `clients/web/tsup.runner.config.ts`) if the release adds or renames an entry point; `npm run verify:bundle-externals` enforces this against the built output.", "- [ ] `npm run format`, then `npm run local:gate`.", "", "An automated review of what actually changed upstream — and which parts of this app it touches — is posted as a comment below.", diff --git a/scripts/verify-bundle-externals.mjs b/scripts/verify-bundle-externals.mjs index b9f2123e3e..7edd976cc4 100644 --- a/scripts/verify-bundle-externals.mjs +++ b/scripts/verify-bundle-externals.mjs @@ -33,11 +33,12 @@ import { fileURLToPath } from "node:url"; const repoRoot = resolve(dirname(fileURLToPath(import.meta.url)), ".."); /** - * Clients that ship a tsup bundle, with the config to read `external` from and - * the build directory to inspect. `entry` names the file whose presence - * proves a build actually ran; it defaults to `index.js` (what web/cli/tui - * each name their single tsup entry) and is overridden only when a client's - * tsup config uses a different entry name, like mcpdo's multi-entry `mcp-bin`. + * Clients that ship a bundle, with the config to read `external` from and + * the build directory to inspect. Most are tsup builds; `cli` is tsdown (#1492), + * which emits the same `// ` module banners. `entry` names the file whose + * presence proves a build actually ran; it defaults to `index.js` (what + * web/cli/tui each name their single entry) and is overridden only when a + * client's config uses a different entry name, like mcpdo's multi-entry `mcp-bin`. * `clients/launcher` is plain `tsc` — it emits no bundle and inlines nothing — * so it has nothing to check. */ @@ -49,7 +50,7 @@ export const BUNDLED_CLIENTS = [ }, { name: "cli", - config: "clients/cli/tsup.config.ts", + config: "clients/cli/tsdown.config.ts", build: "clients/cli/build", }, { @@ -66,17 +67,21 @@ export const BUNDLED_CLIENTS = [ ]; /** - * Extracts the string literals of a tsup config's `external: [...]` array. + * Extracts the string literals of a bundler config's externals array — tsup's + * inline `external: [...]`, or the `const EXTERNALS = [...]` a tsdown config + * expands into `deps.neverBundle` (a bare string there matches no subpath, so + * the config maps each name to a pattern rather than listing them inline). * * Reading the config as *text* rather than importing it keeps this guard free of - * the client's own toolchain (tsup, esbuild, and — for the TUI — a plugin that - * reads `ink-form` off disk at module load). Only bare string entries are - * collected; a regex entry such as `/^@inspector\/core/` is a `noExternal` - * pattern in practice and has no package name to look for. + * the client's own toolchain (tsup or tsdown, the bundler under it, and — for + * the TUI — a plugin that reads `ink-form` off disk at module load). Only bare + * string entries are collected; a regex entry such as `/^@inspector\/core/` is + * a `noExternal` pattern in practice and has no package name to look for. */ export function parseExternals(source) { - const start = source.indexOf("external: ["); - if (start === -1) return []; + const anchor = /\bexternal: \[|\bconst EXTERNALS = \[/.exec(source); + if (!anchor) return []; + const start = anchor.index; let depth = 0; let end = -1; for (let i = source.indexOf("[", start); i < source.length; i++) { @@ -96,14 +101,15 @@ export function parseExternals(source) { const withoutComments = body .replace(/\/\*[\s\S]*?\*\//g, "") .replace(/\/\/[^\n]*/g, ""); - return [...withoutComments.matchAll(/"([^"]+)"|'([^']+)'/g)] - .map((m) => m[1] ?? m[2]) - .filter((name) => name !== "external: ["); + return [...withoutComments.matchAll(/"([^"]+)"|'([^']+)'/g)].map( + (m) => m[1] ?? m[2], + ); } /** * Every module esbuild inlines is emitted under a `// ` banner naming its - * source file, so a package that was bundled despite being declared external + * source file — Rolldown (tsdown) writes the same shape, and some Rolldown + * releases write `//#region ` instead, so both are read — so a package that was bundled despite being declared external * leaves `// ../../node_modules//…` lines behind. Matching on those covers * **both** shapes this can take: a separate `-HASH.js` chunk (what a * dynamically `import()`ed CommonJS package produces, which is what #2067 was) @@ -118,7 +124,7 @@ export function parseExternals(source) { */ export function findInlinedExternals({ externals, files }) { const banners = files.flatMap((file) => - [...file.source.matchAll(/^\/\/ (\S+)$/gm)].map((m) => ({ + [...file.source.matchAll(/^\/\/(?: |#region )(\S+)$/gm)].map((m) => ({ file: file.name, path: m[1], })), @@ -149,7 +155,7 @@ export function findInlinedExternals({ externals, files }) { * The candidate set is the **union of two independently-derived lists**, and the * second is what makes this guard cover #2067 rather than merely its regression: * - * - `externals` — what the client's tsup config declares. Catches a package that + * - `externals` — what the client's bundler config declares. Catches a package that * was meant to stay out and got pulled in anyway. * - `rootDependencies` — the root manifest's runtime dependencies. These are * root-declared *by rule* (see AGENTS.md), reached through `core/`, and must be @@ -160,7 +166,7 @@ export function findInlinedExternals({ externals, files }) { * from an `external` list must not be able to remove it from scrutiny. * * It also **fails closed on an empty `external` list**. `parseExternals` keys off - * the literal text `external: [`, so an ordinary tsup refactor — hoisting the + * the literal text `external: [` (or `const EXTERNALS = [`), so an ordinary refactor — hoisting the * array to a constant, or a line break after the colon — would make it return * nothing. Every enrolled bundle has externals today, so "none parsed" means the * parser lost track of the config, not that the invariant holds. @@ -174,9 +180,10 @@ export function evaluateClient({ }) { if (externals.length === 0) { return [ - `${name}: no \`external\` entries could be parsed from its tsup config. ` + + `${name}: no \`external\` entries could be parsed from its bundler config. ` + `Every bundled client has some, so this means the config no longer matches ` + - `what parseExternals() reads (it keys off the literal text "external: ["). ` + + `what parseExternals() reads (it keys off the literal text "external: [" ` + + `or "const EXTERNALS = ["). ` + `Update the parser rather than leaving the guard checking nothing.`, ]; } @@ -188,7 +195,7 @@ export function evaluateClient({ }); if (noBanners) { return [ - `${name}: ${build} has no esbuild module banners, so this guard cannot see ` + + `${name}: ${build} has no module banners, so this guard cannot see ` + `what was inlined. Has minification been enabled for this bundle?`, ]; } @@ -203,7 +210,7 @@ export function evaluateClient({ ? `${name}: "${v.pkg}" is declared external but was inlined (${v.reason}).` : `${name}: "${v.pkg}" is a root runtime dependency, so it must stay ` + `external, but it was inlined (${v.reason}). Add it to this client's ` + - `tsup \`external\` list.`, + `bundler \`external\` list.`, ); } @@ -252,10 +259,10 @@ function main() { if (failures.some((f) => f.includes("was inlined"))) { console.error( "\nAn externalized package must resolve from the consumer's install. If it was\n" + - "inlined, esbuild rewrote its specifier to a relative chunk that no user-side\n" + + "inlined, the bundler rewrote its specifier to a relative chunk that no user-side\n" + "install can satisfy — and a CommonJS package inlined into an ESM bundle throws\n" + '`Dynamic require of "..." is not supported` on first use (#2067).\n' + - "Add the package to that client's tsup `external` list.", + "Add the package to that client's bundler `external` list.", ); } process.exit(1); diff --git a/scripts/verify-bundle-externals.test.mjs b/scripts/verify-bundle-externals.test.mjs index 36a81590df..af9cb3135c 100644 --- a/scripts/verify-bundle-externals.test.mjs +++ b/scripts/verify-bundle-externals.test.mjs @@ -54,6 +54,19 @@ describe("parseExternals", () => { ); }); + test("reads a tsdown config's hoisted EXTERNALS array", () => { + // tsdown's `neverBundle` matches a bare string on the exact specifier only, + // so the cli config keeps the names in a constant and maps each to a + // subpath pattern. The names are what the guard needs; the mapping is not. + const src = `const EXTERNALS = [ + // "ghost" is prose. + "undici", + "zod", + ]; + export default { deps: { neverBundle: EXTERNALS.flatMap(withSubpaths) } }`; + assert.deepEqual(parseExternals(src), ["undici", "zod"]); + }); + test("returns an empty list when there is no external array", () => { assert.deepEqual(parseExternals(`export default { entry: ["x.ts"] }`), []); }); @@ -134,6 +147,26 @@ describe("findInlinedExternals", () => { assert.deepEqual(violations, []); }); + test("reads Rolldown's #region banners as well as the plain form", () => { + // Rolldown 1.2.15 writes `// ` like esbuild, but other Rolldown + // releases write `//#region `. Missing that form would read every + // such bundle as banner-less rather than checking it. + const { noBanners, violations } = findInlinedExternals({ + externals: ["zod"], + files: [ + { + name: "index.js", + source: + "//#region ../../core/mcp/index.ts\nvar a = 1;\n//#endregion\n" + + "//#region ../../node_modules/zod/v4/index.js\nvar b = 2;\n//#endregion\n", + }, + ], + }); + assert.equal(noBanners, false); + assert.equal(violations.length, 1); + assert.equal(violations[0].pkg, "zod"); + }); + test("matches a scoped package on its full name", () => { const { violations } = findInlinedExternals({ externals: ["@napi-rs/keyring"], @@ -168,7 +201,7 @@ describe("evaluateClient", () => { ]; test("fails closed when no externals could be parsed", () => { - // A tsup refactor — `external: EXTERNALS`, or a line break after the colon — + // A config refactor — `external: EXTERNALS`, or a line break after the colon — // makes parseExternals return nothing. Checking zero packages and reporting // success would silently disable the guard on a change that looks harmless. const failures = evaluateClient({ @@ -189,7 +222,7 @@ describe("evaluateClient", () => { files: [{ name: "index.js", source: "var a=1;" }], }); assert.equal(failures.length, 1); - assert.match(failures[0], /no esbuild module banners/); + assert.match(failures[0], /no module banners/); }); test("reports one failure per inlined package", () => { @@ -298,24 +331,24 @@ describe("evaluateClient", () => { describe("BUNDLED_CLIENTS", () => { test("is enrolled from what is actually on disk, not from itself", () => { // Asserting the hard-coded list equals a hard-coded copy of itself proves - // nothing — adding `clients/foo` with a tsup build would leave it green - // while the new bundle went unchecked. So the expected set is DISCOVERED: - // a client is tsup-bundled iff it ships a tsup config. `clients/launcher` - // is plain tsc, emits no bundle, and is correctly absent. + // nothing — adding `clients/foo` with a tsup or tsdown build would leave it + // green while the new bundle went unchecked. So the expected set is + // DISCOVERED: a client is bundled iff it ships a tsup or tsdown config. + // `clients/launcher` is plain tsc, emits no bundle, and is correctly absent. const clientsDir = path.join(repoRoot, "clients"); const discovered = readdirSync(clientsDir) .filter((name) => readdirSync(path.join(clientsDir, name)).some((f) => - /^tsup(\..+)?\.config\.ts$/.test(f), + /^ts(up|down)(\..+)?\.config\.ts$/.test(f), ), ) .sort(); - assert.ok(discovered.length > 0, "no tsup-bundled clients discovered"); + assert.ok(discovered.length > 0, "no bundled clients discovered"); assert.deepEqual( BUNDLED_CLIENTS.map((c) => c.name).sort(), discovered, - "BUNDLED_CLIENTS is out of sync with the clients that ship a tsup config", + "BUNDLED_CLIENTS is out of sync with the clients that ship a tsup or tsdown config", ); }); diff --git a/specification/v2_cli_tui_launcher.md b/specification/v2_cli_tui_launcher.md index 804bd52937..1898b6175c 100644 --- a/specification/v2_cli_tui_launcher.md +++ b/specification/v2_cli_tui_launcher.md @@ -34,7 +34,7 @@ This document describes how those clients are built, wired, and tested today, an | Artifact | Path | Build | Published bin | | ---------- | ------------------------------- | ------------------------------------------------------ | -------------------------------------------------------- | | Launcher | `clients/launcher/` | `tsc` → `build/index.js` | Root `mcp-inspector` → `clients/launcher/build/index.js` | -| CLI | `clients/cli/` | `tsup` → `build/index.js` | `mcp-inspector-cli` (client package only; one-shot) | +| CLI | `clients/cli/` | `tsdown` → `build/index.js` | `mcp-inspector-cli` (client package only; one-shot) | | mcpdo | `clients/mcpdo/` | `tsup` → `build/mcp-bin.js` + `build/mcpdod.js` | `mcpdo` (experimental; ships in the inspector package) | | TUI | `clients/tui/` | `tsup` → `build/index.js` | `mcp-inspector-tui` (client package only) | | Web runner | `clients/web/server/run-web.ts` | `tsup` (`build:runner`) → `clients/web/build/index.js` | `mcp-inspector-web` (client package only) | From 5498e15bd5b63210a001dbca4eecbeebc0305912 Mon Sep 17 00:00:00 2001 From: cliffhall Date: Sat, 24 Oct 2026 23:34:02 -0400 Subject: [PATCH 2/2] chore(cli): pin rolldown to the root's copy for dep-lockstep (#1492) tsdown resolved rolldown 1.2.15 while the root's vite holds 1.2.13, and verify:dep-lockstep rejects the skew. An overrides entry aligns the cli's transitive copy, as it already does for @types/node. 1.2.13 writes //#region banners, which the guard now reads. Co-Authored-By: Claude Opus 5.5 Signed-off-by: cliffhall --- clients/cli/package-lock.json | 134 +++++++++++------------ clients/cli/package.json | 3 +- docs/tsdown-migration.md | 25 +++-- scripts/verify-bundle-externals.mjs | 4 +- scripts/verify-bundle-externals.test.mjs | 6 +- 5 files changed, 90 insertions(+), 82 deletions(-) diff --git a/clients/cli/package-lock.json b/clients/cli/package-lock.json index b95ddd3dad..0a2188e044 100644 --- a/clients/cli/package-lock.json +++ b/clients/cli/package-lock.json @@ -16,9 +16,9 @@ } }, "node_modules/@oxc-project/types": { - "version": "0.155.0", - "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.155.0.tgz", - "integrity": "sha512-SeE8JPwW1xs1tHeNycjUtUBdhorRa8o4jlvjwk49R7/Z291i+4DQa7JJIgOm/TaYQZx+QrPQbVJ/9c8dMIZN8Q==", + "version": "0.153.0", + "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.153.0.tgz", + "integrity": "sha512-jSNrRIyvPVLL5E1z/tS5zLAprosGz/FuI1PWwEOz59j3E4TTTzSpqKb/RDGqJhhW0QHYISGXxq582wGx6T11Tw==", "dev": true, "license": "MIT", "funding": { @@ -39,9 +39,9 @@ } }, "node_modules/@rolldown/binding-android-arm-eabi": { - "version": "1.2.15", - "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm-eabi/-/binding-android-arm-eabi-1.2.15.tgz", - "integrity": "sha512-aLcgK9gIJ3YRvrrtfSBbRa27F5WrpiTaPulnFpsHPxpUHgFlSgnU4854MHwoRGEBhfRJDWCS2WQ7lIjskE9Olw==", + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm-eabi/-/binding-android-arm-eabi-1.2.13.tgz", + "integrity": "sha512-Vu/NICrgdRvUOeaJZIyB2FP63s6fO/4ud5l8dXmxDx9yDyn+mN0y+gsvsVviSli+T361Aqo0h46EuMoobrwawA==", "cpu": [ "arm" ], @@ -56,9 +56,9 @@ } }, "node_modules/@rolldown/binding-android-arm64": { - "version": "1.2.15", - "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.2.15.tgz", - "integrity": "sha512-xD7DdZCrbThKuxNg7ooQmvp07ys4J/pnSEMTG3/OdOWl6daC67m/Q4fL78sRHMxTH/N4fGUbYhcPM0MF5WFHkg==", + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.2.13.tgz", + "integrity": "sha512-6LEoIrGy5vvCd2boNnv2soPSUZj/PRvhp8R/t9KlX+mIZxThIE/ZqxrGXxmuNX0FuvQFvLdZr7S4HrYpYBVhEQ==", "cpu": [ "arm64" ], @@ -73,9 +73,9 @@ } }, "node_modules/@rolldown/binding-darwin-arm64": { - "version": "1.2.15", - "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.2.15.tgz", - "integrity": "sha512-m2WuQ6r0B4OTYxyPpNLtXaMRbRDUbG8YQV2Q3KTdSSK8Th6KHCnC8jVCJt8bvYeSB5WivkkNbc85mKadaSdOxA==", + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.2.13.tgz", + "integrity": "sha512-CaJSRzlQ6Q+zkDMVA9OkVxBjVoPRCDEE3v0FSJ9kIQBgRjFApA3Si4ijhbNVUji7ZJt+PfO0e46qy4nPInHUPA==", "cpu": [ "arm64" ], @@ -90,9 +90,9 @@ } }, "node_modules/@rolldown/binding-darwin-x64": { - "version": "1.2.15", - "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.2.15.tgz", - "integrity": "sha512-5RtnsHM36nodM9WbMy+zip0LGS/G+y5wro5RHrpOlr4ac24+1zSi9kiV2MP1myZeZ/ifEHfulQcWjnAXzc2C2A==", + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.2.13.tgz", + "integrity": "sha512-e4r340I5hxSzJkD3YJBxgzq/rJ3wwxwdLLb2FPt1Zpyem20nrQPT11DDEEkazwxaHumH8wpglsp/Ozgj/wT6mw==", "cpu": [ "x64" ], @@ -107,9 +107,9 @@ } }, "node_modules/@rolldown/binding-freebsd-x64": { - "version": "1.2.15", - "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.2.15.tgz", - "integrity": "sha512-g3l09pyFqhu+135JKkbkwiKGQmwU5hUMUPJ4VdBADvuqR8d33L6H578rh8m7rtxbdp+VmX/+nzI7nvhSZlzpUQ==", + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.2.13.tgz", + "integrity": "sha512-hoBWDZ4/K/mJKVMbsgUd1jfpA2DiOrJ54mpegObU9TBHBBrtX4FLIXJJQRDPZ/2Dn91GvPob+Z2hwKJzf4E5SQ==", "cpu": [ "x64" ], @@ -124,9 +124,9 @@ } }, "node_modules/@rolldown/binding-linux-arm-gnueabihf": { - "version": "1.2.15", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.2.15.tgz", - "integrity": "sha512-nIe3VugI97nGQtspPxDqA4sXMUpeiocKIP/CqpY/u/vgbT+alX+cVxu1C/oVBPKg4feNTmYovE91v4DgXvXNwQ==", + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.2.13.tgz", + "integrity": "sha512-oF9fZu3vTWnTiVAkDFxU9PJLt1nh20K9RRpuHsR7ZnE2L7XookBbDBVLojCVSLGbvtSlxeUNnjAj6DbNsKyzbg==", "cpu": [ "arm" ], @@ -141,9 +141,9 @@ } }, "node_modules/@rolldown/binding-linux-arm64-gnu": { - "version": "1.2.15", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.2.15.tgz", - "integrity": "sha512-iTBjXx+B5QSvgI89lJfmqh4wTh8NabR1YZIIN3hNx4zSG0EVfVqkOvLulNpG4251pbd6/IAmZ/LefVk1Y4rPhw==", + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.2.13.tgz", + "integrity": "sha512-DTpb/+jMiqWMPgphn4ksW1zW+XLJ6dJJ9FMvnIk9I291LhCctMPhMYJrP5t9p6C9qa3KXadDdUEZHBaPh3kNxQ==", "cpu": [ "arm64" ], @@ -161,9 +161,9 @@ } }, "node_modules/@rolldown/binding-linux-arm64-musl": { - "version": "1.2.15", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.2.15.tgz", - "integrity": "sha512-uN26XOnVR7rqQupG3V9oAG2EGGatWjcJHOeDOHUFCh4TBWmP2tHTFoVN13aYbwfm0aHqJAEmcwhAu6sooIjfqQ==", + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.2.13.tgz", + "integrity": "sha512-xU+Kvv9N2A3SY35zFh1FWWNjxbadE/BKeqnkXe7vScU4GZsw757BlVmDLITZEq8DPpk6m7uoDYkK7P+x/uU5Ow==", "cpu": [ "arm64" ], @@ -181,9 +181,9 @@ } }, "node_modules/@rolldown/binding-linux-ppc64-gnu": { - "version": "1.2.15", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.2.15.tgz", - "integrity": "sha512-9nWkcdd+H+XhaA3fQIwpHnKIrfx/PQ6rO0pivr78Og07tXlUlctBBJoEYLPfhTmCR/QxEVdn6uPjHV5SymPhdw==", + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.2.13.tgz", + "integrity": "sha512-XMk/hnhh25oQ756Lclb1Q11h4ll0xC0Esa5w4Vzp+mAE2S3AGJgeM0SonrIgY8fHhjarb6hcoTuwoFG0VVP2ig==", "cpu": [ "ppc64" ], @@ -201,9 +201,9 @@ } }, "node_modules/@rolldown/binding-linux-s390x-gnu": { - "version": "1.2.15", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.2.15.tgz", - "integrity": "sha512-Ggh0ciFjLwIusLSLz7LZYEaGdxOAUJXI+Qu5JCbhPJJHEt8vP+IjRATTJheiJsdzzTYgUiHUiw3X1Ea3ZpMBdA==", + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.2.13.tgz", + "integrity": "sha512-U1BoTHYmlywE2n3HUWjzZ+8EQsKr+OwpxYuDWaubx42tUL8QSL7nOqRz/NVHanibbFP3M1Rxuprz/wNcbMKjqw==", "cpu": [ "s390x" ], @@ -221,9 +221,9 @@ } }, "node_modules/@rolldown/binding-linux-x64-gnu": { - "version": "1.2.15", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.2.15.tgz", - "integrity": "sha512-FHg60rS6DBePAYZ9X9F67x+JObFdmgn6tupA1C/a3B+CufFmTD4mX+e8M75tCiAO3foR/6xwVBI0KQiI7sn/rw==", + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.2.13.tgz", + "integrity": "sha512-J4cm80Pc6wEwV5AZ42o62sIQgDk+Y7R2s646jIwuvO+4V46QB58N4vVuMPWCBaNgursXLpmUWJV//WQAkPvHBQ==", "cpu": [ "x64" ], @@ -241,9 +241,9 @@ } }, "node_modules/@rolldown/binding-linux-x64-musl": { - "version": "1.2.15", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.2.15.tgz", - "integrity": "sha512-/cvV/7v5VGz/moiz0XKRj2dE8DzsKyhIu1KpOvJGPjRywg3yscON889UGvAe8zfiJLHup7VLjBduoGWi3HusWQ==", + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.2.13.tgz", + "integrity": "sha512-W0euZS40U4V6JkmEnVCIX9mcsL6cbXQ4X8c2w+MMOIjFg68TXUW+u3RT+2e1t1pv9mg/EP3pDtK3POXdQ7Rxyw==", "cpu": [ "x64" ], @@ -261,9 +261,9 @@ } }, "node_modules/@rolldown/binding-openharmony-arm64": { - "version": "1.2.15", - "resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.2.15.tgz", - "integrity": "sha512-MyzC5Hrv/sm+Z7TSGKP/j8001RO2xQm1zOpCNVL4j0cY/VhBZviludA2YFQ7i4lH6ZAXxQm0lcMdBzM+99mE7w==", + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.2.13.tgz", + "integrity": "sha512-do/AF/4n9MRshia3a5aXoy8xM2c6mgfT6D7H/dY6my5z+hfCIR4ab7mk4IRj++nsEQpKy39kd0DQnDq+r692tw==", "cpu": [ "arm64" ], @@ -278,9 +278,9 @@ } }, "node_modules/@rolldown/binding-win32-arm64-msvc": { - "version": "1.2.15", - "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.2.15.tgz", - "integrity": "sha512-+PgYiS+AH5omy6L45ZLxybasauJaj3M8buoT83D+nzPmCayXlxUV9hydhciCKVyIg0B/v0BtXPDE1uGqNwCPpg==", + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.2.13.tgz", + "integrity": "sha512-6FtUf2cJZobutJdxnGYX8z0vtbgqU0b2v8vfBhkXb9wp2MppMFtkunE+IaOntyi01rkIQoPW2GHABtfzsC0BRQ==", "cpu": [ "arm64" ], @@ -295,9 +295,9 @@ } }, "node_modules/@rolldown/binding-win32-x64-msvc": { - "version": "1.2.15", - "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.2.15.tgz", - "integrity": "sha512-HFZd2QNQYn1JbIi+Hpd7H+r/lkWxcfIu28nirZ6eCn2LafuvmExMlb/P96Sfx5tf7pPArw39IdhmCF8vmV+NhQ==", + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.2.13.tgz", + "integrity": "sha512-UKhFaZTeTcbKrb3iU82m17jVcPEAoqDkCN5MBqgPyZSwp/cQmib21crTS0DdH7T1B7wZRWEI89YQAOJMet5yhg==", "cpu": [ "x64" ], @@ -766,13 +766,13 @@ } }, "node_modules/rolldown": { - "version": "1.2.15", - "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.2.15.tgz", - "integrity": "sha512-6odND+fel5zVw3I4Yc2e69gvguDnX0CAAGiNDZSq4ik5WUcaLrkD2GLuog0XcODbor31hZ5ayEMgVDno+KPV5g==", + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.2.13.tgz", + "integrity": "sha512-/5apOkwWxtACcQtZ5WlrAsKS4JwXVThQPJZ3RqIruRY9UG9M8e0VlXN068xum/JRKA4aIUoJ13ghe/kGCvidiQ==", "dev": true, "license": "MIT", "dependencies": { - "@oxc-project/types": "=0.155.0", + "@oxc-project/types": "=0.153.0", "@rolldown/pluginutils": "^1.0.0" }, "bin": { @@ -782,21 +782,21 @@ "node": "^20.19.0 || >=22.12.0" }, "optionalDependencies": { - "@rolldown/binding-android-arm-eabi": "1.2.15", - "@rolldown/binding-android-arm64": "1.2.15", - "@rolldown/binding-darwin-arm64": "1.2.15", - "@rolldown/binding-darwin-x64": "1.2.15", - "@rolldown/binding-freebsd-x64": "1.2.15", - "@rolldown/binding-linux-arm-gnueabihf": "1.2.15", - "@rolldown/binding-linux-arm64-gnu": "1.2.15", - "@rolldown/binding-linux-arm64-musl": "1.2.15", - "@rolldown/binding-linux-ppc64-gnu": "1.2.15", - "@rolldown/binding-linux-s390x-gnu": "1.2.15", - "@rolldown/binding-linux-x64-gnu": "1.2.15", - "@rolldown/binding-linux-x64-musl": "1.2.15", - "@rolldown/binding-openharmony-arm64": "1.2.15", - "@rolldown/binding-win32-arm64-msvc": "1.2.15", - "@rolldown/binding-win32-x64-msvc": "1.2.15" + "@rolldown/binding-android-arm-eabi": "1.2.13", + "@rolldown/binding-android-arm64": "1.2.13", + "@rolldown/binding-darwin-arm64": "1.2.13", + "@rolldown/binding-darwin-x64": "1.2.13", + "@rolldown/binding-freebsd-x64": "1.2.13", + "@rolldown/binding-linux-arm-gnueabihf": "1.2.13", + "@rolldown/binding-linux-arm64-gnu": "1.2.13", + "@rolldown/binding-linux-arm64-musl": "1.2.13", + "@rolldown/binding-linux-ppc64-gnu": "1.2.13", + "@rolldown/binding-linux-s390x-gnu": "1.2.13", + "@rolldown/binding-linux-x64-gnu": "1.2.13", + "@rolldown/binding-linux-x64-musl": "1.2.13", + "@rolldown/binding-openharmony-arm64": "1.2.13", + "@rolldown/binding-win32-arm64-msvc": "1.2.13", + "@rolldown/binding-win32-x64-msvc": "1.2.13" } }, "node_modules/rolldown-plugin-dts": { diff --git a/clients/cli/package.json b/clients/cli/package.json index 65585b04b6..cf41311611 100644 --- a/clients/cli/package.json +++ b/clients/cli/package.json @@ -37,6 +37,7 @@ "tsdown": "^0.23.1" }, "overrides": { - "@types/node": "^24.12.4" + "@types/node": "^24.12.4", + "rolldown": "1.2.13" } } diff --git a/docs/tsdown-migration.md b/docs/tsdown-migration.md index 79111bca50..d291a568c6 100644 --- a/docs/tsdown-migration.md +++ b/docs/tsdown-migration.md @@ -62,22 +62,29 @@ None of these fails the build, so each one needs a guard or a test to catch it. keeps `build/index.js`, which `bin`, `main`, the e2e test and `scripts/pack-and-verify.mjs` all name. 3. **Rolldown keeps JSDoc comments.** That produced a 1.22 MB CLI bundle. - `outputOptions.comments: { jsdoc: false }` brings it to 681 KB, against + `outputOptions.comments: { jsdoc: false }` brings it to 684 KB, against tsup's 844 KB. -4. **Module banners vary by Rolldown release.** Rolldown 1.2.15 (the version - tsdown 0.23.1 resolves here) writes the same `// ` banner as esbuild. - An earlier prototype on Rolldown 1.2.13 saw `//#region `. - `verify:bundle-externals` reads banners to find inlined packages, so it now - accepts both forms. A bundle with neither still fails loudly as banner-less. -5. **The guard parsed only `external: [`.** It now also reads the +4. **Module banners vary by Rolldown release.** Rolldown 1.2.13, the version + this repo builds with, writes `//#region `. 1.2.15 writes esbuild's + `// `. `verify:bundle-externals` reads banners to find inlined + packages, so it now accepts both forms. A bundle with neither still fails + loudly as banner-less. +5. **Rolldown is also Vite's bundler**, so it reaches two installs: the root + (through `vite`) and the CLI (through `tsdown`). tsdown 0.23.1 accepts + `~1.2.13` and resolved 1.2.15, while Vite sits on 1.2.13, and + `verify:dep-lockstep` refuses the skew. The CLI pins its copy to the root's + with an `overrides` entry, the same mechanism it uses for `@types/node`. + That override has to move whenever the root's Vite moves Rolldown, and the + lockstep guard will say so. +6. **The guard parsed only `external: [`.** It now also reads the `const EXTERNALS = [` array, and its enrolment test discovers `tsdown*.config.ts` as well as `tsup*.config.ts`. ## Measurements (CLI) -| | tsup 8.5.1 | tsdown 0.23.1 (Rolldown 1.2.15) | +| | tsup 8.5.1 | tsdown 0.23.1 (Rolldown 1.2.13) | | ----------------- | ---------- | ------------------------------- | -| `build/index.js` | 844 KB | 681 KB | +| `build/index.js` | 844 KB | 684 KB | | Build time | ~110 ms | ~45 ms | | Bare imports | 31 | 31, the identical set | diff --git a/scripts/verify-bundle-externals.mjs b/scripts/verify-bundle-externals.mjs index 7edd976cc4..275aa48831 100644 --- a/scripts/verify-bundle-externals.mjs +++ b/scripts/verify-bundle-externals.mjs @@ -108,8 +108,8 @@ export function parseExternals(source) { /** * Every module esbuild inlines is emitted under a `// ` banner naming its - * source file — Rolldown (tsdown) writes the same shape, and some Rolldown - * releases write `//#region ` instead, so both are read — so a package that was bundled despite being declared external + * source file. Rolldown (tsdown) writes `//#region ` in the release the + * cli builds on and esbuild's shape in others, so both forms are read — so a package that was bundled despite being declared external * leaves `// ../../node_modules//…` lines behind. Matching on those covers * **both** shapes this can take: a separate `-HASH.js` chunk (what a * dynamically `import()`ed CommonJS package produces, which is what #2067 was) diff --git a/scripts/verify-bundle-externals.test.mjs b/scripts/verify-bundle-externals.test.mjs index af9cb3135c..5980a67f06 100644 --- a/scripts/verify-bundle-externals.test.mjs +++ b/scripts/verify-bundle-externals.test.mjs @@ -148,9 +148,9 @@ describe("findInlinedExternals", () => { }); test("reads Rolldown's #region banners as well as the plain form", () => { - // Rolldown 1.2.15 writes `// ` like esbuild, but other Rolldown - // releases write `//#region `. Missing that form would read every - // such bundle as banner-less rather than checking it. + // Rolldown 1.2.13 — what the cli's tsdown build runs on — writes + // `//#region `; 1.2.15 writes `// ` like esbuild. Missing + // either form would read that bundle as banner-less rather than check it. const { noBanners, violations } = findInlinedExternals({ externals: ["zod"], files: [