change-versions 1.2.0 → 1.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -47,3 +47,16 @@ npm pack --dry-run
47
47
  `check` 运行类型检查、单测、临时 Git 仓库的 CLI 回归并重新构建。`prepack` 自动做类型检查和构建,保证 npm pack/publish 收录最新 dist。发布物包含 CLI、命令文档与 README,不包含源码测试。
48
48
 
49
49
  CLI 回归通过临时 npm 替身验证发布顺序、部分失败续发、登录与网络失败、dry-run、hook、版本漂移和正式版 tag,不上传真实包。
50
+
51
+
52
+ ## 发布状态与下一步
53
+
54
+ `publish --dry-run` 会查询 registry,但只展示计划。输出以“发布预览”开头,操作前带 `[计划]`,结束时明确未执行 hook、上传、npm 标签修改或 Git 标签/推送,并给出去掉 `--dry-run` 后的 publish 命令。预览查询失败时不会输出“预览结束”。
55
+
56
+ 真实发布在确认前显示计划数量,执行时用 `[执行]` 标识当前阶段。成功汇总区分已发布、npm 标签已更新、已跳过,并说明 Git 标签是仅本地就绪还是已推送。已有版本只需更新 npm 标签时会单独标注。
57
+
58
+ 完成用绿色、失败用红色、预览和待处理事项用黄色、引导和命令用青色、跳过项及 registry 用弱化颜色;状态始终有文字标签。颜色沿用终端检测,支持 `NO_COLOR`;重定向日志仍保留完整文字,`FORCE_COLOR=1` 可强制显示颜色。
59
+
60
+ 发生部分上传、hook 或 Git 标签失败时,先修复提示中的原因,再使用输出的 publish 命令重试,无需再次 version。重试重新查询 registry,跳过已上传版本并补齐必要标签;配置的 hook 仍会执行。Git 标签阶段失败时,本地或远端可能已有部分标签,不能据此认定全部未创建。
61
+
62
+ `version --dry-run` 也会明确区分计划与修改。升版成功会说明“版本已提交,包尚未发布”,提示先预览或执行 publish。合并或重写 version 提交时须保留 `Co-authored-by: change-versions <publish@change-versions.com>`,否则 publish 可能找不到这一批版本。通过包装脚本使用时,恢复其发布步骤并保留原来的 root、配置、包目录及 dist-tag 选项,不要重新升版。
package/dist/cli.js CHANGED
@@ -1,26 +1,26 @@
1
1
  #!/usr/bin/env node
2
- var le=(e,n,t)=>()=>{if(e)try{n=e(e=0)}catch(r){t=[r]}if(t)throw t[0];return n};function me(){let e=(process.env.LC_ALL||process.env.LC_MESSAGES||process.env.LANG||"").split(".")[0];return/^zh/i.test(e)?"zh":"en"}function i(e,n,t=me()){let r=bn[e][t];if(n)for(let[s,o]of Object.entries(n))r=r.replaceAll(`{${s}}`,String(o));return r}var bn;var S=le(()=>{bn={publishComplete:{zh:"发布完成,汇总:",en:"Publish complete. Summary:"},publishIncomplete:{zh:"发布未完成,汇总:",en:"Publish incomplete. Summary:"},publishSummaryContext:{zh:"版本提交: {commit},dist-tag: {tag}",en:"Version commit: {commit}, dist-tag: {tag}"},publishFailedStage:{zh:"失败或中断阶段: {stage}",en:"Failed or interrupted stage: {stage}"},summaryPublished:{zh:"已发布",en:"Published"},summaryRetagged:{zh:"标签已更新",en:"Tag updated"},summarySkipped:{zh:"已跳过(版本与标签已就绪)",en:"Skipped (version and tag ready)"},summaryPrivate:{zh:"已跳过(私有包)",en:"Skipped (private)"},summaryFailed:{zh:"失败(registry 状态需重跑确认)",en:"Failed (rerun to check registry state)"},summaryPending:{zh:"未执行",en:"Not executed"},alreadyTagged:{zh:"跳过 {name}@{version}:{tag} 已指向该版本,registry: {registry}",en:"Skipping {name}@{version}: {tag} already points to this version, registry: {registry}"},unexpectedRegistryTags:{zh:"registry {registry} 未返回有效标签信息,无法确认 {name} 的 {tag} 标签",en:"Registry {registry} did not return valid tag metadata for {name} ({tag})"},checkingRegistry:{zh:"检查 {name}@{version},registry: {registry}",en:"Checking {name}@{version}, registry: {registry}"},publishHeadChanged:{zh:"发布 hook 改变了 HEAD。下一步: 检查该提交,让 hook 只更新忽略的构建产物后重跑 publish",en:"A publish hook changed HEAD. Review that commit and keep hooks limited to ignored build output before retrying publish"},wrongBranch:{zh:"当前分支不是 {branch}。下一步: 切换到该分支后重跑 version",en:"Current branch is not {branch}. Next: switch to that branch and rerun version"},releaseVersionMismatch:{zh:"{name} 当前版本 {actual} 与 version 提交中的 {expected} 不一致。下一步: 检查提交和 package.json 后再发布",en:"{name} is at {actual}, but the version commit records {expected}. Check the commit and package.json before publishing"},releaseContentsChanged:{zh:"待发布包在 version 提交后又有改动。下一步: 先完成新一轮 version,再发布对应提交",en:"Release packages changed after the version commit. Next: create a new version commit before publishing"},unexpectedRegistryVersion:{zh:"registry {registry} 未返回预期版本 {name}@{version},无法确认是否已发布",en:"The registry did not return the expected version {name}@{version} ({registry})"},dirtyTree:{zh:"工作区不干净。下一步: 提交或还原后,重跑刚才那条命令",en:"Working tree is dirty. Next: commit or restore your changes, then rerun the same command"},gitFailed:{zh:`git 失败。下一步: 在 git 仓库里重跑
2
+ var be=(e,n,t)=>()=>{if(e)try{n=e(e=0)}catch(r){t=[r]}if(t)throw t[0];return n};function ye(){let e=(process.env.LC_ALL||process.env.LC_MESSAGES||process.env.LANG||"").split(".")[0];return/^zh/i.test(e)?"zh":"en"}function i(e,n,t=ye()){let r=Cn[e][t];if(n)for(let[s,o]of Object.entries(n))r=r.replaceAll(`{${s}}`,String(o));return r}var Cn;var z=be(()=>{Cn={publishPreview:{zh:"【发布预览】仅查询 registry 并展示计划,以下操作尚未执行",en:"[Publish preview] Querying the registry and showing a plan; the operations below have not been executed"},publishPreparing:{zh:"【发布检查】正在确认版本、登录状态和 registry;尚未执行发布操作",en:"[Publish checks] Checking versions, authentication and the registry; publication has not started"},publishPlanSummary:{zh:"计划上传: {uploads},更新 npm 标签: {retags},校验/创建 Git 标签: {tags}",en:"Upload: {uploads}, npm tag updates: {retags}, Git tags to check/create: {tags}"},plannedStep:{zh:"[计划] {step}",en:"[Planned] {step}"},executingStep:{zh:"[执行] {step}",en:"[Running] {step}"},publishPreviewComplete:{zh:"预览结束:未执行 hook、上传、npm 标签修改或 Git 标签/推送操作。",en:"Preview complete. No hooks, uploads, npm tag changes or Git tag/push operations were executed."},publishPreviewNext:{zh:"下一步:确认计划后,去掉 --dry-run,沿用原来的 CLI 运行方式执行下方命令;包装脚本请关闭对应预览选项并使用恢复发布入口。",en:"Next: review the plan, then remove --dry-run and run the command below with your usual CLI runner. For wrapper scripts, disable preview and use their resume-publication entry."},publishResumeInfo:{zh:"将重新查询 registry,跳过已上传的版本,仅补必要的 npm 标签;配置的 hook 和正式版 Git 标签阶段仍会执行。",en:"This will query the registry again, skip uploaded versions and update npm tags only as needed. Configured hooks and the formal-release Git tag stage still run."},publishRetry:{zh:"下一步:修复上述错误后,无需再次升版,重试发布。沿用原来的 CLI 运行方式执行下方命令;包装脚本请使用恢复发布入口,不要重新执行 version。",en:"Next: fix the error, then retry publication without bumping versions. Run the command below with your usual CLI runner; wrapper scripts should resume publication instead of running version again."},publishRetryTitle:{zh:"无需再次升版,重试发布",en:"Retry publication without bumping versions"},publishTagRecovery:{zh:"包已在 registry 就绪,Git 标签阶段未完成;本地或远端标签可能已部分完成,请修复 Git 错误后重试。",en:"Packages are ready on the registry, but the Git tag stage is incomplete. Local or remote tags may be partially complete; fix the Git error before retrying."},publishReady:{zh:"目标 npm 版本与标签已就绪;本批次无需再次升版或上传。",en:"Target npm versions and tags are ready; no further version bump or upload is needed for this batch."},gitTagsLocal:{zh:"Git 标签已在本地就绪;未配置推送分支,因此未推送标签。",en:"Git tags are ready locally. No push branch is configured, so tags were not pushed."},gitTagsPushed:{zh:"Git 标签已创建/校验并推送到 origin。",en:"Git tags were created/checked and pushed to origin."},versionPreview:{zh:"【升版预览】以下为计划版本,尚未修改文件或提交",en:"[Version preview] Planned versions only; no files or commits have been changed"},versionPreviewComplete:{zh:"预览结束:未修改文件、提交或推送。确认后去掉 --dry-run,保留相同档位和参数重跑 version。",en:"Preview complete. No files, commits or pushes were made. Remove --dry-run and rerun version with the same bump and options after reviewing the plan."},versionCommitted:{zh:"版本已提交,包尚未发布。版本提交: {commit}",en:"Versions committed; packages have not been published. Version commit: {commit}"},versionTrailerHint:{zh:"合并或重写 version 提交时,请保留正文中的 Co-authored-by: change-versions <publish@change-versions.com>,供 publish 识别。",en:"When squashing or rewriting a version commit, preserve its Co-authored-by: change-versions <publish@change-versions.com> trailer so publish can find it."},versionPublishNext:{zh:"下一步:沿用原来的 CLI 运行方式执行下方 publish 命令;也可以先加 --dry-run 预览发布计划。",en:"Next: run the publish command below with your usual CLI runner, or add --dry-run to preview the publication plan first."},noVersionChangesNext:{zh:"如果上一轮已经升版但尚未发布,请恢复 publish,不要为了重试再次升版。",en:"If the previous version bump still needs publishing, resume publish instead of bumping again."},publishComplete:{zh:"发布完成,汇总:",en:"Publish complete. Summary:"},publishIncomplete:{zh:"发布未完成,汇总:",en:"Publish incomplete. Summary:"},publishSummaryContext:{zh:"版本提交: {commit},dist-tag: {tag}",en:"Version commit: {commit}, dist-tag: {tag}"},publishFailedStage:{zh:"失败或中断阶段: {stage}",en:"Failed or interrupted stage: {stage}"},summaryPublished:{zh:"已发布",en:"Published"},summaryRetagged:{zh:"标签已更新",en:"Tag updated"},summarySkipped:{zh:"已跳过(版本与标签已就绪)",en:"Skipped (version and tag ready)"},summaryPrivate:{zh:"已跳过(私有包)",en:"Skipped (private)"},summaryFailed:{zh:"失败(registry 状态需重跑确认)",en:"Failed (rerun to check registry state)"},summaryPending:{zh:"未执行",en:"Not executed"},alreadyTagged:{zh:"跳过 {name}@{version}:{tag} 已指向该版本,registry: {registry}",en:"Skipping {name}@{version}: {tag} already points to this version, registry: {registry}"},unexpectedRegistryTags:{zh:"registry {registry} 未返回有效标签信息,无法确认 {name} 的 {tag} 标签",en:"Registry {registry} did not return valid tag metadata for {name} ({tag})"},checkingRegistry:{zh:"检查 {name}@{version},registry: {registry}",en:"Checking {name}@{version}, registry: {registry}"},publishHeadChanged:{zh:"发布 hook 改变了 HEAD。下一步: 检查该提交,让 hook 只更新忽略的构建产物后重跑 publish",en:"A publish hook changed HEAD. Review that commit and keep hooks limited to ignored build output before retrying publish"},wrongBranch:{zh:"当前分支不是 {branch}。下一步: 切换到该分支后重跑 version",en:"Current branch is not {branch}. Next: switch to that branch and rerun version"},releaseVersionMismatch:{zh:"{name} 当前版本 {actual} 与 version 提交中的 {expected} 不一致。识别到版本提交: {commit}。下一步: 检查最新升版提交与 package.json,并确认合并/重写后仍保留 change-versions 的 Co-authored-by 标记,再恢复 publish;不要盲目重新升版",en:"{name} is at {actual}, but the version commit records {expected}. Version commit: {commit}. Check the latest version commit and package.json, including the change-versions Co-authored-by trailer after a squash/rewrite, before resuming publish; do not blindly bump again"},releaseContentsChanged:{zh:"待发布包在 version 提交后又有改动。下一步: 先完成新一轮 version,再发布对应提交",en:"Release packages changed after the version commit. Next: create a new version commit before publishing"},unexpectedRegistryVersion:{zh:"registry {registry} 未返回预期版本 {name}@{version},无法确认是否已发布",en:"The registry did not return the expected version {name}@{version} ({registry})"},dirtyTree:{zh:"工作区不干净。下一步: 提交或还原后,重跑刚才那条命令",en:"Working tree is dirty. Next: commit or restore your changes, then rerun the same command"},gitFailed:{zh:`git 失败。下一步: 在 git 仓库里重跑
3
3
  {detail}`,en:`git failed. Next: rerun this inside a git repository
4
- {detail}`},noPackagesSince:{zh:"自 {rev} 以来没有需要升版的包",en:"No packages to version since {rev}"},changedHeader:{zh:"变更:",en:"Changed:"},dependentsHeader:{zh:"依赖方:",en:"Dependents:"},confirmVersions:{zh:"以上版本是否确认?",en:"Apply these versions?"},cancelledVersion:{zh:"已取消。还没改文件。想继续就再跑同一条命令",en:"Cancelled. No files were changed. Rerun the same command to continue"},branchPushFailed:{zh:`分支推送失败。commit 已在本地。下一步: git push origin {branch},不要重跑 version
5
- {detail}`,en:`Branch push failed. The commit is local. Next: git push origin {branch}. Do not rerun version
6
- {detail}`},noVersionCommit:{zh:"没有 version 提交。下一步: 先跑 version,不要直接 publish",en:"No version commit. Next: run version first. Do not publish yet"},packageNotInDir:{zh:"正文里的包不在 {dir}: {name}",en:"Package from the commit body is not in {dir}: {name}"},noGitTag:{zh:"不打 git tag",en:"No git tag"},willPublish:{zh:"将发布:",en:"Will publish:"},privateMark:{zh:"(私有)",en:"(private)"},confirmPublish:{zh:"是否发布?",en:"Publish?"},cancelledPublish:{zh:"已取消。不跑 hook,不上传,不打 git tag",en:"Cancelled. No hooks, no upload, no git tag"},publishInterrupted:{zh:"发布已中断。已经上传的留在 registry,没有打 git tag。下一步: 重跑同一条 publish,不要重跑 version",en:"Publish interrupted. Versions already uploaded stay on the registry. No git tag was created. Next: rerun the same publish. Do not rerun version"},badBaseline:{zh:"修订无法解析: {rev}。下一步: 换成 git rev-parse 能解析的 SHA 或 tag",en:"Cannot resolve revision: {rev}. Next: pass a SHA or tag that git rev-parse accepts"},noBaseline:{zh:"没有基线。下一步: changed 或 version 加上 --baseline=SHA或tag",en:"No baseline. Next: rerun changed or version with --baseline=<sha-or-tag>"},chooseBump:{zh:"选择档位",en:"Select a bump"},versionRestored:{zh:"已退回命令开始时的 HEAD。修好后重跑 version",en:"Restored the tree to HEAD from when the command started. Fix the error, then rerun version"},tagPointsElsewhere:{zh:"git tag {tag} 指向别的 commit。下一步: 人工处理这个同名 tag 后,再重跑 publish。不要重跑 version",en:"git tag {tag} points at another commit. Next: fix that tag by hand, then rerun publish. Do not rerun version"},tagPushFailed:{zh:`git tag 没推上去。包已在 registry。下一步: 重跑同一条 publish,只补 tag,不要重跑 version
7
- {detail}`,en:`git tag was not pushed. Packages are already on the registry. Next: rerun the same publish to finish tags. Do not rerun version
8
- {detail}`},networkFailed:{zh:`网络失败,已重试 2 次。后面的包不发,不打 git tag。下一步: 重跑同一条 publish,不要重跑 version
9
- {detail}`,en:`Network failed after 2 retries. Later packages were not published and no git tag was created. Next: rerun the same publish. Do not rerun version
4
+ {detail}`},noPackagesSince:{zh:"自 {rev} 以来没有需要升版的包",en:"No packages to version since {rev}"},changedHeader:{zh:"变更:",en:"Changed:"},dependentsHeader:{zh:"依赖方:",en:"Dependents:"},confirmVersions:{zh:"以上版本是否确认?",en:"Apply these versions?"},cancelledVersion:{zh:"已取消。还没改文件。想继续就再跑同一条命令",en:"Cancelled. No files were changed. Rerun the same command to continue"},branchPushFailed:{zh:`分支推送失败。commit 已在本地。下一步: git push origin {branch};成功后恢复 publish,不要重跑 version
5
+ {detail}`,en:`Branch push failed. The commit is local. Next: git push origin {branch}, then resume publish. Do not rerun version
6
+ {detail}`},noVersionCommit:{zh:"没有 version 提交。下一步: 尚未升版时先跑 version;若已升版,请先检查提交正文的 Co-authored-by: change-versions <publish@change-versions.com> 是否保留",en:"No version commit. Next: run version first if no bump exists; otherwise check that the version commit retains Co-authored-by: change-versions <publish@change-versions.com>"},packageNotInDir:{zh:"正文里的包不在 {dir}: {name}",en:"Package from the commit body is not in {dir}: {name}"},noGitTag:{zh:"不打 git tag",en:"No git tag"},willPublish:{zh:"即将执行(确认后开始):",en:"Publication plan (starts after confirmation):"},distTagOnlyMark:{zh:"(版本已存在,仅更新 npm 标签)",en:"(version exists; npm tag update only)"},privateMark:{zh:"(私有)",en:"(private)"},confirmPublish:{zh:"是否发布?",en:"Publish?"},cancelledPublish:{zh:"已取消。不跑 hook,不上传,不打 git tag。想继续时重跑同一条 publish,无需再次升版",en:"Cancelled. No hooks, no upload, no git tag. Rerun the same publish to continue without bumping versions"},publishInterrupted:{zh:"发布已中断,已完成的操作保留;registry 和 Git 标签可能部分完成。下一步: 重跑同一条 publish 确认状态,不要重跑 version",en:"Publish interrupted. Completed operations remain; registry and Git tags may be partially complete. Next: rerun the same publish to check state. Do not rerun version"},badBaseline:{zh:"修订无法解析: {rev}。下一步: 换成 git rev-parse 能解析的 SHA 或 tag",en:"Cannot resolve revision: {rev}. Next: pass a SHA or tag that git rev-parse accepts"},noBaseline:{zh:"没有基线。下一步: changed 或 version 加上 --baseline=SHA或tag",en:"No baseline. Next: rerun changed or version with --baseline=<sha-or-tag>"},chooseBump:{zh:"选择档位",en:"Select a bump"},versionRestored:{zh:"已退回命令开始时的 HEAD。修好后重跑 version",en:"Restored the tree to HEAD from when the command started. Fix the error, then rerun version"},tagPointsElsewhere:{zh:"git tag {tag} 指向别的 commit。下一步: 人工处理这个同名 tag 后,再重跑 publish。不要重跑 version",en:"git tag {tag} points at another commit. Next: fix that tag by hand, then rerun publish. Do not rerun version"},tagPushFailed:{zh:`git tag 没推上去。包已在 registry。下一步: 检查 Git 远端权限后重跑同一条 publish,补齐标签阶段;配置的 hook 仍会执行,不要重跑 version
7
+ {detail}`,en:`git tag was not pushed. Packages are already on the registry. Next: check Git remote permissions, then rerun the same publish to finish tags; configured hooks still run. Do not rerun version
8
+ {detail}`},networkFailed:{zh:`操作失败,已重试 2 次。后续发布步骤已停止。下一步: 重跑同一条 publish,不要重跑 version
9
+ {detail}`,en:`Operation failed after 2 retries. Later publication steps were stopped. Next: rerun the same publish. Do not rerun version
10
10
  {detail}`},notLoggedIn:{zh:"未登录 {registry}。下一步: npm login --registry={registry},然后重跑同一条 publish。不要重跑 version",en:"Not logged in to {registry}. Next: npm login --registry={registry}, then rerun the same publish. Do not rerun version"},registryUnreachable:{zh:`无法访问 {registry}。下一步: 检查网络后重跑同一条 publish。不要重跑 version
11
11
  {detail}`,en:`Cannot reach {registry}. Next: check the network, then rerun the same publish. Do not rerun version
12
12
  {detail}`},noNpmRegistry:{zh:`读不到 npm registry:
13
13
  {detail}`,en:`Cannot read the npm registry:
14
14
  {detail}`},npmFailed:{zh:"npm 失败",en:"npm failed"},npmViewFailed:{zh:"npm view 失败",en:"npm view failed"},hookFailed:{zh:`{name} 失败。下一步: 修好 hook 后重跑 publish。已上传的包保留在 registry,尚未执行 git tag 阶段
15
15
  {detail}`,en:`{name} failed. Next: fix the hook, then rerun publish. Uploaded packages remain on the registry; the git tag stage was not reached
16
- {detail}`},beforePublishDirty:{zh:"beforePublish 改了被跟踪的文件。下一步: hook 只能改 git 忽略的构建产物,弄干净后重跑 publish",en:"beforePublish changed tracked files. Next: the hook may only change gitignored build output. Clean the tree, then rerun publish"},afterPublishDirty:{zh:"afterPublish 改了被跟踪的文件,还没打 git tag。下一步: 让 hook 不改被跟踪的文件,弄干净后重跑 publish",en:"afterPublish changed tracked files, so no git tag was created. Next: keep the hook off tracked files, clean the tree, then rerun publish"},configUnreadable:{zh:"配置读不了: {file}。下一步: 补上 include,删掉不认识的字段",en:"Cannot read config: {file}. Next: add include and remove unknown fields"},packagesDirMissing:{zh:"找不到目录 {dir}",en:"Directory not found: {dir}"},packageJsonIncomplete:{zh:"{folder} 的 package.json 缺少 name 或 version",en:"{folder} package.json is missing name or version"},publicDependsOnPrivate:{zh:"public 包 {name} 不能依赖 private 包 {dep}。下一步: 改依赖后重跑 version",en:"Public package {name} cannot depend on private package {dep}. Next: change the dependency, then rerun version"},missingVersionField:{zh:"{folder} 缺少 version",en:"{folder} is missing version"},badBump:{zh:"档位非法: {bump}。可用 {list}",en:"Invalid bump: {bump}. Use {list}"},preidRequired:{zh:"{kind} 必须带 --preid。预发布用 prepatch 这类档位",en:"{kind} requires --preid. Use a pre* bump for prereleases"},preidForbidden:{zh:"正式版不能带 --preid。预发布用 prepatch 这类档位",en:"A stable bump cannot take --preid. Use a pre* bump for prereleases"},badLine:{zh:"第 {line} 行无法解析",en:"Cannot parse line {line}"},unknownField:{zh:"不认识的字段 {name}",en:"Unknown field {name}"},missingValue:{zh:"{name} 缺少值",en:"{name} is missing a value"},includeRequired:{zh:"include 不能为空。下一步: 补上 include,删掉不认识的字段",en:"include must not be empty. Next: add include and remove unknown fields"},commitMessageNeedsToken:{zh:"commitMessage 需要 %s",en:"commitMessage must contain %s"},patternBang:{zh:"模式不能包含 !: {pattern}",en:"Patterns cannot contain !: {pattern}"},patternClass:{zh:"不支持字符组: {pattern}",en:"Character classes are not supported: {pattern}"},badHook:{zh:"hooks 无法解析: {line}",en:"Cannot parse hooks: {line}"},unknownHook:{zh:"不认识的 hook {name}",en:"Unknown hook {name}"},hookMissingCommand:{zh:"{name} 缺少命令",en:"{name} is missing a command"},badPatternLine:{zh:"路径列表无法解析: {line}",en:"Cannot parse path list: {line}"},badSemver:{zh:"无法解析版本 {version}",en:"Cannot parse version {version}"},dependencyCycle:{zh:"依赖成环: {name}",en:"Dependency cycle: {name}"},bumpRequired:{zh:"非交互环境必须写上档位",en:"A bump is required when not interactive"},chooseIndex:{zh:"请输入序号: ",en:"Enter a number: "},invalidChoice:{zh:"无效选择: {answer}",en:"Invalid choice: {answer}"},emptyAnswer:{zh:"(空)",en:"(empty)"},yesRequired:{zh:"非交互环境需要 --yes",en:"Pass --yes when not interactive"},commandFailed:{zh:"{command} 失败: {detail}",en:"{command} failed: {detail}"},commandFailedShort:{zh:"{command} 失败",en:"{command} failed"},commandExit:{zh:"{command} 退出 {code}",en:"{command} exited {code}"},cliDescription:{zh:"只给需要发的包升版本,再按那次提交发布",en:"Version only the packages that need a release, then publish that commit"},optRoot:{zh:"仓库根目录",en:"Repository root"},optVersionsFile:{zh:"配置文件",en:"Config file"},optPackages:{zh:"覆盖 packagesDir",en:"Override packagesDir"},cmdChanged:{zh:"列出会升版的包",en:"List packages that would be versioned"},optBaseline:{zh:"这一次的比较起点,SHA 或 tag",en:"Comparison start for this run, SHA or tag"},cmdVersion:{zh:"升版本并提交",en:"Bump versions and commit"},argBump:{zh:"patch、minor、major、prerelease、prepatch、preminor、premajor",en:"patch, minor, major, prerelease, prepatch, preminor, or premajor"},optPreid:{zh:"预发布标识,pre* 必填",en:"Prerelease identifier, required for pre*"},optYes:{zh:"跳过确认",en:"Skip confirmation"},optDryRunVersion:{zh:"只打印旧版本到新版本",en:"Print old and new versions only"},optBranch:{zh:"覆盖配置里的 branch",en:"Override branch from the config"},optCommitMessage:{zh:"覆盖 commitMessage",en:"Override commitMessage"},cmdPublish:{zh:"发布最近一次 version 提交里的包",en:"Publish packages listed in the latest version commit"},optDistTag:{zh:"npm dist-tag",en:"npm dist-tag"},optDryRunPublish:{zh:"只打印将执行的 hook、npm publish 和 git tag",en:"Print the hooks, npm publish commands, and git tags without running them"},cmdInit:{zh:"写入带注释的配置",en:"Write a commented config file"},optYesInit:{zh:"不提问,按探测到的目录写默认配置",en:"Write defaults from the detected directory, without prompts"},configExists:{zh:"已有 {file}。下一步: 直接改这个文件,或删掉后重跑 init",en:"Config already exists: {file}. Next: edit that file, or delete it and rerun init"},initIntro:{zh:"写入 {file}",en:"Write {file}"},initFoundDirs:{zh:"发现包目录: {dirs}",en:"Package directories: {dirs}"},initPackagesDir:{zh:"包目录",en:"Package directory"},initInclude:{zh:"源码路径,逗号分隔",en:"Source paths, comma-separated"},initExclude:{zh:"排除路径,逗号分隔",en:"Excluded paths, comma-separated"},initBranch:{zh:"推送分支,回车跳过",en:"Branch to push, Enter to skip"},initBeforeCommit:{zh:"beforeCommit,回车跳过",en:"beforeCommit, Enter to skip"},initBeforePublish:{zh:"beforePublish,回车跳过",en:"beforePublish, Enter to skip"},initWrote:{zh:"已写入 {file}",en:"Wrote {file}"},initNotePackagesDir:{zh:"包所在目录。这次可用 --packages 覆盖",en:"Directory of packages. Override once with --packages"},initNoteCommitMessage:{zh:"%s 换成档位。有 --preid 时再空一格接上,例如 bump: prerelease alpha。查找看正文末尾的 Co-authored-by: change-versions <publish@change-versions.com>,不改提交作者",en:"%s becomes the bump. With --preid, a space and the id follow, for example bump: prerelease alpha. Lookup uses the Co-authored-by: change-versions <publish@change-versions.com> trailer. The commit author stays unchanged"},initNoteBranch:{zh:"不写就不推送。version 只推这个分支,不推 tag",en:"Omit to skip pushing. version pushes this branch only, not tags"},initNoteBeforeCommit:{zh:"版本和 CHANGELOG 写完之后、git commit 之前。失败会退回 HEAD",en:"After versions and CHANGELOG are written, before git commit. Failure restores HEAD"},initNoteBeforePublish:{zh:"确认之后、npm publish 之前。只能改 git 忽略的构建产物",en:"After confirm, before npm publish. May only change gitignored build output"},initNoteAfterPublish:{zh:"要发的包都已在 registry 上之后。不能把工作区弄脏",en:"After every selected package is on the registry. Must leave the tree clean"},initNoteInclude:{zh:"相对仓库根。* 和 ? 不跨过 /,** 可以。命中目录时,目录里的文件也算",en:"Relative to the repo root. * and ? do not cross /, ** may. A matching directory includes files under it"},initNoteExclude:{zh:"命中这里的文件不触发升版。package.json 另比,去掉 devDependencies 后有差异才算",en:"Files that match here do not trigger a bump. package.json is compared separately, after dropping devDependencies"}}});import De from"picomatch";import Q from"semver";import{YAMLParseError as yn,parse as wn}from"yaml";function pe(e){return je.has(e)}function Te(e,n){if(!ze.includes(e))throw new d(i("badBump",{bump:e,list:ze.join(", ")}));let t=e;if(kn.has(t)&&!n)throw new d(i("preidRequired",{kind:t}));if(je.has(t)&&n)throw new d(i("preidForbidden"));return t}function ne(e){let n=xn(e);for(let l of Object.keys(n))if(!vn.has(l))throw new d(i("unknownField",{name:l}));let t=n.packagesDir===void 0?"packages":ue(n.packagesDir,"packagesDir"),r=n.commitMessage===void 0?"bump: %s":ue(n.commitMessage,"commitMessage"),s=n.branch===void 0?void 0:ue(n.branch,"branch"),o=n.hooks==null?{}:Sn(n.hooks),a=n.include==null?[]:Fe(n.include,"include"),g=n.exclude==null?[]:Fe(n.exclude,"exclude");if(!a.length)throw new d(i("includeRequired"));if(!r.includes("%s"))throw new d(i("commitMessageNeedsToken"));for(let l of[...a,...g]){if(l.includes("!"))throw new d(i("patternBang",{pattern:l}));if(/\[[^\]]+\]/.test(l))throw new d(i("patternClass",{pattern:l}))}return{packagesDir:t,commitMessage:r,branch:s,hooks:o,include:a,exclude:g}}function xn(e){try{let n=wn(e);if(n==null)return{};if(!Ee(n))throw new d(i("badLine",{line:1}));return n}catch(n){if(n instanceof d)throw n;if(n instanceof yn)throw new d(i("badLine",{line:n.linePos?.[0]?.line??1}));throw n}}function Sn(e){if(!Ee(e))throw new d(i("badHook",{line:"hooks"}));let n={};for(let[t,r]of Object.entries(e)){if(!Pn.has(t))throw new d(i("unknownHook",{name:t}));if(typeof r!=="string"||!r)throw new d(i("hookMissingCommand",{name:t}));n[t]=r}return n}function Fe(e,n){if(!Array.isArray(e))throw new d(i("badPatternLine",{line:n}));return e.map((t)=>{if(typeof t!=="string"||!t)throw new d(i("badPatternLine",{line:n}));return t})}function ue(e,n){if(typeof e!=="string"||!e)throw new d(i("missingValue",{name:n}));return e}function Ee(e){return Boolean(e)&&typeof e==="object"&&!Array.isArray(e)}function Ne(e,n){let t={dot:!0};if(De(n,t)(e))return!0;if(n.endsWith("/**"))return!1;return De(`${n}/**`,t)(e)}function he(e,n,t){return n.some((r)=>Ne(e,r))&&!t.some((r)=>Ne(e,r))}function Ae(e,n,t){let r=new Set(t),s=`${n}/`,o=new Map;for(let a of e.split(`
17
- `)){if(!a.startsWith(s))continue;let g=a.slice(s.length),l=g.split("/")[0];if(!l||!g.includes("/")||!r.has(l))continue;let m=o.get(l)??[];m.push(a),o.set(l,m)}return o}function Be(e,n,t,r,s,o){let a=[],g=[];for(let l of e){let m=n.get(l);if(!m?.length){g.push(l);continue}let u=`${o}/${l}/package.json`;if(m.some((w)=>w!==u&&he(w,t,r))||m.includes(u)&&!s(l))a.push(l);else g.push(l)}return{changed:a,ignored:g}}function Me(e,n){return JSON.stringify(ee(Re(e)))===JSON.stringify(ee(Re(n)))}function Re(e){if(!e||typeof e!=="object"||Array.isArray(e))return e;let n={...e};return delete n.devDependencies,n}function ee(e){if(Array.isArray(e))return e.map(ee);if(e&&typeof e==="object"){let n=e;return Object.fromEntries(Object.keys(n).sort().map((t)=>[t,ee(n[t])]))}return e}function Ie(e,n,t){let r=t?Q.inc(e,n,t):Q.inc(e,n);if(!r)throw new d(i("badSemver",{version:e}));return r}function Oe(e,n,t){let r=new Set(n),s=new Map(e.map((a)=>[a,[]]));for(let a of e)for(let g of t(a))s.get(g)?.push(a);let o=[...n];while(o.length){let a=o.pop();if(!a)break;for(let g of s.get(a)??[]){if(r.has(g))continue;r.add(g),o.push(g)}}return e.filter((a)=>r.has(a))}function He(e,n,t){let r=e.replace("%s",n);return t?`${r} ${t}`:r}function re(e){return e.length>0&&e.every((n)=>Boolean(Q.valid(n.to))&&Q.prerelease(n.to)==null)}function Le(e){return/^v\d/.test(e)}function Ve(e){return/^v\d+\.\d+\.\d+$/.test(e)}function ie(e){let n=[];for(let t of e.split(`
18
- `)){let r=/^(\S+) (\S+) => (\S+)$/.exec(t.trim());if(r)n.push({name:r[1],from:r[2],to:r[3]})}return n}function Ge(e){let n=new Map(e.map((o)=>[o.folder,o])),t=new Set,r=[],s=(o,a)=>{if(t.has(o.folder))return;if(a.has(o.folder))throw new d(i("dependencyCycle",{name:o.name}));a.add(o.folder);for(let g of o.deps){let l=n.get(g);if(l)s(l,a)}a.delete(o.folder),t.add(o.folder),r.push(o)};for(let o of e)s(o,new Set);return r}function K(e){return/ENEEDAUTH|E401|E403|need auth|not logged in|401 Unauthorized|403 Forbidden/i.test(e)}function fe(e){try{return JSON.parse(e)?.error?.code==="E404"}catch{return!1}}var d,ze,je,kn,vn,Pn,Cn="publish@change-versions.com",$n,te;var C=le(()=>{S();d=class d extends Error{auth;constructor(e,n=!1){super(e);this.name="Fail",this.auth=n}};ze=["patch","minor","major","prerelease","prepatch","preminor","premajor"],je=new Set(["patch","minor","major"]),kn=new Set(["prerelease","prepatch","preminor","premajor"]);vn=new Set(["packagesDir","commitMessage","branch","hooks","include","exclude"]),Pn=new Set(["beforeCommit","beforePublish","afterPublish"]);$n=`change-versions <${Cn}>`,te=`Co-authored-by: ${$n}`});import{CommitParser as _n}from"conventional-commits-parser";import{writeChangelogString as Wn}from"conventional-changelog-writer";function ln(e){return e.find((n)=>re(ie(n.body)))?.hash}function mn(e,n,t,r,s,o){let a=`${t}/${n}/package.json`,g=`${t}/${n}/`,l=[];for(let m of e)if(m.files.some((h)=>h!==a&&h.startsWith(g)&&he(h,r,s))||m.files.includes(a)&&o.has(m.hash))l.push({hash:m.hash,body:m.body});return l}async function un(e){let n=new Date().toISOString().slice(0,10),t=[`## ${e.version} (${n})`];if(e.previousTag){let o=`../../compare/${encodeURIComponent(e.previousTag)}...${encodeURIComponent(e.currentTag)}`;t.push(`[${e.previousTag}...${e.currentTag}](${o})`)}let r=new _n({noteKeywords:["BREAKING CHANGE","BREAKING-CHANGE"]}),s=[];for(let o of e.messages){let a;try{a=r.parse(o.body)}catch{continue}s.push({...a,hash:o.hash.slice(0,7),notes:a.notes??[],subject:a.subject})}if(s.length){let a=(await Wn(s,{version:e.version,date:n},{groupBy:"type",mainTemplate:Kn,transform(g){let m=(g.notes??[]).some((h)=>/breaking/i.test(h.title)),u=g.type??"";if(Un.has(u)&&!m)return null;if(!gn[u]&&!m)return null;return{type:gn[u]??null}}})).trim();if(a)t.push("",a);else if(e.dependencies.length)t.push("",dn(e.dependencies))}else if(e.dependencies.length)t.push("",dn(e.dependencies).trimEnd());return`${t.join(`
16
+ {detail}`},beforePublishDirty:{zh:"beforePublish 改了被跟踪的文件。下一步: hook 只能改 git 忽略的构建产物,弄干净后重跑 publish",en:"beforePublish changed tracked files. Next: the hook may only change gitignored build output. Clean the tree, then rerun publish"},afterPublishDirty:{zh:"afterPublish 改了被跟踪的文件,还没打 git tag。下一步: 让 hook 不改被跟踪的文件,弄干净后重跑 publish",en:"afterPublish changed tracked files, so no git tag was created. Next: keep the hook off tracked files, clean the tree, then rerun publish"},configUnreadable:{zh:"配置读不了: {file}。下一步: 补上 include,删掉不认识的字段",en:"Cannot read config: {file}. Next: add include and remove unknown fields"},packagesDirMissing:{zh:"找不到目录 {dir}",en:"Directory not found: {dir}"},packageJsonIncomplete:{zh:"{folder} 的 package.json 缺少 name 或 version",en:"{folder} package.json is missing name or version"},publicDependsOnPrivate:{zh:"public 包 {name} 不能依赖 private 包 {dep}。下一步: 改依赖后重跑 version",en:"Public package {name} cannot depend on private package {dep}. Next: change the dependency, then rerun version"},missingVersionField:{zh:"{folder} 缺少 version",en:"{folder} is missing version"},badBump:{zh:"档位非法: {bump}。可用 {list}",en:"Invalid bump: {bump}. Use {list}"},preidRequired:{zh:"{kind} 必须带 --preid。预发布用 prepatch 这类档位",en:"{kind} requires --preid. Use a pre* bump for prereleases"},preidForbidden:{zh:"正式版不能带 --preid。预发布用 prepatch 这类档位",en:"A stable bump cannot take --preid. Use a pre* bump for prereleases"},badLine:{zh:"第 {line} 行无法解析",en:"Cannot parse line {line}"},unknownField:{zh:"不认识的字段 {name}",en:"Unknown field {name}"},missingValue:{zh:"{name} 缺少值",en:"{name} is missing a value"},includeRequired:{zh:"include 不能为空。下一步: 补上 include,删掉不认识的字段",en:"include must not be empty. Next: add include and remove unknown fields"},commitMessageNeedsToken:{zh:"commitMessage 需要 %s",en:"commitMessage must contain %s"},patternBang:{zh:"模式不能包含 !: {pattern}",en:"Patterns cannot contain !: {pattern}"},patternClass:{zh:"不支持字符组: {pattern}",en:"Character classes are not supported: {pattern}"},badHook:{zh:"hooks 无法解析: {line}",en:"Cannot parse hooks: {line}"},unknownHook:{zh:"不认识的 hook {name}",en:"Unknown hook {name}"},hookMissingCommand:{zh:"{name} 缺少命令",en:"{name} is missing a command"},badPatternLine:{zh:"路径列表无法解析: {line}",en:"Cannot parse path list: {line}"},badSemver:{zh:"无法解析版本 {version}",en:"Cannot parse version {version}"},dependencyCycle:{zh:"依赖成环: {name}",en:"Dependency cycle: {name}"},bumpRequired:{zh:"非交互环境必须写上档位",en:"A bump is required when not interactive"},chooseIndex:{zh:"请输入序号: ",en:"Enter a number: "},invalidChoice:{zh:"无效选择: {answer}",en:"Invalid choice: {answer}"},emptyAnswer:{zh:"(空)",en:"(empty)"},yesRequired:{zh:"非交互环境需要 --yes",en:"Pass --yes when not interactive"},commandFailed:{zh:"{command} 失败: {detail}",en:"{command} failed: {detail}"},commandFailedShort:{zh:"{command} 失败",en:"{command} failed"},commandExit:{zh:"{command} 退出 {code}",en:"{command} exited {code}"},cliDescription:{zh:"只给需要发的包升版本,再按那次提交发布",en:"Version only the packages that need a release, then publish that commit"},optRoot:{zh:"仓库根目录",en:"Repository root"},optVersionsFile:{zh:"配置文件",en:"Config file"},optPackages:{zh:"覆盖 packagesDir",en:"Override packagesDir"},cmdChanged:{zh:"列出会升版的包",en:"List packages that would be versioned"},optBaseline:{zh:"这一次的比较起点,SHA 或 tag",en:"Comparison start for this run, SHA or tag"},cmdVersion:{zh:"升版本并提交",en:"Bump versions and commit"},argBump:{zh:"patch、minor、major、prerelease、prepatch、preminor、premajor",en:"patch, minor, major, prerelease, prepatch, preminor, or premajor"},optPreid:{zh:"预发布标识,pre* 必填",en:"Prerelease identifier, required for pre*"},optYes:{zh:"跳过确认",en:"Skip confirmation"},optDryRunVersion:{zh:"只打印旧版本到新版本",en:"Print old and new versions only"},optBranch:{zh:"覆盖配置里的 branch",en:"Override branch from the config"},optCommitMessage:{zh:"覆盖 commitMessage",en:"Override commitMessage"},cmdPublish:{zh:"发布最近一次 version 提交里的包",en:"Publish packages listed in the latest version commit"},optDistTag:{zh:"npm dist-tag",en:"npm dist-tag"},optDryRunPublish:{zh:"查询 registry 并预览计划;不执行 hook、上传、标签修改或推送",en:"Query the registry and preview the plan without hooks, uploads, tag changes or pushes"},cmdInit:{zh:"写入带注释的配置",en:"Write a commented config file"},optYesInit:{zh:"不提问,按探测到的目录写默认配置",en:"Write defaults from the detected directory, without prompts"},configExists:{zh:"已有 {file}。下一步: 直接改这个文件,或删掉后重跑 init",en:"Config already exists: {file}. Next: edit that file, or delete it and rerun init"},initIntro:{zh:"写入 {file}",en:"Write {file}"},initFoundDirs:{zh:"发现包目录: {dirs}",en:"Package directories: {dirs}"},initPackagesDir:{zh:"包目录",en:"Package directory"},initInclude:{zh:"源码路径,逗号分隔",en:"Source paths, comma-separated"},initExclude:{zh:"排除路径,逗号分隔",en:"Excluded paths, comma-separated"},initBranch:{zh:"推送分支,回车跳过",en:"Branch to push, Enter to skip"},initBeforeCommit:{zh:"beforeCommit,回车跳过",en:"beforeCommit, Enter to skip"},initBeforePublish:{zh:"beforePublish,回车跳过",en:"beforePublish, Enter to skip"},initWrote:{zh:"已写入 {file}",en:"Wrote {file}"},initNotePackagesDir:{zh:"包所在目录。这次可用 --packages 覆盖",en:"Directory of packages. Override once with --packages"},initNoteCommitMessage:{zh:"%s 换成档位。有 --preid 时再空一格接上,例如 bump: prerelease alpha。查找看正文末尾的 Co-authored-by: change-versions <publish@change-versions.com>,不改提交作者",en:"%s becomes the bump. With --preid, a space and the id follow, for example bump: prerelease alpha. Lookup uses the Co-authored-by: change-versions <publish@change-versions.com> trailer. The commit author stays unchanged"},initNoteBranch:{zh:"不写就不推送。version 只推这个分支,不推 tag",en:"Omit to skip pushing. version pushes this branch only, not tags"},initNoteBeforeCommit:{zh:"版本和 CHANGELOG 写完之后、git commit 之前。失败会退回 HEAD",en:"After versions and CHANGELOG are written, before git commit. Failure restores HEAD"},initNoteBeforePublish:{zh:"确认之后、npm publish 之前。只能改 git 忽略的构建产物",en:"After confirm, before npm publish. May only change gitignored build output"},initNoteAfterPublish:{zh:"要发的包都已在 registry 上之后。不能把工作区弄脏",en:"After every selected package is on the registry. Must leave the tree clean"},initNoteInclude:{zh:"相对仓库根。* 和 ? 不跨过 /,** 可以。命中目录时,目录里的文件也算",en:"Relative to the repo root. * and ? do not cross /, ** may. A matching directory includes files under it"},initNoteExclude:{zh:"命中这里的文件不触发升版。package.json 另比,去掉 devDependencies 后有差异才算",en:"Files that match here do not trigger a bump. package.json is compared separately, after dropping devDependencies"}}});import je from"picomatch";import ie from"semver";import{YAMLParseError as Sn,parse as $n}from"yaml";function ve(e){return Me.has(e)}function Oe(e,n){if(!Ae.includes(e))throw new g(i("badBump",{bump:e,list:Ae.join(", ")}));let t=e;if(zn.has(t)&&!n)throw new g(i("preidRequired",{kind:t}));if(Me.has(t)&&n)throw new g(i("preidForbidden"));return t}function oe(e){let n=Nn(e);for(let l of Object.keys(n))if(!Dn.has(l))throw new g(i("unknownField",{name:l}));let t=n.packagesDir===void 0?"packages":we(n.packagesDir,"packagesDir"),r=n.commitMessage===void 0?"bump: %s":we(n.commitMessage,"commitMessage"),s=n.branch===void 0?void 0:we(n.branch,"branch"),o=n.hooks==null?{}:Tn(n.hooks),c=n.include==null?[]:Ee(n.include,"include"),d=n.exclude==null?[]:Ee(n.exclude,"exclude");if(!c.length)throw new g(i("includeRequired"));if(!r.includes("%s"))throw new g(i("commitMessageNeedsToken"));for(let l of[...c,...d]){if(l.includes("!"))throw new g(i("patternBang",{pattern:l}));if(/\[[^\]]+\]/.test(l))throw new g(i("patternClass",{pattern:l}))}return{packagesDir:t,commitMessage:r,branch:s,hooks:o,include:c,exclude:d}}function Nn(e){try{let n=$n(e);if(n==null)return{};if(!He(n))throw new g(i("badLine",{line:1}));return n}catch(n){if(n instanceof g)throw n;if(n instanceof Sn)throw new g(i("badLine",{line:n.linePos?.[0]?.line??1}));throw n}}function Tn(e){if(!He(e))throw new g(i("badHook",{line:"hooks"}));let n={};for(let[t,r]of Object.entries(e)){if(!Rn.has(t))throw new g(i("unknownHook",{name:t}));if(typeof r!=="string"||!r)throw new g(i("hookMissingCommand",{name:t}));n[t]=r}return n}function Ee(e,n){if(!Array.isArray(e))throw new g(i("badPatternLine",{line:n}));return e.map((t)=>{if(typeof t!=="string"||!t)throw new g(i("badPatternLine",{line:n}));return t})}function we(e,n){if(typeof e!=="string"||!e)throw new g(i("missingValue",{name:n}));return e}function He(e){return Boolean(e)&&typeof e==="object"&&!Array.isArray(e)}function Be(e,n){let t={dot:!0};if(je(n,t)(e))return!0;if(n.endsWith("/**"))return!1;return je(`${n}/**`,t)(e)}function ke(e,n,t){return n.some((r)=>Be(e,r))&&!t.some((r)=>Be(e,r))}function Le(e,n,t){let r=new Set(t),s=`${n}/`,o=new Map;for(let c of e.split(`
17
+ `)){if(!c.startsWith(s))continue;let d=c.slice(s.length),l=d.split("/")[0];if(!l||!d.includes("/")||!r.has(l))continue;let u=o.get(l)??[];u.push(c),o.set(l,u)}return o}function Ve(e,n,t,r,s,o){let c=[],d=[];for(let l of e){let u=n.get(l);if(!u?.length){d.push(l);continue}let m=`${o}/${l}/package.json`;if(u.some((P)=>P!==m&&ke(P,t,r))||u.includes(m)&&!s(l))c.push(l);else d.push(l)}return{changed:c,ignored:d}}function Ge(e,n){return JSON.stringify(se(Ie(e)))===JSON.stringify(se(Ie(n)))}function Ie(e){if(!e||typeof e!=="object"||Array.isArray(e))return e;let n={...e};return delete n.devDependencies,n}function se(e){if(Array.isArray(e))return e.map(se);if(e&&typeof e==="object"){let n=e;return Object.fromEntries(Object.keys(n).sort().map((t)=>[t,se(n[t])]))}return e}function qe(e,n,t){let r=t?ie.inc(e,n,t):ie.inc(e,n);if(!r)throw new g(i("badSemver",{version:e}));return r}function _e(e,n,t){let r=new Set(n),s=new Map(e.map((c)=>[c,[]]));for(let c of e)for(let d of t(c))s.get(d)?.push(c);let o=[...n];while(o.length){let c=o.pop();if(!c)break;for(let d of s.get(c)??[]){if(r.has(d))continue;r.add(d),o.push(d)}}return e.filter((c)=>r.has(c))}function Je(e,n,t){let r=e.replace("%s",n);return t?`${r} ${t}`:r}function ce(e){return e.length>0&&e.every((n)=>Boolean(ie.valid(n.to))&&ie.prerelease(n.to)==null)}function We(e){return/^v\d/.test(e)}function Ue(e){return/^v\d+\.\d+\.\d+$/.test(e)}function ge(e){let n=[];for(let t of e.split(`
18
+ `)){let r=/^(\S+) (\S+) => (\S+)$/.exec(t.trim());if(r)n.push({name:r[1],from:r[2],to:r[3]})}return n}function Ke(e){let n=new Map(e.map((o)=>[o.folder,o])),t=new Set,r=[],s=(o,c)=>{if(t.has(o.folder))return;if(c.has(o.folder))throw new g(i("dependencyCycle",{name:o.name}));c.add(o.folder);for(let d of o.deps){let l=n.get(d);if(l)s(l,c)}c.delete(o.folder),t.add(o.folder),r.push(o)};for(let o of e)s(o,new Set);return r}function Z(e){return/ENEEDAUTH|E401|E403|need auth|not logged in|401 Unauthorized|403 Forbidden/i.test(e)}function Pe(e){try{return JSON.parse(e)?.error?.code==="E404"}catch{return!1}}var g,Ae,Me,zn,Dn,Rn,Fn="publish@change-versions.com",jn,ae;var D=be(()=>{z();g=class g extends Error{auth;constructor(e,n=!1){super(e);this.name="Fail",this.auth=n}};Ae=["patch","minor","major","prerelease","prepatch","preminor","premajor"],Me=new Set(["patch","minor","major"]),zn=new Set(["prerelease","prepatch","preminor","premajor"]);Dn=new Set(["packagesDir","commitMessage","branch","hooks","include","exclude"]),Rn=new Set(["beforeCommit","beforePublish","afterPublish"]);jn=`change-versions <${Fn}>`,ae=`Co-authored-by: ${jn}`});import{CommitParser as Xn}from"conventional-commits-parser";import{writeChangelogString as et}from"conventional-changelog-writer";function yn(e){return e.find((n)=>ce(ge(n.body)))?.hash}function wn(e,n,t,r,s,o){let c=`${t}/${n}/package.json`,d=`${t}/${n}/`,l=[];for(let u of e)if(u.files.some((p)=>p!==c&&p.startsWith(d)&&ke(p,r,s))||u.files.includes(c)&&o.has(u.hash))l.push({hash:u.hash,body:u.body});return l}async function vn(e){let n=new Date().toISOString().slice(0,10),t=[`## ${e.version} (${n})`];if(e.previousTag){let o=`../../compare/${encodeURIComponent(e.previousTag)}...${encodeURIComponent(e.currentTag)}`;t.push(`[${e.previousTag}...${e.currentTag}](${o})`)}let r=new Xn({noteKeywords:["BREAKING CHANGE","BREAKING-CHANGE"]}),s=[];for(let o of e.messages){let c;try{c=r.parse(o.body)}catch{continue}s.push({...c,hash:o.hash.slice(0,7),notes:c.notes??[],subject:c.subject})}if(s.length){let c=(await et(s,{version:e.version,date:n},{groupBy:"type",mainTemplate:tt,transform(d){let u=(d.notes??[]).some((p)=>/breaking/i.test(p.title)),m=d.type??"";if(nt.has(m)&&!u)return null;if(!fn[m]&&!u)return null;return{type:fn[m]??null}}})).trim();if(c)t.push("",c);else if(e.dependencies.length)t.push("",bn(e.dependencies))}else if(e.dependencies.length)t.push("",bn(e.dependencies).trimEnd());return`${t.join(`
19
19
  `).trim()}
20
- `}function dn(e){return`### Dependencies
20
+ `}function bn(e){return`### Dependencies
21
21
 
22
22
  * update dependencies ${e.map((n)=>`${n.name}@${n.version}`).join(", ")}
23
- `}var Un,gn,Kn=`{{#each commitGroups}}
23
+ `}var nt,fn,tt=`{{#each commitGroups}}
24
24
  {{#if title}}
25
25
  ### {{title}}
26
26
 
@@ -38,18 +38,18 @@ var le=(e,n,t)=>()=>{if(e)try{n=e(e=0)}catch(r){t=[r]}if(t)throw t[0];return n};
38
38
  {{/each}}
39
39
 
40
40
  {{/each}}
41
- `;var pn=le(()=>{C();Un=new Set(["docs","style","chore","refactor","test","build","ci"]),gn={feat:"Features",feature:"Features",fix:"Bug Fixes",perf:"Performance Improvements",revert:"Reverts"}});import{Command as st}from"commander";import{readFileSync as ot}from"node:fs";import Fn from"node:path";import{styleText as fn}from"node:util";function R(e,n,t){return fn(e,n,{stream:t})}function x(e){return R(["bold","cyan"],e,process.stdout)}function j(e){return R("bold",e,process.stdout)}function T(e){return R("green",e,process.stdout)}function v(e){return R("dim",e,process.stdout)}function U(e){return R("cyan",e,process.stdout)}function $e(e,n,t){return`${j(e)} ${v(n)} ${v("=>")} ${T(t)}`}function V(e){let[n,...t]=e.split(`
42
- `),r=R("red",n,process.stderr);if(!t.length)return r;return[r,...t.map((s)=>R("yellow",s,process.stderr))].join(`
43
- `)}S();S();C();import{spawn as Je,spawnSync as qe}from"node:child_process";function b(e,n,t){return new Promise((r)=>{let s=Je(e,n,{cwd:t,stdio:["ignore","pipe","pipe"]}),o="",a="";s.stdout.on("data",(g)=>{o+=g}),s.stderr.on("data",(g)=>{a+=g}),s.on("error",(g)=>r({code:1,stdout:o,stderr:`${a}${g.message}`})),s.on("close",(g)=>r({code:g??1,stdout:o,stderr:a}))})}async function y(e,n,t){let r=await b(e,n,t);if(r.code!==0){let s=(r.stderr||r.stdout).trim();throw new d(s?i("commandFailed",{command:e,detail:s}):i("commandFailedShort",{command:e}))}return r.stdout}function se(e,n,t,r){return new Promise((s,o)=>{let a=Je(e,n,{cwd:t,stdio:"inherit",env:{...process.env,...r}});a.on("error",o),a.on("exit",(g)=>{if(g===0)s();else o(new d(i("commandExit",{command:e,code:g??1})))})})}function be(e,n="HEAD"){qe("git",["reset","--hard",n],{cwd:e,stdio:"inherit"}),qe("git",["clean","-fd"],{cwd:e,stdio:"inherit"})}S();C();import G from"node:fs";import oe from"node:path";S();C();function _e(e){let n=e.packages.map((l)=>l.folder),t=new Map(e.packages.map((l)=>[l.folder,l])),r=new Map(e.packages.map((l)=>[l.name,l])),s=new Map(e.packages.map((l)=>[l.name,l.folder])),{changed:o}=Be(n,e.filesByFolder,e.include,e.exclude,(l)=>e.devOnly.has(l),e.packagesDir),a=Oe(n,o,(l)=>Dn(t.get(l),s));for(let l of a){let m=t.get(l);if(!m||m.private)continue;for(let u of Object.keys(m.dependencies??{}))if(r.get(u)?.private)throw new d(i("publicDependsOnPrivate",{name:m.name,dep:u}))}let g=new Set(o);return{changed:o,dependents:a.filter((l)=>!g.has(l))}}function Dn(e,n){if(!e)return[];return[...Object.keys(e.dependencies??{}),...Object.keys(e.devDependencies??{})].flatMap((r)=>{let s=n.get(r);return s?[s]:[]})}function q(e,n){let t=oe.resolve(e,n);if(!G.existsSync(t))throw new d(i("configUnreadable",{file:n}));return ne(G.readFileSync(t,"utf8"))}function J(e,n){let t=oe.join(e,n);if(!G.existsSync(t))throw new d(i("packagesDirMissing",{dir:n}));return G.readdirSync(t).filter((r)=>!r.startsWith(".")&&G.existsSync(oe.join(t,r,"package.json")))}function k(e,n,t){let r=JSON.parse(G.readFileSync(oe.join(e,n,t,"package.json"),"utf8"));if(!r.name||!r.version)throw new d(i("packageJsonIncomplete",{folder:t}));return r}function ae(e,n){let t=[];for(let r of["dependencies","devDependencies"])for(let s of Object.keys(e[r]??{})){let o=n.get(s);if(o)t.push(o)}return t}async function _(e){let n=await b("git",["status","--porcelain"],e);if(n.code!==0)throw new d(i("gitFailed",{detail:n.stderr.trim()}));if(n.stdout.trim())throw new d(i("dirtyTree"))}async function ye(e,n){let t=await b("git",["status","--porcelain"],e);if(t.code!==0)throw new d(i("gitFailed",{detail:t.stderr.trim()}));if(t.stdout.trim())throw new d(n)}async function we(e){return(await y("git",["log","--format=%H%x1f%s"],e)).split(`
44
- `).filter(Boolean).map((t)=>{let[r,s]=t.split("\x1F");return{hash:r,subject:s??""}})}async function Y(e){let n=await y("git",["log","-F",`--grep=${te}`,"--format=%H%x1f%s%x1f%b%x1e"],e),t=[];for(let r of n.split("\x1E")){let s=r.replace(/^\n/,"").trim();if(!s)continue;let[o,a,g]=s.split("\x1F");if(!o)continue;t.push({hash:o,subject:a??"",body:g??""})}return t}async function ke(e,n){if(n){let o=await b("git",["rev-parse","--verify",`${n}^{commit}`],e);if(o.code!==0)throw new d(i("badBaseline",{rev:n}));return o.stdout.trim()}if((await b("git",["rev-parse","--verify","HEAD"],e)).code!==0)throw new d(i("noBaseline"));let r=await Y(e);if(r[0])return r[0].hash;return(await we(e)).find((o)=>Le(o.subject))?.hash??zn()}async function ce(e,n,t){let r=await ke(e,t),s=J(e,n.packagesDir),o=await y("git",["diff","--name-only",r,"HEAD"],e),a=Ae(o,n.packagesDir,s),g=new Set;for(let[u,h]of a){let w=`${n.packagesDir}/${u}/package.json`;if(h.includes(w)&&await ve(e,r,"HEAD",w))g.add(u)}let{changed:l,dependents:m}=_e({packages:s.map((u)=>({...k(e,n.packagesDir,u),folder:u})),filesByFolder:a,devOnly:g,include:n.include,exclude:n.exclude,packagesDir:n.packagesDir});return{baseline:r,changed:l,dependents:m}}async function ve(e,n,t,r){let s=await We(e,`${n}:${r}`),o=await We(e,`${t}:${r}`);if(s===null||o===null)return!1;try{return Me(JSON.parse(s),JSON.parse(o))}catch{return!1}}async function We(e,n){let t=await b("git",["show",n],e);return t.code===0?t.stdout:null}function zn(){throw new d(i("noBaseline"))}async function Ue(e){let n=Fn.resolve(e.root),t=q(n,e.versionsFile);if(e.packages)t.packagesDir=e.packages;await _(n);let{baseline:r,changed:s,dependents:o}=await ce(n,t,e.baseline);if(!s.length&&!o.length){let a=(await y("git",["rev-parse","--short",r],n)).trim();console.log(v(i("noPackagesSince",{rev:a})));return}console.log(x(i("changedHeader")));for(let a of s)console.log(` ${j(k(n,t.packagesDir,a).name)}`);if(o.length){console.log(x(i("dependentsHeader")));for(let a of o)console.log(` ${T(k(n,t.packagesDir,a).name)}`)}}import D from"node:fs";import A from"node:path";S();C();import Nn from"node:readline/promises";import{stdin as Ke,stdout as Ye}from"node:process";S();C();function Pe(e){let n=Nn.createInterface({input:Ke,output:Ye});return n.question(e).finally(()=>n.close())}function X(){return Boolean(Ke.isTTY&&Ye.isTTY)}async function Xe(e,n){if(!X())throw new d(i("bumpRequired"));console.log(x(e)),n.forEach((s,o)=>{console.log(` ${j(String(o+1))}) ${s}`)});let t=(await Pe(i("chooseIndex"))).trim(),r=Number(t)-1;if(!Number.isInteger(r)||r<0||r>=n.length)throw new d(i("invalidChoice",{answer:t||i("emptyAnswer")}));return n[r]}async function E(e,n=""){if(!X())throw new d(i("yesRequired"));let t=n?` [${n}]`:"";return(await Pe(`${e}${t} `)).trim()||n}async function ge(e){if(!X())throw new d(i("yesRequired"));console.log(x(e));let n=(await Pe("[y/N] ")).trim().toLowerCase();return n==="y"||n==="yes"}function Rn(e){let n=new Set,t=[];for(let r of[...An(e),...Bn(e)]){if(n.has(r))continue;n.add(r),t.push(r)}return t}function jn(e,n=me()){let t=(o,a="")=>i(o,void 0,n).split(`
45
- `).map((g)=>`${a}# ${g}`).join(`
46
- `),r=(o,a,g,l)=>[t(l," "),a?` ${o}: ${Z(a)}`:` # ${o}: ${g}`].join(`
47
- `),s=[t("initNotePackagesDir"),`packagesDir: ${Z(e.packagesDir)}`,"",t("initNoteCommitMessage"),'commitMessage: "bump: %s"',"",t("initNoteBranch"),e.branch?`branch: ${Z(e.branch)}`:"# branch: main","","hooks:",r("beforeCommit",e.beforeCommit,"bun install","initNoteBeforeCommit"),r("beforePublish",e.beforePublish,"bun run build","initNoteBeforePublish"),r("afterPublish",void 0,"echo published","initNoteAfterPublish"),"",t("initNoteInclude"),"include:",...e.include.map((o)=>` - ${Z(o)}`),` # - ${e.packagesDir}/*/bin`,"",t("initNoteExclude")];if(e.exclude.length)s.push("exclude:",...e.exclude.map((o)=>` - ${Z(o)}`));else s.push("# exclude:",`# - ${e.packagesDir}/*/src/**/__tests__/**`);return`${s.join(`
41
+ `;var kn=be(()=>{D();nt=new Set(["docs","style","chore","refactor","test","build","ci"]),fn={feat:"Features",feature:"Features",fix:"Bug Fixes",perf:"Performance Improvements",revert:"Reverts"}});import{Command as ut}from"commander";import{readFileSync as mt}from"node:fs";import Bn from"node:path";import{styleText as xn}from"node:util";function N(e,n,t){return xn(e,n,{stream:t})}function w(e){return N(["bold","cyan"],e,process.stdout)}function T(e){return N("bold",e,process.stdout)}function M(e){return N("green",e,process.stdout)}function y(e){return N("dim",e,process.stdout)}function A(e){return N("cyan",e,process.stdout)}function Fe(e,n,t){return`${T(e)} ${y(n)} ${y("=>")} ${M(t)}`}function q(e){let[n,...t]=e.split(`
42
+ `),r=N("red",n,process.stderr);if(!t.length)return r;return[r,...t.map((s)=>N("yellow",s,process.stderr))].join(`
43
+ `)}function _(e){return N("green",e,process.stdout)}function S(e){return N("yellow",e,process.stdout)}function re(e){return N("red",e,process.stdout)}z();z();D();import{spawn as Qe,spawnSync as Ye}from"node:child_process";function b(e,n,t){return new Promise((r)=>{let s=Qe(e,n,{cwd:t,stdio:["ignore","pipe","pipe"]}),o="",c="";s.stdout.on("data",(d)=>{o+=d}),s.stderr.on("data",(d)=>{c+=d}),s.on("error",(d)=>r({code:1,stdout:o,stderr:`${c}${d.message}`})),s.on("close",(d)=>r({code:d??1,stdout:o,stderr:c}))})}async function v(e,n,t){let r=await b(e,n,t);if(r.code!==0){let s=(r.stderr||r.stdout).trim();throw new g(s?i("commandFailed",{command:e,detail:s}):i("commandFailedShort",{command:e}))}return r.stdout}function le(e,n,t,r){return new Promise((s,o)=>{let c=Qe(e,n,{cwd:t,stdio:"inherit",env:{...process.env,...r}});c.on("error",o),c.on("exit",(d)=>{if(d===0)s();else o(new g(i("commandExit",{command:e,code:d??1})))})})}function xe(e,n="HEAD"){Ye("git",["reset","--hard",n],{cwd:e,stdio:"inherit"}),Ye("git",["clean","-fd"],{cwd:e,stdio:"inherit"})}z();D();import J from"node:fs";import de from"node:path";z();D();function Ze(e){let n=e.packages.map((l)=>l.folder),t=new Map(e.packages.map((l)=>[l.folder,l])),r=new Map(e.packages.map((l)=>[l.name,l])),s=new Map(e.packages.map((l)=>[l.name,l.folder])),{changed:o}=Ve(n,e.filesByFolder,e.include,e.exclude,(l)=>e.devOnly.has(l),e.packagesDir),c=_e(n,o,(l)=>An(t.get(l),s));for(let l of c){let u=t.get(l);if(!u||u.private)continue;for(let m of Object.keys(u.dependencies??{}))if(r.get(m)?.private)throw new g(i("publicDependsOnPrivate",{name:u.name,dep:m}))}let d=new Set(o);return{changed:o,dependents:c.filter((l)=>!d.has(l))}}function An(e,n){if(!e)return[];return[...Object.keys(e.dependencies??{}),...Object.keys(e.devDependencies??{})].flatMap((r)=>{let s=n.get(r);return s?[s]:[]})}function W(e,n){let t=de.resolve(e,n);if(!J.existsSync(t))throw new g(i("configUnreadable",{file:n}));return oe(J.readFileSync(t,"utf8"))}function U(e,n){let t=de.join(e,n);if(!J.existsSync(t))throw new g(i("packagesDirMissing",{dir:n}));return J.readdirSync(t).filter((r)=>!r.startsWith(".")&&J.existsSync(de.join(t,r,"package.json")))}function k(e,n,t){let r=JSON.parse(J.readFileSync(de.join(e,n,t,"package.json"),"utf8"));if(!r.name||!r.version)throw new g(i("packageJsonIncomplete",{folder:t}));return r}function ue(e,n){let t=[];for(let r of["dependencies","devDependencies"])for(let s of Object.keys(e[r]??{})){let o=n.get(s);if(o)t.push(o)}return t}async function K(e){let n=await b("git",["status","--porcelain"],e);if(n.code!==0)throw new g(i("gitFailed",{detail:n.stderr.trim()}));if(n.stdout.trim())throw new g(i("dirtyTree"))}async function Ce(e,n){let t=await b("git",["status","--porcelain"],e);if(t.code!==0)throw new g(i("gitFailed",{detail:t.stderr.trim()}));if(t.stdout.trim())throw new g(n)}async function Se(e){return(await v("git",["log","--format=%H%x1f%s"],e)).split(`
44
+ `).filter(Boolean).map((t)=>{let[r,s]=t.split("\x1F");return{hash:r,subject:s??""}})}async function X(e){let n=await v("git",["log","-F",`--grep=${ae}`,"--format=%H%x1f%s%x1f%b%x1e"],e),t=[];for(let r of n.split("\x1E")){let s=r.replace(/^\n/,"").trim();if(!s)continue;let[o,c,d]=s.split("\x1F");if(!o)continue;t.push({hash:o,subject:c??"",body:d??""})}return t}async function $e(e,n){if(n){let o=await b("git",["rev-parse","--verify",`${n}^{commit}`],e);if(o.code!==0)throw new g(i("badBaseline",{rev:n}));return o.stdout.trim()}if((await b("git",["rev-parse","--verify","HEAD"],e)).code!==0)throw new g(i("noBaseline"));let r=await X(e);if(r[0])return r[0].hash;return(await Se(e)).find((o)=>We(o.subject))?.hash??En()}async function me(e,n,t){let r=await $e(e,t),s=U(e,n.packagesDir),o=await v("git",["diff","--name-only",r,"HEAD"],e),c=Le(o,n.packagesDir,s),d=new Set;for(let[m,p]of c){let P=`${n.packagesDir}/${m}/package.json`;if(p.includes(P)&&await ze(e,r,"HEAD",P))d.add(m)}let{changed:l,dependents:u}=Ze({packages:s.map((m)=>({...k(e,n.packagesDir,m),folder:m})),filesByFolder:c,devOnly:d,include:n.include,exclude:n.exclude,packagesDir:n.packagesDir});return{baseline:r,changed:l,dependents:u}}async function ze(e,n,t,r){let s=await Xe(e,`${n}:${r}`),o=await Xe(e,`${t}:${r}`);if(s===null||o===null)return!1;try{return Ge(JSON.parse(s),JSON.parse(o))}catch{return!1}}async function Xe(e,n){let t=await b("git",["show",n],e);return t.code===0?t.stdout:null}function En(){throw new g(i("noBaseline"))}async function en(e){let n=Bn.resolve(e.root),t=W(n,e.versionsFile);if(e.packages)t.packagesDir=e.packages;await K(n);let{baseline:r,changed:s,dependents:o}=await me(n,t,e.baseline);if(!s.length&&!o.length){let c=(await v("git",["rev-parse","--short",r],n)).trim();console.log(y(i("noPackagesSince",{rev:c})));return}console.log(w(i("changedHeader")));for(let c of s)console.log(` ${T(k(n,t.packagesDir,c).name)}`);if(o.length){console.log(w(i("dependentsHeader")));for(let c of o)console.log(` ${M(k(n,t.packagesDir,c).name)}`)}}import R from"node:fs";import H from"node:path";z();D();import In from"node:readline/promises";import{stdin as nn,stdout as tn}from"node:process";z();D();function De(e){let n=In.createInterface({input:nn,output:tn});return n.question(e).finally(()=>n.close())}function ee(){return Boolean(nn.isTTY&&tn.isTTY)}async function rn(e,n){if(!ee())throw new g(i("bumpRequired"));console.log(w(e)),n.forEach((s,o)=>{console.log(` ${T(String(o+1))}) ${s}`)});let t=(await De(i("chooseIndex"))).trim(),r=Number(t)-1;if(!Number.isInteger(r)||r<0||r>=n.length)throw new g(i("invalidChoice",{answer:t||i("emptyAnswer")}));return n[r]}async function O(e,n=""){if(!ee())throw new g(i("yesRequired"));let t=n?` [${n}]`:"";return(await De(`${e}${t} `)).trim()||n}async function pe(e){if(!ee())throw new g(i("yesRequired"));console.log(w(e));let n=(await De("[y/N] ")).trim().toLowerCase();return n==="y"||n==="yes"}function Mn(e){let n=new Set,t=[];for(let r of[...Vn(e),...Gn(e)]){if(n.has(r))continue;n.add(r),t.push(r)}return t}function On(e,n=ye()){let t=(o,c="")=>i(o,void 0,n).split(`
45
+ `).map((d)=>`${c}# ${d}`).join(`
46
+ `),r=(o,c,d,l)=>[t(l," "),c?` ${o}: ${ne(c)}`:` # ${o}: ${d}`].join(`
47
+ `),s=[t("initNotePackagesDir"),`packagesDir: ${ne(e.packagesDir)}`,"",t("initNoteCommitMessage"),'commitMessage: "bump: %s"',"",t("initNoteBranch"),e.branch?`branch: ${ne(e.branch)}`:"# branch: main","","hooks:",r("beforeCommit",e.beforeCommit,"bun install","initNoteBeforeCommit"),r("beforePublish",e.beforePublish,"bun run build","initNoteBeforePublish"),r("afterPublish",void 0,"echo published","initNoteAfterPublish"),"",t("initNoteInclude"),"include:",...e.include.map((o)=>` - ${ne(o)}`),` # - ${e.packagesDir}/*/bin`,"",t("initNoteExclude")];if(e.exclude.length)s.push("exclude:",...e.exclude.map((o)=>` - ${ne(o)}`));else s.push("# exclude:",`# - ${e.packagesDir}/*/src/**/__tests__/**`);return`${s.join(`
48
48
  `)}
49
- `}async function Qe(e){let n=A.resolve(e.root),t=A.resolve(n,e.versionsFile);if(D.existsSync(t))throw new d(i("configExists",{file:e.versionsFile}));let r=Rn(n),s=r[0]??"packages",o=e.yes?Tn(s):await En(e.versionsFile,r,s);if(!o.include.length)throw new d(i("includeRequired"));let a=jn(o);ne(a),D.mkdirSync(A.dirname(t),{recursive:!0}),D.writeFileSync(t,a),console.log(T(i("initWrote",{file:e.versionsFile})))}function Tn(e){return{packagesDir:e,include:[`${e}/*/src`],exclude:[`${e}/*/src/**/__tests__/**`]}}async function En(e,n,t){if(!X())throw new d(i("yesRequired"));if(console.log(x(i("initIntro",{file:e}))),n.length)console.log(v(i("initFoundDirs",{dirs:n.join(", ")})));let r=await E(i("initPackagesDir"),t),s=Ze(await E(i("initInclude"),`${r}/*/src`)),o=Ze(await E(i("initExclude"),`${r}/*/src/**/__tests__/**`)),a=await E(i("initBranch")),g=await E(i("initBeforeCommit")),l=await E(i("initBeforePublish"));return{packagesDir:r,branch:a||void 0,beforeCommit:g||void 0,beforePublish:l||void 0,include:s,exclude:o}}function Ze(e){return e.split(",").map((n)=>n.trim()).filter(Boolean)}function Z(e){return/^[A-Za-z0-9_./@*+-]+$/.test(e)?e:JSON.stringify(e)}function An(e){return In(e).flatMap((n)=>{let t=n.replace(/\/\*\*?$/,"");if(!t||t===n||t.includes("*"))return[];return D.existsSync(A.join(e,t))?[t]:[]})}function Bn(e){if(!D.existsSync(e))return[];let n=[];for(let t of D.readdirSync(e)){if(t.startsWith(".")||t==="node_modules")continue;let r=A.join(e,t);if(!D.statSync(r).isDirectory())continue;if(Mn(r))n.push(t)}return n}function Mn(e){return D.readdirSync(e).some((n)=>D.existsSync(A.join(e,n,"package.json")))}function In(e){let n=A.join(e,"package.json");if(!D.existsSync(n))return[];try{let t=JSON.parse(D.readFileSync(n,"utf8")),r=Array.isArray(t.workspaces)?t.workspaces:t.workspaces?.packages;return Array.isArray(r)?r.filter((s)=>typeof s==="string"):[]}catch{return[]}}import xe from"node:path";S();C();C();function en(e){let n=[];if(e.beforePublish)n.push({kind:"hook",name:"beforePublish",command:e.beforePublish});for(let t of Ge(e.packages.filter((r)=>!r.private))){if(t.published&&t.distTagVersion===t.version)continue;let r=t.registry??"";n.push(t.published?{kind:"dist-tag",name:t.name,version:t.version,folder:t.folder,registry:r,tag:e.distTag}:{kind:"publish",name:t.name,version:t.version,folder:t.folder,registry:r,tag:e.distTag})}if(e.afterPublish)n.push({kind:"hook",name:"afterPublish",command:e.afterPublish});if(e.formal)for(let t of e.packages)n.push({kind:"tag",name:t.name,version:t.version,commit:e.commit});return n}async function an(e){let n=xe.resolve(e.root);await _(n);let t=(await y("git",["rev-parse","HEAD"],n)).trim(),r=q(n,e.versionsFile);if(e.packages)r.packagesDir=e.packages;let s=await Hn(n);if(!s?.lines.length)throw new d(i("noVersionCommit"));let o=J(n,r.packagesDir),a=new Map(o.map((c)=>[k(n,r.packagesDir,c).name,c])),g=s.lines.map((c)=>{let p=a.get(c.name);if(!p)throw new d(i("packageNotInDir",{dir:r.packagesDir,name:c.name}));let P=k(n,r.packagesDir,p);if(P.version!==c.to)throw new d(i("releaseVersionMismatch",{name:c.name,expected:c.to,actual:P.version}));return{...c,folder:p,pkg:P,deps:ae(P,a)}}),l=await b("git",["diff","--quiet",s.hash,"HEAD","--",...g.map((c)=>`${r.packagesDir}/${c.folder}`)],n);if(l.code===1)throw new d(i("releaseContentsChanged"));if(l.code!==0)throw new d(i("gitFailed",{detail:l.stderr.trim()}));let m=re(s.lines);if(m)await cn(n,g,s.hash);let u=new Map;for(let c of g){if(c.pkg.private)continue;let p=await Jn(n,c.pkg);u.set(c.folder,p),console.log(i("checkingRegistry",{name:c.name,version:c.to,registry:p}))}let h=new Set;for(let c of g){let p=u.get(c.folder);if(!p||h.has(p))continue;h.add(p),await qn(n,p)}let w=new Set,f=new Map;for(let c of g){if(c.pkg.private)continue;let p=u.get(c.folder);if(!p)continue;await tn(async()=>{if(await Vn(n,c.name,c.to,p)){w.add(c.folder);let P=await Gn(n,c.name,e.distTag,p);f.set(c.folder,P)}})}let I=en({packages:g.map((c)=>({name:c.name,version:c.to,folder:c.folder,private:c.pkg.private,deps:c.deps,registry:u.get(c.folder),published:w.has(c.folder),distTagVersion:f.get(c.folder)})),distTag:e.distTag,formal:m,commit:s.hash,beforePublish:r.hooks.beforePublish,afterPublish:r.hooks.afterPublish}),W={CHANGE_VERSIONS_PUBLISH_CONTEXT:JSON.stringify({schemaVersion:1,root:n,packagesDir:r.packagesDir,commit:s.hash,distTag:e.distTag,packages:I.flatMap((c)=>c.kind==="publish"?[{name:c.name,version:c.version,path:xe.join(r.packagesDir,c.folder)}]:[])})};for(let c of g)if(w.has(c.folder)&&f.get(c.folder)===c.to)console.log(v(i("alreadyTagged",{name:c.name,version:c.to,tag:e.distTag,registry:u.get(c.folder)||""})));if(e.dryRun){for(let c of I)console.log(On(c));if(!m)console.log(v(i("noGitTag")));return}console.log(x(i("willPublish")));for(let c of g){if(w.has(c.folder)&&f.get(c.folder)===c.to)continue;let p=c.pkg.private?` ${v(i("privateMark"))}`:"";console.log(` ${j(c.name)} ${T(c.to)}${p}`)}if(!e.yes&&!await ge(i("confirmPublish")))throw new d(i("cancelledPublish"));let F=new Map(g.map((c)=>[c.folder,c.pkg.private?"summaryPrivate":w.has(c.folder)&&f.get(c.folder)===c.to?"summarySkipped":"summaryPending"])),O="beforePublish",z,H=!1,L=()=>{console.log(x(i(H?"publishComplete":"publishIncomplete"))),console.log(i("publishSummaryContext",{commit:s.hash,tag:e.distTag}));let c=new Map;for(let p of g){let P=F.get(p.folder);c.set(P,(c.get(P)??0)+1);let Ce=u.get(p.folder);console.log(` ${i(P)}: ${p.name}@${p.to}${Ce?` — ${Ce}`:""}`)}if(console.log([...c].map(([p,P])=>`${i(p)}: ${P}`).join(", ")),!H)console.log(i("publishFailedStage",{stage:O}))},N=()=>{if(z)F.set(z,"summaryFailed");L(),console.error(V(i("publishInterrupted"))),process.exit(1)};process.on("SIGINT",N),process.on("SIGTERM",N);try{await on(n,r.hooks.beforePublish,"beforePublish",W),await ye(n,i("beforePublishDirty")),await nn(n,t);for(let c of I){if(c.kind!=="publish"&&c.kind!=="dist-tag")continue;let p=xe.join(n,r.packagesDir,c.folder);O=`${c.kind==="publish"?"npm publish":"npm dist-tag add"} ${c.name}@${c.version}`,z=c.folder,await tn(async()=>{if(c.kind==="dist-tag")await rn(n,["dist-tag","add",`${c.name}@${c.version}`,c.tag,`--registry=${c.registry}`],c.registry);else await rn(p,["publish",`--tag=${c.tag}`,`--registry=${c.registry}`],c.registry)}),F.set(c.folder,c.kind==="publish"?"summaryPublished":"summaryRetagged"),z=void 0}if(O="afterPublish",await on(n,r.hooks.afterPublish,"afterPublish",W),await ye(n,i("afterPublishDirty")),await nn(n,t),O="git tag / git push",m)await Ln(n,r.branch,g,s.hash);H=!0}catch(c){if(z)F.set(z,"summaryFailed");throw c}finally{process.off("SIGINT",N),process.off("SIGTERM",N),L()}}function On(e){if(e.kind==="hook")return`${v(`${e.name}:`)} ${U(e.command)}`;if(e.kind==="tag")return U(`git tag ${e.name}@${e.version} ${e.commit}`);if(e.kind==="dist-tag")return U(`npm dist-tag add ${e.name}@${e.version} ${e.tag} --registry=${e.registry}`);return U(`npm publish --tag=${e.tag} --registry=${e.registry} ${e.name}@${e.version}`)}async function Hn(e){if((await b("git",["rev-parse","--verify","HEAD"],e)).code!==0)return null;let t=(await Y(e))[0];if(!t)return null;let r=ie(t.body);if(!r.length)return null;return{hash:t.hash,subject:t.subject,lines:r}}async function Ln(e,n,t,r){await cn(e,t,r);let s=t.map((a)=>`${a.name}@${a.to}`);for(let a of s){if((await b("git",["rev-parse","--verify",`refs/tags/${a}^{commit}`],e)).code===0)continue;await y("git",["tag",a,r],e)}if(!n)return;let o=await b("git",["push","origin",...s.map((a)=>`refs/tags/${a}`)],e);if(o.code!==0)throw new d(i("tagPushFailed",{detail:o.stderr.trim()}))}async function cn(e,n,t){for(let r of n){let s=`${r.name}@${r.to}`,o=await b("git",["rev-parse","--verify",`refs/tags/${s}^{commit}`],e);if(o.code===0&&o.stdout.trim()!==t)throw new d(i("tagPointsElsewhere",{tag:s}))}}async function nn(e,n){if((await y("git",["rev-parse","HEAD"],e)).trim()!==n)throw new d(i("publishHeadChanged"))}async function tn(e){let n="";for(let t=0;t<3;t++)try{await e();return}catch(r){if(r instanceof d&&r.auth)throw r;n=r instanceof Error?r.message:String(r)}throw new d(i("networkFailed",{detail:n}))}async function rn(e,n,t){let r=await b("npm",n,e);if(r.code===0)return;let s=`${r.stderr}${r.stdout}`;if(process.stderr.write(r.stderr),K(s))throw new d(i("notLoggedIn",{registry:t}),!0);throw Error(s.trim()||i("npmFailed"))}async function Vn(e,n,t,r){let s=await b("npm",["view",`${n}@${t}`,"version","--json",`--registry=${r}`],e);if(s.code===0){let a;try{a=JSON.parse(s.stdout)}catch{}if(a===t||Array.isArray(a)&&a.length===1&&a[0]===t)return!0;throw Error(i("unexpectedRegistryVersion",{name:n,version:t,registry:r}))}let o=`${s.stderr}${s.stdout}`;if(K(o))throw new d(i("notLoggedIn",{registry:r}),!0);if(fe(s.stdout)||fe(s.stderr))return!1;throw Error(o.trim()||i("npmViewFailed"))}async function Gn(e,n,t,r){let s=await b("npm",["view",n,"dist-tags","--json",`--registry=${r}`],e);if(s.code!==0){let g=`${s.stderr}${s.stdout}`.trim();if(K(g))throw new d(i("notLoggedIn",{registry:r}),!0);throw Error(g||i("npmViewFailed"))}let o;try{o=JSON.parse(s.stdout)}catch{}if(Array.isArray(o)&&o.length===1)o=o[0];if(!o||typeof o!=="object"||Array.isArray(o))throw Error(i("unexpectedRegistryTags",{name:n,tag:t,registry:r}));let a=Object.prototype.hasOwnProperty.call(o,t)?o[t]:void 0;if(a!==void 0&&typeof a!=="string")throw Error(i("unexpectedRegistryTags",{name:n,tag:t,registry:r}));return a}async function qn(e,n){let t=await b("npm",["whoami",`--registry=${n}`],e);if(t.code===0)return;let r=`${t.stderr}${t.stdout}`;if(K(r))throw new d(i("notLoggedIn",{registry:n}),!0);throw new d(i("registryUnreachable",{registry:n,detail:r.trim()}))}async function Jn(e,n){if(n.publishConfig?.registry)return n.publishConfig.registry.replace(/\/$/,"");if(n.name.startsWith("@")&&n.name.includes("/")){let r=n.name.slice(0,n.name.indexOf("/")),s=await sn(e,`${r}:registry`);if(s&&s!=="undefined"&&s!=="null")return s.replace(/\/$/,"")}let t=await sn(e,"registry");if(!t||t==="undefined"||t==="null")throw new d(i("noNpmRegistry",{detail:"npm config get registry: empty value"}));return t.replace(/\/$/,"")}async function sn(e,n){let t=await b("npm",["config","get",n],e);if(t.code!==0){let r=t.stderr.trim()||t.stdout.trim()||`npm config get ${n}: exit ${t.code}`;throw new d(i("noNpmRegistry",{detail:r}))}return t.stdout.trim()}async function on(e,n,t,r){if(!n)return;try{await se("sh",["-c",n],e,r)}catch(s){let o=s instanceof Error?s.message:String(s);throw new d(i("hookFailed",{name:t,detail:o}))}}import B from"node:fs";import de from"node:path";S();C();var Yn=["patch","minor","major"],Xn=["prerelease","prepatch","preminor","premajor"];async function hn(e){let n=de.resolve(e.root),t=q(n,e.versionsFile);if(e.packages)t.packagesDir=e.packages;if(e.messageFromCli&&e.commitMessage)t.commitMessage=e.commitMessage;if(e.branchFromCli)t.branch=e.branch||void 0;if(await _(n),t.branch){let m=await b("git",["symbolic-ref","--quiet","--short","HEAD"],n);if(m.code!==0||m.stdout.trim()!==t.branch)throw new d(i("wrongBranch",{branch:t.branch}))}let r=await ce(n,t,e.baseline);if(!r.changed.length&&!r.dependents.length){let m=(await y("git",["rev-parse","--short",r.baseline],n)).trim();console.log(v(i("noPackagesSince",{rev:m})));return}let s=await Zn(e.bump,e.preid),o=pe(s)?void 0:e.preid,a=[...r.changed,...r.dependents].map((m)=>{let u=k(n,t.packagesDir,m);return{folder:m,name:u.name,from:u.version,to:Ie(u.version,s,o)}});for(let m of a)console.log($e(m.name,m.from,m.to));if(e.dryRun)return;if(!e.yes&&!await ge(i("confirmVersions")))throw new d(i("cancelledVersion"));let g=Qn(n,(await y("git",["rev-parse","HEAD"],n)).trim());try{for(let h of a)rt(n,t.packagesDir,h.folder,h.to);if(it(n,t.packagesDir),pe(s))await et(n,t,a,e.baseline);if(t.hooks.beforeCommit)await se("sh",["-c",t.hooks.beforeCommit],n);let m=He(t.commitMessage,s,o),u=a.map((h)=>`${h.name} ${h.from} => ${h.to}`).join(`
50
- `);await y("git",["add","--all"],n),await y("git",["commit","-m",m,"-m",u,"-m",te],n),g.disarm()}catch(m){await g.fail(m)}if(!t.branch)return;let l=await b("git",["push","origin",t.branch],n);if(l.code!==0)throw new d(i("branchPushFailed",{branch:t.branch,detail:l.stderr.trim()}))}async function Zn(e,n){let t=e??await Xe(i("chooseBump"),n?Xn:Yn);return Te(t,n)}function Qn(e,n){let t=!0,r=()=>{if(!t)return;t=!1,be(e,n),console.error(V(i("versionRestored"))),process.exit(1)};return process.on("SIGINT",r),process.on("SIGTERM",r),{disarm(){t=!1,process.off("SIGINT",r),process.off("SIGTERM",r)},fail(s){if(t)t=!1,process.off("SIGINT",r),process.off("SIGTERM",r),be(e,n);throw s}}}async function et(e,n,t,r){await Promise.resolve().then(() => pn());let g=await Y(e),l=(await we(e)).find((f)=>Ve(f.subject))?.hash,m=ln(g)??l??(r?await ke(e,r):void 0),u=await nt(e,m),h=new Set(t.map((f)=>f.folder)),w=new Map(J(e,n.packagesDir).map((f)=>[k(e,n.packagesDir,f).name,f]));for(let f of t){let I=`${n.packagesDir}/${f.folder}/package.json`,W=new Set;for(let c of u)if(c.files.includes(I)&&await tt(e,c.hash,I))W.add(c.hash);let F=mn(u,f.folder,n.packagesDir,n.include,n.exclude,W),O=k(e,n.packagesDir,f.folder),z=F.length?[]:ae(O,w).filter((c)=>h.has(c)).map((c)=>k(e,n.packagesDir,c)).map((c)=>({name:c.name,version:c.version})),H=await un({messages:F,version:f.to,previousTag:`${f.name}@${f.from}`,currentTag:`${f.name}@${f.to}`,dependencies:z}),L=de.join(e,n.packagesDir,f.folder,"CHANGELOG.md"),N=B.existsSync(L)?B.readFileSync(L,"utf8"):"";B.writeFileSync(L,N?`${H}
51
- ${N}`:H)}}async function nt(e,n){let t=n?["rev-list","--reverse",`${n}..HEAD`]:["rev-list","--reverse","HEAD"],r=(await y("git",t,e)).split(`
52
- `).filter(Boolean),s=[];for(let o of r){let a=await y("git",["log","-1","--format=%B",o],e),g=await b("git",["diff-tree","--no-commit-id","--name-only","-r","--root",o],e);s.push({hash:o,body:a,files:g.code===0?g.stdout.split(`
53
- `).filter(Boolean):[]})}return s}async function tt(e,n,t){return!await ve(e,`${n}^`,n,t)}function rt(e,n,t,r){let s=de.join(e,n,t,"package.json"),o=B.readFileSync(s,"utf8"),a=JSON.parse(o);if(typeof a.version!=="string")throw new d(i("missingVersionField",{folder:t}));a.version=r;let g=/\n([\t ]+)"/.exec(o)?.[1]??" ";B.writeFileSync(s,JSON.stringify(a,null,g)+`
54
- `)}function it(e,n){let t=J(e,n),r=new Map(t.map((s)=>[k(e,n,s).name,k(e,n,s)]));for(let s of t){let o=de.join(e,n,s,"package.json"),a=B.readFileSync(o,"utf8"),g=JSON.parse(a),l=!1;for(let m of["dependencies","devDependencies"])for(let u of Object.keys(g[m]??{})){let h=r.get(u);if(!h)continue;let w=`^${h.version}`;if(g[m][u]!==w)g[m][u]=w,l=!0}if(l){let m=/\n([\t ]+)"/.exec(a)?.[1]??" ";B.writeFileSync(o,JSON.stringify(g,null,m)+`
55
- `)}}}S();C();var M=new st;M.name("change-versions").version(JSON.parse(ot(new URL("../package.json",import.meta.url),"utf8")).version).description(i("cliDescription"));function Se(e){return e.option("--root <dir>",i("optRoot"),process.cwd()).option("--versions-file <file>",i("optVersionsFile"),"change-versions.yml").option("--packages <dir>",i("optPackages"))}M.command("init").description(i("cmdInit")).option("--root <dir>",i("optRoot"),process.cwd()).option("--versions-file <file>",i("optVersionsFile"),"change-versions.yml").option("--yes",i("optYesInit")).action(async function(){let e=this.opts();await Qe(e)});Se(M.command("changed").description(i("cmdChanged"))).option("--baseline <rev>",i("optBaseline")).action(async function(){let e=this.opts();await Ue(e)});Se(M.command("version").description(i("cmdVersion")).argument("[bump]",i("argBump"))).option("--preid <id>",i("optPreid")).option("--yes",i("optYes")).option("--dry-run",i("optDryRunVersion")).option("--baseline <rev>",i("optBaseline")).option("--branch <name>",i("optBranch")).option("--commit-message <template>",i("optCommitMessage")).action(async function(e){let n=this.opts();await hn({...n,bump:e,branchFromCli:this.getOptionValueSource("branch")==="cli",messageFromCli:this.getOptionValueSource("commitMessage")==="cli"})});Se(M.command("publish").description(i("cmdPublish"))).option("--dist-tag <tag>",i("optDistTag"),"latest").option("--yes",i("optYes")).option("--dry-run",i("optDryRunPublish")).action(async function(){let e=this.opts();await an(e)});if(process.argv.length<=2)M.help();M.parseAsync(process.argv).catch((e)=>{if(e instanceof d)console.error(V(e.message));else console.error(e);process.exit(1)});
49
+ `}async function on(e){let n=H.resolve(e.root),t=H.resolve(n,e.versionsFile);if(R.existsSync(t))throw new g(i("configExists",{file:e.versionsFile}));let r=Mn(n),s=r[0]??"packages",o=e.yes?Hn(s):await Ln(e.versionsFile,r,s);if(!o.include.length)throw new g(i("includeRequired"));let c=On(o);oe(c),R.mkdirSync(H.dirname(t),{recursive:!0}),R.writeFileSync(t,c),console.log(M(i("initWrote",{file:e.versionsFile})))}function Hn(e){return{packagesDir:e,include:[`${e}/*/src`],exclude:[`${e}/*/src/**/__tests__/**`]}}async function Ln(e,n,t){if(!ee())throw new g(i("yesRequired"));if(console.log(w(i("initIntro",{file:e}))),n.length)console.log(y(i("initFoundDirs",{dirs:n.join(", ")})));let r=await O(i("initPackagesDir"),t),s=sn(await O(i("initInclude"),`${r}/*/src`)),o=sn(await O(i("initExclude"),`${r}/*/src/**/__tests__/**`)),c=await O(i("initBranch")),d=await O(i("initBeforeCommit")),l=await O(i("initBeforePublish"));return{packagesDir:r,branch:c||void 0,beforeCommit:d||void 0,beforePublish:l||void 0,include:s,exclude:o}}function sn(e){return e.split(",").map((n)=>n.trim()).filter(Boolean)}function ne(e){return/^[A-Za-z0-9_./@*+-]+$/.test(e)?e:JSON.stringify(e)}function Vn(e){return _n(e).flatMap((n)=>{let t=n.replace(/\/\*\*?$/,"");if(!t||t===n||t.includes("*"))return[];return R.existsSync(H.join(e,t))?[t]:[]})}function Gn(e){if(!R.existsSync(e))return[];let n=[];for(let t of R.readdirSync(e)){if(t.startsWith(".")||t==="node_modules")continue;let r=H.join(e,t);if(!R.statSync(r).isDirectory())continue;if(qn(r))n.push(t)}return n}function qn(e){return R.readdirSync(e).some((n)=>R.existsSync(H.join(e,n,"package.json")))}function _n(e){let n=H.join(e,"package.json");if(!R.existsSync(n))return[];try{let t=JSON.parse(R.readFileSync(n,"utf8")),r=Array.isArray(t.workspaces)?t.workspaces:t.workspaces?.packages;return Array.isArray(r)?r.filter((s)=>typeof s==="string"):[]}catch{return[]}}import Re from"node:path";z();function Jn(e){if(/^[a-zA-Z0-9_./:@=+-]+$/.test(e))return e;return"'"+e.replaceAll("'","'\\''")+"'"}function he(e){let n=["change-versions","publish",`--dist-tag=${e.distTag}`,`--root=${e.root}`,`--versions-file=${e.versionsFile}`];if(e.packages)n.push(`--packages=${e.packages}`);return n.map(Jn).join(" ")}D();D();function an(e){let n=[];if(e.beforePublish)n.push({kind:"hook",name:"beforePublish",command:e.beforePublish});for(let t of Ke(e.packages.filter((r)=>!r.private))){if(t.published&&t.distTagVersion===t.version)continue;let r=t.registry??"";n.push(t.published?{kind:"dist-tag",name:t.name,version:t.version,folder:t.folder,registry:r,tag:e.distTag}:{kind:"publish",name:t.name,version:t.version,folder:t.folder,registry:r,tag:e.distTag})}if(e.afterPublish)n.push({kind:"hook",name:"afterPublish",command:e.afterPublish});if(e.formal)for(let t of e.packages)n.push({kind:"tag",name:t.name,version:t.version,commit:e.commit});return n}async function pn(e){let n=Re.resolve(e.root),t=he({...e,root:n});console.log(e.dryRun?S(i("publishPreview")):w(i("publishPreparing"))),await K(n);let r=(await v("git",["rev-parse","HEAD"],n)).trim(),s=W(n,e.versionsFile);if(e.packages)s.packagesDir=e.packages;let o=await Wn(n);if(!o?.lines.length)throw new g(i("noVersionCommit"));let c=U(n,s.packagesDir),d=new Map(c.map((a)=>[k(n,s.packagesDir,a).name,a])),l=o.lines.map((a)=>{let h=d.get(a.name);if(!h)throw new g(i("packageNotInDir",{dir:s.packagesDir,name:a.name}));let C=k(n,s.packagesDir,h);if(C.version!==a.to)throw new g(i("releaseVersionMismatch",{name:a.name,expected:a.to,actual:C.version,commit:o.hash}));return{...a,folder:h,pkg:C,deps:ue(C,d)}}),u=await b("git",["diff","--quiet",o.hash,"HEAD","--",...l.map((a)=>`${s.packagesDir}/${a.folder}`)],n);if(u.code===1)throw new g(i("releaseContentsChanged"));if(u.code!==0)throw new g(i("gitFailed",{detail:u.stderr.trim()}));console.log(i("publishSummaryContext",{commit:o.hash,tag:e.distTag}));let m=ce(o.lines);if(m)await hn(n,l,o.hash);let p=new Map;for(let a of l){if(a.pkg.private)continue;let h=await Zn(n,a.pkg);p.set(a.folder,h),console.log(i("checkingRegistry",{name:a.name,version:a.to,registry:h}))}let P=new Set;for(let a of l){let h=p.get(a.folder);if(!h||P.has(h))continue;P.add(h),await Qn(n,h)}let f=new Set,E=new Map;for(let a of l){if(a.pkg.private)continue;let h=p.get(a.folder);if(!h)continue;await ln(async()=>{if(await Kn(n,a.name,a.to,h)){f.add(a.folder);let C=await Yn(n,a.name,e.distTag,h);E.set(a.folder,C)}})}let F=an({packages:l.map((a)=>({name:a.name,version:a.to,folder:a.folder,private:a.pkg.private,deps:a.deps,registry:p.get(a.folder),published:f.has(a.folder),distTagVersion:E.get(a.folder)})),distTag:e.distTag,formal:m,commit:o.hash,beforePublish:s.hooks.beforePublish,afterPublish:s.hooks.afterPublish}),Y={CHANGE_VERSIONS_PUBLISH_CONTEXT:JSON.stringify({schemaVersion:1,root:n,packagesDir:s.packagesDir,commit:o.hash,distTag:e.distTag,packages:F.flatMap((a)=>a.kind==="publish"?[{name:a.name,version:a.version,path:Re.join(s.packagesDir,a.folder)}]:[])})};for(let a of l)if(f.has(a.folder)&&E.get(a.folder)===a.to)console.log(y(i("alreadyTagged",{name:a.name,version:a.to,tag:e.distTag,registry:p.get(a.folder)||""})));if(console.log(i("publishPlanSummary",{uploads:F.filter((a)=>a.kind==="publish").length,retags:F.filter((a)=>a.kind==="dist-tag").length,tags:F.filter((a)=>a.kind==="tag").length})),e.dryRun){for(let a of F)console.log(`${S(i("plannedStep",{step:""}))}${cn(a)}`);if(m&&s.branch)console.log(S(i("plannedStep",{step:`git push origin ${l.map((a)=>`refs/tags/${a.name}@${a.to}`).join(" ")}`})));if(!m)console.log(y(i("noGitTag")));console.log(S(i("publishPreviewComplete"))),console.log(w(i("publishPreviewNext"))),console.log(A(t));return}console.log(y(i("publishResumeInfo"))),console.log(w(i("willPublish")));for(let a of l){if(f.has(a.folder)&&E.get(a.folder)===a.to)continue;let h=a.pkg.private?` ${y(i("privateMark"))}`:f.has(a.folder)?` ${y(i("distTagOnlyMark"))}`:"";console.log(` ${T(a.name)} ${M(a.to)}${h}`)}if(!e.yes&&!await pe(i("confirmPublish")))throw new g(i("cancelledPublish"));let G=new Map(l.map((a)=>[a.folder,a.pkg.private?"summaryPrivate":f.has(a.folder)&&E.get(a.folder)===a.to?"summarySkipped":"summaryPending"])),B="beforePublish",j,I=!1,Q=(a)=>a==="summaryPublished"||a==="summaryRetagged"?_:a==="summaryFailed"?re:a==="summaryPending"?S:y,x=()=>{console.log((I?_:re)(i(I?"publishComplete":"publishIncomplete"))),console.log(i("publishSummaryContext",{commit:o.hash,tag:e.distTag}));let a=new Map;for(let h of l){let C=G.get(h.folder);a.set(C,(a.get(C)??0)+1);let Te=p.get(h.folder);console.log(` ${Q(C)(i(C))}: ${T(h.name)}@${T(h.to)}${Te?` — ${y(Te)}`:""}`)}if(console.log([...a].map(([h,C])=>`${Q(h)(i(h))}: ${T(String(C))}`).join(", ")),I)console.log(_(i("publishReady"))),console.log(y(i(m?s.branch?"gitTagsPushed":"gitTagsLocal":"noGitTag")));else{if(console.log(re(i("publishFailedStage",{stage:B}))),B==="git tag / git push")console.log(S(i("publishTagRecovery")));console.log(S(i("publishRetryTitle"))),console.log(w(i("publishRetry"))),console.log(y(i("publishResumeInfo"))),console.log(A(t))}},te=()=>{if(j)G.set(j,"summaryFailed");x(),console.error(q(i("publishInterrupted"))),process.exit(1)};process.on("SIGINT",te),process.on("SIGTERM",te);try{await mn(n,s.hooks.beforePublish,"beforePublish",Y),await Ce(n,i("beforePublishDirty")),await gn(n,r);for(let a of F){if(a.kind!=="publish"&&a.kind!=="dist-tag")continue;console.log(w(i("executingStep",{step:cn(a)})));let h=Re.join(n,s.packagesDir,a.folder);B=`${a.kind==="publish"?"npm publish":"npm dist-tag add"} ${a.name}@${a.version}`,j=a.folder,await ln(async()=>{if(a.kind==="dist-tag")await dn(n,["dist-tag","add",`${a.name}@${a.version}`,a.tag,`--registry=${a.registry}`],a.registry);else await dn(h,["publish",`--tag=${a.tag}`,`--registry=${a.registry}`],a.registry)}),G.set(a.folder,a.kind==="publish"?"summaryPublished":"summaryRetagged"),j=void 0}if(B="afterPublish",await mn(n,s.hooks.afterPublish,"afterPublish",Y),await Ce(n,i("afterPublishDirty")),await gn(n,r),B="git tag / git push",m)console.log(w(i("executingStep",{step:B}))),await Un(n,s.branch,l,o.hash);I=!0}catch(a){if(j)G.set(j,"summaryFailed");throw a}finally{process.off("SIGINT",te),process.off("SIGTERM",te),x()}}function cn(e){if(e.kind==="hook")return`${y(`${e.name}:`)} ${A(e.command)}`;if(e.kind==="tag")return A(`git tag ${e.name}@${e.version} ${e.commit}`);if(e.kind==="dist-tag")return A(`npm dist-tag add ${e.name}@${e.version} ${e.tag} --registry=${e.registry}`);return A(`npm publish --tag=${e.tag} --registry=${e.registry} ${e.name}@${e.version}`)}async function Wn(e){if((await b("git",["rev-parse","--verify","HEAD"],e)).code!==0)return null;let t=(await X(e))[0];if(!t)return null;let r=ge(t.body);if(!r.length)return null;return{hash:t.hash,subject:t.subject,lines:r}}async function Un(e,n,t,r){await hn(e,t,r);let s=t.map((c)=>`${c.name}@${c.to}`);for(let c of s){if((await b("git",["rev-parse","--verify",`refs/tags/${c}^{commit}`],e)).code===0)continue;await v("git",["tag",c,r],e)}if(!n)return;let o=await b("git",["push","origin",...s.map((c)=>`refs/tags/${c}`)],e);if(o.code!==0)throw new g(i("tagPushFailed",{detail:o.stderr.trim()}))}async function hn(e,n,t){for(let r of n){let s=`${r.name}@${r.to}`,o=await b("git",["rev-parse","--verify",`refs/tags/${s}^{commit}`],e);if(o.code===0&&o.stdout.trim()!==t)throw new g(i("tagPointsElsewhere",{tag:s}))}}async function gn(e,n){if((await v("git",["rev-parse","HEAD"],e)).trim()!==n)throw new g(i("publishHeadChanged"))}async function ln(e){let n="";for(let t=0;t<3;t++)try{await e();return}catch(r){if(r instanceof g&&r.auth)throw r;n=r instanceof Error?r.message:String(r)}throw new g(i("networkFailed",{detail:n}))}async function dn(e,n,t){let r=await b("npm",n,e);if(r.code===0)return;let s=`${r.stderr}${r.stdout}`;if(process.stderr.write(r.stderr),Z(s))throw new g(i("notLoggedIn",{registry:t}),!0);throw Error(s.trim()||i("npmFailed"))}async function Kn(e,n,t,r){let s=await b("npm",["view",`${n}@${t}`,"version","--json",`--registry=${r}`],e);if(s.code===0){let c;try{c=JSON.parse(s.stdout)}catch{}if(c===t||Array.isArray(c)&&c.length===1&&c[0]===t)return!0;throw Error(i("unexpectedRegistryVersion",{name:n,version:t,registry:r}))}let o=`${s.stderr}${s.stdout}`;if(Z(o))throw new g(i("notLoggedIn",{registry:r}),!0);if(Pe(s.stdout)||Pe(s.stderr))return!1;throw Error(o.trim()||i("npmViewFailed"))}async function Yn(e,n,t,r){let s=await b("npm",["view",n,"dist-tags","--json",`--registry=${r}`],e);if(s.code!==0){let d=`${s.stderr}${s.stdout}`.trim();if(Z(d))throw new g(i("notLoggedIn",{registry:r}),!0);throw Error(d||i("npmViewFailed"))}let o;try{o=JSON.parse(s.stdout)}catch{}if(Array.isArray(o)&&o.length===1)o=o[0];if(!o||typeof o!=="object"||Array.isArray(o))throw Error(i("unexpectedRegistryTags",{name:n,tag:t,registry:r}));let c=Object.prototype.hasOwnProperty.call(o,t)?o[t]:void 0;if(c!==void 0&&typeof c!=="string")throw Error(i("unexpectedRegistryTags",{name:n,tag:t,registry:r}));return c}async function Qn(e,n){let t=await b("npm",["whoami",`--registry=${n}`],e);if(t.code===0)return;let r=`${t.stderr}${t.stdout}`;if(Z(r))throw new g(i("notLoggedIn",{registry:n}),!0);throw new g(i("registryUnreachable",{registry:n,detail:r.trim()}))}async function Zn(e,n){if(n.publishConfig?.registry)return n.publishConfig.registry.replace(/\/$/,"");if(n.name.startsWith("@")&&n.name.includes("/")){let r=n.name.slice(0,n.name.indexOf("/")),s=await un(e,`${r}:registry`);if(s&&s!=="undefined"&&s!=="null")return s.replace(/\/$/,"")}let t=await un(e,"registry");if(!t||t==="undefined"||t==="null")throw new g(i("noNpmRegistry",{detail:"npm config get registry: empty value"}));return t.replace(/\/$/,"")}async function un(e,n){let t=await b("npm",["config","get",n],e);if(t.code!==0){let r=t.stderr.trim()||t.stdout.trim()||`npm config get ${n}: exit ${t.code}`;throw new g(i("noNpmRegistry",{detail:r}))}return t.stdout.trim()}async function mn(e,n,t,r){if(!n)return;console.log(w(i("executingStep",{step:`${t}: ${n}`})));try{await le("sh",["-c",n],e,r)}catch(s){let o=s instanceof Error?s.message:String(s);throw new g(i("hookFailed",{name:t,detail:o}))}}import L from"node:fs";import fe from"node:path";z();D();var rt=["patch","minor","major"],it=["prerelease","prepatch","preminor","premajor"];async function Pn(e){let n=fe.resolve(e.root),t=W(n,e.versionsFile);if(e.packages)t.packagesDir=e.packages;if(e.messageFromCli&&e.commitMessage)t.commitMessage=e.commitMessage;if(e.branchFromCli)t.branch=e.branch||void 0;if(await K(n),t.branch){let u=await b("git",["symbolic-ref","--quiet","--short","HEAD"],n);if(u.code!==0||u.stdout.trim()!==t.branch)throw new g(i("wrongBranch",{branch:t.branch}))}let r=await me(n,t,e.baseline);if(!r.changed.length&&!r.dependents.length){let u=(await v("git",["rev-parse","--short",r.baseline],n)).trim();console.log(y(i("noPackagesSince",{rev:u}))),console.log(y(i("noVersionChangesNext")));return}let s=await st(e.bump,e.preid),o=ve(s)?void 0:e.preid,c=[...r.changed,...r.dependents].map((u)=>{let m=k(n,t.packagesDir,u);return{folder:u,name:m.name,from:m.version,to:qe(m.version,s,o)}});if(e.dryRun)console.log(S(i("versionPreview")));for(let u of c)console.log(Fe(u.name,u.from,u.to));if(e.dryRun){console.log(w(i("versionPreviewComplete")));return}if(!e.yes&&!await pe(i("confirmVersions")))throw new g(i("cancelledVersion"));let d=ot(n,(await v("git",["rev-parse","HEAD"],n)).trim());try{for(let p of c)lt(n,t.packagesDir,p.folder,p.to);if(dt(n,t.packagesDir),ve(s))await at(n,t,c,e.baseline);if(t.hooks.beforeCommit)await le("sh",["-c",t.hooks.beforeCommit],n);let u=Je(t.commitMessage,s,o),m=c.map((p)=>`${p.name} ${p.from} => ${p.to}`).join(`
50
+ `);await v("git",["add","--all"],n),await v("git",["commit","-m",u,"-m",m,"-m",ae],n),d.disarm()}catch(u){await d.fail(u)}let l=(await v("git",["rev-parse","HEAD"],n)).trim();if(console.log(_(i("versionCommitted",{commit:l}))),console.log(S(i("versionTrailerHint"))),t.branch){let u=await b("git",["push","origin",t.branch],n);if(u.code!==0)throw new g(i("branchPushFailed",{branch:t.branch,detail:u.stderr.trim()}))}console.log(w(i("versionPublishNext"))),console.log(A(he({...e,root:n,distTag:o??"latest"})))}async function st(e,n){let t=e??await rn(i("chooseBump"),n?it:rt);return Oe(t,n)}function ot(e,n){let t=!0,r=()=>{if(!t)return;t=!1,xe(e,n),console.error(q(i("versionRestored"))),process.exit(1)};return process.on("SIGINT",r),process.on("SIGTERM",r),{disarm(){t=!1,process.off("SIGINT",r),process.off("SIGTERM",r)},fail(s){if(t)t=!1,process.off("SIGINT",r),process.off("SIGTERM",r),xe(e,n);throw s}}}async function at(e,n,t,r){await Promise.resolve().then(() => kn());let d=await X(e),l=(await Se(e)).find((f)=>Ue(f.subject))?.hash,u=yn(d)??l??(r?await $e(e,r):void 0),m=await ct(e,u),p=new Set(t.map((f)=>f.folder)),P=new Map(U(e,n.packagesDir).map((f)=>[k(e,n.packagesDir,f).name,f]));for(let f of t){let E=`${n.packagesDir}/${f.folder}/package.json`,F=new Set;for(let x of m)if(x.files.includes(E)&&await gt(e,x.hash,E))F.add(x.hash);let Y=wn(m,f.folder,n.packagesDir,n.include,n.exclude,F),G=k(e,n.packagesDir,f.folder),B=Y.length?[]:ue(G,P).filter((x)=>p.has(x)).map((x)=>k(e,n.packagesDir,x)).map((x)=>({name:x.name,version:x.version})),j=await vn({messages:Y,version:f.to,previousTag:`${f.name}@${f.from}`,currentTag:`${f.name}@${f.to}`,dependencies:B}),I=fe.join(e,n.packagesDir,f.folder,"CHANGELOG.md"),Q=L.existsSync(I)?L.readFileSync(I,"utf8"):"";L.writeFileSync(I,Q?`${j}
51
+ ${Q}`:j)}}async function ct(e,n){let t=n?["rev-list","--reverse",`${n}..HEAD`]:["rev-list","--reverse","HEAD"],r=(await v("git",t,e)).split(`
52
+ `).filter(Boolean),s=[];for(let o of r){let c=await v("git",["log","-1","--format=%B",o],e),d=await b("git",["diff-tree","--no-commit-id","--name-only","-r","--root",o],e);s.push({hash:o,body:c,files:d.code===0?d.stdout.split(`
53
+ `).filter(Boolean):[]})}return s}async function gt(e,n,t){return!await ze(e,`${n}^`,n,t)}function lt(e,n,t,r){let s=fe.join(e,n,t,"package.json"),o=L.readFileSync(s,"utf8"),c=JSON.parse(o);if(typeof c.version!=="string")throw new g(i("missingVersionField",{folder:t}));c.version=r;let d=/\n([\t ]+)"/.exec(o)?.[1]??" ";L.writeFileSync(s,JSON.stringify(c,null,d)+`
54
+ `)}function dt(e,n){let t=U(e,n),r=new Map(t.map((s)=>[k(e,n,s).name,k(e,n,s)]));for(let s of t){let o=fe.join(e,n,s,"package.json"),c=L.readFileSync(o,"utf8"),d=JSON.parse(c),l=!1;for(let u of["dependencies","devDependencies"])for(let m of Object.keys(d[u]??{})){let p=r.get(m);if(!p)continue;let P=`^${p.version}`;if(d[u][m]!==P)d[u][m]=P,l=!0}if(l){let u=/\n([\t ]+)"/.exec(c)?.[1]??" ";L.writeFileSync(o,JSON.stringify(d,null,u)+`
55
+ `)}}}z();D();var V=new ut;V.name("change-versions").version(JSON.parse(mt(new URL("../package.json",import.meta.url),"utf8")).version).description(i("cliDescription"));function Ne(e){return e.option("--root <dir>",i("optRoot"),process.cwd()).option("--versions-file <file>",i("optVersionsFile"),"change-versions.yml").option("--packages <dir>",i("optPackages"))}V.command("init").description(i("cmdInit")).option("--root <dir>",i("optRoot"),process.cwd()).option("--versions-file <file>",i("optVersionsFile"),"change-versions.yml").option("--yes",i("optYesInit")).action(async function(){let e=this.opts();await on(e)});Ne(V.command("changed").description(i("cmdChanged"))).option("--baseline <rev>",i("optBaseline")).action(async function(){let e=this.opts();await en(e)});Ne(V.command("version").description(i("cmdVersion")).argument("[bump]",i("argBump"))).option("--preid <id>",i("optPreid")).option("--yes",i("optYes")).option("--dry-run",i("optDryRunVersion")).option("--baseline <rev>",i("optBaseline")).option("--branch <name>",i("optBranch")).option("--commit-message <template>",i("optCommitMessage")).action(async function(e){let n=this.opts();await Pn({...n,bump:e,branchFromCli:this.getOptionValueSource("branch")==="cli",messageFromCli:this.getOptionValueSource("commitMessage")==="cli"})});Ne(V.command("publish").description(i("cmdPublish"))).option("--dist-tag <tag>",i("optDistTag"),"latest").option("--yes",i("optYes")).option("--dry-run",i("optDryRunPublish")).action(async function(){let e=this.opts();await pn(e)});if(process.argv.length<=2)V.help();V.parseAsync(process.argv).catch((e)=>{if(e instanceof g)console.error(q(e.message));else console.error(e);process.exit(1)});
package/docs/commands.md CHANGED
@@ -199,7 +199,9 @@ change-versions publish --dist-tag=<tag>
199
199
 
200
200
  确认后跑 `beforePublish`,再按依赖顺序处理非 private 包。发布 hooks 不得改变 HEAD;即便把改动提交成了干净工作区,也会中止。registry 上没有该版本就 `npm publish --tag=<dist-tag> --registry=<url>`;已经有了就跳过上传,并 `npm dist-tag add`。全部上去之后跑 `afterPublish`,然后正式版才打 git tag。`pre*` 不打 git tag。
201
201
 
202
- 确认执行后,无论成功还是中途失败,都会输出汇总:版本提交、dist-tag、各包的版本与 registry,以及已发布、标签已更新、已跳过、失败、未执行的状态和数量。失败或中断时显示所在阶段,具体原因见错误提示;hook 或 git tag 失败不会把已成功上传的包记为发布失败。上传失败可能已在 registry 生效,重跑同一条 publish 会重新查询确认。dry-run 仅展示计划,不输出完成汇总。
202
+ 确认执行后,无论成功还是中途失败,都会输出汇总:版本提交、dist-tag、各包的版本与 registry,以及已发布、标签已更新、已跳过、失败、未执行的状态和数量。失败或中断时显示所在阶段,具体原因见错误提示;hook 或 git tag 失败不会把已成功上传的包记为发布失败。上传失败可能已在 registry 生效,重跑同一条 publish 会重新查询确认。dry-run 仅展示计划,不输出完成汇总。开始显示“发布预览”与版本提交、dist-tag;操作前统一标注 `[计划]`,末尾明确所有计划尚未执行,并给出去掉 `--dry-run` 后的 publish 命令。预览仍需查询 registry;检查失败时不会输出预览完成提示。
203
+
204
+ 真实执行用 `[执行]` 标识当前步骤;失败汇总附带修复后重试的 publish 命令,保留 root、配置文件、包目录和 dist-tag。重试会重新查询 registry,已上传版本不重复上传,配置的 hook 仍执行。Git 标签阶段失败时可能已有部分本地或远端标签。成功、失败、预览、下一步命令和跳过项使用不同颜色,`NO_COLOR` 或关闭颜色时仍有完整状态文字。
203
205
 
204
206
  不升版本,不改 CHANGELOG,不提交,不 unpublish。
205
207
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "change-versions",
3
- "version": "1.2.0",
3
+ "version": "1.2.1",
4
4
  "type": "module",
5
5
  "description": "Version and publish only the workspace packages that changed.",
6
6
  "bin": {