@penvhq/launcher 0.11.0 → 0.13.0
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/bin.cjs +106 -45
- package/dist/bin.cjs.map +1 -1
- package/dist/bin.js +1 -1
- package/dist/{chunk-USYQEKPW.js → chunk-QOQVOYJC.js} +117 -55
- package/dist/chunk-QOQVOYJC.js.map +1 -0
- package/dist/index.cjs +108 -47
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +28 -20
- package/dist/index.d.ts +28 -20
- package/dist/index.js +3 -3
- package/package.json +9 -3
- package/dist/chunk-USYQEKPW.js.map +0 -1
package/dist/index.cjs
CHANGED
|
@@ -24,10 +24,10 @@ __export(src_exports, {
|
|
|
24
24
|
AddLocalFlagError: () => AddLocalFlagError,
|
|
25
25
|
AddLocalInCiError: () => AddLocalInCiError,
|
|
26
26
|
AddNoDownloadError: () => AddNoDownloadError,
|
|
27
|
-
AddNotInteractiveError: () => AddNotInteractiveError,
|
|
28
27
|
AddPackageNameError: () => AddPackageNameError,
|
|
29
28
|
AddRegistryError: () => AddRegistryError,
|
|
30
29
|
AddSubjectError: () => AddSubjectError,
|
|
30
|
+
AddTrustUnattendedError: () => AddTrustUnattendedError,
|
|
31
31
|
ArchiveError: () => ArchiveError,
|
|
32
32
|
BUNDLED_ENGINE_PIN: () => BUNDLED_ENGINE_PIN,
|
|
33
33
|
DEFAULT_REGISTRY: () => DEFAULT_REGISTRY,
|
|
@@ -384,7 +384,7 @@ var AddFlagError = class extends import_core.PenvError {
|
|
|
384
384
|
super(
|
|
385
385
|
"PENV_ADD_FLAG",
|
|
386
386
|
`\`penv add\` does not understand \`${flag}\``,
|
|
387
|
-
`Run \`penv add <package>\` with \`${TRUST_YOUNG_FLAG}\`, \`--registry <url>\`, or \`${
|
|
387
|
+
`Run \`penv add <package>\` with \`${TRUST_YOUNG_FLAG}\`, \`--registry <url>\`, \`${LOCAL_FLAG}\`, or \`${YES_FLAG}\` \u2014 those are the four it takes.`
|
|
388
388
|
);
|
|
389
389
|
}
|
|
390
390
|
};
|
|
@@ -530,13 +530,13 @@ var AddNoDownloadError = class extends import_core.PenvError {
|
|
|
530
530
|
);
|
|
531
531
|
}
|
|
532
532
|
};
|
|
533
|
-
var
|
|
534
|
-
name = "
|
|
535
|
-
constructor(name) {
|
|
533
|
+
var AddTrustUnattendedError = class extends import_core.PenvError {
|
|
534
|
+
name = "AddTrustUnattendedError";
|
|
535
|
+
constructor(name, ceremony) {
|
|
536
536
|
super(
|
|
537
|
-
"
|
|
538
|
-
`Adding ${name}
|
|
539
|
-
`Run \`${addCommand(name)}\` from a terminal
|
|
537
|
+
"PENV_ADD_TRUST_UNATTENDED",
|
|
538
|
+
`Adding ${name} records ${ceremony}, and this run has nobody to write it`,
|
|
539
|
+
`Run \`${addCommand(name)}\` from a terminal, without \`${YES_FLAG}\` \u2014 the trust block is a line only a person can write. In CI, run \`${INSTALL_COMMAND}\`: it installs the versions the committed manifest already pins.`
|
|
540
540
|
);
|
|
541
541
|
}
|
|
542
542
|
};
|
|
@@ -662,11 +662,11 @@ var UpgradeDeclinedError = class extends import_core.PenvError {
|
|
|
662
662
|
};
|
|
663
663
|
var UpgradeInstallFailedError = class extends import_core.PenvError {
|
|
664
664
|
name = "UpgradeInstallFailedError";
|
|
665
|
-
constructor(
|
|
665
|
+
constructor(manager, version) {
|
|
666
666
|
super(
|
|
667
667
|
"PENV_UPGRADE_INSTALL_FAILED",
|
|
668
|
-
`${
|
|
669
|
-
`
|
|
668
|
+
`${manager} did not finish moving this project to ${import_core.ENGINE_PACKAGE} ${version}, so ${import_core.MANIFEST_PATH} still pins the engine it pinned before`,
|
|
669
|
+
`Read what ${manager} printed above \u2014 it names what it refused. Fix that and run \`${UPGRADE_COMMAND} ${version}\` again; the pin and the dependency move together or not at all.`
|
|
670
670
|
);
|
|
671
671
|
}
|
|
672
672
|
};
|
|
@@ -1083,12 +1083,17 @@ function parseRequest(argv) {
|
|
|
1083
1083
|
let registry;
|
|
1084
1084
|
let trustYoung = false;
|
|
1085
1085
|
let local = false;
|
|
1086
|
+
let yes = false;
|
|
1086
1087
|
for (let index = 0; index < argv.length; index += 1) {
|
|
1087
1088
|
const token = argv[index] ?? "";
|
|
1088
1089
|
if (token === LOCAL_FLAG) {
|
|
1089
1090
|
local = true;
|
|
1090
1091
|
continue;
|
|
1091
1092
|
}
|
|
1093
|
+
if (token === YES_FLAG) {
|
|
1094
|
+
yes = true;
|
|
1095
|
+
continue;
|
|
1096
|
+
}
|
|
1092
1097
|
if (token === TRUST_YOUNG_FLAG) {
|
|
1093
1098
|
trustYoung = true;
|
|
1094
1099
|
continue;
|
|
@@ -1128,7 +1133,10 @@ function parseRequest(argv) {
|
|
|
1128
1133
|
throw new AddLocalFlagError(`\`${TRUST_YOUNG_FLAG}\``);
|
|
1129
1134
|
}
|
|
1130
1135
|
}
|
|
1131
|
-
return { name, version, registry, trustYoung, local };
|
|
1136
|
+
return { name, version, registry, trustYoung, local, yes };
|
|
1137
|
+
}
|
|
1138
|
+
function ceremonyFor(tier) {
|
|
1139
|
+
return tier === "official" ? void 0 : "who publishes it and why you trust it";
|
|
1132
1140
|
}
|
|
1133
1141
|
function tierOf(request) {
|
|
1134
1142
|
if (request.name.startsWith(import_core5.OFFICIAL_SCOPE)) {
|
|
@@ -1207,46 +1215,84 @@ function recordExtension(manifestFile, name, entry) {
|
|
|
1207
1215
|
};
|
|
1208
1216
|
return (0, import_core5.serializeManifest)(next);
|
|
1209
1217
|
}
|
|
1210
|
-
|
|
1218
|
+
var NONE = /* @__PURE__ */ new Set(["", "none", "no", "n"]);
|
|
1219
|
+
var ALL = /* @__PURE__ */ new Set(["all", "a", "yes", "y"]);
|
|
1220
|
+
function chooseEnvironments(answer, offered) {
|
|
1221
|
+
const normalized = answer.trim().toLowerCase();
|
|
1222
|
+
if (NONE.has(normalized)) {
|
|
1223
|
+
return { chosen: [], unknown: [] };
|
|
1224
|
+
}
|
|
1225
|
+
if (ALL.has(normalized)) {
|
|
1226
|
+
return { chosen: offered, unknown: [] };
|
|
1227
|
+
}
|
|
1228
|
+
const chosen = [];
|
|
1229
|
+
const unknown = [];
|
|
1230
|
+
for (const token of normalized.split(/[\s,]+/).filter((part) => part !== "")) {
|
|
1231
|
+
const match = offered.find((environment) => environment.toLowerCase() === token);
|
|
1232
|
+
if (match === void 0) {
|
|
1233
|
+
unknown.push(token);
|
|
1234
|
+
} else {
|
|
1235
|
+
chosen.push(match);
|
|
1236
|
+
}
|
|
1237
|
+
}
|
|
1238
|
+
return { chosen, unknown };
|
|
1239
|
+
}
|
|
1240
|
+
function quoted(environments) {
|
|
1241
|
+
return environments.map((environment) => `\`${environment}\``).join(", ");
|
|
1242
|
+
}
|
|
1243
|
+
function configAdvice(name, pointing, unpointed) {
|
|
1244
|
+
const add2 = `Add \`type: ${JSON.stringify(name)}\``;
|
|
1245
|
+
if (pointing.length === 0) {
|
|
1246
|
+
return `${add2} to an environment in penv.config.ts.`;
|
|
1247
|
+
}
|
|
1248
|
+
return `${quoted(pointing)} already ${pointing.length === 1 ? "points" : "point"} at ${name}. ${add2} to ${quoted(unpointed)} in penv.config.ts if ${unpointed.length === 1 ? "it" : "they"} should too.`;
|
|
1249
|
+
}
|
|
1250
|
+
async function offerConfigEdit(options, name, ask) {
|
|
1211
1251
|
const { io, root } = options;
|
|
1212
1252
|
const configFile = (0, import_core5.findConfigFile)(root);
|
|
1213
|
-
const
|
|
1253
|
+
const blind = `Add \`type: ${JSON.stringify(name)}\` to an environment in penv.config.ts.`;
|
|
1214
1254
|
if (configFile === void 0) {
|
|
1215
|
-
io.out(
|
|
1255
|
+
io.out(blind);
|
|
1216
1256
|
return;
|
|
1217
1257
|
}
|
|
1218
1258
|
const shown = (0, import_node_path4.relative)(root, configFile).split(import_node_path4.sep).join("/");
|
|
1219
1259
|
let current = (0, import_node_fs4.readFileSync)(configFile, "utf8");
|
|
1220
1260
|
const entries = readProviderEntries(current);
|
|
1221
1261
|
if (entries === void 0 || entries.length === 0) {
|
|
1222
|
-
io.out(
|
|
1262
|
+
io.out(blind);
|
|
1223
1263
|
return;
|
|
1224
1264
|
}
|
|
1225
|
-
|
|
1265
|
+
const pointing = entries.filter((entry) => entry.type === name).map((entry) => entry.environment);
|
|
1266
|
+
const offered = entries.filter((entry) => entry.type !== name).map((entry) => entry.environment);
|
|
1267
|
+
if (offered.length === 0) {
|
|
1226
1268
|
return;
|
|
1227
1269
|
}
|
|
1228
|
-
|
|
1229
|
-
|
|
1270
|
+
const advice = configAdvice(name, pointing, offered);
|
|
1271
|
+
if (!ask) {
|
|
1272
|
+
io.out(advice);
|
|
1230
1273
|
return;
|
|
1231
1274
|
}
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1275
|
+
const { chosen, unknown } = chooseEnvironments(
|
|
1276
|
+
await io.ask(`Point which of ${offered.join(", ")} at ${name} in ${shown}? all / none / names`),
|
|
1277
|
+
offered
|
|
1278
|
+
);
|
|
1279
|
+
if (unknown.length > 0) {
|
|
1280
|
+
io.out(`${shown} declares no ${unknown.join(", ")}, so nothing was repointed.`);
|
|
1281
|
+
io.out(advice);
|
|
1282
|
+
return;
|
|
1283
|
+
}
|
|
1284
|
+
for (const environment of chosen) {
|
|
1285
|
+
const next = setProviderType(current, environment, name);
|
|
1240
1286
|
if (next === void 0) {
|
|
1241
|
-
io.out(`Add \`type: ${JSON.stringify(name)}\` to \`${
|
|
1287
|
+
io.out(`Add \`type: ${JSON.stringify(name)}\` to \`${environment}\` in ${shown}.`);
|
|
1242
1288
|
continue;
|
|
1243
1289
|
}
|
|
1244
1290
|
current = next;
|
|
1245
1291
|
(0, import_node_fs4.writeFileSync)(configFile, current);
|
|
1246
|
-
io.out(`\u2713 ${shown} points \`${
|
|
1292
|
+
io.out(`\u2713 ${shown} points \`${environment}\` at ${name}`);
|
|
1247
1293
|
}
|
|
1248
1294
|
}
|
|
1249
|
-
async function offerOnboarding(io, name, onboard) {
|
|
1295
|
+
async function offerOnboarding(io, name, onboard, ask) {
|
|
1250
1296
|
if (onboard === void 0) {
|
|
1251
1297
|
return void 0;
|
|
1252
1298
|
}
|
|
@@ -1255,7 +1301,7 @@ async function offerOnboarding(io, name, onboard) {
|
|
|
1255
1301
|
return void 0;
|
|
1256
1302
|
}
|
|
1257
1303
|
const command = `penv ${args.join(" ")}`;
|
|
1258
|
-
if (
|
|
1304
|
+
if (ask && await io.confirm(`Run \`${command}\` now?`)) {
|
|
1259
1305
|
return args;
|
|
1260
1306
|
}
|
|
1261
1307
|
io.out(`Run \`${command}\` to finish setting ${name} up.`);
|
|
@@ -1336,8 +1382,9 @@ async function addLocal(options, request) {
|
|
|
1336
1382
|
io.out(`\u2713 ${request.name} resolves from this project and imports \u2014 nothing is pinned`);
|
|
1337
1383
|
io.out(`\u2713 ${import_core5.LOCAL_EXTENSIONS_PATH} records it`);
|
|
1338
1384
|
io.out(`\u2713 ${declaration} declares its config type`);
|
|
1339
|
-
|
|
1340
|
-
|
|
1385
|
+
const ask = io.interactive && !request.yes;
|
|
1386
|
+
await offerConfigEdit(options, request.name, ask);
|
|
1387
|
+
return { onboard: await offerOnboarding(io, request.name, installed.onboard, ask) };
|
|
1341
1388
|
}
|
|
1342
1389
|
async function add(options) {
|
|
1343
1390
|
const { io, fetcher, home, root, manifestFile } = options;
|
|
@@ -1347,11 +1394,13 @@ async function add(options) {
|
|
|
1347
1394
|
}
|
|
1348
1395
|
const tier = tierOf(request);
|
|
1349
1396
|
const now = (options.now ?? (() => /* @__PURE__ */ new Date()))();
|
|
1397
|
+
const ask = io.interactive && !request.yes;
|
|
1350
1398
|
if (options.noDownload === true) {
|
|
1351
1399
|
throw new AddNoDownloadError(request.name);
|
|
1352
1400
|
}
|
|
1353
|
-
|
|
1354
|
-
|
|
1401
|
+
const ceremony = ceremonyFor(tier);
|
|
1402
|
+
if (ceremony !== void 0 && (options.ci === true || !ask)) {
|
|
1403
|
+
throw new AddTrustUnattendedError(request.name, ceremony);
|
|
1355
1404
|
}
|
|
1356
1405
|
const release = await fetchRelease({
|
|
1357
1406
|
name: request.name,
|
|
@@ -1393,8 +1442,8 @@ async function add(options) {
|
|
|
1393
1442
|
io.out(`\u2713 ${release.name} ${release.version} installed \u2014 ${provenance}`);
|
|
1394
1443
|
io.out(`\u2713 ${import_core5.MANIFEST_PATH} pins it`);
|
|
1395
1444
|
io.out(`\u2713 ${declaration} declares its config type`);
|
|
1396
|
-
await offerConfigEdit(options, release.name);
|
|
1397
|
-
return { onboard: await offerOnboarding(io, release.name, installed.onboard) };
|
|
1445
|
+
await offerConfigEdit(options, release.name, ask);
|
|
1446
|
+
return { onboard: await offerOnboarding(io, release.name, installed.onboard, ask) };
|
|
1398
1447
|
}
|
|
1399
1448
|
|
|
1400
1449
|
// src/delegate.ts
|
|
@@ -1541,10 +1590,15 @@ function printAddHelp(io) {
|
|
|
1541
1590
|
io.out(
|
|
1542
1591
|
` ${TRUST_YOUNG_FLAG} Add a release published less than ${MIN_PACKAGE_AGE_DAYS} days ago`
|
|
1543
1592
|
);
|
|
1593
|
+
io.out(` ${YES_FLAG} Ask nothing \u2014 the config and onboarding offers print instead`);
|
|
1544
1594
|
io.out("");
|
|
1545
1595
|
io.out(`Pins the release in ${import_core7.MANIFEST_PATH} and writes its type declaration to`);
|
|
1546
1596
|
io.out(`${import_core7.EXTENSIONS_PATH}/. Both are committed, so \`${INSTALL_COMMAND}\` gives every machine`);
|
|
1547
1597
|
io.out(`the bytes you reviewed. \`${LOCAL_FLAG}\` pins nothing and touches no manifest.`);
|
|
1598
|
+
io.out("");
|
|
1599
|
+
io.out(`An \`${import_core7.OFFICIAL_SCOPE}*\` package asks nothing, so it adds unattended. Anything else`);
|
|
1600
|
+
io.out("records who publishes it and why you trust it, which needs a person at a terminal \u2014");
|
|
1601
|
+
io.out(`\`${YES_FLAG}\` cannot write that line for you.`);
|
|
1548
1602
|
}
|
|
1549
1603
|
function printUpgradeHelp(io) {
|
|
1550
1604
|
io.out("penv upgrade [version]");
|
|
@@ -1564,8 +1618,8 @@ var DEV_PIN_INTEGRITY = "sha512-development-build-not-a-published-release";
|
|
|
1564
1618
|
var DEV_PIN_VERSION = "0.0.0-dev";
|
|
1565
1619
|
var BUNDLED_ENGINE_PIN = {
|
|
1566
1620
|
package: import_core8.ENGINE_PACKAGE,
|
|
1567
|
-
version: "0.
|
|
1568
|
-
integrity: "sha512-
|
|
1621
|
+
version: "0.13.0",
|
|
1622
|
+
integrity: "sha512-gZ2AlzxmQ4c83OvWSRrBdVMAQdwcGqAoENSv4ZNyZuer0fpIEqiT/xUl2b1+t5JSW8EZto5JpilmBSfiNoWFWA=="
|
|
1569
1623
|
};
|
|
1570
1624
|
function assertReleasePin(pin) {
|
|
1571
1625
|
if (pin.integrity === DEV_PIN_INTEGRITY || pin.version === DEV_PIN_VERSION) {
|
|
@@ -1693,9 +1747,14 @@ async function upgrade(options) {
|
|
|
1693
1747
|
try {
|
|
1694
1748
|
await (options.install ?? import_install2.installWithPackageManager)(plan);
|
|
1695
1749
|
} catch {
|
|
1696
|
-
throw new UpgradeInstallFailedError(plan.
|
|
1750
|
+
throw new UpgradeInstallFailedError(plan.manager, release.version);
|
|
1751
|
+
}
|
|
1752
|
+
const moved = plan.steps.filter(
|
|
1753
|
+
(entry) => !entry.satisfied && entry.packages.some((one) => one.name === import_install2.RUNTIME_PACKAGE)
|
|
1754
|
+
);
|
|
1755
|
+
for (const step of moved) {
|
|
1756
|
+
io.out(`\u2713 ${step.manifest} depends on ${import_install2.RUNTIME_PACKAGE} ${release.version}`);
|
|
1697
1757
|
}
|
|
1698
|
-
io.out(`\u2713 package.json depends on ${import_install2.RUNTIME_PACKAGE} ${release.version}`);
|
|
1699
1758
|
}
|
|
1700
1759
|
(0, import_node_fs7.writeFileSync)(manifestFile, manifestText);
|
|
1701
1760
|
io.out(`\u2713 ${import_core10.MANIFEST_PATH} pins ${import_core10.ENGINE_PACKAGE} ${release.version}`);
|
|
@@ -1924,12 +1983,14 @@ async function install(options, pins, home, broken) {
|
|
|
1924
1983
|
if (state === "corrupt") {
|
|
1925
1984
|
throw new PackageCorruptError(pin.name, pin.version, dir);
|
|
1926
1985
|
}
|
|
1927
|
-
if (state === "
|
|
1928
|
-
|
|
1929
|
-
|
|
1986
|
+
if (state === "absent") {
|
|
1987
|
+
await installPin({ home, kind, pin, fetcher: options.fetcher });
|
|
1988
|
+
}
|
|
1989
|
+
if (kind === "extensions") {
|
|
1990
|
+
await assertLoadable(pin.name, (0, import_core11.packageEntry)(dir), false);
|
|
1930
1991
|
}
|
|
1931
|
-
|
|
1932
|
-
options.io.out(`\u2713 ${pin.name} ${pin.version}
|
|
1992
|
+
const verb = state === "absent" ? "installed" : "already installed";
|
|
1993
|
+
options.io.out(`\u2713 ${pin.name} ${pin.version} ${verb}`);
|
|
1933
1994
|
}
|
|
1934
1995
|
if (broken.length > 0) {
|
|
1935
1996
|
report(new ManifestEntriesUnreadableError(broken), options.io);
|
|
@@ -1978,10 +2039,10 @@ async function delegate(options, engine, forwarded, home, cwd) {
|
|
|
1978
2039
|
AddLocalFlagError,
|
|
1979
2040
|
AddLocalInCiError,
|
|
1980
2041
|
AddNoDownloadError,
|
|
1981
|
-
AddNotInteractiveError,
|
|
1982
2042
|
AddPackageNameError,
|
|
1983
2043
|
AddRegistryError,
|
|
1984
2044
|
AddSubjectError,
|
|
2045
|
+
AddTrustUnattendedError,
|
|
1985
2046
|
ArchiveError,
|
|
1986
2047
|
BUNDLED_ENGINE_PIN,
|
|
1987
2048
|
DEFAULT_REGISTRY,
|