@peiyanlu/cli-utils 0.0.5 → 0.0.7

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/dist/index.cjs CHANGED
@@ -4,6 +4,7 @@ let node_os = require("node:os");
4
4
  let node_path = require("node:path");
5
5
  let node_child_process = require("node:child_process");
6
6
  let node_util = require("node:util");
7
+ let semver = require("semver");
7
8
 
8
9
  //#region src/enums.ts
9
10
  let PkgManager = /* @__PURE__ */ function(PkgManager$1) {
@@ -42,6 +43,9 @@ const red = (text) => (0, node_util.styleText)(["red"], text);
42
43
 
43
44
  //#endregion
44
45
  //#region src/shell.ts
46
+ const formatErr = (caller, cmd, err) => {
47
+ return `${red(caller)} ${dim(cmd)}${eol()}${err}`;
48
+ };
45
49
  /** 异步执行 `spawn` 获取字符串类型的结果 */
46
50
  const spawnAsync = (cmd, args, options) => {
47
51
  return new Promise((resolve$2, reject) => {
@@ -65,7 +69,7 @@ const spawnAsync = (cmd, args, options) => {
65
69
  child.on("error", reject);
66
70
  child.on("close", (code) => {
67
71
  if (code !== 0) {
68
- const msg = `${red("spawnAsync")} ${dim(fullCmd)} ${stderr}`;
72
+ const msg = formatErr("spawnAsync", fullCmd, stderr);
69
73
  if (error === "log") {
70
74
  console.error(msg);
71
75
  return resolve$2(void 0);
@@ -96,7 +100,8 @@ const execAsync = (cmd, argsOrOptions, maybeOptions) => {
96
100
  }
97
101
  (0, node_child_process.exec)(command, { ...others }, (err, stdout, stderr) => {
98
102
  if (err) {
99
- const msg = `${red("execAsync")} ${dim(command)} ${stderr || err.message}`;
103
+ const detail = stderr?.toString?.() || err?.message || "";
104
+ const msg = formatErr("execAsync", command, detail);
100
105
  if (error === "log") {
101
106
  console.error(msg);
102
107
  return resolve$2(void 0);
@@ -121,8 +126,7 @@ const spawnSyncWithString = (cmd, args, options) => {
121
126
  ...others
122
127
  });
123
128
  if (status !== 0 || err) {
124
- const detail = err?.message || stderr?.toString?.() || "";
125
- const msg = `${red("spawnSync")} ${dim(fullCmd)} ${detail}`;
129
+ const msg = formatErr("spawnSync", fullCmd, err?.message || stderr?.toString?.() || "");
126
130
  if (error === "log") {
127
131
  console.error(msg);
128
132
  return;
@@ -156,7 +160,7 @@ const execSyncWithString = (cmd, argsOrOptions, maybeOptions) => {
156
160
  return trim ? stdout.trim() : stdout;
157
161
  } catch (e) {
158
162
  const stderr = e?.stderr?.toString?.() || e?.message || "";
159
- const msg = `${red("execSync")} ${dim(command)} ${stderr}`;
163
+ const msg = formatErr("execSync", command, stderr);
160
164
  if (error === "log") {
161
165
  console.error(msg);
162
166
  return;
@@ -414,7 +418,7 @@ const getAllRemotes = async () => {
414
418
  };
415
419
  /** 获取默认的远程地址 */
416
420
  const getDefaultRemote = async (branch) => {
417
- const targetBranch = branch ?? await getCurrentBranch();
421
+ const targetBranch = branch || await getCurrentBranch();
418
422
  return targetBranch ? await getRemoteForBranch(targetBranch) : void 0;
419
423
  };
420
424
  /** 获取默认远程地址之外的远程地址 */
@@ -432,29 +436,36 @@ const fetchAllBranch = (remoteName = "origin") => {
432
436
  ]);
433
437
  };
434
438
  /**
435
- * 获取本地所有 tag(不区分远程)
439
+ * 获取本地所有 tag
436
440
  * @returns {Promise<string[]>}
437
- * @defaults git tag
441
+ * @defaults git tag --list
438
442
  */
439
- const getTags = async () => {
440
- const tags = await runGit(["tag"]);
441
- return tags ? tags.split("\n").sort() : [];
443
+ const getLocalTags = async () => {
444
+ const tags = await runGit(["tag", "--list"]);
445
+ return tags ? tags.split("\n").filter(Boolean) : [];
446
+ };
447
+ /** 获取远程 tags */
448
+ const getSortedTags = async (match = "*", exclude = "*-beta.*", sort = "v:refname", count = 0) => {
449
+ const res = await runGit([
450
+ "for-each-ref",
451
+ "--format=%(refname:short)",
452
+ `--sort=-${sort}`,
453
+ `--exclude=${exclude}`,
454
+ `--count=${count}`,
455
+ `refs/tags/${match}`
456
+ ]);
457
+ return res ? res.split("\n").filter(Boolean) : [];
442
458
  };
443
459
  /**
444
460
  * 获取远程(或所有 refs)中的 tag
445
461
  * 使用 for-each-ref 以支持版本号排序
446
462
  * @param {string} match 默认 *
463
+ * @param {string} exclude 默认 beta
447
464
  * @returns {Promise<string[]>}
448
465
  * @defaults git for-each-ref --sort=-v:refname --format=%(refname:short) refs/tags/<match>
449
466
  */
450
- const getRemoteTags = async (match = "*") => {
451
- const tags = await runGit([
452
- "for-each-ref",
453
- "--sort=-v:refname",
454
- "--format=%(refname:short)",
455
- `refs/tags/${match}`
456
- ]);
457
- return tags ? tags.split("\n").sort() : [];
467
+ const getRemoteTags = async (match = "*", exclude = "*-beta.*") => {
468
+ return getSortedTags(match, exclude);
458
469
  };
459
470
  /**
460
471
  * 获取当前工作区状态(不包含未跟踪文件)
@@ -514,7 +525,7 @@ const getRemote = async () => {
514
525
  };
515
526
  };
516
527
  /**
517
- * 获取最新 tag(基于 git describe)
528
+ * 获取最新 tag
518
529
  *
519
530
  * 默认:
520
531
  * - 匹配所有 tag
@@ -522,73 +533,40 @@ const getRemote = async () => {
522
533
  * @param {string} match 默认 *
523
534
  * @param {string} exclude 默认 beta
524
535
  * @returns {Promise<string | undefined>}
525
- * @defaults git describe --tags --abbrev=0 --match=<match> --exclude=<exclude>
526
536
  */
527
537
  const getLatestTag = async (match = "*", exclude = "*-beta.*") => {
528
- return runGit([
529
- "describe",
530
- "--tags",
531
- "--abbrev=0",
532
- `--match=${match}`,
533
- `--exclude=${exclude}`
534
- ]);
535
- };
536
- /**
537
- * 从所有 refs 中获取最新 tag
538
- * 适用于 git describe 不可靠的场景(如 tag 不在当前分支)
539
- * @param {string} match
540
- * @returns {Promise<string | undefined>}
541
- * @defaults git -c versionsort.suffix=- for-each-ref --count=1 --sort=-v:refname --format=%(refname:short) refs/tags/<match>
542
- */
543
- const getLatestTagFromAllRefs = async (match = "*") => {
544
- return runGit([
545
- "-c",
546
- "versionsort.suffix=-",
547
- "for-each-ref",
548
- "--count=1",
549
- "--sort=-v:refname",
550
- "--format=%(refname:short)",
551
- `refs/tags/${match}`
552
- ]);
538
+ const [latestTag] = await getSortedTags(match, exclude, void 0, 1);
539
+ return latestTag;
553
540
  };
554
541
  /**
555
542
  * 获取上一个 tag
556
- * @param {string} current
557
- * @returns {Promise<string | undefined>}
558
- */
559
- const getPreviousTag = async (current) => {
560
- return runGit([
561
- "describe",
562
- "--tags",
563
- "--abbrev=0",
564
- `${await runGit([
565
- "rev-list",
566
- "--tags",
567
- current ?? "--skip=1",
568
- "--max-count=1"
569
- ])}^`
570
- ]);
571
- };
572
- /**
573
- * 将短 hash 解析为完整 hash
574
- * @param {string} short
543
+ *
544
+ * 默认:
545
+ * - 匹配所有 tag
546
+ * - 排除 beta 版本
547
+ * @param {string} latestTag
548
+ * @param {string} match 默认 *
549
+ * @param {string} exclude 默认 beta
575
550
  * @returns {Promise<string | undefined>}
576
551
  */
577
- const getFullHash = (short) => {
578
- return runGit(["rev-parse", short]);
552
+ const getPreviousTag = async (latestTag, match = "*", exclude = "*-beta.*") => {
553
+ const all = await getSortedTags(match, exclude, void 0, 2);
554
+ return all[all.findIndex((k) => latestTag === k) + 1];
579
555
  };
580
556
  /**
581
557
  * 计算 changelog 的 commit 范围
582
558
  * @param {boolean} isIncrement 是否为版本递增发布
583
- * @returns {Promise<{from: string, to: string} | {from: string, to: string} | {from: string, to: string}>}
559
+ * @param {string} match tag match
560
+ * @param {string} exclude tag exclude
561
+ * @returns {Promise<{from: string, to: string}>}
584
562
  */
585
- const resolveChangelogRange = async (isIncrement = true) => {
586
- const latestTag = await getLatestTag();
587
- const previousTag = await getPreviousTag(latestTag);
563
+ const resolveChangelogRange = async (isIncrement = true, match = "*", exclude = "*-beta.*") => {
564
+ const latestTag = await getLatestTag(match, exclude);
588
565
  if (!latestTag) return {
589
566
  from: "",
590
567
  to: "HEAD"
591
568
  };
569
+ const previousTag = await getPreviousTag(latestTag);
592
570
  if (!isIncrement && previousTag) return {
593
571
  from: previousTag,
594
572
  to: `${latestTag}^1`
@@ -599,6 +577,14 @@ const resolveChangelogRange = async (isIncrement = true) => {
599
577
  };
600
578
  };
601
579
  /**
580
+ * 将短 hash 解析为完整 hash
581
+ * @param {string} short
582
+ * @returns {Promise<string | undefined>}
583
+ */
584
+ const getFullHash = (short) => {
585
+ return runGit(["rev-parse", short]);
586
+ };
587
+ /**
602
588
  * 获取指定范围内的 commit 日志
603
589
  * @param {string} from
604
590
  * @param {string} to
@@ -634,7 +620,7 @@ const hasUpstreamBranch = async () => {
634
620
  /** 获取 push 所需的 upstream 参数 */
635
621
  const getUpstreamArgs = async (remoteName, branch) => {
636
622
  const hasUpstream = await hasUpstreamBranch();
637
- const target = branch ?? await getCurrentBranch();
623
+ const target = branch || await getCurrentBranch();
638
624
  if (!hasUpstream) return [
639
625
  "--set-upstream",
640
626
  remoteName,
@@ -1015,7 +1001,7 @@ const getRegistry = async (pkgDir) => {
1015
1001
  const getAccess = async (pkgDir) => {
1016
1002
  const { name, publishConfig = {} } = readJsonFile((0, node_path.join)(pkgDir, "package.json"));
1017
1003
  const { access } = publishConfig;
1018
- return access ?? (name.startsWith("@") ? "restricted" : "public");
1004
+ return access || (name.startsWith("@") ? "restricted" : "public");
1019
1005
  };
1020
1006
  /**
1021
1007
  * 检查与仓库的连接
@@ -1126,7 +1112,35 @@ const publishPackage = (options) => {
1126
1112
  ...registryArg(registry),
1127
1113
  "--workspaces=false",
1128
1114
  ...args
1129
- ], { cwd });
1115
+ ], {
1116
+ cwd,
1117
+ error: "throw"
1118
+ });
1119
+ };
1120
+
1121
+ //#endregion
1122
+ //#region src/version.ts
1123
+ const isPrerelease = (version) => {
1124
+ return Boolean((0, semver.prerelease)(version));
1125
+ };
1126
+ const isValid = (version) => {
1127
+ return Boolean((0, semver.valid)(version));
1128
+ };
1129
+ const cleanVersion = (version) => {
1130
+ return (0, semver.clean)(version) ?? version;
1131
+ };
1132
+ const parseVersion = (raw) => {
1133
+ const version = isValid(raw) ? raw : (0, semver.coerce)(raw)?.toString();
1134
+ if (!version) return {};
1135
+ const { prerelease: prerelease$1 } = (0, semver.parse)(version);
1136
+ const isPrerelease$1 = Boolean(prerelease$1.length);
1137
+ const [preId, preBase] = prerelease$1.map(String);
1138
+ return {
1139
+ version,
1140
+ isPrerelease: isPrerelease$1,
1141
+ preId,
1142
+ preBase
1143
+ };
1130
1144
  };
1131
1145
 
1132
1146
  //#endregion
@@ -1140,6 +1154,7 @@ exports.YesOrNo = YesOrNo;
1140
1154
  exports.accessArg = accessArg;
1141
1155
  exports.bumpPackageVersion = bumpPackageVersion;
1142
1156
  exports.checkVersion = checkVersion;
1157
+ exports.cleanVersion = cleanVersion;
1143
1158
  exports.coloredChangeset = coloredChangeset;
1144
1159
  exports.copyDirAsync = copyDirAsync;
1145
1160
  exports.countCommitsSinceLatestTag = countCommitsSinceLatestTag;
@@ -1167,7 +1182,7 @@ exports.getGitRemoteUrl = getGitRemoteUrl;
1167
1182
  exports.getGithubReleaseUrl = getGithubReleaseUrl;
1168
1183
  exports.getGithubUrl = getGithubUrl;
1169
1184
  exports.getLatestTag = getLatestTag;
1170
- exports.getLatestTagFromAllRefs = getLatestTagFromAllRefs;
1185
+ exports.getLocalTags = getLocalTags;
1171
1186
  exports.getLog = getLog;
1172
1187
  exports.getOtherRemotes = getOtherRemotes;
1173
1188
  exports.getPackageInfo = getPackageInfo;
@@ -1178,8 +1193,8 @@ exports.getRegistry = getRegistry;
1178
1193
  exports.getRemote = getRemote;
1179
1194
  exports.getRemoteForBranch = getRemoteForBranch;
1180
1195
  exports.getRemoteTags = getRemoteTags;
1196
+ exports.getSortedTags = getSortedTags;
1181
1197
  exports.getStatus = getStatus;
1182
- exports.getTags = getTags;
1183
1198
  exports.getUpstreamArgs = getUpstreamArgs;
1184
1199
  exports.gitAddAll = gitAddAll;
1185
1200
  exports.gitAddTracked = gitAddTracked;
@@ -1192,13 +1207,16 @@ exports.hasUpstreamBranch = hasUpstreamBranch;
1192
1207
  exports.hasWriteAccess = hasWriteAccess;
1193
1208
  exports.isEmpty = isEmpty;
1194
1209
  exports.isGitRepo = isGitRepo;
1210
+ exports.isPrerelease = isPrerelease;
1195
1211
  exports.isRemoteName = isRemoteName;
1196
1212
  exports.isTestFile = isTestFile;
1213
+ exports.isValid = isValid;
1197
1214
  exports.isValidPackageName = isValidPackageName;
1198
1215
  exports.isWorkingDirClean = isWorkingDirClean;
1199
1216
  exports.joinUrl = joinUrl;
1200
1217
  exports.parseArgs = parseArgs;
1201
1218
  exports.parseGitHubRepo = parseGitHubRepo;
1219
+ exports.parseVersion = parseVersion;
1202
1220
  exports.pingRegistry = pingRegistry;
1203
1221
  exports.pkgFromUserAgent = pkgFromUserAgent;
1204
1222
  exports.publishPackage = publishPackage;
package/dist/index.d.cts CHANGED
@@ -155,19 +155,22 @@ declare const getOtherRemotes: (branch?: string) => Promise<string[]>;
155
155
  /** 提取所有分支 */
156
156
  declare const fetchAllBranch: (remoteName?: string) => Promise<string | undefined>;
157
157
  /**
158
- * 获取本地所有 tag(不区分远程)
158
+ * 获取本地所有 tag
159
159
  * @returns {Promise<string[]>}
160
- * @defaults git tag
160
+ * @defaults git tag --list
161
161
  */
162
- declare const getTags: () => Promise<string[]>;
162
+ declare const getLocalTags: () => Promise<string[]>;
163
+ /** 获取远程 tags */
164
+ declare const getSortedTags: (match?: string, exclude?: string, sort?: "v:refname" | "creatordate", count?: number) => Promise<string[]>;
163
165
  /**
164
166
  * 获取远程(或所有 refs)中的 tag
165
167
  * 使用 for-each-ref 以支持版本号排序
166
168
  * @param {string} match 默认 *
169
+ * @param {string} exclude 默认 beta
167
170
  * @returns {Promise<string[]>}
168
171
  * @defaults git for-each-ref --sort=-v:refname --format=%(refname:short) refs/tags/<match>
169
172
  */
170
- declare const getRemoteTags: (match?: string) => Promise<string[]>;
173
+ declare const getRemoteTags: (match?: string, exclude?: string) => Promise<string[]>;
171
174
  /**
172
175
  * 获取当前工作区状态(不包含未跟踪文件)
173
176
  * @returns {Promise<string | undefined>}
@@ -193,7 +196,7 @@ declare const getRemote: () => Promise<{
193
196
  remoteUrl: string | undefined;
194
197
  }>;
195
198
  /**
196
- * 获取最新 tag(基于 git describe)
199
+ * 获取最新 tag
197
200
  *
198
201
  * 默认:
199
202
  * - 匹配所有 tag
@@ -201,38 +204,37 @@ declare const getRemote: () => Promise<{
201
204
  * @param {string} match 默认 *
202
205
  * @param {string} exclude 默认 beta
203
206
  * @returns {Promise<string | undefined>}
204
- * @defaults git describe --tags --abbrev=0 --match=<match> --exclude=<exclude>
205
207
  */
206
208
  declare const getLatestTag: (match?: string, exclude?: string) => Promise<string | undefined>;
207
- /**
208
- * 从所有 refs 中获取最新 tag
209
- * 适用于 git describe 不可靠的场景(如 tag 不在当前分支)
210
- * @param {string} match
211
- * @returns {Promise<string | undefined>}
212
- * @defaults git -c versionsort.suffix=- for-each-ref --count=1 --sort=-v:refname --format=%(refname:short) refs/tags/<match>
213
- */
214
- declare const getLatestTagFromAllRefs: (match?: string) => Promise<string | undefined>;
215
209
  /**
216
210
  * 获取上一个 tag
217
- * @param {string} current
218
- * @returns {Promise<string | undefined>}
219
- */
220
- declare const getPreviousTag: (current?: string) => Promise<string | undefined>;
221
- /**
222
- * 将短 hash 解析为完整 hash
223
- * @param {string} short
211
+ *
212
+ * 默认:
213
+ * - 匹配所有 tag
214
+ * - 排除 beta 版本
215
+ * @param {string} latestTag
216
+ * @param {string} match 默认 *
217
+ * @param {string} exclude 默认 beta
224
218
  * @returns {Promise<string | undefined>}
225
219
  */
226
- declare const getFullHash: (short: string) => Promise<string | undefined>;
220
+ declare const getPreviousTag: (latestTag: string, match?: string, exclude?: string) => Promise<string | undefined>;
227
221
  /**
228
222
  * 计算 changelog 的 commit 范围
229
223
  * @param {boolean} isIncrement 是否为版本递增发布
230
- * @returns {Promise<{from: string, to: string} | {from: string, to: string} | {from: string, to: string}>}
224
+ * @param {string} match tag match
225
+ * @param {string} exclude tag exclude
226
+ * @returns {Promise<{from: string, to: string}>}
231
227
  */
232
- declare const resolveChangelogRange: (isIncrement?: boolean) => Promise<{
228
+ declare const resolveChangelogRange: (isIncrement?: boolean, match?: string, exclude?: string) => Promise<{
233
229
  from: string;
234
230
  to: string;
235
231
  }>;
232
+ /**
233
+ * 将短 hash 解析为完整 hash
234
+ * @param {string} short
235
+ * @returns {Promise<string | undefined>}
236
+ */
237
+ declare const getFullHash: (short: string) => Promise<string | undefined>;
236
238
  /**
237
239
  * 获取指定范围内的 commit 日志
238
240
  * @param {string} from
@@ -283,7 +285,7 @@ declare const pushTag: (remoteName: string, tag: string, args?: string[]) => Pro
283
285
  * @param {string[]} args
284
286
  * @returns {Promise<string | undefined>}
285
287
  */
286
- declare const pushBranch: (remoteName: string, branch: string, args?: string[]) => Promise<void>;
288
+ declare const pushBranch: (remoteName: string, branch?: string, args?: string[]) => Promise<void>;
287
289
  /**
288
290
  * 撤销【工作区】中某个文件的修改(未暂存的改动)
289
291
  * - 不影响暂存区
@@ -520,4 +522,20 @@ declare const publishPackage: (options?: {
520
522
  cwd?: string;
521
523
  }) => Promise<string | undefined>;
522
524
  //#endregion
523
- export { CliOptions, ConfirmResult, CopyOptions, DEFAULT_ACCESS, DEFAULT_REGISTRY, DEFAULT_TAG, ExecAsyncWithStringOptions, ExecResultOptions, ExecSyncWithStringOptions, HttpLibrary, PkgInfo, PkgManager, SpawnAsyncWithStringOptions, SpawnSyncWithStringOptions, YesOrNo, accessArg, bumpPackageVersion, checkVersion, coloredChangeset, copyDirAsync, countCommitsSinceLatestTag, deleteTag, deleteTagSync, discardAll, discardAllSync, discardFile, editFile, editJsonFile, emptyDir, eol, execAsync, execSyncWithString, fetchAllBranch, getAccess, getAllRemotes, getAuthenticatedUser, getCurrentBranch, getDefaultRemote, getDistTags, getFullHash, getGitConfig, getGitRemoteUrl, getGithubReleaseUrl, getGithubUrl, getLatestTag, getLatestTagFromAllRefs, getLog, getOtherRemotes, getPackageInfo, getPackageUrl, getPreviousTag, getPublishedVersion, getRegistry, getRemote, getRemoteForBranch, getRemoteTags, getStatus, getTags, getUpstreamArgs, gitAddAll, gitAddTracked, gitCommit, gitCommitAmend, gitTagAnnotated, gitTagLightweight, gitUndo, hasUpstreamBranch, hasWriteAccess, isEmpty, isGitRepo, isRemoteName, isTestFile, isValidPackageName, isWorkingDirClean, joinUrl, parseArgs, parseGitHubRepo, pingRegistry, pkgFromUserAgent, publishPackage, pushBranch, pushTag, readJsonFile, readSubDirs, registryArg, resetHard, resetHardSync, resetMixed, resetSoft, resolveChangelogRange, restoreAll, restoreAllSync, restoreFile, restoreFileFromCommit, restoreFromCommit, revertCommit, runCliForTest, runGit, runGitSync, runNode, runNodeSync, runNpm, runNpmSync, space, spawnAsync, spawnSyncWithString, stringifyArgs, tagArg, toValidPackageName, toValidProjectName, trimTemplate, unstageAll, unstageFile };
525
+ //#region src/version.d.ts
526
+ declare const isPrerelease: (version: string) => boolean;
527
+ declare const isValid: (version: string) => boolean;
528
+ declare const cleanVersion: (version: string) => string;
529
+ declare const parseVersion: (raw: string) => {
530
+ version?: undefined;
531
+ isPrerelease?: undefined;
532
+ preId?: undefined;
533
+ preBase?: undefined;
534
+ } | {
535
+ version: string;
536
+ isPrerelease: boolean;
537
+ preId: string;
538
+ preBase: string;
539
+ };
540
+ //#endregion
541
+ export { CliOptions, ConfirmResult, CopyOptions, DEFAULT_ACCESS, DEFAULT_REGISTRY, DEFAULT_TAG, ExecAsyncWithStringOptions, ExecResultOptions, ExecSyncWithStringOptions, HttpLibrary, PkgInfo, PkgManager, SpawnAsyncWithStringOptions, SpawnSyncWithStringOptions, YesOrNo, accessArg, bumpPackageVersion, checkVersion, cleanVersion, coloredChangeset, copyDirAsync, countCommitsSinceLatestTag, deleteTag, deleteTagSync, discardAll, discardAllSync, discardFile, editFile, editJsonFile, emptyDir, eol, execAsync, execSyncWithString, fetchAllBranch, getAccess, getAllRemotes, getAuthenticatedUser, getCurrentBranch, getDefaultRemote, getDistTags, getFullHash, getGitConfig, getGitRemoteUrl, getGithubReleaseUrl, getGithubUrl, getLatestTag, getLocalTags, getLog, getOtherRemotes, getPackageInfo, getPackageUrl, getPreviousTag, getPublishedVersion, getRegistry, getRemote, getRemoteForBranch, getRemoteTags, getSortedTags, getStatus, getUpstreamArgs, gitAddAll, gitAddTracked, gitCommit, gitCommitAmend, gitTagAnnotated, gitTagLightweight, gitUndo, hasUpstreamBranch, hasWriteAccess, isEmpty, isGitRepo, isPrerelease, isRemoteName, isTestFile, isValid, isValidPackageName, isWorkingDirClean, joinUrl, parseArgs, parseGitHubRepo, parseVersion, pingRegistry, pkgFromUserAgent, publishPackage, pushBranch, pushTag, readJsonFile, readSubDirs, registryArg, resetHard, resetHardSync, resetMixed, resetSoft, resolveChangelogRange, restoreAll, restoreAllSync, restoreFile, restoreFileFromCommit, restoreFromCommit, revertCommit, runCliForTest, runGit, runGitSync, runNode, runNodeSync, runNpm, runNpmSync, space, spawnAsync, spawnSyncWithString, stringifyArgs, tagArg, toValidPackageName, toValidProjectName, trimTemplate, unstageAll, unstageFile };
package/dist/index.d.mts CHANGED
@@ -155,19 +155,22 @@ declare const getOtherRemotes: (branch?: string) => Promise<string[]>;
155
155
  /** 提取所有分支 */
156
156
  declare const fetchAllBranch: (remoteName?: string) => Promise<string | undefined>;
157
157
  /**
158
- * 获取本地所有 tag(不区分远程)
158
+ * 获取本地所有 tag
159
159
  * @returns {Promise<string[]>}
160
- * @defaults git tag
160
+ * @defaults git tag --list
161
161
  */
162
- declare const getTags: () => Promise<string[]>;
162
+ declare const getLocalTags: () => Promise<string[]>;
163
+ /** 获取远程 tags */
164
+ declare const getSortedTags: (match?: string, exclude?: string, sort?: "v:refname" | "creatordate", count?: number) => Promise<string[]>;
163
165
  /**
164
166
  * 获取远程(或所有 refs)中的 tag
165
167
  * 使用 for-each-ref 以支持版本号排序
166
168
  * @param {string} match 默认 *
169
+ * @param {string} exclude 默认 beta
167
170
  * @returns {Promise<string[]>}
168
171
  * @defaults git for-each-ref --sort=-v:refname --format=%(refname:short) refs/tags/<match>
169
172
  */
170
- declare const getRemoteTags: (match?: string) => Promise<string[]>;
173
+ declare const getRemoteTags: (match?: string, exclude?: string) => Promise<string[]>;
171
174
  /**
172
175
  * 获取当前工作区状态(不包含未跟踪文件)
173
176
  * @returns {Promise<string | undefined>}
@@ -193,7 +196,7 @@ declare const getRemote: () => Promise<{
193
196
  remoteUrl: string | undefined;
194
197
  }>;
195
198
  /**
196
- * 获取最新 tag(基于 git describe)
199
+ * 获取最新 tag
197
200
  *
198
201
  * 默认:
199
202
  * - 匹配所有 tag
@@ -201,38 +204,37 @@ declare const getRemote: () => Promise<{
201
204
  * @param {string} match 默认 *
202
205
  * @param {string} exclude 默认 beta
203
206
  * @returns {Promise<string | undefined>}
204
- * @defaults git describe --tags --abbrev=0 --match=<match> --exclude=<exclude>
205
207
  */
206
208
  declare const getLatestTag: (match?: string, exclude?: string) => Promise<string | undefined>;
207
- /**
208
- * 从所有 refs 中获取最新 tag
209
- * 适用于 git describe 不可靠的场景(如 tag 不在当前分支)
210
- * @param {string} match
211
- * @returns {Promise<string | undefined>}
212
- * @defaults git -c versionsort.suffix=- for-each-ref --count=1 --sort=-v:refname --format=%(refname:short) refs/tags/<match>
213
- */
214
- declare const getLatestTagFromAllRefs: (match?: string) => Promise<string | undefined>;
215
209
  /**
216
210
  * 获取上一个 tag
217
- * @param {string} current
218
- * @returns {Promise<string | undefined>}
219
- */
220
- declare const getPreviousTag: (current?: string) => Promise<string | undefined>;
221
- /**
222
- * 将短 hash 解析为完整 hash
223
- * @param {string} short
211
+ *
212
+ * 默认:
213
+ * - 匹配所有 tag
214
+ * - 排除 beta 版本
215
+ * @param {string} latestTag
216
+ * @param {string} match 默认 *
217
+ * @param {string} exclude 默认 beta
224
218
  * @returns {Promise<string | undefined>}
225
219
  */
226
- declare const getFullHash: (short: string) => Promise<string | undefined>;
220
+ declare const getPreviousTag: (latestTag: string, match?: string, exclude?: string) => Promise<string | undefined>;
227
221
  /**
228
222
  * 计算 changelog 的 commit 范围
229
223
  * @param {boolean} isIncrement 是否为版本递增发布
230
- * @returns {Promise<{from: string, to: string} | {from: string, to: string} | {from: string, to: string}>}
224
+ * @param {string} match tag match
225
+ * @param {string} exclude tag exclude
226
+ * @returns {Promise<{from: string, to: string}>}
231
227
  */
232
- declare const resolveChangelogRange: (isIncrement?: boolean) => Promise<{
228
+ declare const resolveChangelogRange: (isIncrement?: boolean, match?: string, exclude?: string) => Promise<{
233
229
  from: string;
234
230
  to: string;
235
231
  }>;
232
+ /**
233
+ * 将短 hash 解析为完整 hash
234
+ * @param {string} short
235
+ * @returns {Promise<string | undefined>}
236
+ */
237
+ declare const getFullHash: (short: string) => Promise<string | undefined>;
236
238
  /**
237
239
  * 获取指定范围内的 commit 日志
238
240
  * @param {string} from
@@ -283,7 +285,7 @@ declare const pushTag: (remoteName: string, tag: string, args?: string[]) => Pro
283
285
  * @param {string[]} args
284
286
  * @returns {Promise<string | undefined>}
285
287
  */
286
- declare const pushBranch: (remoteName: string, branch: string, args?: string[]) => Promise<void>;
288
+ declare const pushBranch: (remoteName: string, branch?: string, args?: string[]) => Promise<void>;
287
289
  /**
288
290
  * 撤销【工作区】中某个文件的修改(未暂存的改动)
289
291
  * - 不影响暂存区
@@ -520,4 +522,20 @@ declare const publishPackage: (options?: {
520
522
  cwd?: string;
521
523
  }) => Promise<string | undefined>;
522
524
  //#endregion
523
- export { CliOptions, ConfirmResult, CopyOptions, DEFAULT_ACCESS, DEFAULT_REGISTRY, DEFAULT_TAG, ExecAsyncWithStringOptions, ExecResultOptions, ExecSyncWithStringOptions, HttpLibrary, PkgInfo, PkgManager, SpawnAsyncWithStringOptions, SpawnSyncWithStringOptions, YesOrNo, accessArg, bumpPackageVersion, checkVersion, coloredChangeset, copyDirAsync, countCommitsSinceLatestTag, deleteTag, deleteTagSync, discardAll, discardAllSync, discardFile, editFile, editJsonFile, emptyDir, eol, execAsync, execSyncWithString, fetchAllBranch, getAccess, getAllRemotes, getAuthenticatedUser, getCurrentBranch, getDefaultRemote, getDistTags, getFullHash, getGitConfig, getGitRemoteUrl, getGithubReleaseUrl, getGithubUrl, getLatestTag, getLatestTagFromAllRefs, getLog, getOtherRemotes, getPackageInfo, getPackageUrl, getPreviousTag, getPublishedVersion, getRegistry, getRemote, getRemoteForBranch, getRemoteTags, getStatus, getTags, getUpstreamArgs, gitAddAll, gitAddTracked, gitCommit, gitCommitAmend, gitTagAnnotated, gitTagLightweight, gitUndo, hasUpstreamBranch, hasWriteAccess, isEmpty, isGitRepo, isRemoteName, isTestFile, isValidPackageName, isWorkingDirClean, joinUrl, parseArgs, parseGitHubRepo, pingRegistry, pkgFromUserAgent, publishPackage, pushBranch, pushTag, readJsonFile, readSubDirs, registryArg, resetHard, resetHardSync, resetMixed, resetSoft, resolveChangelogRange, restoreAll, restoreAllSync, restoreFile, restoreFileFromCommit, restoreFromCommit, revertCommit, runCliForTest, runGit, runGitSync, runNode, runNodeSync, runNpm, runNpmSync, space, spawnAsync, spawnSyncWithString, stringifyArgs, tagArg, toValidPackageName, toValidProjectName, trimTemplate, unstageAll, unstageFile };
525
+ //#region src/version.d.ts
526
+ declare const isPrerelease: (version: string) => boolean;
527
+ declare const isValid: (version: string) => boolean;
528
+ declare const cleanVersion: (version: string) => string;
529
+ declare const parseVersion: (raw: string) => {
530
+ version?: undefined;
531
+ isPrerelease?: undefined;
532
+ preId?: undefined;
533
+ preBase?: undefined;
534
+ } | {
535
+ version: string;
536
+ isPrerelease: boolean;
537
+ preId: string;
538
+ preBase: string;
539
+ };
540
+ //#endregion
541
+ export { CliOptions, ConfirmResult, CopyOptions, DEFAULT_ACCESS, DEFAULT_REGISTRY, DEFAULT_TAG, ExecAsyncWithStringOptions, ExecResultOptions, ExecSyncWithStringOptions, HttpLibrary, PkgInfo, PkgManager, SpawnAsyncWithStringOptions, SpawnSyncWithStringOptions, YesOrNo, accessArg, bumpPackageVersion, checkVersion, cleanVersion, coloredChangeset, copyDirAsync, countCommitsSinceLatestTag, deleteTag, deleteTagSync, discardAll, discardAllSync, discardFile, editFile, editJsonFile, emptyDir, eol, execAsync, execSyncWithString, fetchAllBranch, getAccess, getAllRemotes, getAuthenticatedUser, getCurrentBranch, getDefaultRemote, getDistTags, getFullHash, getGitConfig, getGitRemoteUrl, getGithubReleaseUrl, getGithubUrl, getLatestTag, getLocalTags, getLog, getOtherRemotes, getPackageInfo, getPackageUrl, getPreviousTag, getPublishedVersion, getRegistry, getRemote, getRemoteForBranch, getRemoteTags, getSortedTags, getStatus, getUpstreamArgs, gitAddAll, gitAddTracked, gitCommit, gitCommitAmend, gitTagAnnotated, gitTagLightweight, gitUndo, hasUpstreamBranch, hasWriteAccess, isEmpty, isGitRepo, isPrerelease, isRemoteName, isTestFile, isValid, isValidPackageName, isWorkingDirClean, joinUrl, parseArgs, parseGitHubRepo, parseVersion, pingRegistry, pkgFromUserAgent, publishPackage, pushBranch, pushTag, readJsonFile, readSubDirs, registryArg, resetHard, resetHardSync, resetMixed, resetSoft, resolveChangelogRange, restoreAll, restoreAllSync, restoreFile, restoreFileFromCommit, restoreFromCommit, revertCommit, runCliForTest, runGit, runGitSync, runNode, runNodeSync, runNpm, runNpmSync, space, spawnAsync, spawnSyncWithString, stringifyArgs, tagArg, toValidPackageName, toValidProjectName, trimTemplate, unstageAll, unstageFile };
package/dist/index.mjs CHANGED
@@ -4,6 +4,7 @@ import { EOL } from "node:os";
4
4
  import { join, resolve } from "node:path";
5
5
  import { exec, execSync, spawn, spawnSync } from "node:child_process";
6
6
  import { styleText } from "node:util";
7
+ import { clean, coerce, parse, prerelease, valid } from "semver";
7
8
 
8
9
  //#region src/enums.ts
9
10
  let PkgManager = /* @__PURE__ */ function(PkgManager$1) {
@@ -42,6 +43,9 @@ const red = (text) => styleText(["red"], text);
42
43
 
43
44
  //#endregion
44
45
  //#region src/shell.ts
46
+ const formatErr = (caller, cmd, err) => {
47
+ return `${red(caller)} ${dim(cmd)}${eol()}${err}`;
48
+ };
45
49
  /** 异步执行 `spawn` 获取字符串类型的结果 */
46
50
  const spawnAsync = (cmd, args, options) => {
47
51
  return new Promise((resolve$1, reject) => {
@@ -65,7 +69,7 @@ const spawnAsync = (cmd, args, options) => {
65
69
  child.on("error", reject);
66
70
  child.on("close", (code) => {
67
71
  if (code !== 0) {
68
- const msg = `${red("spawnAsync")} ${dim(fullCmd)} ${stderr}`;
72
+ const msg = formatErr("spawnAsync", fullCmd, stderr);
69
73
  if (error === "log") {
70
74
  console.error(msg);
71
75
  return resolve$1(void 0);
@@ -96,7 +100,8 @@ const execAsync = (cmd, argsOrOptions, maybeOptions) => {
96
100
  }
97
101
  exec(command, { ...others }, (err, stdout, stderr) => {
98
102
  if (err) {
99
- const msg = `${red("execAsync")} ${dim(command)} ${stderr || err.message}`;
103
+ const detail = stderr?.toString?.() || err?.message || "";
104
+ const msg = formatErr("execAsync", command, detail);
100
105
  if (error === "log") {
101
106
  console.error(msg);
102
107
  return resolve$1(void 0);
@@ -121,8 +126,7 @@ const spawnSyncWithString = (cmd, args, options) => {
121
126
  ...others
122
127
  });
123
128
  if (status !== 0 || err) {
124
- const detail = err?.message || stderr?.toString?.() || "";
125
- const msg = `${red("spawnSync")} ${dim(fullCmd)} ${detail}`;
129
+ const msg = formatErr("spawnSync", fullCmd, err?.message || stderr?.toString?.() || "");
126
130
  if (error === "log") {
127
131
  console.error(msg);
128
132
  return;
@@ -156,7 +160,7 @@ const execSyncWithString = (cmd, argsOrOptions, maybeOptions) => {
156
160
  return trim ? stdout.trim() : stdout;
157
161
  } catch (e) {
158
162
  const stderr = e?.stderr?.toString?.() || e?.message || "";
159
- const msg = `${red("execSync")} ${dim(command)} ${stderr}`;
163
+ const msg = formatErr("execSync", command, stderr);
160
164
  if (error === "log") {
161
165
  console.error(msg);
162
166
  return;
@@ -414,7 +418,7 @@ const getAllRemotes = async () => {
414
418
  };
415
419
  /** 获取默认的远程地址 */
416
420
  const getDefaultRemote = async (branch) => {
417
- const targetBranch = branch ?? await getCurrentBranch();
421
+ const targetBranch = branch || await getCurrentBranch();
418
422
  return targetBranch ? await getRemoteForBranch(targetBranch) : void 0;
419
423
  };
420
424
  /** 获取默认远程地址之外的远程地址 */
@@ -432,29 +436,36 @@ const fetchAllBranch = (remoteName = "origin") => {
432
436
  ]);
433
437
  };
434
438
  /**
435
- * 获取本地所有 tag(不区分远程)
439
+ * 获取本地所有 tag
436
440
  * @returns {Promise<string[]>}
437
- * @defaults git tag
441
+ * @defaults git tag --list
438
442
  */
439
- const getTags = async () => {
440
- const tags = await runGit(["tag"]);
441
- return tags ? tags.split("\n").sort() : [];
443
+ const getLocalTags = async () => {
444
+ const tags = await runGit(["tag", "--list"]);
445
+ return tags ? tags.split("\n").filter(Boolean) : [];
446
+ };
447
+ /** 获取远程 tags */
448
+ const getSortedTags = async (match = "*", exclude = "*-beta.*", sort = "v:refname", count = 0) => {
449
+ const res = await runGit([
450
+ "for-each-ref",
451
+ "--format=%(refname:short)",
452
+ `--sort=-${sort}`,
453
+ `--exclude=${exclude}`,
454
+ `--count=${count}`,
455
+ `refs/tags/${match}`
456
+ ]);
457
+ return res ? res.split("\n").filter(Boolean) : [];
442
458
  };
443
459
  /**
444
460
  * 获取远程(或所有 refs)中的 tag
445
461
  * 使用 for-each-ref 以支持版本号排序
446
462
  * @param {string} match 默认 *
463
+ * @param {string} exclude 默认 beta
447
464
  * @returns {Promise<string[]>}
448
465
  * @defaults git for-each-ref --sort=-v:refname --format=%(refname:short) refs/tags/<match>
449
466
  */
450
- const getRemoteTags = async (match = "*") => {
451
- const tags = await runGit([
452
- "for-each-ref",
453
- "--sort=-v:refname",
454
- "--format=%(refname:short)",
455
- `refs/tags/${match}`
456
- ]);
457
- return tags ? tags.split("\n").sort() : [];
467
+ const getRemoteTags = async (match = "*", exclude = "*-beta.*") => {
468
+ return getSortedTags(match, exclude);
458
469
  };
459
470
  /**
460
471
  * 获取当前工作区状态(不包含未跟踪文件)
@@ -514,7 +525,7 @@ const getRemote = async () => {
514
525
  };
515
526
  };
516
527
  /**
517
- * 获取最新 tag(基于 git describe)
528
+ * 获取最新 tag
518
529
  *
519
530
  * 默认:
520
531
  * - 匹配所有 tag
@@ -522,73 +533,40 @@ const getRemote = async () => {
522
533
  * @param {string} match 默认 *
523
534
  * @param {string} exclude 默认 beta
524
535
  * @returns {Promise<string | undefined>}
525
- * @defaults git describe --tags --abbrev=0 --match=<match> --exclude=<exclude>
526
536
  */
527
537
  const getLatestTag = async (match = "*", exclude = "*-beta.*") => {
528
- return runGit([
529
- "describe",
530
- "--tags",
531
- "--abbrev=0",
532
- `--match=${match}`,
533
- `--exclude=${exclude}`
534
- ]);
535
- };
536
- /**
537
- * 从所有 refs 中获取最新 tag
538
- * 适用于 git describe 不可靠的场景(如 tag 不在当前分支)
539
- * @param {string} match
540
- * @returns {Promise<string | undefined>}
541
- * @defaults git -c versionsort.suffix=- for-each-ref --count=1 --sort=-v:refname --format=%(refname:short) refs/tags/<match>
542
- */
543
- const getLatestTagFromAllRefs = async (match = "*") => {
544
- return runGit([
545
- "-c",
546
- "versionsort.suffix=-",
547
- "for-each-ref",
548
- "--count=1",
549
- "--sort=-v:refname",
550
- "--format=%(refname:short)",
551
- `refs/tags/${match}`
552
- ]);
538
+ const [latestTag] = await getSortedTags(match, exclude, void 0, 1);
539
+ return latestTag;
553
540
  };
554
541
  /**
555
542
  * 获取上一个 tag
556
- * @param {string} current
557
- * @returns {Promise<string | undefined>}
558
- */
559
- const getPreviousTag = async (current) => {
560
- return runGit([
561
- "describe",
562
- "--tags",
563
- "--abbrev=0",
564
- `${await runGit([
565
- "rev-list",
566
- "--tags",
567
- current ?? "--skip=1",
568
- "--max-count=1"
569
- ])}^`
570
- ]);
571
- };
572
- /**
573
- * 将短 hash 解析为完整 hash
574
- * @param {string} short
543
+ *
544
+ * 默认:
545
+ * - 匹配所有 tag
546
+ * - 排除 beta 版本
547
+ * @param {string} latestTag
548
+ * @param {string} match 默认 *
549
+ * @param {string} exclude 默认 beta
575
550
  * @returns {Promise<string | undefined>}
576
551
  */
577
- const getFullHash = (short) => {
578
- return runGit(["rev-parse", short]);
552
+ const getPreviousTag = async (latestTag, match = "*", exclude = "*-beta.*") => {
553
+ const all = await getSortedTags(match, exclude, void 0, 2);
554
+ return all[all.findIndex((k) => latestTag === k) + 1];
579
555
  };
580
556
  /**
581
557
  * 计算 changelog 的 commit 范围
582
558
  * @param {boolean} isIncrement 是否为版本递增发布
583
- * @returns {Promise<{from: string, to: string} | {from: string, to: string} | {from: string, to: string}>}
559
+ * @param {string} match tag match
560
+ * @param {string} exclude tag exclude
561
+ * @returns {Promise<{from: string, to: string}>}
584
562
  */
585
- const resolveChangelogRange = async (isIncrement = true) => {
586
- const latestTag = await getLatestTag();
587
- const previousTag = await getPreviousTag(latestTag);
563
+ const resolveChangelogRange = async (isIncrement = true, match = "*", exclude = "*-beta.*") => {
564
+ const latestTag = await getLatestTag(match, exclude);
588
565
  if (!latestTag) return {
589
566
  from: "",
590
567
  to: "HEAD"
591
568
  };
569
+ const previousTag = await getPreviousTag(latestTag);
592
570
  if (!isIncrement && previousTag) return {
593
571
  from: previousTag,
594
572
  to: `${latestTag}^1`
@@ -599,6 +577,14 @@ const resolveChangelogRange = async (isIncrement = true) => {
599
577
  };
600
578
  };
601
579
  /**
580
+ * 将短 hash 解析为完整 hash
581
+ * @param {string} short
582
+ * @returns {Promise<string | undefined>}
583
+ */
584
+ const getFullHash = (short) => {
585
+ return runGit(["rev-parse", short]);
586
+ };
587
+ /**
602
588
  * 获取指定范围内的 commit 日志
603
589
  * @param {string} from
604
590
  * @param {string} to
@@ -634,7 +620,7 @@ const hasUpstreamBranch = async () => {
634
620
  /** 获取 push 所需的 upstream 参数 */
635
621
  const getUpstreamArgs = async (remoteName, branch) => {
636
622
  const hasUpstream = await hasUpstreamBranch();
637
- const target = branch ?? await getCurrentBranch();
623
+ const target = branch || await getCurrentBranch();
638
624
  if (!hasUpstream) return [
639
625
  "--set-upstream",
640
626
  remoteName,
@@ -1015,7 +1001,7 @@ const getRegistry = async (pkgDir) => {
1015
1001
  const getAccess = async (pkgDir) => {
1016
1002
  const { name, publishConfig = {} } = readJsonFile(join(pkgDir, "package.json"));
1017
1003
  const { access } = publishConfig;
1018
- return access ?? (name.startsWith("@") ? "restricted" : "public");
1004
+ return access || (name.startsWith("@") ? "restricted" : "public");
1019
1005
  };
1020
1006
  /**
1021
1007
  * 检查与仓库的连接
@@ -1126,8 +1112,36 @@ const publishPackage = (options) => {
1126
1112
  ...registryArg(registry),
1127
1113
  "--workspaces=false",
1128
1114
  ...args
1129
- ], { cwd });
1115
+ ], {
1116
+ cwd,
1117
+ error: "throw"
1118
+ });
1119
+ };
1120
+
1121
+ //#endregion
1122
+ //#region src/version.ts
1123
+ const isPrerelease = (version) => {
1124
+ return Boolean(prerelease(version));
1125
+ };
1126
+ const isValid = (version) => {
1127
+ return Boolean(valid(version));
1128
+ };
1129
+ const cleanVersion = (version) => {
1130
+ return clean(version) ?? version;
1131
+ };
1132
+ const parseVersion = (raw) => {
1133
+ const version = isValid(raw) ? raw : coerce(raw)?.toString();
1134
+ if (!version) return {};
1135
+ const { prerelease: prerelease$1 } = parse(version);
1136
+ const isPrerelease$1 = Boolean(prerelease$1.length);
1137
+ const [preId, preBase] = prerelease$1.map(String);
1138
+ return {
1139
+ version,
1140
+ isPrerelease: isPrerelease$1,
1141
+ preId,
1142
+ preBase
1143
+ };
1130
1144
  };
1131
1145
 
1132
1146
  //#endregion
1133
- export { ConfirmResult, DEFAULT_ACCESS, DEFAULT_REGISTRY, DEFAULT_TAG, HttpLibrary, PkgManager, YesOrNo, accessArg, bumpPackageVersion, checkVersion, coloredChangeset, copyDirAsync, countCommitsSinceLatestTag, deleteTag, deleteTagSync, discardAll, discardAllSync, discardFile, editFile, editJsonFile, emptyDir, eol, execAsync, execSyncWithString, fetchAllBranch, getAccess, getAllRemotes, getAuthenticatedUser, getCurrentBranch, getDefaultRemote, getDistTags, getFullHash, getGitConfig, getGitRemoteUrl, getGithubReleaseUrl, getGithubUrl, getLatestTag, getLatestTagFromAllRefs, getLog, getOtherRemotes, getPackageInfo, getPackageUrl, getPreviousTag, getPublishedVersion, getRegistry, getRemote, getRemoteForBranch, getRemoteTags, getStatus, getTags, getUpstreamArgs, gitAddAll, gitAddTracked, gitCommit, gitCommitAmend, gitTagAnnotated, gitTagLightweight, gitUndo, hasUpstreamBranch, hasWriteAccess, isEmpty, isGitRepo, isRemoteName, isTestFile, isValidPackageName, isWorkingDirClean, joinUrl, parseArgs, parseGitHubRepo, pingRegistry, pkgFromUserAgent, publishPackage, pushBranch, pushTag, readJsonFile, readSubDirs, registryArg, resetHard, resetHardSync, resetMixed, resetSoft, resolveChangelogRange, restoreAll, restoreAllSync, restoreFile, restoreFileFromCommit, restoreFromCommit, revertCommit, runCliForTest, runGit, runGitSync, runNode, runNodeSync, runNpm, runNpmSync, space, spawnAsync, spawnSyncWithString, stringifyArgs, tagArg, toValidPackageName, toValidProjectName, trimTemplate, unstageAll, unstageFile };
1147
+ export { ConfirmResult, DEFAULT_ACCESS, DEFAULT_REGISTRY, DEFAULT_TAG, HttpLibrary, PkgManager, YesOrNo, accessArg, bumpPackageVersion, checkVersion, cleanVersion, coloredChangeset, copyDirAsync, countCommitsSinceLatestTag, deleteTag, deleteTagSync, discardAll, discardAllSync, discardFile, editFile, editJsonFile, emptyDir, eol, execAsync, execSyncWithString, fetchAllBranch, getAccess, getAllRemotes, getAuthenticatedUser, getCurrentBranch, getDefaultRemote, getDistTags, getFullHash, getGitConfig, getGitRemoteUrl, getGithubReleaseUrl, getGithubUrl, getLatestTag, getLocalTags, getLog, getOtherRemotes, getPackageInfo, getPackageUrl, getPreviousTag, getPublishedVersion, getRegistry, getRemote, getRemoteForBranch, getRemoteTags, getSortedTags, getStatus, getUpstreamArgs, gitAddAll, gitAddTracked, gitCommit, gitCommitAmend, gitTagAnnotated, gitTagLightweight, gitUndo, hasUpstreamBranch, hasWriteAccess, isEmpty, isGitRepo, isPrerelease, isRemoteName, isTestFile, isValid, isValidPackageName, isWorkingDirClean, joinUrl, parseArgs, parseGitHubRepo, parseVersion, pingRegistry, pkgFromUserAgent, publishPackage, pushBranch, pushTag, readJsonFile, readSubDirs, registryArg, resetHard, resetHardSync, resetMixed, resetSoft, resolveChangelogRange, restoreAll, restoreAllSync, restoreFile, restoreFileFromCommit, restoreFromCommit, revertCommit, runCliForTest, runGit, runGitSync, runNode, runNodeSync, runNpm, runNpmSync, space, spawnAsync, spawnSyncWithString, stringifyArgs, tagArg, toValidPackageName, toValidProjectName, trimTemplate, unstageAll, unstageFile };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@peiyanlu/cli-utils",
3
- "version": "0.0.5",
3
+ "version": "0.0.7",
4
4
  "description": "Shared utils for building interactive Node.js CLI applications.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -21,6 +21,7 @@
21
21
  "devDependencies": {
22
22
  "@release-it/conventional-changelog": "^10.0.2",
23
23
  "@types/node": "^24.10.3",
24
+ "@types/semver": "^7.7.1",
24
25
  "@vitest/coverage-v8": "^4.0.15",
25
26
  "release-it": "^19.0.2",
26
27
  "release-it-pnpm": "^4.6.6",
@@ -54,6 +55,9 @@
54
55
  "url": "https://github.com/peiyanlu/cli-utils/issues"
55
56
  },
56
57
  "homepage": "https://github.com/peiyanlu/cli-utils#readme",
58
+ "dependencies": {
59
+ "semver": "^7.7.3"
60
+ },
57
61
  "scripts": {
58
62
  "dev": "tsdown -w",
59
63
  "build": "tsdown",