@penvhq/launcher 0.9.5 → 0.11.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 +325 -54
- package/dist/bin.cjs.map +1 -1
- package/dist/bin.js +1 -1
- package/dist/{chunk-4YZYBC5T.js → chunk-USYQEKPW.js} +349 -59
- package/dist/chunk-USYQEKPW.js.map +1 -0
- package/dist/index.cjs +349 -62
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +147 -49
- package/dist/index.d.ts +147 -49
- package/dist/index.js +23 -7
- package/package.json +3 -3
- package/dist/chunk-4YZYBC5T.js.map +0 -1
package/dist/bin.js
CHANGED
|
@@ -170,12 +170,17 @@ import {
|
|
|
170
170
|
PenvError
|
|
171
171
|
} from "@penvhq/core";
|
|
172
172
|
var INSTALL_COMMAND = "penv install";
|
|
173
|
+
var UPGRADE_COMMAND = "penv upgrade";
|
|
174
|
+
var YES_FLAG = "--yes";
|
|
173
175
|
var MIN_PACKAGE_AGE_DAYS = 7;
|
|
174
176
|
var TRUST_YOUNG_FLAG = "--trust-young";
|
|
175
177
|
function addCommand(name, version, extra) {
|
|
176
178
|
const spec = version === void 0 ? name : `${name}@${version}`;
|
|
177
179
|
return `penv add ${spec}${extra === void 0 ? "" : ` ${extra}`}`;
|
|
178
180
|
}
|
|
181
|
+
function addCommandFor(name, local) {
|
|
182
|
+
return local ? `penv add ${LOCAL_FLAG} ${name}` : addCommand(name);
|
|
183
|
+
}
|
|
179
184
|
var NoProjectError = class extends PenvError {
|
|
180
185
|
name = "NoProjectError";
|
|
181
186
|
constructor(cwd) {
|
|
@@ -287,6 +292,26 @@ var AddLocalFlagError = class extends PenvError {
|
|
|
287
292
|
);
|
|
288
293
|
}
|
|
289
294
|
};
|
|
295
|
+
var ExtensionNotImportableError = class extends PenvError {
|
|
296
|
+
name = "ExtensionNotImportableError";
|
|
297
|
+
constructor(name, entry, local) {
|
|
298
|
+
super(
|
|
299
|
+
"PENV_EXTENSION_NOT_IMPORTABLE",
|
|
300
|
+
entry === void 0 ? `${name} declares no entry point penv can import` : `${name} resolves to ${entry}, which penv cannot import`,
|
|
301
|
+
`penv imports a provider with no transform, so its entry has to be built JavaScript. Point the package's \`exports\` at its build output \u2014 \`dist/index.js\` \u2014 then run \`${addCommandFor(name, local)}\` again.`
|
|
302
|
+
);
|
|
303
|
+
}
|
|
304
|
+
};
|
|
305
|
+
var ExtensionUnloadableError = class extends PenvError {
|
|
306
|
+
name = "ExtensionUnloadableError";
|
|
307
|
+
constructor(name, entry, detail, local) {
|
|
308
|
+
super(
|
|
309
|
+
"PENV_EXTENSION_UNLOADABLE",
|
|
310
|
+
`${name} threw while penv imported ${entry}: ${detail}`,
|
|
311
|
+
`Build the package and install its dependencies, then run \`${addCommandFor(name, local)}\` again. penv adds a provider it has loaded once, or none.`
|
|
312
|
+
);
|
|
313
|
+
}
|
|
314
|
+
};
|
|
290
315
|
var LocalExtensionUnresolvedError = class extends PenvError {
|
|
291
316
|
name = "LocalExtensionUnresolvedError";
|
|
292
317
|
constructor(name, root) {
|
|
@@ -329,11 +354,11 @@ var OfficialRegistryError = class extends PenvError {
|
|
|
329
354
|
};
|
|
330
355
|
var RegistryUnreadableError = class extends PenvError {
|
|
331
356
|
name = "RegistryUnreadableError";
|
|
332
|
-
constructor(name, url, detail) {
|
|
357
|
+
constructor(name, url, detail, retry = addCommand(name)) {
|
|
333
358
|
super(
|
|
334
359
|
"PENV_REGISTRY_UNREADABLE",
|
|
335
360
|
`Reading ${name} from ${url} failed: ${detail}`,
|
|
336
|
-
`Run \`${
|
|
361
|
+
`Run \`${retry}\` again when the registry is reachable.`
|
|
337
362
|
);
|
|
338
363
|
}
|
|
339
364
|
};
|
|
@@ -349,11 +374,11 @@ var PackageUnknownError = class extends PenvError {
|
|
|
349
374
|
};
|
|
350
375
|
var VersionUnknownError = class extends PenvError {
|
|
351
376
|
name = "VersionUnknownError";
|
|
352
|
-
constructor(name, version, url) {
|
|
377
|
+
constructor(name, version, url, retry = addCommand(name)) {
|
|
353
378
|
super(
|
|
354
379
|
"PENV_VERSION_UNKNOWN",
|
|
355
380
|
`${url} publishes no ${version} of ${name}`,
|
|
356
|
-
`Run \`${
|
|
381
|
+
`Run \`${retry}\` to take the version \`latest\` points at.`
|
|
357
382
|
);
|
|
358
383
|
}
|
|
359
384
|
};
|
|
@@ -478,6 +503,66 @@ var EnginePinMismatchError = class extends PenvError {
|
|
|
478
503
|
);
|
|
479
504
|
}
|
|
480
505
|
};
|
|
506
|
+
var UpgradeSubjectError = class extends PenvError {
|
|
507
|
+
name = "UpgradeSubjectError";
|
|
508
|
+
constructor() {
|
|
509
|
+
super(
|
|
510
|
+
"PENV_UPGRADE_SUBJECT",
|
|
511
|
+
"`penv upgrade` takes one version, or none",
|
|
512
|
+
`Run \`${UPGRADE_COMMAND}\` to move to whatever \`latest\` points at, or \`${UPGRADE_COMMAND} 0.9.6\` to move to an exact release.`
|
|
513
|
+
);
|
|
514
|
+
}
|
|
515
|
+
};
|
|
516
|
+
var UpgradeFlagError = class extends PenvError {
|
|
517
|
+
name = "UpgradeFlagError";
|
|
518
|
+
constructor(flag) {
|
|
519
|
+
super(
|
|
520
|
+
"PENV_UPGRADE_FLAG",
|
|
521
|
+
`\`${UPGRADE_COMMAND}\` does not understand \`${flag}\``,
|
|
522
|
+
`Run \`${UPGRADE_COMMAND} [version]\` with \`${YES_FLAG}\` \u2014 that is the one flag it takes.`
|
|
523
|
+
);
|
|
524
|
+
}
|
|
525
|
+
};
|
|
526
|
+
var UpgradeNoDownloadError = class extends PenvError {
|
|
527
|
+
name = "UpgradeNoDownloadError";
|
|
528
|
+
constructor() {
|
|
529
|
+
super(
|
|
530
|
+
"PENV_UPGRADE_NO_DOWNLOAD",
|
|
531
|
+
`Upgrading means reading the registry for the version and integrity to pin, and \`--no-download\` says this run does not`,
|
|
532
|
+
`Run \`${UPGRADE_COMMAND}\` without \`--no-download\`. Nothing was fetched or written.`
|
|
533
|
+
);
|
|
534
|
+
}
|
|
535
|
+
};
|
|
536
|
+
var UpgradeUnattendedError = class extends PenvError {
|
|
537
|
+
name = "UpgradeUnattendedError";
|
|
538
|
+
constructor() {
|
|
539
|
+
super(
|
|
540
|
+
"PENV_UPGRADE_UNATTENDED",
|
|
541
|
+
`Upgrading rewrites ${MANIFEST_PATH} and package.json, and this run has nobody to decide that`,
|
|
542
|
+
`Run \`${UPGRADE_COMMAND} <version> ${YES_FLAG}\` \u2014 unattended, penv moves the pin only to a version you named. In CI, run \`${INSTALL_COMMAND}\`: it installs what the committed manifest already pins.`
|
|
543
|
+
);
|
|
544
|
+
}
|
|
545
|
+
};
|
|
546
|
+
var UpgradeDeclinedError = class extends PenvError {
|
|
547
|
+
name = "UpgradeDeclinedError";
|
|
548
|
+
constructor(version) {
|
|
549
|
+
super(
|
|
550
|
+
"PENV_UPGRADE_DECLINED",
|
|
551
|
+
`${ENGINE_PACKAGE} ${version} was not installed, so ${MANIFEST_PATH} and package.json are unchanged`,
|
|
552
|
+
`Run \`${UPGRADE_COMMAND} ${version}\` again when you want both of them to move.`
|
|
553
|
+
);
|
|
554
|
+
}
|
|
555
|
+
};
|
|
556
|
+
var UpgradeInstallFailedError = class extends PenvError {
|
|
557
|
+
name = "UpgradeInstallFailedError";
|
|
558
|
+
constructor(command) {
|
|
559
|
+
super(
|
|
560
|
+
"PENV_UPGRADE_INSTALL_FAILED",
|
|
561
|
+
`${command} did not finish, so ${MANIFEST_PATH} still pins the engine it pinned before`,
|
|
562
|
+
`Run \`${command}\` yourself, then run \`${UPGRADE_COMMAND}\` again \u2014 the pin and the dependency move together or not at all.`
|
|
563
|
+
);
|
|
564
|
+
}
|
|
565
|
+
};
|
|
481
566
|
var EngineEntryError = class extends PenvError {
|
|
482
567
|
name = "EngineEntryError";
|
|
483
568
|
constructor(name, version, dir) {
|
|
@@ -593,32 +678,10 @@ function writeDeclaration(options) {
|
|
|
593
678
|
|
|
594
679
|
// src/home.ts
|
|
595
680
|
import { readFileSync as readFileSync2 } from "fs";
|
|
596
|
-
import {
|
|
597
|
-
import { join as join2, resolve as resolve2, sep as sep2 } from "path";
|
|
598
|
-
import { PenvError as PenvError2 } from "@penvhq/core";
|
|
599
|
-
var PENV_HOME_VAR = "PENV_HOME";
|
|
681
|
+
import { join as join2 } from "path";
|
|
600
682
|
var HOME_META_FILE = "meta.json";
|
|
601
683
|
var INTEGRITY_FILE = ".penv-integrity";
|
|
602
684
|
var NPM_UPDATE_COMMAND = "npm install -g @penvhq/launcher";
|
|
603
|
-
function penvHome(env) {
|
|
604
|
-
const declared = env[PENV_HOME_VAR];
|
|
605
|
-
if (declared !== void 0 && declared.trim() !== "") {
|
|
606
|
-
return resolve2(declared);
|
|
607
|
-
}
|
|
608
|
-
return join2(homedir(), ".penv");
|
|
609
|
-
}
|
|
610
|
-
function packageDir(home, kind, name, version) {
|
|
611
|
-
const bucket = resolve2(home, kind);
|
|
612
|
-
const dir = resolve2(bucket, ...name.split("/"), version);
|
|
613
|
-
if (!dir.startsWith(bucket + sep2)) {
|
|
614
|
-
throw new PenvError2(
|
|
615
|
-
"PENV_HOME_ESCAPE",
|
|
616
|
-
`\`${name}\` at \`${version}\` resolves to ${dir}, which is outside ${bucket}`,
|
|
617
|
-
"Name the package exactly as npm does, e.g. `@penvhq/provider-vault`."
|
|
618
|
-
);
|
|
619
|
-
}
|
|
620
|
-
return dir;
|
|
621
|
-
}
|
|
622
685
|
function launcherUpdateCommand(home) {
|
|
623
686
|
let meta;
|
|
624
687
|
try {
|
|
@@ -723,6 +786,7 @@ import {
|
|
|
723
786
|
writeFileSync as writeFileSync2
|
|
724
787
|
} from "fs";
|
|
725
788
|
import { dirname as dirname2, join as join3 } from "path";
|
|
789
|
+
import { packageDir } from "@penvhq/core";
|
|
726
790
|
var DEFAULT_REGISTRY = "https://registry.npmjs.org";
|
|
727
791
|
function tarballUrl(pin) {
|
|
728
792
|
const registry = (pin.registry ?? DEFAULT_REGISTRY).replace(/\/+$/, "");
|
|
@@ -809,7 +873,8 @@ async function fetchRelease(query) {
|
|
|
809
873
|
throw new RegistryUnreadableError(
|
|
810
874
|
query.name,
|
|
811
875
|
url,
|
|
812
|
-
cause instanceof Error ? cause.message : String(cause)
|
|
876
|
+
cause instanceof Error ? cause.message : String(cause),
|
|
877
|
+
query.retry
|
|
813
878
|
);
|
|
814
879
|
}
|
|
815
880
|
let parsed;
|
|
@@ -819,7 +884,8 @@ async function fetchRelease(query) {
|
|
|
819
884
|
throw new RegistryUnreadableError(
|
|
820
885
|
query.name,
|
|
821
886
|
url,
|
|
822
|
-
cause instanceof Error ? cause.message : String(cause)
|
|
887
|
+
cause instanceof Error ? cause.message : String(cause),
|
|
888
|
+
query.retry
|
|
823
889
|
);
|
|
824
890
|
}
|
|
825
891
|
const packument = record(parsed);
|
|
@@ -835,7 +901,7 @@ async function fetchRelease(query) {
|
|
|
835
901
|
const version = record(at(versions, asked)) === void 0 ? text3(at(tags, asked)) ?? asked : asked;
|
|
836
902
|
const release = record(at(versions, version));
|
|
837
903
|
if (release === void 0) {
|
|
838
|
-
throw new VersionUnknownError(query.name, asked, url);
|
|
904
|
+
throw new VersionUnknownError(query.name, asked, url, query.retry);
|
|
839
905
|
}
|
|
840
906
|
const dist = record(at(release, "dist"));
|
|
841
907
|
const integrity = text3(at(dist, "integrity"));
|
|
@@ -859,13 +925,16 @@ async function fetchRelease(query) {
|
|
|
859
925
|
// src/add.ts
|
|
860
926
|
import { mkdirSync as mkdirSync3, readFileSync as readFileSync4, writeFileSync as writeFileSync3 } from "fs";
|
|
861
927
|
import { createRequire } from "module";
|
|
862
|
-
import { dirname as dirname3, relative, resolve as
|
|
928
|
+
import { dirname as dirname3, relative, resolve as resolve2, sep as sep2 } from "path";
|
|
929
|
+
import { pathToFileURL } from "url";
|
|
863
930
|
import {
|
|
864
931
|
findConfigFile,
|
|
932
|
+
isImportableEntry,
|
|
865
933
|
LOCAL_EXTENSIONS_PATH as LOCAL_EXTENSIONS_PATH2,
|
|
866
934
|
localExtensionsFile,
|
|
867
935
|
MANIFEST_PATH as MANIFEST_PATH2,
|
|
868
936
|
OFFICIAL_SCOPE as OFFICIAL_SCOPE2,
|
|
937
|
+
packageEntry,
|
|
869
938
|
parseLocalExtensions,
|
|
870
939
|
serializeLocalExtensions,
|
|
871
940
|
serializeManifest
|
|
@@ -1066,7 +1135,7 @@ async function offerConfigEdit(options, name) {
|
|
|
1066
1135
|
io.out(line);
|
|
1067
1136
|
return;
|
|
1068
1137
|
}
|
|
1069
|
-
const shown = relative(root, configFile).split(
|
|
1138
|
+
const shown = relative(root, configFile).split(sep2).join("/");
|
|
1070
1139
|
let current = readFileSync4(configFile, "utf8");
|
|
1071
1140
|
const entries = readProviderEntries(current);
|
|
1072
1141
|
if (entries === void 0 || entries.length === 0) {
|
|
@@ -1113,7 +1182,7 @@ async function offerOnboarding(io, name, onboard) {
|
|
|
1113
1182
|
return void 0;
|
|
1114
1183
|
}
|
|
1115
1184
|
function resolvePackageDir(name, root) {
|
|
1116
|
-
const require2 = createRequire(
|
|
1185
|
+
const require2 = createRequire(resolve2(root, "noop.js"));
|
|
1117
1186
|
try {
|
|
1118
1187
|
return dirname3(require2.resolve(`${name}/package.json`));
|
|
1119
1188
|
} catch {
|
|
@@ -1132,6 +1201,26 @@ function resolvePackageDir(name, root) {
|
|
|
1132
1201
|
return void 0;
|
|
1133
1202
|
}
|
|
1134
1203
|
}
|
|
1204
|
+
function resolveProjectEntry(name, root) {
|
|
1205
|
+
let file;
|
|
1206
|
+
try {
|
|
1207
|
+
file = createRequire(resolve2(root, "noop.js")).resolve(name);
|
|
1208
|
+
} catch {
|
|
1209
|
+
return void 0;
|
|
1210
|
+
}
|
|
1211
|
+
return { file, importable: isImportableEntry(file) };
|
|
1212
|
+
}
|
|
1213
|
+
async function assertLoadable(name, entry, local) {
|
|
1214
|
+
if (entry === void 0 || !entry.importable) {
|
|
1215
|
+
throw new ExtensionNotImportableError(name, entry?.file, local);
|
|
1216
|
+
}
|
|
1217
|
+
try {
|
|
1218
|
+
await import(pathToFileURL(entry.file).href);
|
|
1219
|
+
} catch (cause) {
|
|
1220
|
+
const detail = cause instanceof Error ? cause.message : String(cause);
|
|
1221
|
+
throw new ExtensionUnloadableError(name, entry.file, detail, local);
|
|
1222
|
+
}
|
|
1223
|
+
}
|
|
1135
1224
|
function recordLocalExtension(root, name) {
|
|
1136
1225
|
const file = localExtensionsFile(root);
|
|
1137
1226
|
let current;
|
|
@@ -1152,6 +1241,7 @@ async function addLocal(options, request) {
|
|
|
1152
1241
|
if (dir === void 0) {
|
|
1153
1242
|
throw new LocalExtensionUnresolvedError(request.name, root);
|
|
1154
1243
|
}
|
|
1244
|
+
await assertLoadable(request.name, resolveProjectEntry(request.name, root), true);
|
|
1155
1245
|
const installed = readExtensionPackage(dir);
|
|
1156
1246
|
const declaration = writeDeclaration({
|
|
1157
1247
|
root,
|
|
@@ -1163,7 +1253,7 @@ async function addLocal(options, request) {
|
|
|
1163
1253
|
types: installed.types
|
|
1164
1254
|
});
|
|
1165
1255
|
recordLocalExtension(root, request.name);
|
|
1166
|
-
io.out(`\u2713 ${request.name} resolves from this project \u2014 nothing is pinned`);
|
|
1256
|
+
io.out(`\u2713 ${request.name} resolves from this project and imports \u2014 nothing is pinned`);
|
|
1167
1257
|
io.out(`\u2713 ${LOCAL_EXTENSIONS_PATH2} records it`);
|
|
1168
1258
|
io.out(`\u2713 ${declaration} declares its config type`);
|
|
1169
1259
|
await offerConfigEdit(options, request.name);
|
|
@@ -1208,6 +1298,7 @@ async function add(options) {
|
|
|
1208
1298
|
},
|
|
1209
1299
|
fetcher
|
|
1210
1300
|
});
|
|
1301
|
+
await assertLoadable(release.name, packageEntry(dir), false);
|
|
1211
1302
|
const installed = readExtensionPackage(dir);
|
|
1212
1303
|
const declaration = writeDeclaration({
|
|
1213
1304
|
root,
|
|
@@ -1272,8 +1363,8 @@ function nodeSpawner() {
|
|
|
1272
1363
|
// src/engine.ts
|
|
1273
1364
|
import { existsSync as existsSync2, readFileSync as readFileSync5 } from "fs";
|
|
1274
1365
|
import { createRequire as createRequire2 } from "module";
|
|
1275
|
-
import { dirname as dirname4, join as join5, resolve as
|
|
1276
|
-
import { ENGINE_PACKAGE as ENGINE_PACKAGE2, PenvError as
|
|
1366
|
+
import { dirname as dirname4, join as join5, resolve as resolve3, sep as sep3 } from "path";
|
|
1367
|
+
import { ENGINE_PACKAGE as ENGINE_PACKAGE2, PenvError as PenvError2 } from "@penvhq/core";
|
|
1277
1368
|
var ENGINE_BIN = "penv-engine";
|
|
1278
1369
|
function readPackageManifest(dir) {
|
|
1279
1370
|
try {
|
|
@@ -1299,9 +1390,9 @@ function binPath(bin) {
|
|
|
1299
1390
|
function engineAt(dir, name, version) {
|
|
1300
1391
|
const manifest = readPackageManifest(dir);
|
|
1301
1392
|
const bin = manifest === void 0 ? void 0 : binPath(manifest.bin);
|
|
1302
|
-
const root =
|
|
1303
|
-
const entry = bin === void 0 ? void 0 :
|
|
1304
|
-
if (entry === void 0 || !entry.startsWith(root +
|
|
1393
|
+
const root = resolve3(dir);
|
|
1394
|
+
const entry = bin === void 0 ? void 0 : resolve3(root, bin);
|
|
1395
|
+
if (entry === void 0 || !entry.startsWith(root + sep3) || !existsSync2(entry)) {
|
|
1305
1396
|
throw new EngineEntryError(name, version, dir);
|
|
1306
1397
|
}
|
|
1307
1398
|
return { name, version, dir, entry };
|
|
@@ -1312,7 +1403,7 @@ function bundledEngine() {
|
|
|
1312
1403
|
try {
|
|
1313
1404
|
manifestFile = require2.resolve(`${ENGINE_PACKAGE2}/package.json`);
|
|
1314
1405
|
} catch {
|
|
1315
|
-
throw new
|
|
1406
|
+
throw new PenvError2(
|
|
1316
1407
|
"PENV_NO_BUNDLED_ENGINE",
|
|
1317
1408
|
`This penv installation is missing ${ENGINE_PACKAGE2}, the engine it runs \`init\` with`,
|
|
1318
1409
|
"Reinstall the launcher with `npm install -g @penvhq/launcher`."
|
|
@@ -1342,8 +1433,8 @@ var DEV_PIN_INTEGRITY = "sha512-development-build-not-a-published-release";
|
|
|
1342
1433
|
var DEV_PIN_VERSION = "0.0.0-dev";
|
|
1343
1434
|
var BUNDLED_ENGINE_PIN = {
|
|
1344
1435
|
package: ENGINE_PACKAGE3,
|
|
1345
|
-
version: "0.
|
|
1346
|
-
integrity: "sha512-
|
|
1436
|
+
version: "0.11.0",
|
|
1437
|
+
integrity: "sha512-Y+WKyuPsX4U8/1j0e+VMUhj0LaGrp67YEoDAWyyinrgA+c8IM4H1blqje/YK4LsQwzQDQQDF9bhWIhfmDAWoxA=="
|
|
1347
1438
|
};
|
|
1348
1439
|
function assertReleasePin(pin) {
|
|
1349
1440
|
if (pin.integrity === DEV_PIN_INTEGRITY || pin.version === DEV_PIN_VERSION) {
|
|
@@ -1360,11 +1451,11 @@ function releaseEnginePin(pin, ranVersion) {
|
|
|
1360
1451
|
|
|
1361
1452
|
// src/project.ts
|
|
1362
1453
|
import { existsSync as existsSync3 } from "fs";
|
|
1363
|
-
import { dirname as dirname5, join as join6, resolve as
|
|
1454
|
+
import { dirname as dirname5, join as join6, resolve as resolve4 } from "path";
|
|
1364
1455
|
import { MANIFEST_PATH as MANIFEST_PATH3, stateDir } from "@penvhq/core";
|
|
1365
1456
|
var MANIFEST_SEGMENTS = MANIFEST_PATH3.split("/");
|
|
1366
1457
|
function findUp(cwd, matches) {
|
|
1367
|
-
let dir =
|
|
1458
|
+
let dir = resolve4(cwd);
|
|
1368
1459
|
for (; ; ) {
|
|
1369
1460
|
if (matches(dir)) {
|
|
1370
1461
|
return dir;
|
|
@@ -1384,19 +1475,174 @@ function findAdoptedRoot(cwd) {
|
|
|
1384
1475
|
return findUp(cwd, (dir) => existsSync3(stateDir(dir)));
|
|
1385
1476
|
}
|
|
1386
1477
|
|
|
1478
|
+
// src/upgrade.ts
|
|
1479
|
+
import { writeFileSync as writeFileSync4 } from "fs";
|
|
1480
|
+
import {
|
|
1481
|
+
installWithPackageManager,
|
|
1482
|
+
planInstall,
|
|
1483
|
+
RUNTIME_PACKAGE,
|
|
1484
|
+
renderInstallPlan
|
|
1485
|
+
} from "@penvhq/cli/install";
|
|
1486
|
+
import { ENGINE_PACKAGE as ENGINE_PACKAGE4, MANIFEST_PATH as MANIFEST_PATH4, serializeManifest as serializeManifest2 } from "@penvhq/core";
|
|
1487
|
+
function parseRequest2(argv) {
|
|
1488
|
+
let version;
|
|
1489
|
+
let yes = false;
|
|
1490
|
+
for (const token of argv) {
|
|
1491
|
+
if (token === YES_FLAG) {
|
|
1492
|
+
yes = true;
|
|
1493
|
+
continue;
|
|
1494
|
+
}
|
|
1495
|
+
if (token.startsWith("-")) {
|
|
1496
|
+
throw new UpgradeFlagError(token);
|
|
1497
|
+
}
|
|
1498
|
+
if (version !== void 0 || token === "") {
|
|
1499
|
+
throw new UpgradeSubjectError();
|
|
1500
|
+
}
|
|
1501
|
+
version = token;
|
|
1502
|
+
}
|
|
1503
|
+
return { version, yes };
|
|
1504
|
+
}
|
|
1505
|
+
function renderPinChange(engine, release) {
|
|
1506
|
+
return [
|
|
1507
|
+
MANIFEST_PATH4,
|
|
1508
|
+
` - "integrity": "${engine.integrity}"`,
|
|
1509
|
+
` - "version": "${engine.version}"`,
|
|
1510
|
+
` + "integrity": "${release.integrity}"`,
|
|
1511
|
+
` + "version": "${release.version}"`
|
|
1512
|
+
];
|
|
1513
|
+
}
|
|
1514
|
+
function pinnedElsewhere(manifest, version) {
|
|
1515
|
+
return Object.entries(manifest.extensions).filter(([, entry]) => entry.version !== version).map(([name]) => name);
|
|
1516
|
+
}
|
|
1517
|
+
async function consent(options, release, plan, yes) {
|
|
1518
|
+
const { io, manifest } = options;
|
|
1519
|
+
io.out(`${ENGINE_PACKAGE4} ${manifest.engine.version} \u2192 ${release.version}`);
|
|
1520
|
+
io.out("");
|
|
1521
|
+
for (const line of renderPinChange(manifest.engine, release)) {
|
|
1522
|
+
io.out(line);
|
|
1523
|
+
}
|
|
1524
|
+
for (const line of renderInstallPlan(plan)) {
|
|
1525
|
+
io.out(line);
|
|
1526
|
+
}
|
|
1527
|
+
if (yes) {
|
|
1528
|
+
return;
|
|
1529
|
+
}
|
|
1530
|
+
if (!await io.confirm(`Move this project to ${release.version}?`)) {
|
|
1531
|
+
throw new UpgradeDeclinedError(release.version);
|
|
1532
|
+
}
|
|
1533
|
+
}
|
|
1534
|
+
async function upgrade(options) {
|
|
1535
|
+
const { io, fetcher, home, root, manifest, manifestFile } = options;
|
|
1536
|
+
const request = parseRequest2(options.argv);
|
|
1537
|
+
if (options.noDownload === true) {
|
|
1538
|
+
throw new UpgradeNoDownloadError();
|
|
1539
|
+
}
|
|
1540
|
+
if ((options.ci === true || !io.interactive) && !(request.yes && request.version !== void 0)) {
|
|
1541
|
+
throw new UpgradeUnattendedError();
|
|
1542
|
+
}
|
|
1543
|
+
const release = await fetchRelease({
|
|
1544
|
+
name: ENGINE_PACKAGE4,
|
|
1545
|
+
...request.version === void 0 ? {} : { version: request.version },
|
|
1546
|
+
retry: UPGRADE_COMMAND,
|
|
1547
|
+
fetcher
|
|
1548
|
+
});
|
|
1549
|
+
const plan = planInstall(root, release.version);
|
|
1550
|
+
if (manifest.engine.version === release.version && plan.satisfied) {
|
|
1551
|
+
io.out(`\u2713 Already on ${ENGINE_PACKAGE4} ${release.version} \u2014 nothing to move`);
|
|
1552
|
+
return;
|
|
1553
|
+
}
|
|
1554
|
+
const manifestText = serializeManifest2({
|
|
1555
|
+
...manifest,
|
|
1556
|
+
engine: { package: ENGINE_PACKAGE4, version: release.version, integrity: release.integrity }
|
|
1557
|
+
});
|
|
1558
|
+
await consent(options, release, plan, request.yes);
|
|
1559
|
+
await installPin({
|
|
1560
|
+
home,
|
|
1561
|
+
kind: "engines",
|
|
1562
|
+
pin: { name: ENGINE_PACKAGE4, version: release.version, integrity: release.integrity },
|
|
1563
|
+
fetcher
|
|
1564
|
+
});
|
|
1565
|
+
io.out(`\u2713 ${ENGINE_PACKAGE4} ${release.version} installed`);
|
|
1566
|
+
if (!plan.satisfied) {
|
|
1567
|
+
try {
|
|
1568
|
+
await (options.install ?? installWithPackageManager)(plan);
|
|
1569
|
+
} catch {
|
|
1570
|
+
throw new UpgradeInstallFailedError(plan.command.join(" "));
|
|
1571
|
+
}
|
|
1572
|
+
io.out(`\u2713 package.json depends on ${RUNTIME_PACKAGE} ${release.version}`);
|
|
1573
|
+
}
|
|
1574
|
+
writeFileSync4(manifestFile, manifestText);
|
|
1575
|
+
io.out(`\u2713 ${MANIFEST_PATH4} pins ${ENGINE_PACKAGE4} ${release.version}`);
|
|
1576
|
+
const kept = pinnedElsewhere(manifest, release.version);
|
|
1577
|
+
if (kept.length > 0) {
|
|
1578
|
+
const subject = kept.length === 1 ? "keeps its own pin" : "keep their own pins";
|
|
1579
|
+
io.out(`\u2192 ${kept.join(", ")} ${subject} \u2014 \`penv add <package>@<version>\` moves one.`);
|
|
1580
|
+
}
|
|
1581
|
+
}
|
|
1582
|
+
|
|
1387
1583
|
// src/launcher.ts
|
|
1388
|
-
import { existsSync as existsSync4, readFileSync as readFileSync6, writeFileSync as
|
|
1584
|
+
import { existsSync as existsSync4, readFileSync as readFileSync6, writeFileSync as writeFileSync5 } from "fs";
|
|
1389
1585
|
import { join as join7 } from "path";
|
|
1390
1586
|
import {
|
|
1391
1587
|
MANIFEST_FORMAT,
|
|
1392
|
-
MANIFEST_PATH as
|
|
1393
|
-
|
|
1588
|
+
MANIFEST_PATH as MANIFEST_PATH6,
|
|
1589
|
+
PENV_HOME_VAR,
|
|
1590
|
+
PenvError as PenvError3,
|
|
1394
1591
|
parseManifest as parseManifest2,
|
|
1395
|
-
|
|
1592
|
+
penvHome,
|
|
1593
|
+
serializeManifest as serializeManifest3,
|
|
1396
1594
|
UnsupportedManifestFormatError
|
|
1397
1595
|
} from "@penvhq/core";
|
|
1596
|
+
|
|
1597
|
+
// src/help.ts
|
|
1598
|
+
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";
|
|
1600
|
+
function printLauncherCommands(io) {
|
|
1601
|
+
io.out("");
|
|
1602
|
+
io.out("LAUNCHER COMMANDS (penv itself, whatever engine a project pins)");
|
|
1603
|
+
io.out("");
|
|
1604
|
+
io.out(` install Installs everything ${MANIFEST_PATH5} pins`);
|
|
1605
|
+
io.out(" add <package> Pins a provider extension, and commits the decision");
|
|
1606
|
+
io.out(` add ${LOCAL_FLAG} <package> Adds the one this repository builds \u2014 nothing is pinned`);
|
|
1607
|
+
io.out(` upgrade [version] Moves the engine pin and ${RUNTIME_PACKAGE2} together`);
|
|
1608
|
+
io.out("");
|
|
1609
|
+
}
|
|
1610
|
+
function printInstallHelp(io) {
|
|
1611
|
+
io.out(`${INSTALL_COMMAND}`);
|
|
1612
|
+
io.out("");
|
|
1613
|
+
io.out(`Downloads, verifies and installs every version ${MANIFEST_PATH5} pins \u2014 the engine and`);
|
|
1614
|
+
io.out("every extension \u2014 into $PENV_HOME. The one penv command CI and production run that");
|
|
1615
|
+
io.out("may reach the registry.");
|
|
1616
|
+
}
|
|
1617
|
+
function printAddHelp(io) {
|
|
1618
|
+
io.out("penv add <package>[@<version>]");
|
|
1619
|
+
io.out("");
|
|
1620
|
+
io.out(` ${LOCAL_FLAG} Add the package this repository builds, resolved from it`);
|
|
1621
|
+
io.out(" --registry <url> Take the release from a private registry instead of npmjs");
|
|
1622
|
+
io.out(
|
|
1623
|
+
` ${TRUST_YOUNG_FLAG} Add a release published less than ${MIN_PACKAGE_AGE_DAYS} days ago`
|
|
1624
|
+
);
|
|
1625
|
+
io.out("");
|
|
1626
|
+
io.out(`Pins the release in ${MANIFEST_PATH5} and writes its type declaration to`);
|
|
1627
|
+
io.out(`${EXTENSIONS_PATH3}/. Both are committed, so \`${INSTALL_COMMAND}\` gives every machine`);
|
|
1628
|
+
io.out(`the bytes you reviewed. \`${LOCAL_FLAG}\` pins nothing and touches no manifest.`);
|
|
1629
|
+
}
|
|
1630
|
+
function printUpgradeHelp(io) {
|
|
1631
|
+
io.out("penv upgrade [version]");
|
|
1632
|
+
io.out("");
|
|
1633
|
+
io.out(` ${YES_FLAG} Skip the question \u2014 unattended runs need it and a version`);
|
|
1634
|
+
io.out("");
|
|
1635
|
+
io.out(`Moves the ${ENGINE_PACKAGE5} pin in ${MANIFEST_PATH5} and this project's`);
|
|
1636
|
+
io.out(`${RUNTIME_PACKAGE2} dependency to the same exact version. No version takes whatever`);
|
|
1637
|
+
io.out("`latest` points at; the integrity is the one the registry states, never one penv");
|
|
1638
|
+
io.out("computed. Both files are shown before either moves, and they move together or not");
|
|
1639
|
+
io.out("at all. Extensions keep their own pins.");
|
|
1640
|
+
}
|
|
1641
|
+
|
|
1642
|
+
// src/launcher.ts
|
|
1398
1643
|
var INSTALL = "install";
|
|
1399
1644
|
var ADD = "add";
|
|
1645
|
+
var UPGRADE = "upgrade";
|
|
1400
1646
|
var VERSION_FLAGS = /* @__PURE__ */ new Set(["--version", "-v"]);
|
|
1401
1647
|
var HELP_FLAGS = /* @__PURE__ */ new Set(["--help", "-h"]);
|
|
1402
1648
|
var NO_DOWNLOAD = "--no-download";
|
|
@@ -1460,7 +1706,7 @@ function readManifestToRepair(manifestFile, home, argv) {
|
|
|
1460
1706
|
}
|
|
1461
1707
|
}
|
|
1462
1708
|
function report(error, io) {
|
|
1463
|
-
if (error instanceof
|
|
1709
|
+
if (error instanceof PenvError3 && error.remedy !== void 0) {
|
|
1464
1710
|
const suffix = `
|
|
1465
1711
|
${error.remedy}`;
|
|
1466
1712
|
const message = error.message.endsWith(suffix) ? error.message.slice(0, -suffix.length) : error.message;
|
|
@@ -1483,6 +1729,20 @@ async function launch(options) {
|
|
|
1483
1729
|
const { noDownload, forwarded } = splitLauncherFlags(argv);
|
|
1484
1730
|
const first = forwarded[0];
|
|
1485
1731
|
const home = penvHome(env);
|
|
1732
|
+
if (first !== void 0 && forwarded.slice(1).some((token) => HELP_FLAGS.has(token))) {
|
|
1733
|
+
if (first === INSTALL) {
|
|
1734
|
+
printInstallHelp(io);
|
|
1735
|
+
return 0;
|
|
1736
|
+
}
|
|
1737
|
+
if (first === ADD) {
|
|
1738
|
+
printAddHelp(io);
|
|
1739
|
+
return 0;
|
|
1740
|
+
}
|
|
1741
|
+
if (first === UPGRADE) {
|
|
1742
|
+
printUpgradeHelp(io);
|
|
1743
|
+
return 0;
|
|
1744
|
+
}
|
|
1745
|
+
}
|
|
1486
1746
|
const project = findProject(cwd);
|
|
1487
1747
|
if (project === void 0) {
|
|
1488
1748
|
if (first !== void 0 && VERSION_FLAGS.has(first)) {
|
|
@@ -1509,6 +1769,20 @@ async function launch(options) {
|
|
|
1509
1769
|
io.out(`penv ${manifest.engine.version}`);
|
|
1510
1770
|
return 0;
|
|
1511
1771
|
}
|
|
1772
|
+
if (first === UPGRADE) {
|
|
1773
|
+
await upgrade({
|
|
1774
|
+
argv: forwarded.slice(1),
|
|
1775
|
+
root: project.root,
|
|
1776
|
+
manifestFile: project.manifestFile,
|
|
1777
|
+
manifest,
|
|
1778
|
+
home,
|
|
1779
|
+
io,
|
|
1780
|
+
fetcher: options.fetcher,
|
|
1781
|
+
noDownload,
|
|
1782
|
+
ci: isCi(env)
|
|
1783
|
+
});
|
|
1784
|
+
return 0;
|
|
1785
|
+
}
|
|
1512
1786
|
const enginePin = enginePinOf(manifest);
|
|
1513
1787
|
const engineDir = await ensure(options, "engines", enginePin, home, noDownload);
|
|
1514
1788
|
for (const pin of extensionPinsOf(manifest)) {
|
|
@@ -1527,16 +1801,16 @@ async function adopt(options, forwarded, home, cwd, noDownload) {
|
|
|
1527
1801
|
if (root === void 0) {
|
|
1528
1802
|
return 0;
|
|
1529
1803
|
}
|
|
1530
|
-
const manifestFile = join7(root, ...
|
|
1804
|
+
const manifestFile = join7(root, ...MANIFEST_PATH6.split("/"));
|
|
1531
1805
|
if (existsSync4(manifestFile)) {
|
|
1532
1806
|
return 0;
|
|
1533
1807
|
}
|
|
1534
1808
|
const pin = releaseEnginePin(options.bundledPin, engine.version);
|
|
1535
|
-
|
|
1809
|
+
writeFileSync5(
|
|
1536
1810
|
manifestFile,
|
|
1537
|
-
|
|
1811
|
+
serializeManifest3({ format: MANIFEST_FORMAT, engine: pin, extensions: {} })
|
|
1538
1812
|
);
|
|
1539
|
-
options.io.out(`\u2713 ${
|
|
1813
|
+
options.io.out(`\u2713 ${MANIFEST_PATH6} pins ${pin.package} ${pin.version}`);
|
|
1540
1814
|
await ensureAdoptedEngine(
|
|
1541
1815
|
options,
|
|
1542
1816
|
{ name: pin.package, version: pin.version, integrity: pin.integrity },
|
|
@@ -1615,19 +1889,29 @@ async function addExtension(options, project, home, argv, noDownload) {
|
|
|
1615
1889
|
const engine = engineAt(dir, enginePin.name, enginePin.version);
|
|
1616
1890
|
return delegate(options, engine, onboard, home, options.cwd);
|
|
1617
1891
|
}
|
|
1618
|
-
function
|
|
1619
|
-
|
|
1892
|
+
function isRootHelp(forwarded) {
|
|
1893
|
+
const first = forwarded[0];
|
|
1894
|
+
return first === void 0 || HELP_FLAGS.has(first);
|
|
1895
|
+
}
|
|
1896
|
+
async function delegate(options, engine, forwarded, home, cwd) {
|
|
1897
|
+
const code = await options.spawn({
|
|
1620
1898
|
command: process.execPath,
|
|
1621
1899
|
args: [engine.entry, ...forwarded],
|
|
1622
1900
|
cwd,
|
|
1623
1901
|
env: { ...options.env, [PENV_HOME_VAR]: home }
|
|
1624
1902
|
});
|
|
1903
|
+
if (code === 0 && isRootHelp(forwarded)) {
|
|
1904
|
+
printLauncherCommands(options.io);
|
|
1905
|
+
}
|
|
1906
|
+
return code;
|
|
1625
1907
|
}
|
|
1626
1908
|
|
|
1627
1909
|
export {
|
|
1628
1910
|
readProviderEntries,
|
|
1629
1911
|
setProviderType,
|
|
1630
1912
|
INSTALL_COMMAND,
|
|
1913
|
+
UPGRADE_COMMAND,
|
|
1914
|
+
YES_FLAG,
|
|
1631
1915
|
MIN_PACKAGE_AGE_DAYS,
|
|
1632
1916
|
TRUST_YOUNG_FLAG,
|
|
1633
1917
|
NoProjectError,
|
|
@@ -1642,6 +1926,8 @@ export {
|
|
|
1642
1926
|
AddFlagError,
|
|
1643
1927
|
LOCAL_FLAG,
|
|
1644
1928
|
AddLocalFlagError,
|
|
1929
|
+
ExtensionNotImportableError,
|
|
1930
|
+
ExtensionUnloadableError,
|
|
1645
1931
|
LocalExtensionUnresolvedError,
|
|
1646
1932
|
AddLocalInCiError,
|
|
1647
1933
|
AddRegistryError,
|
|
@@ -1660,17 +1946,20 @@ export {
|
|
|
1660
1946
|
DeclarationNotSelfContainedError,
|
|
1661
1947
|
EnginePinUnreleasedError,
|
|
1662
1948
|
EnginePinMismatchError,
|
|
1949
|
+
UpgradeSubjectError,
|
|
1950
|
+
UpgradeFlagError,
|
|
1951
|
+
UpgradeNoDownloadError,
|
|
1952
|
+
UpgradeUnattendedError,
|
|
1953
|
+
UpgradeDeclinedError,
|
|
1954
|
+
UpgradeInstallFailedError,
|
|
1663
1955
|
EngineEntryError,
|
|
1664
1956
|
readExtensionPackage,
|
|
1665
1957
|
renderDeclaration,
|
|
1666
1958
|
declarationPath,
|
|
1667
1959
|
writeDeclaration,
|
|
1668
|
-
PENV_HOME_VAR,
|
|
1669
1960
|
HOME_META_FILE,
|
|
1670
1961
|
INTEGRITY_FILE,
|
|
1671
1962
|
NPM_UPDATE_COMMAND,
|
|
1672
|
-
penvHome,
|
|
1673
|
-
packageDir,
|
|
1674
1963
|
launcherUpdateCommand,
|
|
1675
1964
|
integrityOf,
|
|
1676
1965
|
readTarball,
|
|
@@ -1693,6 +1982,7 @@ export {
|
|
|
1693
1982
|
releaseEnginePin,
|
|
1694
1983
|
findProject,
|
|
1695
1984
|
findAdoptedRoot,
|
|
1985
|
+
upgrade,
|
|
1696
1986
|
runLauncher
|
|
1697
1987
|
};
|
|
1698
|
-
//# sourceMappingURL=chunk-
|
|
1988
|
+
//# sourceMappingURL=chunk-USYQEKPW.js.map
|