fix: tsdown overwrites "sta" bin command.
Recently I found that somehow "sta" command was gone from the npm registry even it exists in the code.
I've asked an AI for the investigation and found a cause, so here's the fix.
It seems tsdown can generate whole "exports" section as well, but I focused on fixing the "bin" section.
Here's the AI analysis
Context
Starting with v13.12.1, the package published to npm no longer includes the sta command in the bin field — only swagger-typescript-api remains. Verified via npm view:
swagger-typescript-api@13.12.0→{ "sta": "dist/cli.mjs", "swagger-typescript-api": "dist/cli.mjs" }swagger-typescript-api@13.12.1…@13.12.4(latest) →{ "swagger-typescript-api": "dist/cli.mjs" }
The repo's package.json still declares both bins at every tag, so the source is not the problem — the published tarball is rewritten at publish time.
Root cause
package.jsonhas"prepack": "tsdown", so tsdown runs right beforenpm pack/publish.tsdown.config.tssetsexports: true, which lets tsdown's package-exports feature rewritepackage.json.- v13.12.1 bumped tsdown 0.21.10 → 0.22.2. tsdown v0.22.0 added automatic
bingeneration: whenexports.binis unset, it scans entry chunks for a shebang, and if exactly one is found it overwrites thebinfield with a single command named after the package (src/features/pkg/exports.tsin rolldown/tsdown:binName = pkg.name[0] === '@' ? … : pkg.name,return { [binName]: detected }). index.ts(the CLI entry, bundled todist/cli.mjs) starts with#!/usr/bin/env node— exactly one shebang chunk — so tsdown replaces the hand-written two-entrybinmap with{ "swagger-typescript-api": "./dist/cli.mjs" }in the packed tarball, silently droppingsta.
Fix
Edit tsdown.config.ts to configure bin explicitly instead of relying on shebang auto-detection:
export default defineConfig({
entry: {
index: "src/index.ts",
cli: "index.ts",
},
dts: true,
format: ["esm", "cjs"],
sourcemap: true,
exports: {
bin: {
sta: "./index.ts",
"swagger-typescript-api": "./index.ts",
},
},
});
(Alternative: exports: { bin: false } also works — tsdown then leaves the manually-authored bin field untouched. The explicit map is preferred since it keeps tsdown as the single source of truth for the generated fields.)
Verification
bun install --frozen-lockfile && bun run build— confirmpackage.jsonbinstill contains bothstaandswagger-typescript-apiafter the build (tsdown rewrites it during build whenexportsis enabled).npm pack --dry-run(orbun pm pack) and inspect the packedpackage.jsonto confirm both bin entries survive theprepackhook.bun run testto make sure nothing else regressed.
Summary by cubic
Restore the missing sta CLI by configuring tsdown to emit both bin commands and prevent overwrite during pack/publish. Both sta and swagger-typescript-api now install correctly.
- Bug Fixes
- Set
exports.binintsdown.config.tsto mapstaandswagger-typescript-apito./index.ts. - Removed
binfrompackage.jsonsotsdownis the single source of truth and avoids the single-bin auto-detection intsdown@0.22.x. - Added a changeset to release this as a patch.
- Set