pubm 0.2.1 → 0.2.3
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 +18 -1
- package/bin/cli.js +660 -404
- package/dist/index.cjs +369 -151
- package/dist/index.d.cts +5 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.js +368 -150
- package/package.json +1 -1
package/bin/cli.js
CHANGED
|
@@ -453,7 +453,7 @@ __export(base_exports, {
|
|
|
453
453
|
scrollDown: () => scrollDown,
|
|
454
454
|
scrollUp: () => scrollUp
|
|
455
455
|
});
|
|
456
|
-
import
|
|
456
|
+
import process4 from "node:process";
|
|
457
457
|
var ESC, OSC, BEL, SEP, isTerminalApp, isWindows3, cwdFunction, cursorTo, cursorMove, cursorUp, cursorDown, cursorForward, cursorBackward, cursorLeft, cursorSavePosition, cursorRestorePosition, cursorGetPosition, cursorNextLine, cursorPrevLine, cursorHide, cursorShow, eraseLines, eraseEndLine, eraseStartLine, eraseLine, eraseDown, eraseUp, eraseScreen, scrollUp, scrollDown, clearScreen, clearTerminal, enterAlternativeScreen, exitAlternativeScreen, beep, link, image, iTerm;
|
|
458
458
|
var init_base = __esm({
|
|
459
459
|
"node_modules/.pnpm/ansi-escapes@7.0.0/node_modules/ansi-escapes/base.js"() {
|
|
@@ -463,11 +463,11 @@ var init_base = __esm({
|
|
|
463
463
|
OSC = "\x1B]";
|
|
464
464
|
BEL = "\x07";
|
|
465
465
|
SEP = ";";
|
|
466
|
-
isTerminalApp = !isBrowser &&
|
|
467
|
-
isWindows3 = !isBrowser &&
|
|
466
|
+
isTerminalApp = !isBrowser && process4.env.TERM_PROGRAM === "Apple_Terminal";
|
|
467
|
+
isWindows3 = !isBrowser && process4.platform === "win32";
|
|
468
468
|
cwdFunction = isBrowser ? () => {
|
|
469
469
|
throw new Error("`process.cwd()` only works in Node.js, not the browser.");
|
|
470
|
-
} :
|
|
470
|
+
} : process4.cwd;
|
|
471
471
|
cursorTo = (x, y) => {
|
|
472
472
|
if (typeof x !== "number") {
|
|
473
473
|
throw new TypeError("The `x` argument is required");
|
|
@@ -708,7 +708,7 @@ var init_signals = __esm({
|
|
|
708
708
|
});
|
|
709
709
|
|
|
710
710
|
// node_modules/.pnpm/signal-exit@4.1.0/node_modules/signal-exit/dist/mjs/index.js
|
|
711
|
-
var processOk, kExitEmitter, global, ObjectDefineProperty, Emitter, SignalExitBase, signalExitWrap, SignalExitFallback, _hupSig, _emitter, _process, _originalProcessEmit, _originalProcessReallyExit, _sigListeners, _loaded, _SignalExit_instances, processReallyExit_fn, processEmit_fn, SignalExit,
|
|
711
|
+
var processOk, kExitEmitter, global, ObjectDefineProperty, Emitter, SignalExitBase, signalExitWrap, SignalExitFallback, _hupSig, _emitter, _process, _originalProcessEmit, _originalProcessReallyExit, _sigListeners, _loaded, _SignalExit_instances, processReallyExit_fn, processEmit_fn, SignalExit, process5, onExit, load, unload;
|
|
712
712
|
var init_mjs = __esm({
|
|
713
713
|
"node_modules/.pnpm/signal-exit@4.1.0/node_modules/signal-exit/dist/mjs/index.js"() {
|
|
714
714
|
"use strict";
|
|
@@ -801,7 +801,7 @@ var init_mjs = __esm({
|
|
|
801
801
|
// "SIGHUP" throws an `ENOSYS` error on Windows,
|
|
802
802
|
// so use a supported signal instead
|
|
803
803
|
/* c8 ignore start */
|
|
804
|
-
__privateAdd(this, _hupSig,
|
|
804
|
+
__privateAdd(this, _hupSig, process5.platform === "win32" ? "SIGINT" : "SIGHUP");
|
|
805
805
|
/* c8 ignore stop */
|
|
806
806
|
__privateAdd(this, _emitter, new Emitter());
|
|
807
807
|
__privateAdd(this, _process);
|
|
@@ -918,7 +918,7 @@ var init_mjs = __esm({
|
|
|
918
918
|
return og.call(__privateGet(this, _process), ev, ...args);
|
|
919
919
|
}
|
|
920
920
|
};
|
|
921
|
-
|
|
921
|
+
process5 = globalThis.process;
|
|
922
922
|
({
|
|
923
923
|
onExit: (
|
|
924
924
|
/**
|
|
@@ -952,19 +952,19 @@ var init_mjs = __esm({
|
|
|
952
952
|
*/
|
|
953
953
|
unload
|
|
954
954
|
)
|
|
955
|
-
} = signalExitWrap(processOk(
|
|
955
|
+
} = signalExitWrap(processOk(process5) ? new SignalExit(process5) : new SignalExitFallback()));
|
|
956
956
|
}
|
|
957
957
|
});
|
|
958
958
|
|
|
959
959
|
// node_modules/.pnpm/restore-cursor@5.1.0/node_modules/restore-cursor/index.js
|
|
960
|
-
import
|
|
960
|
+
import process6 from "node:process";
|
|
961
961
|
var terminal, restoreCursor, restore_cursor_default;
|
|
962
962
|
var init_restore_cursor = __esm({
|
|
963
963
|
"node_modules/.pnpm/restore-cursor@5.1.0/node_modules/restore-cursor/index.js"() {
|
|
964
964
|
"use strict";
|
|
965
965
|
init_onetime();
|
|
966
966
|
init_mjs();
|
|
967
|
-
terminal =
|
|
967
|
+
terminal = process6.stderr.isTTY ? process6.stderr : process6.stdout.isTTY ? process6.stdout : void 0;
|
|
968
968
|
restoreCursor = terminal ? onetime_default(() => {
|
|
969
969
|
onExit(() => {
|
|
970
970
|
terminal.write("\x1B[?25h");
|
|
@@ -976,7 +976,7 @@ var init_restore_cursor = __esm({
|
|
|
976
976
|
});
|
|
977
977
|
|
|
978
978
|
// node_modules/.pnpm/cli-cursor@5.0.0/node_modules/cli-cursor/index.js
|
|
979
|
-
import
|
|
979
|
+
import process7 from "node:process";
|
|
980
980
|
var isHidden, cliCursor, cli_cursor_default;
|
|
981
981
|
var init_cli_cursor = __esm({
|
|
982
982
|
"node_modules/.pnpm/cli-cursor@5.0.0/node_modules/cli-cursor/index.js"() {
|
|
@@ -984,14 +984,14 @@ var init_cli_cursor = __esm({
|
|
|
984
984
|
init_restore_cursor();
|
|
985
985
|
isHidden = false;
|
|
986
986
|
cliCursor = {};
|
|
987
|
-
cliCursor.show = (writableStream =
|
|
987
|
+
cliCursor.show = (writableStream = process7.stderr) => {
|
|
988
988
|
if (!writableStream.isTTY) {
|
|
989
989
|
return;
|
|
990
990
|
}
|
|
991
991
|
isHidden = false;
|
|
992
992
|
writableStream.write("\x1B[?25h");
|
|
993
993
|
};
|
|
994
|
-
cliCursor.hide = (writableStream =
|
|
994
|
+
cliCursor.hide = (writableStream = process7.stderr) => {
|
|
995
995
|
if (!writableStream.isTTY) {
|
|
996
996
|
return;
|
|
997
997
|
}
|
|
@@ -1667,7 +1667,7 @@ __export(log_update_exports, {
|
|
|
1667
1667
|
default: () => log_update_default,
|
|
1668
1668
|
logUpdateStderr: () => logUpdateStderr
|
|
1669
1669
|
});
|
|
1670
|
-
import
|
|
1670
|
+
import process8 from "node:process";
|
|
1671
1671
|
function createLogUpdate(stream, { showCursor = false } = {}) {
|
|
1672
1672
|
let previousLineCount = 0;
|
|
1673
1673
|
let previousWidth = getWidth(stream);
|
|
@@ -1721,9 +1721,9 @@ var init_log_update = __esm({
|
|
|
1721
1721
|
const toRemove = Math.max(0, lines.length - terminalHeight);
|
|
1722
1722
|
return toRemove ? sliceAnsi(text, stripAnsi(lines.slice(0, toRemove).join("\n")).length + 1) : text;
|
|
1723
1723
|
};
|
|
1724
|
-
logUpdate = createLogUpdate(
|
|
1724
|
+
logUpdate = createLogUpdate(process8.stdout);
|
|
1725
1725
|
log_update_default = logUpdate;
|
|
1726
|
-
logUpdateStderr = createLogUpdate(
|
|
1726
|
+
logUpdateStderr = createLogUpdate(process8.stderr);
|
|
1727
1727
|
}
|
|
1728
1728
|
});
|
|
1729
1729
|
|
|
@@ -2225,178 +2225,6 @@ function registerPreCommand(cli2) {
|
|
|
2225
2225
|
});
|
|
2226
2226
|
}
|
|
2227
2227
|
|
|
2228
|
-
// src/commands/snapshot.ts
|
|
2229
|
-
function registerSnapshotCommand(cli2) {
|
|
2230
|
-
cli2.command("snapshot [tag]", "Create a snapshot release").action(async (tag) => {
|
|
2231
|
-
console.log(`pubm snapshot ${tag ?? ""} \u2014 coming in next phase`);
|
|
2232
|
-
});
|
|
2233
|
-
}
|
|
2234
|
-
|
|
2235
|
-
// src/changeset/status.ts
|
|
2236
|
-
import process5 from "node:process";
|
|
2237
|
-
|
|
2238
|
-
// src/changeset/bump-utils.ts
|
|
2239
|
-
var BUMP_ORDER = {
|
|
2240
|
-
patch: 0,
|
|
2241
|
-
minor: 1,
|
|
2242
|
-
major: 2
|
|
2243
|
-
};
|
|
2244
|
-
function maxBump(a2, b) {
|
|
2245
|
-
return BUMP_ORDER[a2] >= BUMP_ORDER[b] ? a2 : b;
|
|
2246
|
-
}
|
|
2247
|
-
|
|
2248
|
-
// src/changeset/reader.ts
|
|
2249
|
-
import { existsSync as existsSync4, readdirSync as readdirSync2, readFileSync as readFileSync2 } from "node:fs";
|
|
2250
|
-
import path5 from "node:path";
|
|
2251
|
-
import process4 from "node:process";
|
|
2252
|
-
|
|
2253
|
-
// src/changeset/parser.ts
|
|
2254
|
-
import { parse as parseYaml } from "yaml";
|
|
2255
|
-
var VALID_BUMP_TYPES = /* @__PURE__ */ new Set(["patch", "minor", "major"]);
|
|
2256
|
-
function parseChangeset(content, fileName) {
|
|
2257
|
-
const frontmatterRegex = /^---\n([\s\S]*?)---/;
|
|
2258
|
-
const match = content.match(frontmatterRegex);
|
|
2259
|
-
if (!match) {
|
|
2260
|
-
throw new Error(
|
|
2261
|
-
`Invalid changeset format in "${fileName}": missing frontmatter`
|
|
2262
|
-
);
|
|
2263
|
-
}
|
|
2264
|
-
const yamlContent = match[1];
|
|
2265
|
-
const body = content.slice(match[0].length).trim();
|
|
2266
|
-
const parsed = parseYaml(yamlContent);
|
|
2267
|
-
const releases = [];
|
|
2268
|
-
if (parsed) {
|
|
2269
|
-
for (const [name, type] of Object.entries(parsed)) {
|
|
2270
|
-
if (!VALID_BUMP_TYPES.has(type)) {
|
|
2271
|
-
throw new Error(
|
|
2272
|
-
`Invalid bump type "${type}" for package "${name}" in "${fileName}". Expected: patch, minor, or major.`
|
|
2273
|
-
);
|
|
2274
|
-
}
|
|
2275
|
-
releases.push({ name, type });
|
|
2276
|
-
}
|
|
2277
|
-
}
|
|
2278
|
-
const id = fileName.replace(/\.md$/, "");
|
|
2279
|
-
return {
|
|
2280
|
-
id,
|
|
2281
|
-
summary: body,
|
|
2282
|
-
releases
|
|
2283
|
-
};
|
|
2284
|
-
}
|
|
2285
|
-
|
|
2286
|
-
// src/changeset/reader.ts
|
|
2287
|
-
function readChangesets(cwd = process4.cwd()) {
|
|
2288
|
-
const changesetsDir = path5.join(cwd, ".pubm", "changesets");
|
|
2289
|
-
if (!existsSync4(changesetsDir)) {
|
|
2290
|
-
return [];
|
|
2291
|
-
}
|
|
2292
|
-
const files = readdirSync2(changesetsDir);
|
|
2293
|
-
const changesets = [];
|
|
2294
|
-
for (const file of files) {
|
|
2295
|
-
if (!file.endsWith(".md") || file === "README.md") {
|
|
2296
|
-
continue;
|
|
2297
|
-
}
|
|
2298
|
-
const filePath = path5.join(changesetsDir, file);
|
|
2299
|
-
const content = readFileSync2(filePath, "utf-8");
|
|
2300
|
-
changesets.push(parseChangeset(content, file));
|
|
2301
|
-
}
|
|
2302
|
-
return changesets;
|
|
2303
|
-
}
|
|
2304
|
-
|
|
2305
|
-
// src/changeset/status.ts
|
|
2306
|
-
function getStatus(cwd = process5.cwd()) {
|
|
2307
|
-
const changesets = readChangesets(cwd);
|
|
2308
|
-
const packages = /* @__PURE__ */ new Map();
|
|
2309
|
-
for (const changeset of changesets) {
|
|
2310
|
-
for (const release of changeset.releases) {
|
|
2311
|
-
const existing = packages.get(release.name);
|
|
2312
|
-
if (existing) {
|
|
2313
|
-
existing.bumpType = maxBump(existing.bumpType, release.type);
|
|
2314
|
-
existing.changesetCount += 1;
|
|
2315
|
-
existing.summaries.push(changeset.summary);
|
|
2316
|
-
} else {
|
|
2317
|
-
packages.set(release.name, {
|
|
2318
|
-
bumpType: release.type,
|
|
2319
|
-
changesetCount: 1,
|
|
2320
|
-
summaries: [changeset.summary]
|
|
2321
|
-
});
|
|
2322
|
-
}
|
|
2323
|
-
}
|
|
2324
|
-
}
|
|
2325
|
-
return {
|
|
2326
|
-
packages,
|
|
2327
|
-
changesets,
|
|
2328
|
-
hasChangesets: changesets.length > 0
|
|
2329
|
-
};
|
|
2330
|
-
}
|
|
2331
|
-
|
|
2332
|
-
// src/commands/status.ts
|
|
2333
|
-
function registerStatusCommand(cli2) {
|
|
2334
|
-
cli2.command("status", "Show pending changeset status").option("--verbose", "Show full changeset contents").option("--since <ref>", "Only check changesets since git ref").action(async (options) => {
|
|
2335
|
-
const status = getStatus();
|
|
2336
|
-
if (!status.hasChangesets) {
|
|
2337
|
-
if (options.since) {
|
|
2338
|
-
console.log("No changesets found.");
|
|
2339
|
-
process.exit(1);
|
|
2340
|
-
}
|
|
2341
|
-
console.log("No pending changesets.");
|
|
2342
|
-
return;
|
|
2343
|
-
}
|
|
2344
|
-
console.log("Pending changesets:");
|
|
2345
|
-
for (const [name, info] of status.packages) {
|
|
2346
|
-
console.log(
|
|
2347
|
-
` ${name}: ${info.bumpType} (${info.changesetCount} changeset${info.changesetCount > 1 ? "s" : ""})`
|
|
2348
|
-
);
|
|
2349
|
-
if (options.verbose) {
|
|
2350
|
-
for (const summary of info.summaries) {
|
|
2351
|
-
console.log(` - ${summary}`);
|
|
2352
|
-
}
|
|
2353
|
-
}
|
|
2354
|
-
}
|
|
2355
|
-
});
|
|
2356
|
-
}
|
|
2357
|
-
|
|
2358
|
-
// src/commands/update.ts
|
|
2359
|
-
import { UpdateKit } from "update-kit";
|
|
2360
|
-
function registerUpdateCommand(cli2) {
|
|
2361
|
-
cli2.command("update", "Update pubm to the latest version").action(async () => {
|
|
2362
|
-
const kit = await UpdateKit.create({
|
|
2363
|
-
sources: [{ type: "npm", packageName: "pubm" }],
|
|
2364
|
-
delegateMode: "execute"
|
|
2365
|
-
});
|
|
2366
|
-
const result = await kit.autoUpdate({
|
|
2367
|
-
onProgress: (p) => {
|
|
2368
|
-
if (p.phase === "downloading" && p.totalBytes) {
|
|
2369
|
-
const pct = Math.round(p.bytesDownloaded / p.totalBytes * 100);
|
|
2370
|
-
process.stderr.write(`\rDownloading... ${pct}%`);
|
|
2371
|
-
} else {
|
|
2372
|
-
console.error(`${p.phase}...`);
|
|
2373
|
-
}
|
|
2374
|
-
}
|
|
2375
|
-
});
|
|
2376
|
-
switch (result.kind) {
|
|
2377
|
-
case "success":
|
|
2378
|
-
console.log(
|
|
2379
|
-
`Updated from ${result.fromVersion} to ${result.toVersion}`
|
|
2380
|
-
);
|
|
2381
|
-
break;
|
|
2382
|
-
case "needs-restart":
|
|
2383
|
-
console.log(result.message);
|
|
2384
|
-
break;
|
|
2385
|
-
case "failed":
|
|
2386
|
-
console.error(`Update failed: ${result.error.message}`);
|
|
2387
|
-
process.exitCode = 1;
|
|
2388
|
-
break;
|
|
2389
|
-
}
|
|
2390
|
-
});
|
|
2391
|
-
}
|
|
2392
|
-
|
|
2393
|
-
// src/commands/version-cmd.ts
|
|
2394
|
-
function registerVersionCommand(cli2) {
|
|
2395
|
-
cli2.command("version", "Consume changesets and bump versions").action(async () => {
|
|
2396
|
-
console.log("pubm version \u2014 coming in next phase");
|
|
2397
|
-
});
|
|
2398
|
-
}
|
|
2399
|
-
|
|
2400
2228
|
// node_modules/.pnpm/eventemitter3@5.0.1/node_modules/eventemitter3/index.mjs
|
|
2401
2229
|
var import_index = __toESM(require_eventemitter3(), 1);
|
|
2402
2230
|
var eventemitter3_default = import_index.default;
|
|
@@ -4865,56 +4693,435 @@ function consoleError(error) {
|
|
|
4865
4693
|
`);
|
|
4866
4694
|
}
|
|
4867
4695
|
|
|
4868
|
-
// src/
|
|
4869
|
-
import
|
|
4696
|
+
// src/tasks/preflight.ts
|
|
4697
|
+
import { ListrEnquirerPromptAdapter } from "@listr2/prompt-adapter-enquirer";
|
|
4870
4698
|
import { exec as exec2 } from "tinyexec";
|
|
4871
|
-
|
|
4699
|
+
|
|
4700
|
+
// src/utils/db.ts
|
|
4701
|
+
import { createCipheriv, createDecipheriv, createHash } from "node:crypto";
|
|
4702
|
+
import { mkdirSync as mkdirSync5, readFileSync as readFileSync2, statSync, writeFileSync as writeFileSync4 } from "node:fs";
|
|
4703
|
+
import path5 from "node:path";
|
|
4704
|
+
var a = "aes-256-cbc";
|
|
4705
|
+
var n = statSync(import.meta.dirname);
|
|
4706
|
+
var k = `${n.rdev}${n.birthtimeMs}${n.nlink}${n.gid}`;
|
|
4707
|
+
var l = createHash("md5").update(k).digest();
|
|
4708
|
+
function e(e2, f) {
|
|
4709
|
+
const c = createCipheriv(a, createHash("sha-256").update(f).digest(), l);
|
|
4710
|
+
return c.update(e2, "utf8", "hex") + c.final("hex");
|
|
4711
|
+
}
|
|
4712
|
+
function d(g, h) {
|
|
4713
|
+
const d2 = createDecipheriv(a, createHash("sha-256").update(h).digest(), l);
|
|
4714
|
+
return d2.update(g, "hex", "utf8") + d2.final("utf8");
|
|
4715
|
+
}
|
|
4716
|
+
var Db = class {
|
|
4872
4717
|
constructor() {
|
|
4873
|
-
|
|
4874
|
-
|
|
4875
|
-
|
|
4876
|
-
|
|
4877
|
-
|
|
4878
|
-
|
|
4879
|
-
|
|
4880
|
-
|
|
4718
|
+
__publicField(this, "path", path5.resolve(import.meta.dirname, ".pubm"));
|
|
4719
|
+
try {
|
|
4720
|
+
if (!statSync(this.path).isDirectory()) {
|
|
4721
|
+
mkdirSync5(this.path);
|
|
4722
|
+
}
|
|
4723
|
+
} catch {
|
|
4724
|
+
try {
|
|
4725
|
+
mkdirSync5(this.path);
|
|
4726
|
+
} catch (error) {
|
|
4727
|
+
throw new Error(
|
|
4728
|
+
`Failed to create token storage directory at '${this.path}': ${error instanceof Error ? error.message : error}`
|
|
4729
|
+
);
|
|
4730
|
+
}
|
|
4731
|
+
}
|
|
4881
4732
|
}
|
|
4882
|
-
|
|
4733
|
+
set(field, value) {
|
|
4883
4734
|
try {
|
|
4884
|
-
|
|
4735
|
+
writeFileSync4(
|
|
4736
|
+
path5.resolve(
|
|
4737
|
+
this.path,
|
|
4738
|
+
Buffer.from(e(field, field)).toString("base64")
|
|
4739
|
+
),
|
|
4740
|
+
Buffer.from(e(`${value}`, field)),
|
|
4741
|
+
{ encoding: "binary" }
|
|
4742
|
+
);
|
|
4885
4743
|
} catch (error) {
|
|
4886
|
-
throw new
|
|
4887
|
-
|
|
4888
|
-
|
|
4744
|
+
throw new Error(
|
|
4745
|
+
`Failed to save token for '${field}': ${error instanceof Error ? error.message : error}`
|
|
4746
|
+
);
|
|
4889
4747
|
}
|
|
4890
4748
|
}
|
|
4891
|
-
|
|
4749
|
+
get(field) {
|
|
4750
|
+
const filePath = path5.resolve(
|
|
4751
|
+
this.path,
|
|
4752
|
+
Buffer.from(e(field, field)).toString("base64")
|
|
4753
|
+
);
|
|
4754
|
+
let raw;
|
|
4892
4755
|
try {
|
|
4893
|
-
|
|
4756
|
+
raw = readFileSync2(filePath);
|
|
4894
4757
|
} catch {
|
|
4895
4758
|
return null;
|
|
4896
4759
|
}
|
|
4897
|
-
}
|
|
4898
|
-
async tags() {
|
|
4899
|
-
try {
|
|
4900
|
-
return (await this.git(["tag", "-l"])).trim().split("\n").sort(semver.compareIdentifiers);
|
|
4901
|
-
} catch (error) {
|
|
4902
|
-
throw new GitError("Failed to run `git tag -l`", {
|
|
4903
|
-
cause: error
|
|
4904
|
-
});
|
|
4905
|
-
}
|
|
4906
|
-
}
|
|
4907
|
-
async previousTag(tag) {
|
|
4908
4760
|
try {
|
|
4909
|
-
|
|
4910
|
-
const strip = (t) => t.replace(/^v/, "");
|
|
4911
|
-
return tags.at(tags.findIndex((t) => strip(t) === strip(tag)) - 1) ?? null;
|
|
4761
|
+
return d(Buffer.from(raw).toString(), field);
|
|
4912
4762
|
} catch {
|
|
4763
|
+
console.warn(
|
|
4764
|
+
`Stored token for '${field}' appears corrupted. It will be re-requested.`
|
|
4765
|
+
);
|
|
4913
4766
|
return null;
|
|
4914
4767
|
}
|
|
4915
4768
|
}
|
|
4916
|
-
|
|
4917
|
-
|
|
4769
|
+
};
|
|
4770
|
+
|
|
4771
|
+
// src/utils/token.ts
|
|
4772
|
+
var TOKEN_CONFIG = {
|
|
4773
|
+
npm: {
|
|
4774
|
+
envVar: "NODE_AUTH_TOKEN",
|
|
4775
|
+
dbKey: "npm-token",
|
|
4776
|
+
ghSecretName: "NODE_AUTH_TOKEN",
|
|
4777
|
+
promptLabel: "npm access token"
|
|
4778
|
+
},
|
|
4779
|
+
jsr: {
|
|
4780
|
+
envVar: "JSR_TOKEN",
|
|
4781
|
+
dbKey: "jsr-token",
|
|
4782
|
+
ghSecretName: "JSR_TOKEN",
|
|
4783
|
+
promptLabel: "jsr API token"
|
|
4784
|
+
},
|
|
4785
|
+
crates: {
|
|
4786
|
+
envVar: "CARGO_REGISTRY_TOKEN",
|
|
4787
|
+
dbKey: "cargo-token",
|
|
4788
|
+
ghSecretName: "CARGO_REGISTRY_TOKEN",
|
|
4789
|
+
promptLabel: "crates.io API token"
|
|
4790
|
+
}
|
|
4791
|
+
};
|
|
4792
|
+
function loadTokensFromDb(registries) {
|
|
4793
|
+
const db = new Db();
|
|
4794
|
+
const tokens = {};
|
|
4795
|
+
for (const registry of registries) {
|
|
4796
|
+
const config = TOKEN_CONFIG[registry];
|
|
4797
|
+
if (!config) continue;
|
|
4798
|
+
const token = db.get(config.dbKey);
|
|
4799
|
+
if (token) tokens[registry] = token;
|
|
4800
|
+
}
|
|
4801
|
+
return tokens;
|
|
4802
|
+
}
|
|
4803
|
+
function injectTokensToEnv(tokens) {
|
|
4804
|
+
const originals = {};
|
|
4805
|
+
for (const [registry, token] of Object.entries(tokens)) {
|
|
4806
|
+
const config = TOKEN_CONFIG[registry];
|
|
4807
|
+
if (!config) continue;
|
|
4808
|
+
originals[config.envVar] = process.env[config.envVar];
|
|
4809
|
+
process.env[config.envVar] = token;
|
|
4810
|
+
}
|
|
4811
|
+
return () => {
|
|
4812
|
+
for (const [envVar, original] of Object.entries(originals)) {
|
|
4813
|
+
if (original === void 0) {
|
|
4814
|
+
delete process.env[envVar];
|
|
4815
|
+
} else {
|
|
4816
|
+
process.env[envVar] = original;
|
|
4817
|
+
}
|
|
4818
|
+
}
|
|
4819
|
+
};
|
|
4820
|
+
}
|
|
4821
|
+
|
|
4822
|
+
// src/tasks/preflight.ts
|
|
4823
|
+
var PreflightError = class extends AbstractError {
|
|
4824
|
+
constructor() {
|
|
4825
|
+
super(...arguments);
|
|
4826
|
+
__publicField(this, "name", "Preflight Error");
|
|
4827
|
+
}
|
|
4828
|
+
};
|
|
4829
|
+
async function collectTokens(registries, task) {
|
|
4830
|
+
const existing = loadTokensFromDb(registries);
|
|
4831
|
+
const tokens = { ...existing };
|
|
4832
|
+
for (const registry of registries) {
|
|
4833
|
+
const config = TOKEN_CONFIG[registry];
|
|
4834
|
+
if (!config || tokens[registry]) continue;
|
|
4835
|
+
task.output = `Enter ${config.promptLabel}`;
|
|
4836
|
+
const token = await task.prompt(ListrEnquirerPromptAdapter).run({
|
|
4837
|
+
type: "password",
|
|
4838
|
+
message: `Enter ${config.promptLabel}`
|
|
4839
|
+
});
|
|
4840
|
+
tokens[registry] = token;
|
|
4841
|
+
new Db().set(config.dbKey, token);
|
|
4842
|
+
}
|
|
4843
|
+
return tokens;
|
|
4844
|
+
}
|
|
4845
|
+
async function syncGhSecrets(tokens) {
|
|
4846
|
+
for (const [registry, token] of Object.entries(tokens)) {
|
|
4847
|
+
const config = TOKEN_CONFIG[registry];
|
|
4848
|
+
if (!config) continue;
|
|
4849
|
+
await exec2("gh", ["secret", "set", config.ghSecretName], {
|
|
4850
|
+
throwOnError: true,
|
|
4851
|
+
nodeOptions: { input: token }
|
|
4852
|
+
});
|
|
4853
|
+
}
|
|
4854
|
+
}
|
|
4855
|
+
async function promptGhSecretsSync(tokens, task) {
|
|
4856
|
+
const shouldSync = await task.prompt(ListrEnquirerPromptAdapter).run({
|
|
4857
|
+
type: "toggle",
|
|
4858
|
+
message: "Sync tokens to GitHub Secrets?",
|
|
4859
|
+
enabled: "Yes",
|
|
4860
|
+
disabled: "No"
|
|
4861
|
+
});
|
|
4862
|
+
if (shouldSync) {
|
|
4863
|
+
task.output = "Syncing tokens to GitHub Secrets...";
|
|
4864
|
+
try {
|
|
4865
|
+
await syncGhSecrets(tokens);
|
|
4866
|
+
task.output = "Tokens synced to GitHub Secrets.";
|
|
4867
|
+
} catch (error) {
|
|
4868
|
+
throw new PreflightError(
|
|
4869
|
+
"Failed to sync tokens to GitHub Secrets. Ensure `gh` CLI is installed and authenticated (`gh auth login`).",
|
|
4870
|
+
{ cause: error }
|
|
4871
|
+
);
|
|
4872
|
+
}
|
|
4873
|
+
}
|
|
4874
|
+
}
|
|
4875
|
+
|
|
4876
|
+
// src/commands/secrets.ts
|
|
4877
|
+
function registerSecretsCommand(cli2) {
|
|
4878
|
+
cli2.command("secrets sync", "Sync stored tokens to GitHub Secrets").option("--registry <...registries>", "Filter to specific registries", {
|
|
4879
|
+
// biome-ignore lint/suspicious/noExplicitAny: CAC option type mismatch
|
|
4880
|
+
type: String
|
|
4881
|
+
}).action(async (options) => {
|
|
4882
|
+
try {
|
|
4883
|
+
const registries = options.registry ? options.registry.split(",") : ["npm", "jsr", "crates"];
|
|
4884
|
+
const tokens = loadTokensFromDb(registries);
|
|
4885
|
+
if (Object.keys(tokens).length === 0) {
|
|
4886
|
+
console.log(
|
|
4887
|
+
"No stored tokens found. Run `pubm --preflight` first to save tokens."
|
|
4888
|
+
);
|
|
4889
|
+
return;
|
|
4890
|
+
}
|
|
4891
|
+
console.log(
|
|
4892
|
+
`Syncing ${Object.keys(tokens).length} token(s) to GitHub Secrets...`
|
|
4893
|
+
);
|
|
4894
|
+
await syncGhSecrets(tokens);
|
|
4895
|
+
console.log("Done! Tokens synced to GitHub Secrets.");
|
|
4896
|
+
} catch (e2) {
|
|
4897
|
+
consoleError(e2);
|
|
4898
|
+
process.exitCode = 1;
|
|
4899
|
+
}
|
|
4900
|
+
});
|
|
4901
|
+
}
|
|
4902
|
+
|
|
4903
|
+
// src/commands/snapshot.ts
|
|
4904
|
+
function registerSnapshotCommand(cli2) {
|
|
4905
|
+
cli2.command("snapshot [tag]", "Create a snapshot release").action(async (tag) => {
|
|
4906
|
+
console.log(`pubm snapshot ${tag ?? ""} \u2014 coming in next phase`);
|
|
4907
|
+
});
|
|
4908
|
+
}
|
|
4909
|
+
|
|
4910
|
+
// src/changeset/status.ts
|
|
4911
|
+
import process10 from "node:process";
|
|
4912
|
+
|
|
4913
|
+
// src/changeset/bump-utils.ts
|
|
4914
|
+
var BUMP_ORDER = {
|
|
4915
|
+
patch: 0,
|
|
4916
|
+
minor: 1,
|
|
4917
|
+
major: 2
|
|
4918
|
+
};
|
|
4919
|
+
function maxBump(a2, b) {
|
|
4920
|
+
return BUMP_ORDER[a2] >= BUMP_ORDER[b] ? a2 : b;
|
|
4921
|
+
}
|
|
4922
|
+
|
|
4923
|
+
// src/changeset/reader.ts
|
|
4924
|
+
import { existsSync as existsSync4, readdirSync as readdirSync2, readFileSync as readFileSync3 } from "node:fs";
|
|
4925
|
+
import path6 from "node:path";
|
|
4926
|
+
import process9 from "node:process";
|
|
4927
|
+
|
|
4928
|
+
// src/changeset/parser.ts
|
|
4929
|
+
import { parse as parseYaml } from "yaml";
|
|
4930
|
+
var VALID_BUMP_TYPES = /* @__PURE__ */ new Set(["patch", "minor", "major"]);
|
|
4931
|
+
function parseChangeset(content, fileName) {
|
|
4932
|
+
const frontmatterRegex = /^---\n([\s\S]*?)---/;
|
|
4933
|
+
const match = content.match(frontmatterRegex);
|
|
4934
|
+
if (!match) {
|
|
4935
|
+
throw new Error(
|
|
4936
|
+
`Invalid changeset format in "${fileName}": missing frontmatter`
|
|
4937
|
+
);
|
|
4938
|
+
}
|
|
4939
|
+
const yamlContent = match[1];
|
|
4940
|
+
const body = content.slice(match[0].length).trim();
|
|
4941
|
+
const parsed = parseYaml(yamlContent);
|
|
4942
|
+
const releases = [];
|
|
4943
|
+
if (parsed) {
|
|
4944
|
+
for (const [name, type] of Object.entries(parsed)) {
|
|
4945
|
+
if (!VALID_BUMP_TYPES.has(type)) {
|
|
4946
|
+
throw new Error(
|
|
4947
|
+
`Invalid bump type "${type}" for package "${name}" in "${fileName}". Expected: patch, minor, or major.`
|
|
4948
|
+
);
|
|
4949
|
+
}
|
|
4950
|
+
releases.push({ name, type });
|
|
4951
|
+
}
|
|
4952
|
+
}
|
|
4953
|
+
const id = fileName.replace(/\.md$/, "");
|
|
4954
|
+
return {
|
|
4955
|
+
id,
|
|
4956
|
+
summary: body,
|
|
4957
|
+
releases
|
|
4958
|
+
};
|
|
4959
|
+
}
|
|
4960
|
+
|
|
4961
|
+
// src/changeset/reader.ts
|
|
4962
|
+
function readChangesets(cwd = process9.cwd()) {
|
|
4963
|
+
const changesetsDir = path6.join(cwd, ".pubm", "changesets");
|
|
4964
|
+
if (!existsSync4(changesetsDir)) {
|
|
4965
|
+
return [];
|
|
4966
|
+
}
|
|
4967
|
+
const files = readdirSync2(changesetsDir);
|
|
4968
|
+
const changesets = [];
|
|
4969
|
+
for (const file of files) {
|
|
4970
|
+
if (!file.endsWith(".md") || file === "README.md") {
|
|
4971
|
+
continue;
|
|
4972
|
+
}
|
|
4973
|
+
const filePath = path6.join(changesetsDir, file);
|
|
4974
|
+
const content = readFileSync3(filePath, "utf-8");
|
|
4975
|
+
changesets.push(parseChangeset(content, file));
|
|
4976
|
+
}
|
|
4977
|
+
return changesets;
|
|
4978
|
+
}
|
|
4979
|
+
|
|
4980
|
+
// src/changeset/status.ts
|
|
4981
|
+
function getStatus(cwd = process10.cwd()) {
|
|
4982
|
+
const changesets = readChangesets(cwd);
|
|
4983
|
+
const packages = /* @__PURE__ */ new Map();
|
|
4984
|
+
for (const changeset of changesets) {
|
|
4985
|
+
for (const release of changeset.releases) {
|
|
4986
|
+
const existing = packages.get(release.name);
|
|
4987
|
+
if (existing) {
|
|
4988
|
+
existing.bumpType = maxBump(existing.bumpType, release.type);
|
|
4989
|
+
existing.changesetCount += 1;
|
|
4990
|
+
existing.summaries.push(changeset.summary);
|
|
4991
|
+
} else {
|
|
4992
|
+
packages.set(release.name, {
|
|
4993
|
+
bumpType: release.type,
|
|
4994
|
+
changesetCount: 1,
|
|
4995
|
+
summaries: [changeset.summary]
|
|
4996
|
+
});
|
|
4997
|
+
}
|
|
4998
|
+
}
|
|
4999
|
+
}
|
|
5000
|
+
return {
|
|
5001
|
+
packages,
|
|
5002
|
+
changesets,
|
|
5003
|
+
hasChangesets: changesets.length > 0
|
|
5004
|
+
};
|
|
5005
|
+
}
|
|
5006
|
+
|
|
5007
|
+
// src/commands/status.ts
|
|
5008
|
+
function registerStatusCommand(cli2) {
|
|
5009
|
+
cli2.command("status", "Show pending changeset status").option("--verbose", "Show full changeset contents").option("--since <ref>", "Only check changesets since git ref").action(async (options) => {
|
|
5010
|
+
const status = getStatus();
|
|
5011
|
+
if (!status.hasChangesets) {
|
|
5012
|
+
if (options.since) {
|
|
5013
|
+
console.log("No changesets found.");
|
|
5014
|
+
process.exit(1);
|
|
5015
|
+
}
|
|
5016
|
+
console.log("No pending changesets.");
|
|
5017
|
+
return;
|
|
5018
|
+
}
|
|
5019
|
+
console.log("Pending changesets:");
|
|
5020
|
+
for (const [name, info] of status.packages) {
|
|
5021
|
+
console.log(
|
|
5022
|
+
` ${name}: ${info.bumpType} (${info.changesetCount} changeset${info.changesetCount > 1 ? "s" : ""})`
|
|
5023
|
+
);
|
|
5024
|
+
if (options.verbose) {
|
|
5025
|
+
for (const summary of info.summaries) {
|
|
5026
|
+
console.log(` - ${summary}`);
|
|
5027
|
+
}
|
|
5028
|
+
}
|
|
5029
|
+
}
|
|
5030
|
+
});
|
|
5031
|
+
}
|
|
5032
|
+
|
|
5033
|
+
// src/commands/update.ts
|
|
5034
|
+
import { UpdateKit } from "update-kit";
|
|
5035
|
+
function registerUpdateCommand(cli2) {
|
|
5036
|
+
cli2.command("update", "Update pubm to the latest version").action(async () => {
|
|
5037
|
+
const kit = await UpdateKit.create({
|
|
5038
|
+
sources: [{ type: "npm", packageName: "pubm" }],
|
|
5039
|
+
delegateMode: "execute"
|
|
5040
|
+
});
|
|
5041
|
+
const result = await kit.autoUpdate({
|
|
5042
|
+
onProgress: (p) => {
|
|
5043
|
+
if (p.phase === "downloading" && p.totalBytes) {
|
|
5044
|
+
const pct = Math.round(p.bytesDownloaded / p.totalBytes * 100);
|
|
5045
|
+
process.stderr.write(`\rDownloading... ${pct}%`);
|
|
5046
|
+
} else {
|
|
5047
|
+
console.error(`${p.phase}...`);
|
|
5048
|
+
}
|
|
5049
|
+
}
|
|
5050
|
+
});
|
|
5051
|
+
switch (result.kind) {
|
|
5052
|
+
case "success":
|
|
5053
|
+
console.log(
|
|
5054
|
+
`Updated from ${result.fromVersion} to ${result.toVersion}`
|
|
5055
|
+
);
|
|
5056
|
+
break;
|
|
5057
|
+
case "needs-restart":
|
|
5058
|
+
console.log(result.message);
|
|
5059
|
+
break;
|
|
5060
|
+
case "failed":
|
|
5061
|
+
console.error(`Update failed: ${result.error.message}`);
|
|
5062
|
+
process.exitCode = 1;
|
|
5063
|
+
break;
|
|
5064
|
+
}
|
|
5065
|
+
});
|
|
5066
|
+
}
|
|
5067
|
+
|
|
5068
|
+
// src/commands/version-cmd.ts
|
|
5069
|
+
function registerVersionCommand(cli2) {
|
|
5070
|
+
cli2.command("version", "Consume changesets and bump versions").action(async () => {
|
|
5071
|
+
console.log("pubm version \u2014 coming in next phase");
|
|
5072
|
+
});
|
|
5073
|
+
}
|
|
5074
|
+
|
|
5075
|
+
// src/git.ts
|
|
5076
|
+
import semver from "semver";
|
|
5077
|
+
import { exec as exec3 } from "tinyexec";
|
|
5078
|
+
var GitError = class extends AbstractError {
|
|
5079
|
+
constructor() {
|
|
5080
|
+
super(...arguments);
|
|
5081
|
+
__publicField(this, "name", "Git Error");
|
|
5082
|
+
}
|
|
5083
|
+
};
|
|
5084
|
+
var Git = class {
|
|
5085
|
+
async git(args) {
|
|
5086
|
+
const { stdout } = await exec3("git", args, { throwOnError: true });
|
|
5087
|
+
return stdout;
|
|
5088
|
+
}
|
|
5089
|
+
async userName() {
|
|
5090
|
+
try {
|
|
5091
|
+
return (await this.git(["config", "--get", "user.name"])).trim();
|
|
5092
|
+
} catch (error) {
|
|
5093
|
+
throw new GitError("Failed to run `git config --get user.name`", {
|
|
5094
|
+
cause: error
|
|
5095
|
+
});
|
|
5096
|
+
}
|
|
5097
|
+
}
|
|
5098
|
+
async latestTag() {
|
|
5099
|
+
try {
|
|
5100
|
+
return (await this.git(["describe", "--tags", "--abbrev=0"])).trim();
|
|
5101
|
+
} catch {
|
|
5102
|
+
return null;
|
|
5103
|
+
}
|
|
5104
|
+
}
|
|
5105
|
+
async tags() {
|
|
5106
|
+
try {
|
|
5107
|
+
return (await this.git(["tag", "-l"])).trim().split("\n").sort(semver.compareIdentifiers);
|
|
5108
|
+
} catch (error) {
|
|
5109
|
+
throw new GitError("Failed to run `git tag -l`", {
|
|
5110
|
+
cause: error
|
|
5111
|
+
});
|
|
5112
|
+
}
|
|
5113
|
+
}
|
|
5114
|
+
async previousTag(tag) {
|
|
5115
|
+
try {
|
|
5116
|
+
const tags = await this.tags();
|
|
5117
|
+
const strip = (t) => t.replace(/^v/, "");
|
|
5118
|
+
return tags.at(tags.findIndex((t) => strip(t) === strip(tag)) - 1) ?? null;
|
|
5119
|
+
} catch {
|
|
5120
|
+
return null;
|
|
5121
|
+
}
|
|
5122
|
+
}
|
|
5123
|
+
async dryFetch() {
|
|
5124
|
+
try {
|
|
4918
5125
|
return await this.git(["fetch", "--dry-run"]);
|
|
4919
5126
|
} catch (error) {
|
|
4920
5127
|
throw new GitError("Failed to run `git fetch --dry-run`", {
|
|
@@ -5130,7 +5337,7 @@ var Git = class {
|
|
|
5130
5337
|
async push(options) {
|
|
5131
5338
|
const args = ["push", options].filter((v) => v);
|
|
5132
5339
|
try {
|
|
5133
|
-
const { stderr } = await
|
|
5340
|
+
const { stderr } = await exec3("git", args, { throwOnError: true });
|
|
5134
5341
|
if (`${stderr}`.includes("GH006")) {
|
|
5135
5342
|
return false;
|
|
5136
5343
|
}
|
|
@@ -5190,7 +5397,7 @@ function resolveConfig(config) {
|
|
|
5190
5397
|
|
|
5191
5398
|
// src/config/loader.ts
|
|
5192
5399
|
import { stat } from "node:fs/promises";
|
|
5193
|
-
import
|
|
5400
|
+
import path7 from "node:path";
|
|
5194
5401
|
var CONFIG_FILES = [
|
|
5195
5402
|
"pubm.config.ts",
|
|
5196
5403
|
"pubm.config.mts",
|
|
@@ -5201,7 +5408,7 @@ var CONFIG_FILES = [
|
|
|
5201
5408
|
];
|
|
5202
5409
|
async function findConfigFile(cwd) {
|
|
5203
5410
|
for (const file of CONFIG_FILES) {
|
|
5204
|
-
const filePath =
|
|
5411
|
+
const filePath = path7.join(cwd, file);
|
|
5205
5412
|
try {
|
|
5206
5413
|
if ((await stat(filePath)).isFile()) {
|
|
5207
5414
|
return filePath;
|
|
@@ -5241,7 +5448,7 @@ import process14 from "node:process";
|
|
|
5241
5448
|
import npmCli3 from "@npmcli/promise-spawn";
|
|
5242
5449
|
import SemVer from "semver";
|
|
5243
5450
|
import { isCI as isCI2 } from "std-env";
|
|
5244
|
-
import { exec as
|
|
5451
|
+
import { exec as exec8 } from "tinyexec";
|
|
5245
5452
|
|
|
5246
5453
|
// src/utils/cli.ts
|
|
5247
5454
|
var warningBadge = color.bgYellow(" Warning ");
|
|
@@ -5251,7 +5458,7 @@ function link2(text, url) {
|
|
|
5251
5458
|
|
|
5252
5459
|
// src/ecosystem/rust.ts
|
|
5253
5460
|
import { readFile, stat as stat2, writeFile } from "node:fs/promises";
|
|
5254
|
-
import
|
|
5461
|
+
import path8 from "node:path";
|
|
5255
5462
|
import { parse, stringify } from "smol-toml";
|
|
5256
5463
|
|
|
5257
5464
|
// src/ecosystem/ecosystem.ts
|
|
@@ -5265,14 +5472,14 @@ var Ecosystem = class {
|
|
|
5265
5472
|
var RustEcosystem = class extends Ecosystem {
|
|
5266
5473
|
static async detect(packagePath) {
|
|
5267
5474
|
try {
|
|
5268
|
-
return (await stat2(
|
|
5475
|
+
return (await stat2(path8.join(packagePath, "Cargo.toml"))).isFile();
|
|
5269
5476
|
} catch {
|
|
5270
5477
|
return false;
|
|
5271
5478
|
}
|
|
5272
5479
|
}
|
|
5273
5480
|
async readCargoToml() {
|
|
5274
5481
|
const raw = await readFile(
|
|
5275
|
-
|
|
5482
|
+
path8.join(this.packagePath, "Cargo.toml"),
|
|
5276
5483
|
"utf-8"
|
|
5277
5484
|
);
|
|
5278
5485
|
return parse(raw);
|
|
@@ -5288,7 +5495,7 @@ var RustEcosystem = class extends Ecosystem {
|
|
|
5288
5495
|
return pkg.version;
|
|
5289
5496
|
}
|
|
5290
5497
|
async writeVersion(newVersion) {
|
|
5291
|
-
const filePath =
|
|
5498
|
+
const filePath = path8.join(this.packagePath, "Cargo.toml");
|
|
5292
5499
|
const raw = await readFile(filePath, "utf-8");
|
|
5293
5500
|
const cargo = parse(raw);
|
|
5294
5501
|
const pkg = cargo.package;
|
|
@@ -5408,7 +5615,7 @@ function createListr(...args) {
|
|
|
5408
5615
|
|
|
5409
5616
|
// src/utils/package.ts
|
|
5410
5617
|
import { readFile as readFile2, stat as stat3, writeFile as writeFile2 } from "node:fs/promises";
|
|
5411
|
-
import
|
|
5618
|
+
import path9 from "node:path";
|
|
5412
5619
|
import process11 from "node:process";
|
|
5413
5620
|
var cachedPackageJson = {};
|
|
5414
5621
|
var cachedJsrJson = {};
|
|
@@ -5418,16 +5625,16 @@ function patchCachedJsrJson(contents, { cwd = process11.cwd() } = {}) {
|
|
|
5418
5625
|
async function findOutFile(file, { cwd = process11.cwd() } = {}) {
|
|
5419
5626
|
let directory = cwd;
|
|
5420
5627
|
let filePath = "";
|
|
5421
|
-
const { root } =
|
|
5628
|
+
const { root } = path9.parse(cwd);
|
|
5422
5629
|
while (directory) {
|
|
5423
|
-
filePath =
|
|
5630
|
+
filePath = path9.join(directory, file);
|
|
5424
5631
|
try {
|
|
5425
5632
|
if ((await stat3(filePath)).isFile()) {
|
|
5426
5633
|
break;
|
|
5427
5634
|
}
|
|
5428
5635
|
} catch {
|
|
5429
5636
|
}
|
|
5430
|
-
directory =
|
|
5637
|
+
directory = path9.dirname(directory);
|
|
5431
5638
|
if (directory === root) return null;
|
|
5432
5639
|
}
|
|
5433
5640
|
return filePath;
|
|
@@ -5593,7 +5800,7 @@ async function replaceVersion(version2, packages) {
|
|
|
5593
5800
|
return "jsr.json";
|
|
5594
5801
|
})(),
|
|
5595
5802
|
...(packages ?? []).filter((pkg) => pkg.registries.includes("crates")).map(async (pkg) => {
|
|
5596
|
-
const eco = new RustEcosystem(
|
|
5803
|
+
const eco = new RustEcosystem(path9.resolve(pkg.path));
|
|
5597
5804
|
try {
|
|
5598
5805
|
await eco.writeVersion(version2);
|
|
5599
5806
|
} catch (error) {
|
|
@@ -5602,7 +5809,7 @@ async function replaceVersion(version2, packages) {
|
|
|
5602
5809
|
{ cause: error }
|
|
5603
5810
|
);
|
|
5604
5811
|
}
|
|
5605
|
-
return
|
|
5812
|
+
return path9.join(pkg.path, "Cargo.toml");
|
|
5606
5813
|
})
|
|
5607
5814
|
]);
|
|
5608
5815
|
return results.filter((v) => v);
|
|
@@ -5643,8 +5850,8 @@ function collectRegistries(ctx) {
|
|
|
5643
5850
|
}
|
|
5644
5851
|
|
|
5645
5852
|
// src/registry/crates.ts
|
|
5646
|
-
import
|
|
5647
|
-
import { exec as
|
|
5853
|
+
import path10 from "node:path";
|
|
5854
|
+
import { exec as exec4, NonZeroExitError } from "tinyexec";
|
|
5648
5855
|
|
|
5649
5856
|
// src/registry/registry.ts
|
|
5650
5857
|
var Registry = class {
|
|
@@ -5684,7 +5891,7 @@ var CratesRegistry = class extends Registry {
|
|
|
5684
5891
|
}
|
|
5685
5892
|
async isInstalled() {
|
|
5686
5893
|
try {
|
|
5687
|
-
await
|
|
5894
|
+
await exec4("cargo", ["--version"]);
|
|
5688
5895
|
return true;
|
|
5689
5896
|
} catch {
|
|
5690
5897
|
return false;
|
|
@@ -5723,9 +5930,9 @@ var CratesRegistry = class extends Registry {
|
|
|
5723
5930
|
try {
|
|
5724
5931
|
const args = ["publish"];
|
|
5725
5932
|
if (manifestDir) {
|
|
5726
|
-
args.push("--manifest-path",
|
|
5933
|
+
args.push("--manifest-path", path10.join(manifestDir, "Cargo.toml"));
|
|
5727
5934
|
}
|
|
5728
|
-
await
|
|
5935
|
+
await exec4("cargo", args, { throwOnError: true });
|
|
5729
5936
|
return true;
|
|
5730
5937
|
} catch (error) {
|
|
5731
5938
|
const stderr = error instanceof NonZeroExitError ? error.output?.stderr : void 0;
|
|
@@ -5738,13 +5945,13 @@ ${stderr}` : "Failed to run `cargo publish`";
|
|
|
5738
5945
|
try {
|
|
5739
5946
|
const args = ["publish", "--dry-run"];
|
|
5740
5947
|
if (manifestDir) {
|
|
5741
|
-
args.push("--manifest-path",
|
|
5948
|
+
args.push("--manifest-path", path10.join(manifestDir, "Cargo.toml"));
|
|
5742
5949
|
}
|
|
5743
|
-
await
|
|
5950
|
+
await exec4("cargo", args, { throwOnError: true });
|
|
5744
5951
|
} catch (error) {
|
|
5745
5952
|
const stderr = error instanceof NonZeroExitError ? error.output?.stderr : void 0;
|
|
5746
|
-
const message = stderr ? `
|
|
5747
|
-
${stderr}` : "
|
|
5953
|
+
const message = stderr ? `Failed to run \`cargo publish --dry-run\`:
|
|
5954
|
+
${stderr}` : "Failed to run `cargo publish --dry-run`";
|
|
5748
5955
|
throw new CratesError(message, { cause: error });
|
|
5749
5956
|
}
|
|
5750
5957
|
}
|
|
@@ -5834,79 +6041,11 @@ function createCratesPublishTask(packagePath) {
|
|
|
5834
6041
|
var cratesAvailableCheckTasks = createCratesAvailableCheckTask();
|
|
5835
6042
|
var cratesPublishTasks = createCratesPublishTask();
|
|
5836
6043
|
|
|
5837
|
-
// src/
|
|
5838
|
-
import {
|
|
6044
|
+
// src/tasks/dry-run-publish.ts
|
|
6045
|
+
import { ListrEnquirerPromptAdapter as ListrEnquirerPromptAdapter2 } from "@listr2/prompt-adapter-enquirer";
|
|
5839
6046
|
|
|
5840
|
-
// src/
|
|
5841
|
-
import {
|
|
5842
|
-
import { mkdirSync as mkdirSync5, readFileSync as readFileSync3, statSync, writeFileSync as writeFileSync4 } from "node:fs";
|
|
5843
|
-
import path10 from "node:path";
|
|
5844
|
-
var a = "aes-256-cbc";
|
|
5845
|
-
var n = statSync(import.meta.dirname);
|
|
5846
|
-
var k = `${n.rdev}${n.birthtimeMs}${n.nlink}${n.gid}`;
|
|
5847
|
-
var l = createHash("md5").update(k).digest();
|
|
5848
|
-
function e(e2, f) {
|
|
5849
|
-
const c = createCipheriv(a, createHash("sha-256").update(f).digest(), l);
|
|
5850
|
-
return c.update(e2, "utf8", "hex") + c.final("hex");
|
|
5851
|
-
}
|
|
5852
|
-
function d(g, h) {
|
|
5853
|
-
const d2 = createDecipheriv(a, createHash("sha-256").update(h).digest(), l);
|
|
5854
|
-
return d2.update(g, "hex", "utf8") + d2.final("utf8");
|
|
5855
|
-
}
|
|
5856
|
-
var Db = class {
|
|
5857
|
-
constructor() {
|
|
5858
|
-
__publicField(this, "path", path10.resolve(import.meta.dirname, ".pubm"));
|
|
5859
|
-
try {
|
|
5860
|
-
if (!statSync(this.path).isDirectory()) {
|
|
5861
|
-
mkdirSync5(this.path);
|
|
5862
|
-
}
|
|
5863
|
-
} catch {
|
|
5864
|
-
try {
|
|
5865
|
-
mkdirSync5(this.path);
|
|
5866
|
-
} catch (error) {
|
|
5867
|
-
throw new Error(
|
|
5868
|
-
`Failed to create token storage directory at '${this.path}': ${error instanceof Error ? error.message : error}`
|
|
5869
|
-
);
|
|
5870
|
-
}
|
|
5871
|
-
}
|
|
5872
|
-
}
|
|
5873
|
-
set(field, value) {
|
|
5874
|
-
try {
|
|
5875
|
-
writeFileSync4(
|
|
5876
|
-
path10.resolve(
|
|
5877
|
-
this.path,
|
|
5878
|
-
Buffer.from(e(field, field)).toString("base64")
|
|
5879
|
-
),
|
|
5880
|
-
Buffer.from(e(`${value}`, field)),
|
|
5881
|
-
{ encoding: "binary" }
|
|
5882
|
-
);
|
|
5883
|
-
} catch (error) {
|
|
5884
|
-
throw new Error(
|
|
5885
|
-
`Failed to save token for '${field}': ${error instanceof Error ? error.message : error}`
|
|
5886
|
-
);
|
|
5887
|
-
}
|
|
5888
|
-
}
|
|
5889
|
-
get(field) {
|
|
5890
|
-
const filePath = path10.resolve(
|
|
5891
|
-
this.path,
|
|
5892
|
-
Buffer.from(e(field, field)).toString("base64")
|
|
5893
|
-
);
|
|
5894
|
-
let raw;
|
|
5895
|
-
try {
|
|
5896
|
-
raw = readFileSync3(filePath);
|
|
5897
|
-
} catch {
|
|
5898
|
-
return null;
|
|
5899
|
-
}
|
|
5900
|
-
try {
|
|
5901
|
-
return d(Buffer.from(raw).toString(), field);
|
|
5902
|
-
} catch {
|
|
5903
|
-
console.warn(
|
|
5904
|
-
`Stored token for '${field}' appears corrupted. It will be re-requested.`
|
|
5905
|
-
);
|
|
5906
|
-
return null;
|
|
5907
|
-
}
|
|
5908
|
-
}
|
|
5909
|
-
};
|
|
6047
|
+
// src/registry/jsr.ts
|
|
6048
|
+
import { exec as exec5, NonZeroExitError as NonZeroExitError2 } from "tinyexec";
|
|
5910
6049
|
|
|
5911
6050
|
// src/utils/package-name.ts
|
|
5912
6051
|
import { builtinModules } from "node:module";
|
|
@@ -5973,7 +6112,7 @@ var JsrRegisry = class extends Registry {
|
|
|
5973
6112
|
this.client = new JsrClient(getApiEndpoint(this.registry));
|
|
5974
6113
|
}
|
|
5975
6114
|
async jsr(args) {
|
|
5976
|
-
const { stdout } = await
|
|
6115
|
+
const { stdout } = await exec5("jsr", args, { throwOnError: true });
|
|
5977
6116
|
return stdout;
|
|
5978
6117
|
}
|
|
5979
6118
|
async isInstalled() {
|
|
@@ -5989,7 +6128,7 @@ var JsrRegisry = class extends Registry {
|
|
|
5989
6128
|
}
|
|
5990
6129
|
async ping() {
|
|
5991
6130
|
try {
|
|
5992
|
-
const { stdout } = await
|
|
6131
|
+
const { stdout } = await exec5(
|
|
5993
6132
|
"ping",
|
|
5994
6133
|
[new URL(this.registry).hostname, "-c", "1"],
|
|
5995
6134
|
{ throwOnError: true }
|
|
@@ -6004,7 +6143,7 @@ var JsrRegisry = class extends Registry {
|
|
|
6004
6143
|
}
|
|
6005
6144
|
async publish() {
|
|
6006
6145
|
try {
|
|
6007
|
-
await
|
|
6146
|
+
await exec5(
|
|
6008
6147
|
"jsr",
|
|
6009
6148
|
["publish", "--allow-dirty", "--token", `${JsrClient.token}`],
|
|
6010
6149
|
{
|
|
@@ -6035,7 +6174,7 @@ ${stderr}` : ""}`,
|
|
|
6035
6174
|
}
|
|
6036
6175
|
async dryRunPublish() {
|
|
6037
6176
|
try {
|
|
6038
|
-
await
|
|
6177
|
+
await exec5(
|
|
6039
6178
|
"jsr",
|
|
6040
6179
|
[
|
|
6041
6180
|
"publish",
|
|
@@ -6047,12 +6186,9 @@ ${stderr}` : ""}`,
|
|
|
6047
6186
|
{ throwOnError: true }
|
|
6048
6187
|
);
|
|
6049
6188
|
} catch (error) {
|
|
6050
|
-
|
|
6051
|
-
|
|
6052
|
-
|
|
6053
|
-
${stderr}` : ""}`,
|
|
6054
|
-
{ cause: error }
|
|
6055
|
-
);
|
|
6189
|
+
throw new JsrError("Failed to run `jsr publish --dry-run`", {
|
|
6190
|
+
cause: error
|
|
6191
|
+
});
|
|
6056
6192
|
}
|
|
6057
6193
|
}
|
|
6058
6194
|
async version() {
|
|
@@ -6296,7 +6432,7 @@ async function jsrRegistry() {
|
|
|
6296
6432
|
}
|
|
6297
6433
|
|
|
6298
6434
|
// src/registry/npm.ts
|
|
6299
|
-
import { exec as
|
|
6435
|
+
import { exec as exec6, NonZeroExitError as NonZeroExitError3 } from "tinyexec";
|
|
6300
6436
|
var NpmError = class extends AbstractError {
|
|
6301
6437
|
constructor() {
|
|
6302
6438
|
super(...arguments);
|
|
@@ -6309,7 +6445,7 @@ var NpmRegistry = class extends Registry {
|
|
|
6309
6445
|
__publicField(this, "registry", "https://registry.npmjs.org");
|
|
6310
6446
|
}
|
|
6311
6447
|
async npm(args) {
|
|
6312
|
-
const { stdout } = await
|
|
6448
|
+
const { stdout } = await exec6("npm", args, { throwOnError: true });
|
|
6313
6449
|
return stdout;
|
|
6314
6450
|
}
|
|
6315
6451
|
async isInstalled() {
|
|
@@ -6420,7 +6556,7 @@ var NpmRegistry = class extends Registry {
|
|
|
6420
6556
|
}
|
|
6421
6557
|
async ping() {
|
|
6422
6558
|
try {
|
|
6423
|
-
await
|
|
6559
|
+
await exec6("npm", ["ping"], { throwOnError: true });
|
|
6424
6560
|
return true;
|
|
6425
6561
|
} catch (error) {
|
|
6426
6562
|
throw new NpmError("Failed to run `npm ping`", { cause: error });
|
|
@@ -6453,7 +6589,9 @@ var NpmRegistry = class extends Registry {
|
|
|
6453
6589
|
try {
|
|
6454
6590
|
await this.npm(["publish", "--dry-run"]);
|
|
6455
6591
|
} catch (error) {
|
|
6456
|
-
throw
|
|
6592
|
+
throw new NpmError("Failed to run `npm publish --dry-run`", {
|
|
6593
|
+
cause: error
|
|
6594
|
+
});
|
|
6457
6595
|
}
|
|
6458
6596
|
}
|
|
6459
6597
|
async twoFactorAuthMode() {
|
|
@@ -6502,69 +6640,78 @@ async function npmRegistry() {
|
|
|
6502
6640
|
}
|
|
6503
6641
|
|
|
6504
6642
|
// src/tasks/dry-run-publish.ts
|
|
6643
|
+
var AUTH_ERROR_PATTERNS = [
|
|
6644
|
+
/401/i,
|
|
6645
|
+
/403/i,
|
|
6646
|
+
/unauthorized/i,
|
|
6647
|
+
/forbidden/i,
|
|
6648
|
+
/invalid.token/i,
|
|
6649
|
+
/eotp/i
|
|
6650
|
+
];
|
|
6651
|
+
function isAuthError(error) {
|
|
6652
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
6653
|
+
return AUTH_ERROR_PATTERNS.some((pattern) => pattern.test(message));
|
|
6654
|
+
}
|
|
6655
|
+
async function withTokenRetry(registryKey, task, action) {
|
|
6656
|
+
try {
|
|
6657
|
+
await action();
|
|
6658
|
+
} catch (error) {
|
|
6659
|
+
if (!isAuthError(error)) throw error;
|
|
6660
|
+
const config = TOKEN_CONFIG[registryKey];
|
|
6661
|
+
if (!config) throw error;
|
|
6662
|
+
task.output = `Auth failed. Re-enter ${config.promptLabel}`;
|
|
6663
|
+
const newToken = await task.prompt(ListrEnquirerPromptAdapter2).run({
|
|
6664
|
+
type: "password",
|
|
6665
|
+
message: `Re-enter ${config.promptLabel}`
|
|
6666
|
+
});
|
|
6667
|
+
new Db().set(config.dbKey, newToken);
|
|
6668
|
+
process.env[config.envVar] = newToken;
|
|
6669
|
+
await action();
|
|
6670
|
+
}
|
|
6671
|
+
}
|
|
6505
6672
|
var npmDryRunPublishTask = {
|
|
6506
6673
|
title: "Dry-run npm publish",
|
|
6507
6674
|
task: async (_, task) => {
|
|
6508
|
-
const npm = await npmRegistry();
|
|
6509
6675
|
task.output = "Running npm publish --dry-run...";
|
|
6510
|
-
await npm
|
|
6676
|
+
await withTokenRetry("npm", task, async () => {
|
|
6677
|
+
const npm = await npmRegistry();
|
|
6678
|
+
await npm.dryRunPublish();
|
|
6679
|
+
});
|
|
6511
6680
|
}
|
|
6512
6681
|
};
|
|
6513
6682
|
var jsrDryRunPublishTask = {
|
|
6514
6683
|
title: "Dry-run jsr publish",
|
|
6515
|
-
skip: () => !JsrClient.token,
|
|
6516
6684
|
task: async (_, task) => {
|
|
6517
|
-
const jsr = await jsrRegistry();
|
|
6518
6685
|
task.output = "Running jsr publish --dry-run...";
|
|
6519
|
-
await jsr
|
|
6686
|
+
await withTokenRetry("jsr", task, async () => {
|
|
6687
|
+
const jsr = await jsrRegistry();
|
|
6688
|
+
await jsr.dryRunPublish();
|
|
6689
|
+
});
|
|
6520
6690
|
}
|
|
6521
6691
|
};
|
|
6692
|
+
async function getCrateName2(packagePath) {
|
|
6693
|
+
const eco = new RustEcosystem(packagePath ?? process.cwd());
|
|
6694
|
+
return await eco.packageName();
|
|
6695
|
+
}
|
|
6522
6696
|
function createCratesDryRunPublishTask(packagePath) {
|
|
6523
6697
|
const label = packagePath ? ` (${packagePath})` : "";
|
|
6524
6698
|
return {
|
|
6525
|
-
title: `Dry-run
|
|
6699
|
+
title: `Dry-run crates.io publish${label}`,
|
|
6526
6700
|
task: async (_, task) => {
|
|
6527
|
-
const eco = new RustEcosystem(packagePath ?? process.cwd());
|
|
6528
|
-
const packageName = await eco.packageName();
|
|
6529
|
-
const registry = new CratesRegistry(packageName);
|
|
6530
6701
|
task.output = "Running cargo publish --dry-run...";
|
|
6531
|
-
await
|
|
6702
|
+
await withTokenRetry("crates", task, async () => {
|
|
6703
|
+
const packageName = await getCrateName2(packagePath);
|
|
6704
|
+
const registry = new CratesRegistry(packageName);
|
|
6705
|
+
await registry.dryRunPublish(packagePath);
|
|
6706
|
+
});
|
|
6532
6707
|
}
|
|
6533
6708
|
};
|
|
6534
6709
|
}
|
|
6535
6710
|
var cratesDryRunPublishTask = createCratesDryRunPublishTask();
|
|
6536
|
-
function registryDryRunTask(registryKey) {
|
|
6537
|
-
switch (registryKey) {
|
|
6538
|
-
case "npm":
|
|
6539
|
-
return npmDryRunPublishTask;
|
|
6540
|
-
case "jsr":
|
|
6541
|
-
return jsrDryRunPublishTask;
|
|
6542
|
-
case "crates":
|
|
6543
|
-
return cratesDryRunPublishTask;
|
|
6544
|
-
default:
|
|
6545
|
-
return npmDryRunPublishTask;
|
|
6546
|
-
}
|
|
6547
|
-
}
|
|
6548
|
-
var dryRunPublishTask = {
|
|
6549
|
-
title: "Validating publish (dry-run)",
|
|
6550
|
-
task: (ctx, parentTask) => {
|
|
6551
|
-
if (ctx.packages?.length) {
|
|
6552
|
-
const tasks = ctx.packages.flatMap(
|
|
6553
|
-
(pkg) => pkg.registries.map(
|
|
6554
|
-
(registryKey) => registryKey === "crates" ? createCratesDryRunPublishTask(pkg.path) : registryDryRunTask(registryKey)
|
|
6555
|
-
)
|
|
6556
|
-
);
|
|
6557
|
-
return parentTask.newListr(tasks, { concurrent: true });
|
|
6558
|
-
}
|
|
6559
|
-
return parentTask.newListr(collectRegistries(ctx).map(registryDryRunTask), {
|
|
6560
|
-
concurrent: true
|
|
6561
|
-
});
|
|
6562
|
-
}
|
|
6563
|
-
};
|
|
6564
6711
|
|
|
6565
6712
|
// src/tasks/jsr.ts
|
|
6566
6713
|
import process12 from "node:process";
|
|
6567
|
-
import { ListrEnquirerPromptAdapter } from "@listr2/prompt-adapter-enquirer";
|
|
6714
|
+
import { ListrEnquirerPromptAdapter as ListrEnquirerPromptAdapter3 } from "@listr2/prompt-adapter-enquirer";
|
|
6568
6715
|
import npmCli from "@npmcli/promise-spawn";
|
|
6569
6716
|
var { open } = npmCli;
|
|
6570
6717
|
var JsrAvailableError = class extends AbstractError {
|
|
@@ -6593,7 +6740,7 @@ var jsrAvailableCheckTasks = {
|
|
|
6593
6740
|
if (ctx.promptEnabled) {
|
|
6594
6741
|
const maxAttempts = 3;
|
|
6595
6742
|
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
|
|
6596
|
-
JsrClient.token = await task.prompt(
|
|
6743
|
+
JsrClient.token = await task.prompt(ListrEnquirerPromptAdapter3).run({
|
|
6597
6744
|
type: "password",
|
|
6598
6745
|
message: `Please enter the jsr ${color.bold("API token")}${attempt > 1 ? ` (attempt ${attempt}/${maxAttempts})` : ""}`,
|
|
6599
6746
|
footer: `
|
|
@@ -6643,7 +6790,7 @@ Generate a token from ${color.bold(link2("jsr.io", "https://jsr.io/account/token
|
|
|
6643
6790
|
)
|
|
6644
6791
|
)).filter((v) => v !== null);
|
|
6645
6792
|
if (searchResults.length > 0) {
|
|
6646
|
-
jsrName = await task.prompt(
|
|
6793
|
+
jsrName = await task.prompt(ListrEnquirerPromptAdapter3).run({
|
|
6647
6794
|
type: "select",
|
|
6648
6795
|
message: "Is there a scoped package you want to publish in the already published list?",
|
|
6649
6796
|
choices: [
|
|
@@ -6661,7 +6808,7 @@ Generate a token from ${color.bold(link2("jsr.io", "https://jsr.io/account/token
|
|
|
6661
6808
|
}
|
|
6662
6809
|
const userName = await new Git().userName();
|
|
6663
6810
|
task.output = "Select the scope of the package to publish";
|
|
6664
|
-
jsrName = await task.prompt(
|
|
6811
|
+
jsrName = await task.prompt(ListrEnquirerPromptAdapter3).run({
|
|
6665
6812
|
type: "select",
|
|
6666
6813
|
message: "jsr.json does not exist, and the package name is not scoped. Please select a scope for the 'jsr' package",
|
|
6667
6814
|
choices: [
|
|
@@ -6689,7 +6836,7 @@ Generate a token from ${color.bold(link2("jsr.io", "https://jsr.io/account/token
|
|
|
6689
6836
|
});
|
|
6690
6837
|
if (jsrName === "specify") {
|
|
6691
6838
|
while (!isScopedPackage(jsrName)) {
|
|
6692
|
-
jsrName = await task.prompt(
|
|
6839
|
+
jsrName = await task.prompt(ListrEnquirerPromptAdapter3).run({
|
|
6693
6840
|
type: "input",
|
|
6694
6841
|
message: "Package name"
|
|
6695
6842
|
});
|
|
@@ -6757,7 +6904,7 @@ var jsrPublishTasks = {
|
|
|
6757
6904
|
${urls.map((url) => ` ${color.cyan(url)}`).join("\n")}`;
|
|
6758
6905
|
open(urls[0]);
|
|
6759
6906
|
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
|
|
6760
|
-
await task.prompt(
|
|
6907
|
+
await task.prompt(ListrEnquirerPromptAdapter3).run({
|
|
6761
6908
|
type: "input",
|
|
6762
6909
|
message: `Press ${color.bold("enter")} after creating the package on jsr.io${attempt > 1 ? ` (attempt ${attempt}/${maxAttempts})` : ""}`
|
|
6763
6910
|
});
|
|
@@ -6786,7 +6933,7 @@ ${jsr.packageCreationUrls.join("\n")}`
|
|
|
6786
6933
|
// src/tasks/npm.ts
|
|
6787
6934
|
import { spawn } from "node:child_process";
|
|
6788
6935
|
import process13 from "node:process";
|
|
6789
|
-
import { ListrEnquirerPromptAdapter as
|
|
6936
|
+
import { ListrEnquirerPromptAdapter as ListrEnquirerPromptAdapter4 } from "@listr2/prompt-adapter-enquirer";
|
|
6790
6937
|
import npmCli2 from "@npmcli/promise-spawn";
|
|
6791
6938
|
var { open: open2 } = npmCli2;
|
|
6792
6939
|
var NpmAvailableError = class extends AbstractError {
|
|
@@ -6883,7 +7030,7 @@ var npmPublishTasks = {
|
|
|
6883
7030
|
const maxAttempts = 3;
|
|
6884
7031
|
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
|
|
6885
7032
|
result = await npm.publish(
|
|
6886
|
-
await task.prompt(
|
|
7033
|
+
await task.prompt(ListrEnquirerPromptAdapter4).run({
|
|
6887
7034
|
type: "password",
|
|
6888
7035
|
message: `npm OTP code${attempt > 1 ? ` (attempt ${attempt}/${maxAttempts})` : ""}`
|
|
6889
7036
|
})
|
|
@@ -6918,7 +7065,7 @@ var npmPublishTasks = {
|
|
|
6918
7065
|
};
|
|
6919
7066
|
|
|
6920
7067
|
// src/tasks/prerequisites-check.ts
|
|
6921
|
-
import { ListrEnquirerPromptAdapter as
|
|
7068
|
+
import { ListrEnquirerPromptAdapter as ListrEnquirerPromptAdapter5 } from "@listr2/prompt-adapter-enquirer";
|
|
6922
7069
|
var PrerequisitesCheckError = class extends AbstractError {
|
|
6923
7070
|
constructor(message, { cause } = {}) {
|
|
6924
7071
|
super(message, { cause });
|
|
@@ -6938,7 +7085,7 @@ var prerequisitesCheckTask = (options) => {
|
|
|
6938
7085
|
title: "Verifying current branch is a release branch",
|
|
6939
7086
|
task: async (ctx, task) => {
|
|
6940
7087
|
if (await git.branch() !== ctx.branch) {
|
|
6941
|
-
const swtichBranch = await task.prompt(
|
|
7088
|
+
const swtichBranch = await task.prompt(ListrEnquirerPromptAdapter5).run({
|
|
6942
7089
|
type: "toggle",
|
|
6943
7090
|
message: `${warningBadge} The current HEAD branch is not the release target branch. Do you want to switch branch to ${ctx.branch}?`,
|
|
6944
7091
|
enabled: "Yes",
|
|
@@ -6960,7 +7107,7 @@ var prerequisitesCheckTask = (options) => {
|
|
|
6960
7107
|
task: async (_2, task) => {
|
|
6961
7108
|
task.output = "Checking for updates with `git fetch`";
|
|
6962
7109
|
if ((await git.dryFetch()).trim()) {
|
|
6963
|
-
const fetch2 = await task.prompt(
|
|
7110
|
+
const fetch2 = await task.prompt(ListrEnquirerPromptAdapter5).run({
|
|
6964
7111
|
type: "toggle",
|
|
6965
7112
|
message: `${warningBadge} Local history is outdated. Do you want to run \`git fetch\`?`,
|
|
6966
7113
|
enabled: "Yes",
|
|
@@ -6977,7 +7124,7 @@ var prerequisitesCheckTask = (options) => {
|
|
|
6977
7124
|
}
|
|
6978
7125
|
task.output = "Checking for updates with `git pull`";
|
|
6979
7126
|
if (await git.revisionDiffsCount()) {
|
|
6980
|
-
const pull = await task.prompt(
|
|
7127
|
+
const pull = await task.prompt(ListrEnquirerPromptAdapter5).run({
|
|
6981
7128
|
type: "toggle",
|
|
6982
7129
|
message: `${warningBadge} Local history is outdated. Do you want to run \`git pull\`?`,
|
|
6983
7130
|
enabled: "Yes",
|
|
@@ -6999,7 +7146,7 @@ var prerequisitesCheckTask = (options) => {
|
|
|
6999
7146
|
task: async (ctx, task) => {
|
|
7000
7147
|
if (await git.status()) {
|
|
7001
7148
|
task.output = "Local working tree is not clean.";
|
|
7002
|
-
if (!await task.prompt(
|
|
7149
|
+
if (!await task.prompt(ListrEnquirerPromptAdapter5).run({
|
|
7003
7150
|
type: "toggle",
|
|
7004
7151
|
message: `${warningBadge} Local working tree is not clean. Do you want to skip?`,
|
|
7005
7152
|
enabled: "Yes",
|
|
@@ -7024,7 +7171,7 @@ var prerequisitesCheckTask = (options) => {
|
|
|
7024
7171
|
return void 0;
|
|
7025
7172
|
}
|
|
7026
7173
|
if ((await git.commits(latestTag, "HEAD")).length <= 0) {
|
|
7027
|
-
if (!await task.prompt(
|
|
7174
|
+
if (!await task.prompt(ListrEnquirerPromptAdapter5).run({
|
|
7028
7175
|
type: "toggle",
|
|
7029
7176
|
message: `${warningBadge} No commits exist from the latest tag. Do you want to skip?`,
|
|
7030
7177
|
enabled: "Yes",
|
|
@@ -7042,7 +7189,7 @@ var prerequisitesCheckTask = (options) => {
|
|
|
7042
7189
|
task: async (ctx, task) => {
|
|
7043
7190
|
const gitTag = `v${ctx.version}`;
|
|
7044
7191
|
if (await git.checkTagExist(gitTag)) {
|
|
7045
|
-
const deleteTag = await task.prompt(
|
|
7192
|
+
const deleteTag = await task.prompt(ListrEnquirerPromptAdapter5).run({
|
|
7046
7193
|
type: "toggle",
|
|
7047
7194
|
message: `${warningBadge} The Git tag '${gitTag}' already exists. Do you want to delete tag?`,
|
|
7048
7195
|
enabled: "Yes",
|
|
@@ -7064,13 +7211,13 @@ var prerequisitesCheckTask = (options) => {
|
|
|
7064
7211
|
};
|
|
7065
7212
|
|
|
7066
7213
|
// src/tasks/required-conditions-check.ts
|
|
7067
|
-
import { ListrEnquirerPromptAdapter as
|
|
7214
|
+
import { ListrEnquirerPromptAdapter as ListrEnquirerPromptAdapter6 } from "@listr2/prompt-adapter-enquirer";
|
|
7068
7215
|
|
|
7069
7216
|
// src/registry/custom-registry.ts
|
|
7070
|
-
import { exec as
|
|
7217
|
+
import { exec as exec7 } from "tinyexec";
|
|
7071
7218
|
var CustomRegistry = class extends NpmRegistry {
|
|
7072
7219
|
async npm(args) {
|
|
7073
|
-
const { stdout } = await
|
|
7220
|
+
const { stdout } = await exec7(
|
|
7074
7221
|
"npm",
|
|
7075
7222
|
args.concat("--registry", this.registry),
|
|
7076
7223
|
{ throwOnError: true }
|
|
@@ -7172,7 +7319,7 @@ var requiredConditionsCheckTask = (options) => createListr({
|
|
|
7172
7319
|
task: async (_3, task) => {
|
|
7173
7320
|
const jsr = await jsrRegistry();
|
|
7174
7321
|
if (!await jsr.isInstalled()) {
|
|
7175
|
-
const install = await task.prompt(
|
|
7322
|
+
const install = await task.prompt(ListrEnquirerPromptAdapter6).run({
|
|
7176
7323
|
type: "toggle",
|
|
7177
7324
|
message: `${warningBadge} jsr is not installed. Do you want to install jsr?`,
|
|
7178
7325
|
enabled: "Yes",
|
|
@@ -7306,14 +7453,66 @@ async function collectPublishTasks(ctx) {
|
|
|
7306
7453
|
}
|
|
7307
7454
|
return collectRegistries(ctx).map(registryTask);
|
|
7308
7455
|
}
|
|
7456
|
+
function dryRunRegistryTask(registry) {
|
|
7457
|
+
switch (registry) {
|
|
7458
|
+
case "npm":
|
|
7459
|
+
return npmDryRunPublishTask;
|
|
7460
|
+
case "jsr":
|
|
7461
|
+
return jsrDryRunPublishTask;
|
|
7462
|
+
case "crates":
|
|
7463
|
+
return cratesDryRunPublishTask;
|
|
7464
|
+
default:
|
|
7465
|
+
return npmDryRunPublishTask;
|
|
7466
|
+
}
|
|
7467
|
+
}
|
|
7468
|
+
async function collectDryRunPublishTasks(ctx) {
|
|
7469
|
+
if (ctx.packages?.length) {
|
|
7470
|
+
const nonCratesTasks = ctx.packages.flatMap(
|
|
7471
|
+
(pkg) => pkg.registries.filter((reg) => reg !== "crates").map((reg) => dryRunRegistryTask(reg))
|
|
7472
|
+
);
|
|
7473
|
+
const cratesPaths = ctx.packages.filter((pkg) => pkg.registries.includes("crates")).map((pkg) => pkg.path);
|
|
7474
|
+
if (cratesPaths.length === 0) {
|
|
7475
|
+
return nonCratesTasks;
|
|
7476
|
+
}
|
|
7477
|
+
const sortedPaths = await sortCratesByDependencyOrder(cratesPaths);
|
|
7478
|
+
const sequentialCratesTask = {
|
|
7479
|
+
title: "Dry-run crates.io publish (sequential)",
|
|
7480
|
+
task: (_ctx, task) => task.newListr(
|
|
7481
|
+
sortedPaths.map((p) => createCratesDryRunPublishTask(p)),
|
|
7482
|
+
{ concurrent: false }
|
|
7483
|
+
)
|
|
7484
|
+
};
|
|
7485
|
+
return [...nonCratesTasks, sequentialCratesTask];
|
|
7486
|
+
}
|
|
7487
|
+
return collectRegistries(ctx).map(dryRunRegistryTask);
|
|
7488
|
+
}
|
|
7309
7489
|
async function run(options) {
|
|
7310
7490
|
const ctx = {
|
|
7311
7491
|
...options,
|
|
7312
7492
|
promptEnabled: !isCI2 && process14.stdin.isTTY
|
|
7313
7493
|
};
|
|
7494
|
+
let cleanupEnv;
|
|
7314
7495
|
try {
|
|
7315
7496
|
if (options.contents) process14.chdir(options.contents);
|
|
7316
|
-
if (
|
|
7497
|
+
if (options.preflight) {
|
|
7498
|
+
await createListr({
|
|
7499
|
+
title: "Collecting registry tokens",
|
|
7500
|
+
task: async (ctx2, task) => {
|
|
7501
|
+
const registries2 = collectRegistries(ctx2);
|
|
7502
|
+
const tokens = await collectTokens(registries2, task);
|
|
7503
|
+
await promptGhSecretsSync(tokens, task);
|
|
7504
|
+
cleanupEnv = injectTokensToEnv(tokens);
|
|
7505
|
+
ctx2.promptEnabled = false;
|
|
7506
|
+
}
|
|
7507
|
+
}).run(ctx);
|
|
7508
|
+
await prerequisitesCheckTask({
|
|
7509
|
+
skip: options.skipPrerequisitesCheck
|
|
7510
|
+
}).run(ctx);
|
|
7511
|
+
await requiredConditionsCheckTask({
|
|
7512
|
+
skip: options.skipConditionsCheck
|
|
7513
|
+
}).run(ctx);
|
|
7514
|
+
}
|
|
7515
|
+
if (!options.publishOnly && !options.preflight) {
|
|
7317
7516
|
await prerequisitesCheckTask({
|
|
7318
7517
|
skip: options.skipPrerequisitesCheck
|
|
7319
7518
|
}).run(ctx);
|
|
@@ -7327,14 +7526,14 @@ async function run(options) {
|
|
|
7327
7526
|
task: async (ctx2, parentTask) => parentTask.newListr(await collectPublishTasks(ctx2), {
|
|
7328
7527
|
concurrent: true
|
|
7329
7528
|
})
|
|
7330
|
-
} : [
|
|
7529
|
+
} : options.preflight ? [
|
|
7331
7530
|
{
|
|
7332
7531
|
skip: options.skipTests,
|
|
7333
7532
|
title: "Running tests",
|
|
7334
7533
|
task: async (ctx2) => {
|
|
7335
7534
|
const packageManager = await getPackageManager();
|
|
7336
7535
|
try {
|
|
7337
|
-
await
|
|
7536
|
+
await exec8(packageManager, ["run", ctx2.testScript], {
|
|
7338
7537
|
throwOnError: true
|
|
7339
7538
|
});
|
|
7340
7539
|
} catch (error) {
|
|
@@ -7351,7 +7550,7 @@ async function run(options) {
|
|
|
7351
7550
|
task: async (ctx2) => {
|
|
7352
7551
|
const packageManager = await getPackageManager();
|
|
7353
7552
|
try {
|
|
7354
|
-
await
|
|
7553
|
+
await exec8(packageManager, ["run", ctx2.buildScript], {
|
|
7355
7554
|
throwOnError: true
|
|
7356
7555
|
});
|
|
7357
7556
|
} catch (error) {
|
|
@@ -7363,8 +7562,45 @@ async function run(options) {
|
|
|
7363
7562
|
}
|
|
7364
7563
|
},
|
|
7365
7564
|
{
|
|
7366
|
-
|
|
7367
|
-
|
|
7565
|
+
title: "Validating publish (dry-run)",
|
|
7566
|
+
task: async (ctx2, parentTask) => parentTask.newListr(await collectDryRunPublishTasks(ctx2), {
|
|
7567
|
+
concurrent: true
|
|
7568
|
+
})
|
|
7569
|
+
}
|
|
7570
|
+
] : [
|
|
7571
|
+
{
|
|
7572
|
+
skip: options.skipTests,
|
|
7573
|
+
title: "Running tests",
|
|
7574
|
+
task: async (ctx2) => {
|
|
7575
|
+
const packageManager = await getPackageManager();
|
|
7576
|
+
try {
|
|
7577
|
+
await exec8(packageManager, ["run", ctx2.testScript], {
|
|
7578
|
+
throwOnError: true
|
|
7579
|
+
});
|
|
7580
|
+
} catch (error) {
|
|
7581
|
+
throw new AbstractError(
|
|
7582
|
+
`Test script '${ctx2.testScript}' failed. Run \`${packageManager} run ${ctx2.testScript}\` locally to see full output.`,
|
|
7583
|
+
{ cause: error }
|
|
7584
|
+
);
|
|
7585
|
+
}
|
|
7586
|
+
}
|
|
7587
|
+
},
|
|
7588
|
+
{
|
|
7589
|
+
skip: options.skipBuild,
|
|
7590
|
+
title: "Building the project",
|
|
7591
|
+
task: async (ctx2) => {
|
|
7592
|
+
const packageManager = await getPackageManager();
|
|
7593
|
+
try {
|
|
7594
|
+
await exec8(packageManager, ["run", ctx2.buildScript], {
|
|
7595
|
+
throwOnError: true
|
|
7596
|
+
});
|
|
7597
|
+
} catch (error) {
|
|
7598
|
+
throw new AbstractError(
|
|
7599
|
+
`Build script '${ctx2.buildScript}' failed. Run \`${packageManager} run ${ctx2.buildScript}\` locally to see full output.`,
|
|
7600
|
+
{ cause: error }
|
|
7601
|
+
);
|
|
7602
|
+
}
|
|
7603
|
+
}
|
|
7368
7604
|
},
|
|
7369
7605
|
{
|
|
7370
7606
|
title: "Bumping version",
|
|
@@ -7480,13 +7716,24 @@ ${repositoryUrl}/compare/${lastRev}...${latestTag}`;
|
|
|
7480
7716
|
parts.push(`${color.bold(name)} on ${color.red("crates.io")}`);
|
|
7481
7717
|
}
|
|
7482
7718
|
}
|
|
7483
|
-
|
|
7484
|
-
|
|
7719
|
+
if (options.preflight) {
|
|
7720
|
+
cleanupEnv?.();
|
|
7721
|
+
console.log(
|
|
7722
|
+
`
|
|
7723
|
+
|
|
7724
|
+
\u2705 Preflight check passed. CI publish should succeed for ${parts.join(", ")}.
|
|
7725
|
+
`
|
|
7726
|
+
);
|
|
7727
|
+
} else {
|
|
7728
|
+
console.log(
|
|
7729
|
+
`
|
|
7485
7730
|
|
|
7486
7731
|
\u{1F680} Successfully published ${parts.join(", ")} ${color.blueBright(`v${ctx.version}`)} \u{1F680}
|
|
7487
7732
|
`
|
|
7488
|
-
|
|
7733
|
+
);
|
|
7734
|
+
}
|
|
7489
7735
|
} catch (e2) {
|
|
7736
|
+
cleanupEnv?.();
|
|
7490
7737
|
consoleError(e2);
|
|
7491
7738
|
await rollback();
|
|
7492
7739
|
process14.exit(1);
|
|
@@ -7535,7 +7782,7 @@ async function pubm(options) {
|
|
|
7535
7782
|
}
|
|
7536
7783
|
|
|
7537
7784
|
// src/tasks/required-missing-information.ts
|
|
7538
|
-
import { ListrEnquirerPromptAdapter as
|
|
7785
|
+
import { ListrEnquirerPromptAdapter as ListrEnquirerPromptAdapter7 } from "@listr2/prompt-adapter-enquirer";
|
|
7539
7786
|
import semver2 from "semver";
|
|
7540
7787
|
var { RELEASE_TYPES, SemVer: SemVer2, prerelease: prerelease2 } = semver2;
|
|
7541
7788
|
var requiredMissingInformationTasks = (options) => createListr({
|
|
@@ -7547,7 +7794,7 @@ var requiredMissingInformationTasks = (options) => createListr({
|
|
|
7547
7794
|
skip: (ctx) => !!ctx.version,
|
|
7548
7795
|
task: async (ctx, task) => {
|
|
7549
7796
|
const currentVersion = await version();
|
|
7550
|
-
let nextVersion = await task.prompt(
|
|
7797
|
+
let nextVersion = await task.prompt(ListrEnquirerPromptAdapter7).run({
|
|
7551
7798
|
type: "select",
|
|
7552
7799
|
message: "Select SemVer increment or specify new version",
|
|
7553
7800
|
choices: RELEASE_TYPES.map((releaseType) => {
|
|
@@ -7562,7 +7809,7 @@ var requiredMissingInformationTasks = (options) => createListr({
|
|
|
7562
7809
|
name: "version"
|
|
7563
7810
|
});
|
|
7564
7811
|
if (nextVersion === "specify") {
|
|
7565
|
-
nextVersion = await task.prompt(
|
|
7812
|
+
nextVersion = await task.prompt(ListrEnquirerPromptAdapter7).run({
|
|
7566
7813
|
type: "input",
|
|
7567
7814
|
message: "Version",
|
|
7568
7815
|
name: "version"
|
|
@@ -7584,7 +7831,7 @@ var requiredMissingInformationTasks = (options) => createListr({
|
|
|
7584
7831
|
)
|
|
7585
7832
|
].filter((tag2) => tag2 !== defaultOptions.tag);
|
|
7586
7833
|
if (distTags.length <= 0) distTags.push("next");
|
|
7587
|
-
let tag = await task.prompt(
|
|
7834
|
+
let tag = await task.prompt(ListrEnquirerPromptAdapter7).run({
|
|
7588
7835
|
type: "select",
|
|
7589
7836
|
message: "Select the tag for this pre-release version in npm",
|
|
7590
7837
|
choices: distTags.map((distTag) => ({
|
|
@@ -7596,7 +7843,7 @@ var requiredMissingInformationTasks = (options) => createListr({
|
|
|
7596
7843
|
name: "tag"
|
|
7597
7844
|
});
|
|
7598
7845
|
if (tag === "specify") {
|
|
7599
|
-
tag = await task.prompt(
|
|
7846
|
+
tag = await task.prompt(ListrEnquirerPromptAdapter7).run({
|
|
7600
7847
|
type: "input",
|
|
7601
7848
|
message: "Tag",
|
|
7602
7849
|
name: "tag"
|
|
@@ -7682,6 +7929,11 @@ var publishOptions = [
|
|
|
7682
7929
|
description: "Run only publish task for latest tag",
|
|
7683
7930
|
options: { type: Boolean }
|
|
7684
7931
|
},
|
|
7932
|
+
{
|
|
7933
|
+
rawName: "--preflight",
|
|
7934
|
+
description: "Simulate CI publish locally (dry-run with token-based auth)",
|
|
7935
|
+
options: { type: Boolean }
|
|
7936
|
+
},
|
|
7685
7937
|
{
|
|
7686
7938
|
rawName: "-t, --tag <name>",
|
|
7687
7939
|
description: "Publish under a specific dist-tag",
|
|
@@ -7712,7 +7964,8 @@ function resolveCliOptions(options) {
|
|
|
7712
7964
|
skipBuild: !options.build,
|
|
7713
7965
|
registries: options.registry?.split(","),
|
|
7714
7966
|
skipPrerequisitesCheck: !options.preCheck,
|
|
7715
|
-
skipConditionsCheck: !options.conditionCheck
|
|
7967
|
+
skipConditionsCheck: !options.conditionCheck,
|
|
7968
|
+
preflight: options.preflight
|
|
7716
7969
|
};
|
|
7717
7970
|
}
|
|
7718
7971
|
var cli = cac("pubm");
|
|
@@ -7724,6 +7977,7 @@ registerSnapshotCommand(cli);
|
|
|
7724
7977
|
registerInitCommand(cli);
|
|
7725
7978
|
registerMigrateCommand(cli);
|
|
7726
7979
|
registerUpdateCommand(cli);
|
|
7980
|
+
registerSecretsCommand(cli);
|
|
7727
7981
|
var defaultCmd = cli.command("[version]", "Publish packages to registries");
|
|
7728
7982
|
for (const option of publishOptions) {
|
|
7729
7983
|
defaultCmd.option(option.rawName, option.description, option.options);
|
|
@@ -7739,7 +7993,9 @@ defaultCmd.action(
|
|
|
7739
7993
|
tag: options.tag
|
|
7740
7994
|
};
|
|
7741
7995
|
try {
|
|
7742
|
-
if (
|
|
7996
|
+
if (options.preflight) {
|
|
7997
|
+
context.version = nextVersion || "0.0.0-preflight";
|
|
7998
|
+
} else if (isCI3) {
|
|
7743
7999
|
if (options.publishOnly) {
|
|
7744
8000
|
const git = new Git();
|
|
7745
8001
|
const latestVersion = (await git.latestTag())?.slice(1);
|