@penvhq/launcher 0.11.0 → 0.12.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 +87 -41
- package/dist/bin.cjs.map +1 -1
- package/dist/bin.js +1 -1
- package/dist/{chunk-USYQEKPW.js → chunk-A5LJQPYS.js} +98 -51
- package/dist/chunk-A5LJQPYS.js.map +1 -0
- package/dist/index.cjs +89 -43
- 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/bin.js
CHANGED
|
@@ -277,7 +277,7 @@ var AddFlagError = class extends PenvError {
|
|
|
277
277
|
super(
|
|
278
278
|
"PENV_ADD_FLAG",
|
|
279
279
|
`\`penv add\` does not understand \`${flag}\``,
|
|
280
|
-
`Run \`penv add <package>\` with \`${TRUST_YOUNG_FLAG}\`, \`--registry <url>\`, or \`${
|
|
280
|
+
`Run \`penv add <package>\` with \`${TRUST_YOUNG_FLAG}\`, \`--registry <url>\`, \`${LOCAL_FLAG}\`, or \`${YES_FLAG}\` \u2014 those are the four it takes.`
|
|
281
281
|
);
|
|
282
282
|
}
|
|
283
283
|
};
|
|
@@ -423,13 +423,13 @@ var AddNoDownloadError = class extends PenvError {
|
|
|
423
423
|
);
|
|
424
424
|
}
|
|
425
425
|
};
|
|
426
|
-
var
|
|
427
|
-
name = "
|
|
428
|
-
constructor(name) {
|
|
426
|
+
var AddTrustUnattendedError = class extends PenvError {
|
|
427
|
+
name = "AddTrustUnattendedError";
|
|
428
|
+
constructor(name, ceremony) {
|
|
429
429
|
super(
|
|
430
|
-
"
|
|
431
|
-
`Adding ${name}
|
|
432
|
-
`Run \`${addCommand(name)}\` from a terminal
|
|
430
|
+
"PENV_ADD_TRUST_UNATTENDED",
|
|
431
|
+
`Adding ${name} records ${ceremony}, and this run has nobody to write it`,
|
|
432
|
+
`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.`
|
|
433
433
|
);
|
|
434
434
|
}
|
|
435
435
|
};
|
|
@@ -555,11 +555,11 @@ var UpgradeDeclinedError = class extends PenvError {
|
|
|
555
555
|
};
|
|
556
556
|
var UpgradeInstallFailedError = class extends PenvError {
|
|
557
557
|
name = "UpgradeInstallFailedError";
|
|
558
|
-
constructor(
|
|
558
|
+
constructor(manager, version) {
|
|
559
559
|
super(
|
|
560
560
|
"PENV_UPGRADE_INSTALL_FAILED",
|
|
561
|
-
`${
|
|
562
|
-
`
|
|
561
|
+
`${manager} did not finish moving this project to ${ENGINE_PACKAGE} ${version}, so ${MANIFEST_PATH} still pins the engine it pinned before`,
|
|
562
|
+
`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.`
|
|
563
563
|
);
|
|
564
564
|
}
|
|
565
565
|
};
|
|
@@ -1003,12 +1003,17 @@ function parseRequest(argv) {
|
|
|
1003
1003
|
let registry;
|
|
1004
1004
|
let trustYoung = false;
|
|
1005
1005
|
let local = false;
|
|
1006
|
+
let yes = false;
|
|
1006
1007
|
for (let index = 0; index < argv.length; index += 1) {
|
|
1007
1008
|
const token = argv[index] ?? "";
|
|
1008
1009
|
if (token === LOCAL_FLAG) {
|
|
1009
1010
|
local = true;
|
|
1010
1011
|
continue;
|
|
1011
1012
|
}
|
|
1013
|
+
if (token === YES_FLAG) {
|
|
1014
|
+
yes = true;
|
|
1015
|
+
continue;
|
|
1016
|
+
}
|
|
1012
1017
|
if (token === TRUST_YOUNG_FLAG) {
|
|
1013
1018
|
trustYoung = true;
|
|
1014
1019
|
continue;
|
|
@@ -1048,7 +1053,10 @@ function parseRequest(argv) {
|
|
|
1048
1053
|
throw new AddLocalFlagError(`\`${TRUST_YOUNG_FLAG}\``);
|
|
1049
1054
|
}
|
|
1050
1055
|
}
|
|
1051
|
-
return { name, version, registry, trustYoung, local };
|
|
1056
|
+
return { name, version, registry, trustYoung, local, yes };
|
|
1057
|
+
}
|
|
1058
|
+
function ceremonyFor(tier) {
|
|
1059
|
+
return tier === "official" ? void 0 : "who publishes it and why you trust it";
|
|
1052
1060
|
}
|
|
1053
1061
|
function tierOf(request) {
|
|
1054
1062
|
if (request.name.startsWith(OFFICIAL_SCOPE2)) {
|
|
@@ -1127,7 +1135,29 @@ function recordExtension(manifestFile, name, entry) {
|
|
|
1127
1135
|
};
|
|
1128
1136
|
return serializeManifest(next);
|
|
1129
1137
|
}
|
|
1130
|
-
|
|
1138
|
+
var NONE = /* @__PURE__ */ new Set(["", "none", "no", "n"]);
|
|
1139
|
+
var ALL = /* @__PURE__ */ new Set(["all", "a", "yes", "y"]);
|
|
1140
|
+
function chooseEnvironments(answer, offered) {
|
|
1141
|
+
const normalized = answer.trim().toLowerCase();
|
|
1142
|
+
if (NONE.has(normalized)) {
|
|
1143
|
+
return { chosen: [], unknown: [] };
|
|
1144
|
+
}
|
|
1145
|
+
if (ALL.has(normalized)) {
|
|
1146
|
+
return { chosen: offered, unknown: [] };
|
|
1147
|
+
}
|
|
1148
|
+
const chosen = [];
|
|
1149
|
+
const unknown = [];
|
|
1150
|
+
for (const token of normalized.split(/[\s,]+/).filter((part) => part !== "")) {
|
|
1151
|
+
const match = offered.find((environment) => environment.toLowerCase() === token);
|
|
1152
|
+
if (match === void 0) {
|
|
1153
|
+
unknown.push(token);
|
|
1154
|
+
} else {
|
|
1155
|
+
chosen.push(match);
|
|
1156
|
+
}
|
|
1157
|
+
}
|
|
1158
|
+
return { chosen, unknown };
|
|
1159
|
+
}
|
|
1160
|
+
async function offerConfigEdit(options, name, ask) {
|
|
1131
1161
|
const { io, root } = options;
|
|
1132
1162
|
const configFile = findConfigFile(root);
|
|
1133
1163
|
const line = `Add \`type: ${JSON.stringify(name)}\` to an environment in penv.config.ts.`;
|
|
@@ -1142,31 +1172,35 @@ async function offerConfigEdit(options, name) {
|
|
|
1142
1172
|
io.out(line);
|
|
1143
1173
|
return;
|
|
1144
1174
|
}
|
|
1145
|
-
|
|
1175
|
+
const offered = entries.filter((entry) => entry.type !== name).map((entry) => entry.environment);
|
|
1176
|
+
if (offered.length === 0) {
|
|
1146
1177
|
return;
|
|
1147
1178
|
}
|
|
1148
|
-
if (!
|
|
1179
|
+
if (!ask) {
|
|
1149
1180
|
io.out(line);
|
|
1150
1181
|
return;
|
|
1151
1182
|
}
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1183
|
+
const { chosen, unknown } = chooseEnvironments(
|
|
1184
|
+
await io.ask(`Point which of ${offered.join(", ")} at ${name} in ${shown}? all / none / names`),
|
|
1185
|
+
offered
|
|
1186
|
+
);
|
|
1187
|
+
if (unknown.length > 0) {
|
|
1188
|
+
io.out(`${shown} declares no ${unknown.join(", ")}, so nothing was repointed.`);
|
|
1189
|
+
io.out(line);
|
|
1190
|
+
return;
|
|
1191
|
+
}
|
|
1192
|
+
for (const environment of chosen) {
|
|
1193
|
+
const next = setProviderType(current, environment, name);
|
|
1160
1194
|
if (next === void 0) {
|
|
1161
|
-
io.out(`Add \`type: ${JSON.stringify(name)}\` to \`${
|
|
1195
|
+
io.out(`Add \`type: ${JSON.stringify(name)}\` to \`${environment}\` in ${shown}.`);
|
|
1162
1196
|
continue;
|
|
1163
1197
|
}
|
|
1164
1198
|
current = next;
|
|
1165
1199
|
writeFileSync3(configFile, current);
|
|
1166
|
-
io.out(`\u2713 ${shown} points \`${
|
|
1200
|
+
io.out(`\u2713 ${shown} points \`${environment}\` at ${name}`);
|
|
1167
1201
|
}
|
|
1168
1202
|
}
|
|
1169
|
-
async function offerOnboarding(io, name, onboard) {
|
|
1203
|
+
async function offerOnboarding(io, name, onboard, ask) {
|
|
1170
1204
|
if (onboard === void 0) {
|
|
1171
1205
|
return void 0;
|
|
1172
1206
|
}
|
|
@@ -1175,7 +1209,7 @@ async function offerOnboarding(io, name, onboard) {
|
|
|
1175
1209
|
return void 0;
|
|
1176
1210
|
}
|
|
1177
1211
|
const command = `penv ${args.join(" ")}`;
|
|
1178
|
-
if (
|
|
1212
|
+
if (ask && await io.confirm(`Run \`${command}\` now?`)) {
|
|
1179
1213
|
return args;
|
|
1180
1214
|
}
|
|
1181
1215
|
io.out(`Run \`${command}\` to finish setting ${name} up.`);
|
|
@@ -1256,8 +1290,9 @@ async function addLocal(options, request) {
|
|
|
1256
1290
|
io.out(`\u2713 ${request.name} resolves from this project and imports \u2014 nothing is pinned`);
|
|
1257
1291
|
io.out(`\u2713 ${LOCAL_EXTENSIONS_PATH2} records it`);
|
|
1258
1292
|
io.out(`\u2713 ${declaration} declares its config type`);
|
|
1259
|
-
|
|
1260
|
-
|
|
1293
|
+
const ask = io.interactive && !request.yes;
|
|
1294
|
+
await offerConfigEdit(options, request.name, ask);
|
|
1295
|
+
return { onboard: await offerOnboarding(io, request.name, installed.onboard, ask) };
|
|
1261
1296
|
}
|
|
1262
1297
|
async function add(options) {
|
|
1263
1298
|
const { io, fetcher, home, root, manifestFile } = options;
|
|
@@ -1267,11 +1302,13 @@ async function add(options) {
|
|
|
1267
1302
|
}
|
|
1268
1303
|
const tier = tierOf(request);
|
|
1269
1304
|
const now = (options.now ?? (() => /* @__PURE__ */ new Date()))();
|
|
1305
|
+
const ask = io.interactive && !request.yes;
|
|
1270
1306
|
if (options.noDownload === true) {
|
|
1271
1307
|
throw new AddNoDownloadError(request.name);
|
|
1272
1308
|
}
|
|
1273
|
-
|
|
1274
|
-
|
|
1309
|
+
const ceremony = ceremonyFor(tier);
|
|
1310
|
+
if (ceremony !== void 0 && (options.ci === true || !ask)) {
|
|
1311
|
+
throw new AddTrustUnattendedError(request.name, ceremony);
|
|
1275
1312
|
}
|
|
1276
1313
|
const release = await fetchRelease({
|
|
1277
1314
|
name: request.name,
|
|
@@ -1313,8 +1350,8 @@ async function add(options) {
|
|
|
1313
1350
|
io.out(`\u2713 ${release.name} ${release.version} installed \u2014 ${provenance}`);
|
|
1314
1351
|
io.out(`\u2713 ${MANIFEST_PATH2} pins it`);
|
|
1315
1352
|
io.out(`\u2713 ${declaration} declares its config type`);
|
|
1316
|
-
await offerConfigEdit(options, release.name);
|
|
1317
|
-
return { onboard: await offerOnboarding(io, release.name, installed.onboard) };
|
|
1353
|
+
await offerConfigEdit(options, release.name, ask);
|
|
1354
|
+
return { onboard: await offerOnboarding(io, release.name, installed.onboard, ask) };
|
|
1318
1355
|
}
|
|
1319
1356
|
|
|
1320
1357
|
// src/delegate.ts
|
|
@@ -1363,12 +1400,12 @@ function nodeSpawner() {
|
|
|
1363
1400
|
// src/engine.ts
|
|
1364
1401
|
import { existsSync as existsSync2, readFileSync as readFileSync5 } from "fs";
|
|
1365
1402
|
import { createRequire as createRequire2 } from "module";
|
|
1366
|
-
import { dirname as dirname4, join as
|
|
1403
|
+
import { dirname as dirname4, join as join4, resolve as resolve3, sep as sep3 } from "path";
|
|
1367
1404
|
import { ENGINE_PACKAGE as ENGINE_PACKAGE2, PenvError as PenvError2 } from "@penvhq/core";
|
|
1368
1405
|
var ENGINE_BIN = "penv-engine";
|
|
1369
1406
|
function readPackageManifest(dir) {
|
|
1370
1407
|
try {
|
|
1371
|
-
return JSON.parse(readFileSync5(
|
|
1408
|
+
return JSON.parse(readFileSync5(join4(dir, "package.json"), "utf8"));
|
|
1372
1409
|
} catch {
|
|
1373
1410
|
return void 0;
|
|
1374
1411
|
}
|
|
@@ -1433,8 +1470,8 @@ var DEV_PIN_INTEGRITY = "sha512-development-build-not-a-published-release";
|
|
|
1433
1470
|
var DEV_PIN_VERSION = "0.0.0-dev";
|
|
1434
1471
|
var BUNDLED_ENGINE_PIN = {
|
|
1435
1472
|
package: ENGINE_PACKAGE3,
|
|
1436
|
-
version: "0.
|
|
1437
|
-
integrity: "sha512-
|
|
1473
|
+
version: "0.12.0",
|
|
1474
|
+
integrity: "sha512-9HUylEIbFq0BGTOW54Vxhkzv8AvuB7H3bImTFP5J+dfglkR7udP2KUsr8b0I2mf45YMTQO5xsYpI5+nhLERGtA=="
|
|
1438
1475
|
};
|
|
1439
1476
|
function assertReleasePin(pin) {
|
|
1440
1477
|
if (pin.integrity === DEV_PIN_INTEGRITY || pin.version === DEV_PIN_VERSION) {
|
|
@@ -1451,7 +1488,7 @@ function releaseEnginePin(pin, ranVersion) {
|
|
|
1451
1488
|
|
|
1452
1489
|
// src/project.ts
|
|
1453
1490
|
import { existsSync as existsSync3 } from "fs";
|
|
1454
|
-
import { dirname as dirname5, join as
|
|
1491
|
+
import { dirname as dirname5, join as join5, resolve as resolve4 } from "path";
|
|
1455
1492
|
import { MANIFEST_PATH as MANIFEST_PATH3, stateDir } from "@penvhq/core";
|
|
1456
1493
|
var MANIFEST_SEGMENTS = MANIFEST_PATH3.split("/");
|
|
1457
1494
|
function findUp(cwd, matches) {
|
|
@@ -1468,8 +1505,8 @@ function findUp(cwd, matches) {
|
|
|
1468
1505
|
}
|
|
1469
1506
|
}
|
|
1470
1507
|
function findProject(cwd) {
|
|
1471
|
-
const root = findUp(cwd, (dir) => existsSync3(
|
|
1472
|
-
return root === void 0 ? void 0 : { root, manifestFile:
|
|
1508
|
+
const root = findUp(cwd, (dir) => existsSync3(join5(dir, ...MANIFEST_SEGMENTS)));
|
|
1509
|
+
return root === void 0 ? void 0 : { root, manifestFile: join5(root, ...MANIFEST_SEGMENTS) };
|
|
1473
1510
|
}
|
|
1474
1511
|
function findAdoptedRoot(cwd) {
|
|
1475
1512
|
return findUp(cwd, (dir) => existsSync3(stateDir(dir)));
|
|
@@ -1567,9 +1604,11 @@ async function upgrade(options) {
|
|
|
1567
1604
|
try {
|
|
1568
1605
|
await (options.install ?? installWithPackageManager)(plan);
|
|
1569
1606
|
} catch {
|
|
1570
|
-
throw new UpgradeInstallFailedError(plan.
|
|
1607
|
+
throw new UpgradeInstallFailedError(plan.manager, release.version);
|
|
1608
|
+
}
|
|
1609
|
+
for (const step of plan.steps.filter((entry) => !entry.satisfied)) {
|
|
1610
|
+
io.out(`\u2713 ${step.manifest} depends on ${RUNTIME_PACKAGE} ${release.version}`);
|
|
1571
1611
|
}
|
|
1572
|
-
io.out(`\u2713 package.json depends on ${RUNTIME_PACKAGE} ${release.version}`);
|
|
1573
1612
|
}
|
|
1574
1613
|
writeFileSync4(manifestFile, manifestText);
|
|
1575
1614
|
io.out(`\u2713 ${MANIFEST_PATH4} pins ${ENGINE_PACKAGE4} ${release.version}`);
|
|
@@ -1582,12 +1621,13 @@ async function upgrade(options) {
|
|
|
1582
1621
|
|
|
1583
1622
|
// src/launcher.ts
|
|
1584
1623
|
import { existsSync as existsSync4, readFileSync as readFileSync6, writeFileSync as writeFileSync5 } from "fs";
|
|
1585
|
-
import { join as
|
|
1624
|
+
import { join as join6 } from "path";
|
|
1586
1625
|
import {
|
|
1587
1626
|
MANIFEST_FORMAT,
|
|
1588
1627
|
MANIFEST_PATH as MANIFEST_PATH6,
|
|
1589
1628
|
PENV_HOME_VAR,
|
|
1590
1629
|
PenvError as PenvError3,
|
|
1630
|
+
packageEntry as packageEntry2,
|
|
1591
1631
|
parseManifest as parseManifest2,
|
|
1592
1632
|
penvHome,
|
|
1593
1633
|
serializeManifest as serializeManifest3,
|
|
@@ -1596,7 +1636,7 @@ import {
|
|
|
1596
1636
|
|
|
1597
1637
|
// src/help.ts
|
|
1598
1638
|
import { RUNTIME_PACKAGE as RUNTIME_PACKAGE2 } from "@penvhq/cli/install";
|
|
1599
|
-
import { ENGINE_PACKAGE as ENGINE_PACKAGE5, EXTENSIONS_PATH as EXTENSIONS_PATH3, MANIFEST_PATH as MANIFEST_PATH5 } from "@penvhq/core";
|
|
1639
|
+
import { ENGINE_PACKAGE as ENGINE_PACKAGE5, EXTENSIONS_PATH as EXTENSIONS_PATH3, MANIFEST_PATH as MANIFEST_PATH5, OFFICIAL_SCOPE as OFFICIAL_SCOPE3 } from "@penvhq/core";
|
|
1600
1640
|
function printLauncherCommands(io) {
|
|
1601
1641
|
io.out("");
|
|
1602
1642
|
io.out("LAUNCHER COMMANDS (penv itself, whatever engine a project pins)");
|
|
@@ -1622,10 +1662,15 @@ function printAddHelp(io) {
|
|
|
1622
1662
|
io.out(
|
|
1623
1663
|
` ${TRUST_YOUNG_FLAG} Add a release published less than ${MIN_PACKAGE_AGE_DAYS} days ago`
|
|
1624
1664
|
);
|
|
1665
|
+
io.out(` ${YES_FLAG} Ask nothing \u2014 the config and onboarding offers print instead`);
|
|
1625
1666
|
io.out("");
|
|
1626
1667
|
io.out(`Pins the release in ${MANIFEST_PATH5} and writes its type declaration to`);
|
|
1627
1668
|
io.out(`${EXTENSIONS_PATH3}/. Both are committed, so \`${INSTALL_COMMAND}\` gives every machine`);
|
|
1628
1669
|
io.out(`the bytes you reviewed. \`${LOCAL_FLAG}\` pins nothing and touches no manifest.`);
|
|
1670
|
+
io.out("");
|
|
1671
|
+
io.out(`An \`${OFFICIAL_SCOPE3}*\` package asks nothing, so it adds unattended. Anything else`);
|
|
1672
|
+
io.out("records who publishes it and why you trust it, which needs a person at a terminal \u2014");
|
|
1673
|
+
io.out(`\`${YES_FLAG}\` cannot write that line for you.`);
|
|
1629
1674
|
}
|
|
1630
1675
|
function printUpgradeHelp(io) {
|
|
1631
1676
|
io.out("penv upgrade [version]");
|
|
@@ -1801,7 +1846,7 @@ async function adopt(options, forwarded, home, cwd, noDownload) {
|
|
|
1801
1846
|
if (root === void 0) {
|
|
1802
1847
|
return 0;
|
|
1803
1848
|
}
|
|
1804
|
-
const manifestFile =
|
|
1849
|
+
const manifestFile = join6(root, ...MANIFEST_PATH6.split("/"));
|
|
1805
1850
|
if (existsSync4(manifestFile)) {
|
|
1806
1851
|
return 0;
|
|
1807
1852
|
}
|
|
@@ -1857,12 +1902,14 @@ async function install(options, pins, home, broken) {
|
|
|
1857
1902
|
if (state === "corrupt") {
|
|
1858
1903
|
throw new PackageCorruptError(pin.name, pin.version, dir);
|
|
1859
1904
|
}
|
|
1860
|
-
if (state === "
|
|
1861
|
-
|
|
1862
|
-
|
|
1905
|
+
if (state === "absent") {
|
|
1906
|
+
await installPin({ home, kind, pin, fetcher: options.fetcher });
|
|
1907
|
+
}
|
|
1908
|
+
if (kind === "extensions") {
|
|
1909
|
+
await assertLoadable(pin.name, packageEntry2(dir), false);
|
|
1863
1910
|
}
|
|
1864
|
-
|
|
1865
|
-
options.io.out(`\u2713 ${pin.name} ${pin.version}
|
|
1911
|
+
const verb = state === "absent" ? "installed" : "already installed";
|
|
1912
|
+
options.io.out(`\u2713 ${pin.name} ${pin.version} ${verb}`);
|
|
1866
1913
|
}
|
|
1867
1914
|
if (broken.length > 0) {
|
|
1868
1915
|
report(new ManifestEntriesUnreadableError(broken), options.io);
|
|
@@ -1938,7 +1985,7 @@ export {
|
|
|
1938
1985
|
ReleaseIncompleteError,
|
|
1939
1986
|
PackageTooYoungError,
|
|
1940
1987
|
AddNoDownloadError,
|
|
1941
|
-
|
|
1988
|
+
AddTrustUnattendedError,
|
|
1942
1989
|
TrustDeclinedError,
|
|
1943
1990
|
TrustPublisherMissingError,
|
|
1944
1991
|
TrustReasonMissingError,
|
|
@@ -1985,4 +2032,4 @@ export {
|
|
|
1985
2032
|
upgrade,
|
|
1986
2033
|
runLauncher
|
|
1987
2034
|
};
|
|
1988
|
-
//# sourceMappingURL=chunk-
|
|
2035
|
+
//# sourceMappingURL=chunk-A5LJQPYS.js.map
|