fix: tsdown overwrites "sta" bin command.#1808
Conversation
Also remove the bin command section from package.json to make sure that the tsdown configuration is the single source of truth. From tsdown 0.22.0, they started to support generating "bin" automatically, but that behaviour was not matching with this repository's structure.
🦋 Changeset detectedLatest commit: eaf5c3b The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
There was a problem hiding this comment.
1 issue found across 2 files
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="package.json">
<violation number="1" location="package.json:28">
P2: Removing the static `bin` declaration from `package.json` makes CLI availability depend entirely on `tsdown` rewriting the manifest at build/pack time. This breaks workflows where `prepack` does not run, such as git dependency installs (`npm install <git-repo>`) and `npm link` before a local build, because the source manifest no longer advertises any bin commands. A safer alternative is to keep the `bin` field in `package.json` and set `exports: { bin: false }` in `tsdown.config.ts` so tsdown stops overwriting it.</violation>
</file>
Reply with feedback, questions, or to request a fix.
Re-trigger cubic
| "sta": "./dist/cli.mjs", | ||
| "swagger-typescript-api": "./dist/cli.mjs" | ||
| }, | ||
| "files": [ |
There was a problem hiding this comment.
P2: Removing the static bin declaration from package.json makes CLI availability depend entirely on tsdown rewriting the manifest at build/pack time. This breaks workflows where prepack does not run, such as git dependency installs (npm install <git-repo>) and npm link before a local build, because the source manifest no longer advertises any bin commands. A safer alternative is to keep the bin field in package.json and set exports: { bin: false } in tsdown.config.ts so tsdown stops overwriting it.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At package.json, line 28:
<comment>Removing the static `bin` declaration from `package.json` makes CLI availability depend entirely on `tsdown` rewriting the manifest at build/pack time. This breaks workflows where `prepack` does not run, such as git dependency installs (`npm install <git-repo>`) and `npm link` before a local build, because the source manifest no longer advertises any bin commands. A safer alternative is to keep the `bin` field in `package.json` and set `exports: { bin: false }` in `tsdown.config.ts` so tsdown stops overwriting it.</comment>
<file context>
@@ -25,10 +25,6 @@
- "sta": "./dist/cli.mjs",
- "swagger-typescript-api": "./dist/cli.mjs"
- },
"files": [
"dist",
"templates"
</file context>
|
@takayukioda haha "someone who remove sta" that was me, thanks for your PR, please add changeset! |
|
@js2me added the changeset 👍🏽 btw, I would like to have an opinion about removing bin section from package.json. |
|
@takayukioda thank you |
|
@takayukioda if this removed bin property will not brake executing this package using |
|
@js2me thanks for sharing your opinion. Then I think it's ready to review.👍🏽 |
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
stacommand in thebinfield — onlyswagger-typescript-apiremains. Verified vianpm 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.jsonstill 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.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.tsto configurebinexplicitly instead of relying on shebang auto-detection:(Alternative:
exports: { bin: false }also works — tsdown then leaves the manually-authoredbinfield 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
staCLI by configuringtsdownto emit both bin commands and prevent overwrite during pack/publish. Bothstaandswagger-typescript-apinow install correctly.exports.binintsdown.config.tsto mapstaandswagger-typescript-apito./index.ts.binfrompackage.jsonsotsdownis the single source of truth and avoids the single-bin auto-detection intsdown@0.22.x.Written for commit eaf5c3b. Summary will update on new commits.