@peiyanlu/release 0.0.1 → 0.0.2

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/cli.mjs CHANGED
@@ -1,21 +1,20 @@
1
- import { execAsync, isGitRepo, readJsonFile } from "@peiyanlu/cli-utils";
2
- import { blue, dim, gray, green, red, rgb, yellow } from "ansis";
3
- import { program } from "commander";
4
1
  import path, { dirname, join, resolve } from "node:path";
5
2
  import { fileURLToPath, pathToFileURL } from "node:url";
3
+ import { eol, execAsync, isGitRepo, parseGitHubRepo, readJsonFile, runGit, runNpm } from "@peiyanlu/cli-utils";
4
+ import { blue, dim, gray, green, red, rgb, underline, yellow } from "ansis";
5
+ import { program } from "commander";
6
6
  import { cancel, confirm, group, intro, isCancel, log, outro, select, tasks, text } from "@clack/prompts";
7
- import { inspect, styleText } from "node:util";
8
7
  import { clean, coerce, gt, gte, inc, parse, prerelease, valid } from "semver";
9
8
  import { createReadStream, existsSync, statSync } from "node:fs";
10
- import { EOL } from "node:os";
11
9
  import { readFile, writeFile } from "node:fs/promises";
12
10
  import { Octokit } from "@octokit/rest";
13
11
  import { contentType } from "mime-types";
14
12
  import open from "open";
15
13
  import { glob } from "tinyglobby";
16
- import { spawn } from "node:child_process";
14
+ import { inspect, styleText } from "node:util";
15
+ import { castArray, isUndefined } from "@peiyanlu/ts-utils";
17
16
 
18
- //#region node_modules/.pnpm/tsdown@0.18.2_typescript@5.9.3/node_modules/tsdown/esm-shims.js
17
+ //#region node_modules/.pnpm/tsdown@0.18.4_typescript@5.9.3/node_modules/tsdown/esm-shims.js
19
18
  const getFilename = () => fileURLToPath(import.meta.url);
20
19
  const getDirname = () => path.dirname(getFilename());
21
20
  const __dirname$1 = /* @__PURE__ */ getDirname();
@@ -66,57 +65,17 @@ const mergeConfig = (defaults, overrides) => {
66
65
  return result;
67
66
  };
68
67
 
69
- //#endregion
70
- //#region src/utils.ts
71
- const __filename = fileURLToPath(import.meta.url);
72
- const __dirname = dirname(__filename);
73
- function joinUrl(input) {
74
- const temps = Array.isArray(input) ? input : [...arguments];
75
- if (temps.length === 0) return "";
76
- const result = [];
77
- const parts = [...temps];
78
- /** 协议正则 */
79
- const PROTOCOL_RE = /^[^/:]+:\/*$/;
80
- const FILE_PROTOCOL_RE = /^file:\/\/\//;
81
- if (PROTOCOL_RE.test(parts[0]) && parts.length > 1) {
82
- parts[1] = parts[0] + parts[1];
83
- parts.shift();
84
- }
85
- if (FILE_PROTOCOL_RE.test(parts[0])) parts[0] = parts[0].replace(/^([^/:]+):\/*/, "$1:///");
86
- else parts[0] = parts[0].replace(/^([^/:]+):\/*/, "$1://");
87
- parts.forEach((part, index) => {
88
- if (!part) return;
89
- let segment = part;
90
- if (index > 0) segment = segment.replace(/^\/+/, "");
91
- if (index < parts.length - 1) segment = segment.replace(/\/+$/, "");
92
- else segment = segment.replace(/\/+$/, "/");
93
- result.push(segment);
94
- });
95
- let url = result.join("/");
96
- url = url.replace(/\/(\?|&|#[^!])/g, "$1");
97
- const [base, ...queryParts] = url.split("?");
98
- url = base + (queryParts.length ? "?" + queryParts.join("&") : "");
99
- return url;
100
- }
101
- const isUndefined = (val) => {
102
- return void 0 === val;
103
- };
104
- const eol = (n$1 = 1) => EOL.repeat(n$1);
105
- const underline = (text$1) => {
106
- return styleText(["dim", "underline"], text$1);
107
- };
108
- const castArray = (arr) => {
109
- return Array.isArray(arr) ? arr : [arr];
110
- };
111
-
112
68
  //#endregion
113
69
  //#region src/messages.ts
114
70
  const n = (b) => {
115
- return b ? " (dry run)" : "";
71
+ return b ? "(dry run)" : "";
72
+ };
73
+ const t = () => {
74
+ return green(Math.floor(process.uptime()));
116
75
  };
117
76
  const MSG = {
118
- INTRO: (pkgName, dryRun) => `🚀 Starting release ${yellow(pkgName)}${n(dryRun)}`,
119
- OUTRO: (dryRun) => `🎉 Release finished successfully${n(dryRun)}`,
77
+ INTRO: (pkgName, dryRun) => `🚀 Starting release ${yellow(pkgName)} ${n(dryRun)}`,
78
+ OUTRO: (dryRun) => `🎉 Release finished successfully in ${t()}s ${n(dryRun)} `,
120
79
  LOG: {
121
80
  SHOW_VERSION: (version) => `🎉 Released ${green(version)}`,
122
81
  SHOW_CHANGELOG: "🎉 Changelog collected",
@@ -126,11 +85,11 @@ const MSG = {
126
85
  CHECK: {
127
86
  GIT: {
128
87
  CHECKING: "Checking Git repository",
129
- CHECKED: (name, url) => `Git remote resolved: ${dim(name)} → ${underline(url)}`
88
+ CHECKED: (name, url) => `Git remote resolved: ${dim(name)} → ${underline(dim(url))}`
130
89
  },
131
90
  NPM: {
132
91
  CHECKING: "Checking npm registry",
133
- CHECKED: (registry, msg$1) => `NPM registry: ${underline(registry)}${msg$1 ? ` ${msg$1}` : ""}`
92
+ CHECKED: (registry, msg$1) => `NPM registry: ${underline(dim(registry))}${msg$1 ? ` ${msg$1}` : ""}`
134
93
  }
135
94
  },
136
95
  TASK: {
@@ -154,11 +113,11 @@ const MSG = {
154
113
  PROMPT: {
155
114
  SELECT_VERSION: "Select version bump:",
156
115
  INPUT_VERSION: "Enter custom version:",
157
- NPM_PUBLISH: (pkg$1) => `Publish to npm ${underline(`(${pkg$1})`)}?`,
116
+ NPM_PUBLISH: (pkg$1) => `Publish to npm ${underline(dim`(${pkg$1})`)}?`,
158
117
  NPM_OTP: "Enter npm one-time password (OTP):",
159
- GITHUB_RELEASE: (title) => `Create a new GitHub release ${underline(`(${title})`)}?`,
160
- GIT_COMMIT: (msg$1) => `Create git commit ${underline(`(${msg$1})`)}?`,
161
- GIT_TAG: (msg$1) => `Create git tag ${underline(`(${msg$1})`)}?`,
118
+ GITHUB_RELEASE: (title) => `Create a new GitHub release ${underline(dim`(${title})`)}?`,
119
+ GIT_COMMIT: (msg$1) => `Create git commit ${underline(dim`(${msg$1})`)}?`,
120
+ GIT_TAG: (msg$1) => `Create git tag ${underline(dim`(${msg$1})`)}?`,
162
121
  GIT_PUSH: "Push commits and tags to remote?"
163
122
  },
164
123
  ERROR: {
@@ -168,7 +127,7 @@ const MSG = {
168
127
  GITHUB_TOKEN: (tokenRef) => `[github] Missing GitHub token. Please set ${yellow(tokenRef ?? "GITHUB_TOKEN")}`,
169
128
  GITHUB_AUTH: "[github] Invalid GitHub token or insufficient permissions",
170
129
  GITHUB_USER: "[github] User does not have permission to create releases",
171
- NPM_REGISTRY: (registry) => `[npm] Unable to reach npm registry ${underline(registry)}`,
130
+ NPM_REGISTRY: (registry) => `[npm] Unable to reach npm registry ${underline(dim(registry))}`,
172
131
  NPM_AUTH: `[npm] Not authenticated with npm. Please run ${yellow("npm login")} and try again.`,
173
132
  NPM_USER: (user, name) => `[npm] User ${dim(user)} is not a collaborator of ${dim(name)}.`
174
133
  }
@@ -340,10 +299,7 @@ const runVersionPrompts = async (ctx, config) => {
340
299
  const parsed = parseVersion(next);
341
300
  Object.assign(ctx.pkg, { ...parsed });
342
301
  ctx.isIncrement = gte(next, current);
343
- log.message(gray`
344
- from ${dim(current)}
345
- to ${diff(current, next)}
346
- `);
302
+ log.message(gray`from ${dim(current)}${eol()} to ${diff(current, next)}`);
347
303
  return { next };
348
304
  };
349
305
 
@@ -353,12 +309,11 @@ const createDefaultContext = () => {
353
309
  return {
354
310
  ci: false,
355
311
  release: false,
356
- noNpm: false,
357
312
  dryRun: false,
358
313
  changelog: false,
359
314
  increment: "",
360
315
  isIncrement: false,
361
- noGithub: false,
316
+ configFileExists: false,
362
317
  pkg: {
363
318
  current: "",
364
319
  next: "",
@@ -368,8 +323,7 @@ const createDefaultContext = () => {
368
323
  toPreRelease: false,
369
324
  publishConfig: {
370
325
  access: "public",
371
- registry: "https://registry.npmjs.org",
372
- publicPath: ""
326
+ registry: "https://registry.npmjs.org"
373
327
  },
374
328
  preId: PreId.BETA,
375
329
  preBase: "0"
@@ -440,64 +394,61 @@ const createDefaultConfig = (isCI) => {
440
394
  };
441
395
 
442
396
  //#endregion
443
- //#region src/git/commit.ts
444
- const spawnAsync = (cmd, args, options) => {
445
- return new Promise((resolve$1) => {
446
- const { trim, error, dryRun, ...others } = options ?? {};
447
- const fullCmd = [cmd, ...args].join(" ");
448
- const dim$1 = (text$1) => styleText(["dim"], text$1);
449
- const red$1 = (text$1) => styleText(["red"], text$1);
450
- if (dryRun) {
451
- console.log(`${dim$1("[dry-run]")} ${fullCmd}`);
452
- return resolve$1(void 0);
453
- }
454
- const child = spawn(cmd, args, { ...others });
455
- let stdout = "";
456
- child.stdout?.setEncoding("utf-8");
457
- child.stdout?.on("data", (data) => stdout += trim ? data.trim() : data);
458
- let stderr = "";
459
- child.stderr?.setEncoding("utf-8");
460
- child.stderr?.on("data", (data) => stderr += trim ? data.trim() : data);
461
- child.on("close", (code) => {
462
- if (stderr) {
463
- const err = `${red$1("spawnAsync")} ${dim$1(fullCmd)} ${stderr}`;
464
- switch (error) {
465
- case "log":
466
- console.error(err);
467
- break;
468
- case "throw": throw new Error(err);
469
- }
470
- }
471
- resolve$1(0 === code ? stdout : void 0);
472
- });
473
- });
397
+ //#region src/utils.ts
398
+ const __filename = fileURLToPath(import.meta.url);
399
+ const __dirname = dirname(__filename);
400
+ const info = (msg$1) => {
401
+ console.log(`${rgb(33, 91, 184)(`ℹ`)} ${gray(msg$1)}`);
474
402
  };
475
- const runGit = async (args, trim = true) => {
476
- return spawnAsync("git", args, { trim });
403
+ const success = (msg$1, dryRun) => {
404
+ return `${(dryRun ? rgb(123, 115, 66) : green)("✔")} ${msg$1}`;
405
+ };
406
+ const runLifeCycleHook = async (hooks, key, dryRun) => {
407
+ const handler = hooks[key];
408
+ if (typeof handler === "function") {
409
+ if (!dryRun) await handler();
410
+ log.success(success(`${dim`run`} ${inspect(handler)}`, dryRun));
411
+ return;
412
+ }
413
+ return Promise.allSettled(castArray(handler).filter(Boolean).map(async (hook) => {
414
+ if (!dryRun) await execAsync(hook, { shell: true }).catch(console.error);
415
+ log.success(success(hook.replace("echo", dim("echo")), dryRun));
416
+ }));
417
+ };
418
+ const format = (str, ctx) => {
419
+ const { pkg: { next } } = ctx;
420
+ return str.replace("${version}", next);
421
+ };
422
+
423
+ //#endregion
424
+ //#region src/git/commit.ts
425
+ const runGitProxy = (...args) => {
426
+ if (process.env["dryRun"]) log.message(`${dim("$")} ${gray(["git", ...args[0]].join(" "))}`);
427
+ return runGit(...args);
477
428
  };
478
429
  const getBranchName = () => {
479
- return runGit([
430
+ return runGitProxy([
480
431
  "rev-parse",
481
432
  "--abbrev-ref",
482
433
  "HEAD"
483
434
  ]);
484
435
  };
485
436
  const getRemoteForBranch = (branch) => {
486
- return runGit([
437
+ return runGitProxy([
487
438
  "config",
488
439
  "--get",
489
440
  `branch.${branch}.remote`
490
441
  ]);
491
442
  };
492
443
  const getStatus = () => {
493
- return runGit([
444
+ return runGitProxy([
494
445
  "status",
495
446
  "--short",
496
447
  "--untracked-files=no"
497
- ], false);
448
+ ], { trim: false });
498
449
  };
499
450
  const gitRestore = () => {
500
- return runGit(["restore", "."]);
451
+ return runGitProxy(["restore", "."]);
501
452
  };
502
453
  const coloredChangeset = (log$1) => {
503
454
  const colorStatusChar = (ch) => {
@@ -520,23 +471,19 @@ const getRemote = async () => {
520
471
  const remoteName = branch && await getRemoteForBranch(branch) || "origin";
521
472
  return {
522
473
  remoteName,
523
- remoteUrl: await runGit([
474
+ remoteUrl: await runGitProxy([
524
475
  "remote",
525
476
  "get-url",
526
477
  remoteName
527
- ]).catch((_) => runGit([
478
+ ]).catch((_) => runGitProxy([
528
479
  "config",
529
480
  "--get",
530
481
  `remote.${remoteName}.url`
531
482
  ]))
532
483
  };
533
484
  };
534
- const parseGitHubRepo = (url) => {
535
- const match = url.trim().match(/github(?:\.com)?[:/](.+?)\/(.+?)(\/.+?)?(\.git)?$/);
536
- return match ? match.slice(1, 3) : [];
537
- };
538
485
  const getLatestTag = async (match = "*", exclude = "*-beta.*") => {
539
- return runGit([
486
+ return runGitProxy([
540
487
  "describe",
541
488
  "--tags",
542
489
  "--abbrev=0",
@@ -545,11 +492,11 @@ const getLatestTag = async (match = "*", exclude = "*-beta.*") => {
545
492
  ]);
546
493
  };
547
494
  const getPreviousTag = async (current) => {
548
- return runGit([
495
+ return runGitProxy([
549
496
  "describe",
550
497
  "--tags",
551
498
  "--abbrev=0",
552
- `${await runGit([
499
+ `${await runGitProxy([
553
500
  "rev-list",
554
501
  "--tags",
555
502
  current || "--skip=1",
@@ -577,7 +524,7 @@ const getLog = async (print, isIncrement) => {
577
524
  const cmd = ["log", `--pretty=format:${print ? "* %s (%h)" : "%s %h %H"}`];
578
525
  const { from, to } = await resolveChangelogRange(isIncrement);
579
526
  if (from) cmd.push(`${from}...${to}`);
580
- return runGit(cmd, false);
527
+ return runGitProxy(cmd, { trim: false });
581
528
  };
582
529
  const normalizeTag = (tag) => clean(tag) ?? tag;
583
530
  const resolveTag$1 = async (ctx, config) => {
@@ -602,10 +549,10 @@ const gitCheck = async (ctx, config) => {
602
549
  parseGithubUrl(ctx);
603
550
  };
604
551
  const hasUpstreamBranch = async () => {
605
- const branch = await runGit([
552
+ const branch = await runGitProxy([
606
553
  "for-each-ref",
607
554
  "--format=%(upstream:short)",
608
- await runGit(["symbolic-ref", "HEAD"])
555
+ await runGitProxy(["symbolic-ref", "HEAD"])
609
556
  ]);
610
557
  return Boolean(branch);
611
558
  };
@@ -624,22 +571,18 @@ const getUpstreamArgs = async (remoteName) => {
624
571
  if (remoteName) return [remoteName];
625
572
  return [];
626
573
  };
627
- const format = (str, ctx) => {
628
- const { pkg: { next } } = ctx;
629
- return str.replace("${version}", next);
630
- };
631
574
  const commitAndTag = async (ctx, config) => {
632
575
  const { git: { currentTag, remoteName }, dryRun } = ctx;
633
576
  const { git: { commit, tag, push, tagMessage, commitMessage } } = config;
634
577
  if (!commit) return;
635
578
  const args = dryRun ? ["--dry-run"] : [];
636
- await runGit([
579
+ await runGitProxy([
637
580
  "add",
638
581
  ".",
639
582
  "--all",
640
583
  ...args
641
584
  ]);
642
- await runGit([
585
+ await runGitProxy([
643
586
  "commit",
644
587
  "--message",
645
588
  format(commitMessage, ctx),
@@ -647,7 +590,7 @@ const commitAndTag = async (ctx, config) => {
647
590
  ]);
648
591
  if (!dryRun) Object.assign(ctx.git, { isCommitted: true });
649
592
  if (tag) {
650
- await runGit([
593
+ await runGitProxy([
651
594
  "tag",
652
595
  "--annotate",
653
596
  "--message",
@@ -657,7 +600,7 @@ const commitAndTag = async (ctx, config) => {
657
600
  ]);
658
601
  if (!dryRun) Object.assign(ctx.git, { isTagged: true });
659
602
  }
660
- if (push) await runGit([
603
+ if (push) await runGitProxy([
661
604
  "push",
662
605
  ...await getUpstreamArgs(remoteName),
663
606
  "--follow-tags",
@@ -667,12 +610,12 @@ const commitAndTag = async (ctx, config) => {
667
610
  const gitRollback = async (ctx) => {
668
611
  const { git: { currentTag, isCommitted, isTagged } } = ctx;
669
612
  await gitRestore();
670
- if (isTagged) await runGit([
613
+ if (isTagged) await runGitProxy([
671
614
  "tag",
672
615
  "--delete",
673
616
  currentTag
674
617
  ]);
675
- await runGit([
618
+ await runGitProxy([
676
619
  "reset",
677
620
  "--hard",
678
621
  isCommitted ? "HEAD~1" : "HEAD"
@@ -930,19 +873,18 @@ const renderChangelog = async (ctx, sections) => {
930
873
  const { pkg: { next: to }, github: { owner, repo }, git: { latestTag } } = ctx;
931
874
  const date = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
932
875
  const github = getGithubUrl(owner, repo);
933
- const eol$1 = (n$1) => EOL.repeat(n$1);
934
876
  let md;
935
- if (!latestTag) md = `## ${to} (${date})${eol$1(2)}`;
936
- else md = `## [${to}](${github}/compare/${latestTag}...${to}) (${date})${eol$1(2)}`;
877
+ if (!latestTag) md = `## ${to} (${date})${eol(2)}`;
878
+ else md = `## [${to}](${github}/compare/${latestTag}...${to}) (${date})${eol(2)}`;
937
879
  for (const [type, items] of Object.entries(sections)) {
938
880
  if (!items.length) continue;
939
- md += `### ${findType(type)}${eol$1(2)}`;
940
- for (const [desc, hash, fullHash] of items) md += `* **${type}** ${desc} [${hash}](${github}/commit/${fullHash})${eol$1(1)}`;
941
- md += eol$1(2);
881
+ md += `### ${findType(type)}${eol(2)}`;
882
+ for (const [desc, hash, fullHash] of items) md += `* **${type}** ${desc} [${hash}](${github}/commit/${fullHash})${eol(1)}`;
883
+ md += eol(2);
942
884
  }
943
885
  if (latestTag) {
944
886
  md += `**Full Changelog**: ${github}/compare/${latestTag}...${to}`;
945
- md += eol$1(3);
887
+ md += eol(3);
946
888
  }
947
889
  return md;
948
890
  };
@@ -958,7 +900,7 @@ const updateChangelog = async (newContent) => {
958
900
  const file = "CHANGELOG.md";
959
901
  const title = `# Changelog${eol(3)}`;
960
902
  await writeFile(file, `${(existsSync(file) && await readFile(file, "utf-8") || title).replace(/* @__PURE__ */ new RegExp(`^${title}`), `${title}${newContent}`).trim()}${eol()}`);
961
- await runGit(["add", file]);
903
+ await runGitProxy(["add", file]);
962
904
  };
963
905
 
964
906
  //#endregion
@@ -1059,23 +1001,24 @@ const runNpmOptPrompts = async (ctx, config) => {
1059
1001
 
1060
1002
  //#endregion
1061
1003
  //#region src/npm/publish.ts
1004
+ const runNpmProxy = (...args) => {
1005
+ if (process.env["dryRun"]) log.message(`${dim("$")} ${gray(["npm", ...args[0]].join(" "))}`);
1006
+ return runNpm(...args);
1007
+ };
1062
1008
  const DEFAULT_TAG = "latest";
1063
1009
  const DEFAULT_TAG_PRERELEASE = "next";
1064
- const runNpm = (args) => {
1065
- return execAsync(["npm", ...args].join(" "));
1066
- };
1067
1010
  const getRegistry = (publishConfig = {}) => {
1068
1011
  return (publishConfig.registry ? [publishConfig.registry] : Object.keys(publishConfig).filter((key) => key.endsWith("registry")).map((key) => publishConfig[key]))[0];
1069
1012
  };
1070
1013
  const isRegistryUp = async (registry) => {
1071
- return void 0 !== await runNpm(["ping", ...registry ? [`--registry ${registry}`] : []]);
1014
+ return void 0 !== await runNpmProxy(["ping", ...registry ? [`--registry ${registry}`] : []]);
1072
1015
  };
1073
1016
  const isAuthenticated = (registry) => {
1074
- return runNpm(["whoami", ...registry ? [`--registry ${registry}`] : []]);
1017
+ return runNpmProxy(["whoami", ...registry ? [`--registry ${registry}`] : []]);
1075
1018
  };
1076
1019
  const getLatestRegistryVersion = (name, tag, registry) => {
1077
1020
  const registryArg = registry ? [`--registry ${registry}`] : [];
1078
- return runNpm([
1021
+ return runNpmProxy([
1079
1022
  "show",
1080
1023
  `${name}@${tag}`,
1081
1024
  "version",
@@ -1083,7 +1026,7 @@ const getLatestRegistryVersion = (name, tag, registry) => {
1083
1026
  ]);
1084
1027
  };
1085
1028
  const getRegistryTags = async (name, registry) => {
1086
- const res = await runNpm([
1029
+ const res = await runNpmProxy([
1087
1030
  "view",
1088
1031
  name,
1089
1032
  "dist-tags",
@@ -1094,7 +1037,7 @@ const getRegistryTags = async (name, registry) => {
1094
1037
  };
1095
1038
  const bump = (version, allowSameVersion, args = []) => {
1096
1039
  allowSameVersion && args.push(`--allow-same-version`);
1097
- return runNpm([
1040
+ return runNpmProxy([
1098
1041
  "version",
1099
1042
  version,
1100
1043
  "--no-git-tag-version",
@@ -1113,10 +1056,10 @@ const resolveTag = async (ctx, config) => {
1113
1056
  else return tag || preId || await guessPreReleaseTag(name);
1114
1057
  };
1115
1058
  const isCollaborator = async (ctx) => {
1116
- const { name, publishConfig } = ctx.pkg;
1059
+ const { pkg: { name, publishConfig }, npm: { username } } = ctx;
1117
1060
  const registry = getRegistry(publishConfig);
1118
1061
  const registryArg = registry ? [`--registry ${registry}`] : [];
1119
- let npmVersion = await runNpm(["--version"]);
1062
+ let npmVersion = await runNpmProxy(["--version"]);
1120
1063
  let accessCommand;
1121
1064
  if (gt(npmVersion, "9.0.0")) accessCommand = [
1122
1065
  "access",
@@ -1125,24 +1068,20 @@ const isCollaborator = async (ctx) => {
1125
1068
  "--json"
1126
1069
  ];
1127
1070
  else accessCommand = ["access", "ls-collaborators"];
1128
- const res = await runNpm([
1071
+ const res = await runNpmProxy([
1129
1072
  ...accessCommand,
1130
1073
  name,
1131
1074
  ...registryArg
1132
1075
  ]);
1133
1076
  if (res) {
1134
- const permissions = JSON.parse(res ?? "{}")[ctx.npm.username];
1077
+ const permissions = JSON.parse(res ?? "{}")[username];
1135
1078
  return permissions && permissions.includes("write");
1136
1079
  }
1137
- log.error(`Unable to verify if user ${ctx.npm.username} is a collaborator for ${name}.`);
1080
+ log.error(`Unable to verify if user ${username} is a collaborator for ${name}.`);
1138
1081
  };
1139
1082
  const getPackageUrl = (ctx) => {
1140
- const { name } = ctx.pkg;
1141
- return joinUrl([
1142
- "https://www.npmjs.com",
1143
- "/package",
1144
- name
1145
- ]);
1083
+ const { pkg: { name, next } } = ctx;
1084
+ return `https://www.npmjs.com/package/${name}/v/${next}`;
1146
1085
  };
1147
1086
  const npmCheck = async (ctx, config) => {
1148
1087
  const { pkg: { name, publishConfig }, npm: { username } } = ctx;
@@ -1171,39 +1110,22 @@ const publishNpm = async (ctx, config) => {
1171
1110
  if (tag) args.push("--tag", tag);
1172
1111
  if (otp) args.push("--otp", otp);
1173
1112
  if (dryRun) args.push("--dry-run");
1174
- return runNpm(args);
1113
+ return runNpmProxy(args);
1175
1114
  };
1176
1115
 
1177
1116
  //#endregion
1178
1117
  //#region src/action.ts
1179
- const info = (msg$1) => {
1180
- console.log(`${rgb(33, 91, 184)(`ℹ`)} ${gray(msg$1)}`);
1181
- };
1182
- const success = (msg$1, dryRun) => {
1183
- return `${(dryRun ? rgb(123, 115, 66) : green)("✔")} ${msg$1}`;
1184
- };
1185
- const runLifeCycleHook = async (hooks, key, dryRun) => {
1186
- const handler = hooks[key];
1187
- if (typeof handler === "function") {
1188
- if (!dryRun) await handler();
1189
- log.success(success(`${dim`run`} ${inspect(handler)}`, dryRun));
1190
- return;
1191
- }
1192
- return Promise.allSettled(castArray(handler).map(async (hook) => {
1193
- if (!dryRun) await execAsync(hook).catch(console.error);
1194
- handler && log.success(success(hook.replace("echo", dim("echo")), dryRun));
1195
- }));
1196
- };
1197
1118
  var Action = class {
1198
1119
  async handle(cmdArgs, options) {
1199
1120
  const { version: cVersion, name: cName } = readJsonFile(join(__dirname$1, "../package.json"));
1200
1121
  info(`${cName} ${dim(`v${cVersion}`)} `);
1201
1122
  const { otp, ...others } = options;
1202
1123
  const { showChangelog, showRelease, ci, dryRun } = Object.fromEntries(Object.entries(others).map(([k, v]) => [k, Boolean(v)]));
1124
+ process.env["dryRun"] = String(dryRun);
1203
1125
  const { version: pkgVersion, private: pkgPrivate, name: pkgName, publishConfig = {} } = readJsonFile("package.json");
1204
1126
  const nextVersion = inc(pkgVersion, cmdArgs) ?? "";
1205
1127
  const local = await resolveConfig(process.cwd(), (path$1) => {
1206
- info(`config file: ${underline(path$1)}`);
1128
+ info(`config file: ${underline(dim(path$1))}`);
1207
1129
  });
1208
1130
  const config = mergeConfig(createDefaultConfig(ci ? true : void 0), local);
1209
1131
  const ctx = mergeConfig(createDefaultContext(), {
@@ -1340,7 +1262,7 @@ var Action = class {
1340
1262
 
1341
1263
  //#endregion
1342
1264
  //#region src/cli.ts
1343
- const pkg = readJsonFile(join(__dirname, "..", "package.json"));
1265
+ const pkg = readJsonFile(join(__dirname$1, "..", "package.json"));
1344
1266
  program.name(pkg.name).description(pkg.description).version(pkg.version, "-v, --version", "Output the current version.").usage("[ARGUMENT] [OPTION]...").argument("[argument]", "patch|minor|major").option("-n, --dry-run", "Report actions that would be performed without writing out results.", false).option("--ci", "CI mode", false).option("--otp", "npm publish otp", "").option("--show-changelog", "Skip npm publish", false).option("--show-release", "Skip github release", false).action(async (argName, options) => {
1345
1267
  await new Action().handle(argName, options);
1346
1268
  }).helpOption("-h, --help", "Output usage information.").parse(process.argv);
package/dist/index.d.cts CHANGED
@@ -1,3 +1,5 @@
1
+ import { DeepPartial, DeepRequired } from "@peiyanlu/ts-utils";
2
+
1
3
  //#region src/types.d.ts
2
4
 
3
5
  type HookTiming = 'before' | 'after';
@@ -29,10 +31,6 @@ interface ReleaseConfig {
29
31
  assets: string[];
30
32
  };
31
33
  }
32
- type Primitive = string | number | boolean | bigint | symbol | null | undefined;
33
- type Builtin = Primitive | Date | RegExp | Error | Map<any, any> | Set<any> | WeakMap<any, any> | WeakSet<any>;
34
- type DeepRequired<T> = T extends Builtin ? T : T extends ((...args: any[]) => any) ? T : T extends readonly (infer U)[] ? DeepRequired<U>[] : T extends Array<infer U> ? Array<DeepRequired<U>> : { [K in keyof T]-?: DeepRequired<T[K]> };
35
- type DeepPartial<T> = T extends Builtin ? T : T extends ((...args: any[]) => any) ? T : T extends readonly (infer U)[] ? DeepPartial<U>[] : T extends Array<infer U> ? Array<DeepPartial<U>> : { [K in keyof T]?: DeepPartial<T[K]> };
36
34
  //#endregion
37
35
  //#region src/config.d.ts
38
36
  type UserConfig = DeepPartial<ReleaseConfig>;
package/dist/index.d.mts CHANGED
@@ -1,3 +1,5 @@
1
+ import { DeepPartial, DeepRequired } from "@peiyanlu/ts-utils";
2
+
1
3
  //#region src/types.d.ts
2
4
 
3
5
  type HookTiming = 'before' | 'after';
@@ -29,10 +31,6 @@ interface ReleaseConfig {
29
31
  assets: string[];
30
32
  };
31
33
  }
32
- type Primitive = string | number | boolean | bigint | symbol | null | undefined;
33
- type Builtin = Primitive | Date | RegExp | Error | Map<any, any> | Set<any> | WeakMap<any, any> | WeakSet<any>;
34
- type DeepRequired<T> = T extends Builtin ? T : T extends ((...args: any[]) => any) ? T : T extends readonly (infer U)[] ? DeepRequired<U>[] : T extends Array<infer U> ? Array<DeepRequired<U>> : { [K in keyof T]-?: DeepRequired<T[K]> };
35
- type DeepPartial<T> = T extends Builtin ? T : T extends ((...args: any[]) => any) ? T : T extends readonly (infer U)[] ? DeepPartial<U>[] : T extends Array<infer U> ? Array<DeepPartial<U>> : { [K in keyof T]?: DeepPartial<T[K]> };
36
34
  //#endregion
37
35
  //#region src/config.d.ts
38
36
  type UserConfig = DeepPartial<ReleaseConfig>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@peiyanlu/release",
3
- "version": "0.0.1",
3
+ "version": "0.0.2",
4
4
  "description": "Release project tool.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -8,8 +8,6 @@
8
8
  "bin": {
9
9
  "release": "index.js"
10
10
  },
11
- "main": "dist/index.cjs",
12
- "types": "dist/index.d.cts",
13
11
  "exports": {
14
12
  ".": {
15
13
  "import": {
@@ -32,8 +30,8 @@
32
30
  "dependencies": {
33
31
  "@clack/prompts": "^0.11.0",
34
32
  "@octokit/rest": "^22.0.1",
35
- "@peiyanlu/cli-utils": "^0.0.1",
36
- "@peiyanlu/ts-utils": "^0.0.1",
33
+ "@peiyanlu/cli-utils": "^0.0.3",
34
+ "@peiyanlu/ts-utils": "^0.0.3",
37
35
  "ansis": "^4.2.0",
38
36
  "commander": "^14.0.2",
39
37
  "mime-types": "^3.0.2",
@@ -46,7 +44,7 @@
46
44
  "@types/mime-types": "^3.0.1",
47
45
  "@types/node": "^24.10.3",
48
46
  "@vitest/coverage-v8": "^4.0.15",
49
- "tsdown": "^0.18.1",
47
+ "tsdown": "^0.18.4",
50
48
  "typescript": "^5.9.3",
51
49
  "vitest": "^4.0.15"
52
50
  },