@penvhq/cli 0.9.3 → 0.9.5
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 +515 -186
- package/dist/bin.cjs.map +1 -1
- package/dist/index.cjs +436 -179
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +39 -12
- package/dist/index.d.ts +39 -12
- package/dist/index.js +425 -150
- package/dist/index.js.map +1 -1
- package/package.json +7 -7
package/dist/bin.cjs
CHANGED
|
@@ -47374,17 +47374,55 @@ var import_url = require("url");
|
|
|
47374
47374
|
var import_crypto2 = require("crypto");
|
|
47375
47375
|
var import_fs2 = require("fs");
|
|
47376
47376
|
var import_path2 = require("path");
|
|
47377
|
+
var REMEDY_ARROW = "\u2192";
|
|
47378
|
+
function framesOf(stack) {
|
|
47379
|
+
return (stack ?? "").split("\n").filter((line) => /^\s+at\s/.test(line));
|
|
47380
|
+
}
|
|
47381
|
+
function renderRefusal(error51) {
|
|
47382
|
+
const captured = error51.stack;
|
|
47383
|
+
Object.defineProperty(error51, "stack", {
|
|
47384
|
+
configurable: true,
|
|
47385
|
+
get: () => [error51.toString(), ...framesOf(captured)].join("\n"),
|
|
47386
|
+
set(value2) {
|
|
47387
|
+
Object.defineProperty(error51, "stack", { value: value2, writable: true, configurable: true });
|
|
47388
|
+
}
|
|
47389
|
+
});
|
|
47390
|
+
}
|
|
47377
47391
|
var PenvError = class extends Error {
|
|
47378
47392
|
name = "PenvError";
|
|
47379
47393
|
/** A stable, machine-readable discriminator. */
|
|
47380
47394
|
code;
|
|
47381
47395
|
/** What the user should do about it. */
|
|
47382
47396
|
remedy;
|
|
47397
|
+
/** The message alone, without the remedy the constructor folds into it. */
|
|
47398
|
+
summary;
|
|
47383
47399
|
constructor(code, message, remedy) {
|
|
47384
47400
|
super(remedy ? `${message}
|
|
47385
47401
|
${remedy}` : message);
|
|
47386
47402
|
this.code = code;
|
|
47387
47403
|
this.remedy = remedy;
|
|
47404
|
+
this.summary = message;
|
|
47405
|
+
renderRefusal(this);
|
|
47406
|
+
}
|
|
47407
|
+
/**
|
|
47408
|
+
* Drops every frame from `below` upward, so the stack shows where the
|
|
47409
|
+
* application called in rather than the path penv took inside itself. The
|
|
47410
|
+
* caller names its own entry point; nothing here guesses which files are
|
|
47411
|
+
* penv's.
|
|
47412
|
+
*/
|
|
47413
|
+
hideFramesAbove(below) {
|
|
47414
|
+
const capture = Error.captureStackTrace;
|
|
47415
|
+
if (capture !== void 0) {
|
|
47416
|
+
capture(this, below);
|
|
47417
|
+
renderRefusal(this);
|
|
47418
|
+
}
|
|
47419
|
+
return this;
|
|
47420
|
+
}
|
|
47421
|
+
/** The refusal as every penv command prints it: the message, then the remedy. */
|
|
47422
|
+
toString() {
|
|
47423
|
+
const head = `${this.name}: ${this.summary}`;
|
|
47424
|
+
return this.remedy === void 0 ? head : `${head}
|
|
47425
|
+
${REMEDY_ARROW} ${this.remedy}`;
|
|
47388
47426
|
}
|
|
47389
47427
|
};
|
|
47390
47428
|
var FilenameGrammarError = class extends PenvError {
|
|
@@ -47720,8 +47758,8 @@ var META_FORMATS = ["json", "toml", "yml"];
|
|
|
47720
47758
|
function assertNever2(value2, context) {
|
|
47721
47759
|
throw new Error(`Unhandled ${context}: ${JSON.stringify(value2)}`);
|
|
47722
47760
|
}
|
|
47723
|
-
function own(
|
|
47724
|
-
return
|
|
47761
|
+
function own(record3, key) {
|
|
47762
|
+
return record3 !== void 0 && Object.hasOwn(record3, key) ? record3[key] : void 0;
|
|
47725
47763
|
}
|
|
47726
47764
|
function retainsPrevious(provider) {
|
|
47727
47765
|
return typeof provider.readPrevious === "function";
|
|
@@ -48912,6 +48950,7 @@ var RECORDS_PATH2 = `${STATE_PATH}/records`;
|
|
|
48912
48950
|
var STATE_GITIGNORE_PATH = `${STATE_PATH}/.gitignore`;
|
|
48913
48951
|
var MANIFEST_PATH = `${STATE_PATH}/manifest.json`;
|
|
48914
48952
|
var EXTENSIONS_PATH = `${STATE_PATH}/extensions`;
|
|
48953
|
+
var LOCAL_EXTENSIONS_PATH = `${STATE_PATH}/local-extensions.json`;
|
|
48915
48954
|
var CUTOVER_FILE = "cutover.json";
|
|
48916
48955
|
var ROLLBACK_DIR = "rollback";
|
|
48917
48956
|
var CUTOVER_PATH = `${STATE_PATH}/${CUTOVER_FILE}`;
|
|
@@ -48920,6 +48959,9 @@ var ROLLBACK_DOTENV_PATH = `${ROLLBACK_PATH}/dotenv`;
|
|
|
48920
48959
|
function penvDir(projectRoot) {
|
|
48921
48960
|
return (0, import_path2.resolve)(projectRoot, PENV_DIR);
|
|
48922
48961
|
}
|
|
48962
|
+
function localExtensionsFile(projectRoot) {
|
|
48963
|
+
return (0, import_path2.resolve)(projectRoot, ...LOCAL_EXTENSIONS_PATH.split("/"));
|
|
48964
|
+
}
|
|
48923
48965
|
function recordsDir(projectRoot) {
|
|
48924
48966
|
return (0, import_path2.resolve)(projectRoot, ...RECORDS_PATH2.split("/"));
|
|
48925
48967
|
}
|
|
@@ -48964,6 +49006,33 @@ ${inside === void 0 ? "" : `!${inside}
|
|
|
48964
49006
|
${ROLLBACK_DIR}/
|
|
48965
49007
|
`;
|
|
48966
49008
|
}
|
|
49009
|
+
function invalid(problem) {
|
|
49010
|
+
return new PenvError(
|
|
49011
|
+
"LOCAL_EXTENSIONS_INVALID",
|
|
49012
|
+
`${LOCAL_EXTENSIONS_PATH} does not hold the list penv writes: ${problem}`,
|
|
49013
|
+
"It is a JSON array of package names. Delete it and run `penv add --local <package>` for each extension this project develops."
|
|
49014
|
+
);
|
|
49015
|
+
}
|
|
49016
|
+
function parseLocalExtensions(text) {
|
|
49017
|
+
let parsed;
|
|
49018
|
+
try {
|
|
49019
|
+
parsed = JSON.parse(text);
|
|
49020
|
+
} catch {
|
|
49021
|
+
throw invalid("it is not valid JSON");
|
|
49022
|
+
}
|
|
49023
|
+
if (!Array.isArray(parsed)) {
|
|
49024
|
+
throw invalid("its root is not an array");
|
|
49025
|
+
}
|
|
49026
|
+
for (const name of parsed) {
|
|
49027
|
+
if (typeof name !== "string" || name.trim() === "") {
|
|
49028
|
+
throw invalid("it holds something that is not a package name");
|
|
49029
|
+
}
|
|
49030
|
+
}
|
|
49031
|
+
return normalize(parsed);
|
|
49032
|
+
}
|
|
49033
|
+
function normalize(names) {
|
|
49034
|
+
return [...new Set(names.map((name) => name.trim()))].sort();
|
|
49035
|
+
}
|
|
48967
49036
|
var MANIFEST_FORMAT = 1;
|
|
48968
49037
|
var ENGINE_PACKAGE = "@penvhq/cli";
|
|
48969
49038
|
var OFFICIAL_SCOPE = "@penvhq/";
|
|
@@ -49969,7 +50038,7 @@ function _getBuiltinFlags(long, short, userNames, userAliases) {
|
|
|
49969
50038
|
|
|
49970
50039
|
// src/commands/artifact.ts
|
|
49971
50040
|
init_cjs_shims();
|
|
49972
|
-
var
|
|
50041
|
+
var import_node_fs7 = require("fs");
|
|
49973
50042
|
var import_node_path7 = require("path");
|
|
49974
50043
|
|
|
49975
50044
|
// ../runtime/dist/index.js
|
|
@@ -50139,11 +50208,13 @@ var RUN_MARKER = "PENV_RUN";
|
|
|
50139
50208
|
var ENVIRONMENT_VARIABLE = "PENV_ENV";
|
|
50140
50209
|
var DELIVERY_VARIABLE = "PENV_DELIVERY";
|
|
50141
50210
|
var SNAPSHOT_VARIABLE = "PENV_SNAPSHOT";
|
|
50211
|
+
var LAUNCHER_HOME = "PENV_HOME";
|
|
50142
50212
|
var CONTROL_VARIABLES = [
|
|
50143
50213
|
RUN_MARKER,
|
|
50144
50214
|
DELIVERY_VARIABLE,
|
|
50145
50215
|
SCHEMA_HARVEST_ENV,
|
|
50146
|
-
SNAPSHOT_VARIABLE
|
|
50216
|
+
SNAPSHOT_VARIABLE,
|
|
50217
|
+
LAUNCHER_HOME
|
|
50147
50218
|
];
|
|
50148
50219
|
var RESERVED_VARIABLES = [...CONTROL_VARIABLES, ENVIRONMENT_VARIABLE];
|
|
50149
50220
|
function assertDeliverableNames(refs, config2) {
|
|
@@ -50275,15 +50346,15 @@ function caseInsensitiveNames() {
|
|
|
50275
50346
|
return process.platform === "win32";
|
|
50276
50347
|
}
|
|
50277
50348
|
function childRecord(host) {
|
|
50278
|
-
const
|
|
50349
|
+
const record3 = { ...host };
|
|
50279
50350
|
if (!caseInsensitiveNames()) {
|
|
50280
|
-
return
|
|
50351
|
+
return record3;
|
|
50281
50352
|
}
|
|
50282
50353
|
const spelling = (name) => {
|
|
50283
50354
|
const upper = name.toUpperCase();
|
|
50284
|
-
return Object.keys(
|
|
50355
|
+
return Object.keys(record3).find((key) => key.toUpperCase() === upper);
|
|
50285
50356
|
};
|
|
50286
|
-
return new Proxy(
|
|
50357
|
+
return new Proxy(record3, {
|
|
50287
50358
|
get: (target, property) => typeof property === "string" ? target[spelling(property) ?? property] : Reflect.get(target, property),
|
|
50288
50359
|
set(target, property, value2) {
|
|
50289
50360
|
if (typeof property !== "string") {
|
|
@@ -50437,7 +50508,7 @@ var startChild = (invocation) => {
|
|
|
50437
50508
|
const ended = new Promise((resolve12, reject) => {
|
|
50438
50509
|
child.on("error", (cause) => {
|
|
50439
50510
|
release();
|
|
50440
|
-
reject(cannotStart(executable, cause));
|
|
50511
|
+
reject(cannotStart(executable, cause, invocation.purpose));
|
|
50441
50512
|
});
|
|
50442
50513
|
child.on("exit", (code, signal) => {
|
|
50443
50514
|
release();
|
|
@@ -50458,8 +50529,15 @@ function noCommand() {
|
|
|
50458
50529
|
"Put the command after `--`, e.g. `penv run -- pnpm dev`."
|
|
50459
50530
|
);
|
|
50460
50531
|
}
|
|
50461
|
-
function cannotStart(executable, cause) {
|
|
50532
|
+
function cannotStart(executable, cause, purpose) {
|
|
50462
50533
|
const detail = cause instanceof Error ? cause.message : String(cause);
|
|
50534
|
+
if (purpose !== void 0) {
|
|
50535
|
+
return new PenvError(
|
|
50536
|
+
"PENV_COMMAND_NOT_STARTED",
|
|
50537
|
+
`penv could not start \`${executable}\` to ${purpose}: ${detail}`,
|
|
50538
|
+
`Check that \`${executable}\` runs on its own \u2014 penv starts it the way your shell does, so it has to be on PATH. Nothing was changed.`
|
|
50539
|
+
);
|
|
50540
|
+
}
|
|
50463
50541
|
return new PenvError(
|
|
50464
50542
|
"RUN_COMMAND_NOT_STARTED",
|
|
50465
50543
|
`\`${executable}\` could not be started: ${detail}`,
|
|
@@ -50488,12 +50566,15 @@ function cmdCommandLine(resolved, args) {
|
|
|
50488
50566
|
" "
|
|
50489
50567
|
);
|
|
50490
50568
|
}
|
|
50491
|
-
function extensions(env) {
|
|
50569
|
+
function extensions(env, platform) {
|
|
50570
|
+
if (platform !== "win32") {
|
|
50571
|
+
return [""];
|
|
50572
|
+
}
|
|
50492
50573
|
const declared = env.PATHEXT ?? ".COM;.EXE;.BAT;.CMD";
|
|
50493
|
-
return [
|
|
50574
|
+
return [...declared.split(";").filter((extension) => extension.length > 0), ""];
|
|
50494
50575
|
}
|
|
50495
|
-
function findExecutable(executable, env) {
|
|
50496
|
-
const candidates = extensions(env);
|
|
50576
|
+
function findExecutable(executable, env, platform = process.platform) {
|
|
50577
|
+
const candidates = extensions(env, platform);
|
|
50497
50578
|
const isFile = (path2) => (0, import_node_fs.existsSync)(path2) && (0, import_node_fs.statSync)(path2).isFile();
|
|
50498
50579
|
if (executable.includes("/") || executable.includes("\\") || (0, import_node_path.isAbsolute)(executable)) {
|
|
50499
50580
|
return candidates.map((extension) => executable + extension).find(isFile);
|
|
@@ -50519,6 +50600,7 @@ function escapeArgument(argument, doubleEscape) {
|
|
|
50519
50600
|
|
|
50520
50601
|
// src/install.ts
|
|
50521
50602
|
var RUNTIME_PACKAGE = "@penvhq/penv";
|
|
50603
|
+
var SCHEMA_PACKAGE = "zod";
|
|
50522
50604
|
var LOCKFILES = [
|
|
50523
50605
|
["pnpm", "pnpm-lock.yaml"],
|
|
50524
50606
|
["yarn", "yarn.lock"],
|
|
@@ -50533,13 +50615,9 @@ var ADD = {
|
|
|
50533
50615
|
bun: ["bun", "add", "--exact"]
|
|
50534
50616
|
};
|
|
50535
50617
|
function engineVersion() {
|
|
50536
|
-
const
|
|
50537
|
-
|
|
50538
|
-
|
|
50539
|
-
if (typeof version2 === "string" && version2.length > 0) {
|
|
50540
|
-
return version2;
|
|
50541
|
-
}
|
|
50542
|
-
} catch {
|
|
50618
|
+
const version2 = ownManifest()?.version;
|
|
50619
|
+
if (typeof version2 === "string" && version2.length > 0) {
|
|
50620
|
+
return version2;
|
|
50543
50621
|
}
|
|
50544
50622
|
throw new PenvError(
|
|
50545
50623
|
"ENGINE_VERSION_UNREADABLE",
|
|
@@ -50547,6 +50625,29 @@ function engineVersion() {
|
|
|
50547
50625
|
`Reinstall penv, then run \`penv init\` again.`
|
|
50548
50626
|
);
|
|
50549
50627
|
}
|
|
50628
|
+
function schemaPackageVersion() {
|
|
50629
|
+
const peers = ownManifest()?.peerDependencies;
|
|
50630
|
+
const declared = peers !== null && typeof peers === "object" && !Array.isArray(peers) ? peers[SCHEMA_PACKAGE] : void 0;
|
|
50631
|
+
const floor = typeof declared === "string" ? declared.replace(/^[\^~>=\s]+/, "").trim() : "";
|
|
50632
|
+
if (floor.length > 0) {
|
|
50633
|
+
return floor;
|
|
50634
|
+
}
|
|
50635
|
+
throw new PenvError(
|
|
50636
|
+
"ENGINE_PEER_UNREADABLE",
|
|
50637
|
+
`penv could not read its own \`${SCHEMA_PACKAGE}\` peer range, so it cannot say which ${SCHEMA_PACKAGE} this project needs`,
|
|
50638
|
+
`Reinstall penv, then run \`penv init\` again.`
|
|
50639
|
+
);
|
|
50640
|
+
}
|
|
50641
|
+
function ownManifest() {
|
|
50642
|
+
try {
|
|
50643
|
+
const parsed = JSON.parse(
|
|
50644
|
+
(0, import_node_fs2.readFileSync)(new URL("../package.json", importMetaUrl), "utf8")
|
|
50645
|
+
);
|
|
50646
|
+
return parsed !== null && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : void 0;
|
|
50647
|
+
} catch {
|
|
50648
|
+
return void 0;
|
|
50649
|
+
}
|
|
50650
|
+
}
|
|
50550
50651
|
function detectPackageManager(root) {
|
|
50551
50652
|
for (const [manager, lockfile] of LOCKFILES) {
|
|
50552
50653
|
if ((0, import_node_fs2.existsSync)((0, import_node_path2.join)(root, lockfile))) {
|
|
@@ -50575,12 +50676,12 @@ function manifestOf(root) {
|
|
|
50575
50676
|
return void 0;
|
|
50576
50677
|
}
|
|
50577
50678
|
}
|
|
50578
|
-
function declaredVersion(root) {
|
|
50679
|
+
function declaredVersion(root, name) {
|
|
50579
50680
|
const manifest = manifestOf(root);
|
|
50580
50681
|
for (const field of ["dependencies", "devDependencies"]) {
|
|
50581
50682
|
const block = manifest?.[field];
|
|
50582
50683
|
if (block !== null && typeof block === "object" && !Array.isArray(block)) {
|
|
50583
|
-
const version2 = block[
|
|
50684
|
+
const version2 = block[name];
|
|
50584
50685
|
if (typeof version2 === "string") {
|
|
50585
50686
|
return version2;
|
|
50586
50687
|
}
|
|
@@ -50593,27 +50694,61 @@ function planInstall(root, version2 = engineVersion()) {
|
|
|
50593
50694
|
const lockfile = LOCKFILES.find(
|
|
50594
50695
|
([name, file2]) => name === manager && (0, import_node_fs2.existsSync)((0, import_node_path2.join)(root, file2))
|
|
50595
50696
|
)?.[1];
|
|
50596
|
-
const
|
|
50697
|
+
const runtimeDeclared = declaredVersion(root, RUNTIME_PACKAGE);
|
|
50698
|
+
const zodDeclared = declaredVersion(root, SCHEMA_PACKAGE);
|
|
50699
|
+
const packages = [
|
|
50700
|
+
{
|
|
50701
|
+
name: RUNTIME_PACKAGE,
|
|
50702
|
+
version: version2,
|
|
50703
|
+
...runtimeDeclared === void 0 ? {} : { declared: runtimeDeclared },
|
|
50704
|
+
satisfied: runtimeDeclared === version2
|
|
50705
|
+
},
|
|
50706
|
+
{
|
|
50707
|
+
name: SCHEMA_PACKAGE,
|
|
50708
|
+
version: schemaPackageVersion(),
|
|
50709
|
+
...zodDeclared === void 0 ? {} : { declared: zodDeclared },
|
|
50710
|
+
// Any declared zod counts: which zod a project uses is the project's
|
|
50711
|
+
// decision, and penv is here to make sure there is one, not to move it.
|
|
50712
|
+
satisfied: zodDeclared !== void 0
|
|
50713
|
+
}
|
|
50714
|
+
];
|
|
50715
|
+
const pending = packages.filter((entry) => !entry.satisfied);
|
|
50716
|
+
const specs = (pending.length === 0 ? packages : pending).map(
|
|
50717
|
+
(entry) => `${entry.name}@${entry.version}`
|
|
50718
|
+
);
|
|
50597
50719
|
return {
|
|
50598
50720
|
root,
|
|
50599
50721
|
manager,
|
|
50600
|
-
|
|
50601
|
-
|
|
50602
|
-
command: [...ADD[manager], `${RUNTIME_PACKAGE}@${version2}`],
|
|
50722
|
+
packages,
|
|
50723
|
+
command: [...ADD[manager], ...specs],
|
|
50603
50724
|
...lockfile === void 0 ? {} : { lockfile },
|
|
50604
|
-
|
|
50605
|
-
satisfied: declared === version2
|
|
50725
|
+
satisfied: pending.length === 0
|
|
50606
50726
|
};
|
|
50607
50727
|
}
|
|
50728
|
+
function describe4(entry) {
|
|
50729
|
+
return `${entry.name} ${entry.version}`;
|
|
50730
|
+
}
|
|
50608
50731
|
function renderInstallPlan(plan2) {
|
|
50609
50732
|
if (plan2.satisfied) {
|
|
50610
|
-
return [
|
|
50733
|
+
return [
|
|
50734
|
+
`package.json already has ${plan2.packages.map(describe4).join(" and ")} \u2014 nothing to install.`
|
|
50735
|
+
];
|
|
50611
50736
|
}
|
|
50612
|
-
const
|
|
50737
|
+
const pending = plan2.packages.filter((entry) => !entry.satisfied);
|
|
50738
|
+
const added = pending.filter((entry) => entry.declared === void 0);
|
|
50739
|
+
const replaced = pending.filter((entry) => entry.declared !== void 0);
|
|
50613
50740
|
return [
|
|
50614
50741
|
"package.json",
|
|
50615
|
-
...
|
|
50616
|
-
|
|
50742
|
+
...added.length === 0 ? [] : [
|
|
50743
|
+
' + "dependencies": {',
|
|
50744
|
+
...added.map((entry) => ` + "${entry.name}": "${entry.version}"`),
|
|
50745
|
+
" + }"
|
|
50746
|
+
],
|
|
50747
|
+
...replaced.flatMap((entry) => [
|
|
50748
|
+
` - "${entry.name}": "${entry.declared}"`,
|
|
50749
|
+
` + "${entry.name}": "${entry.version}"`
|
|
50750
|
+
]),
|
|
50751
|
+
...plan2.lockfile === void 0 ? [] : [plan2.lockfile, ...pending.map((entry) => ` + ${entry.name}@${entry.version}`)],
|
|
50617
50752
|
"",
|
|
50618
50753
|
`Run with: ${plan2.command.join(" ")}`
|
|
50619
50754
|
];
|
|
@@ -50622,7 +50757,8 @@ var installWithPackageManager = async (plan2) => {
|
|
|
50622
50757
|
const child = startChild({
|
|
50623
50758
|
command: plan2.command,
|
|
50624
50759
|
env: process.env,
|
|
50625
|
-
cwd: plan2.root
|
|
50760
|
+
cwd: plan2.root,
|
|
50761
|
+
purpose: `install ${plan2.packages.map(describe4).join(" and ")}`
|
|
50626
50762
|
});
|
|
50627
50763
|
const ended = await child.ended;
|
|
50628
50764
|
if (ended.exitCode !== 0 || ended.signal !== null) {
|
|
@@ -50639,7 +50775,7 @@ function installFailed(plan2) {
|
|
|
50639
50775
|
|
|
50640
50776
|
// src/project.ts
|
|
50641
50777
|
init_cjs_shims();
|
|
50642
|
-
var
|
|
50778
|
+
var import_node_fs4 = require("fs");
|
|
50643
50779
|
var import_node_path4 = require("path");
|
|
50644
50780
|
|
|
50645
50781
|
// src/env-flags.ts
|
|
@@ -50702,6 +50838,7 @@ function environmentFromShorthand(config2, candidates, explicit) {
|
|
|
50702
50838
|
|
|
50703
50839
|
// src/registry.ts
|
|
50704
50840
|
init_cjs_shims();
|
|
50841
|
+
var import_node_fs3 = require("fs");
|
|
50705
50842
|
var import_node_module = require("module");
|
|
50706
50843
|
var import_node_path3 = require("path");
|
|
50707
50844
|
var import_node_url = require("url");
|
|
@@ -50889,16 +51026,40 @@ async function loadPluginProvider(type, context) {
|
|
|
50889
51026
|
assertSatisfiesContract(provider, type);
|
|
50890
51027
|
return provider;
|
|
50891
51028
|
}
|
|
50892
|
-
function assertProvidersRegistered(config2, projectRoot) {
|
|
51029
|
+
function assertProvidersRegistered(config2, projectRoot, options) {
|
|
51030
|
+
const local = localExtensions(projectRoot);
|
|
51031
|
+
const ci = options?.ci ?? isCi(process.env.CI);
|
|
50893
51032
|
for (const [environment, provider] of Object.entries(config2.providers)) {
|
|
50894
51033
|
if (isProviderRegistered(provider.type)) {
|
|
50895
51034
|
continue;
|
|
50896
51035
|
}
|
|
51036
|
+
if (ci && local.includes(provider.type)) {
|
|
51037
|
+
throw localExtensionInCi(provider.type, environment);
|
|
51038
|
+
}
|
|
50897
51039
|
if (resolvePlugin(provider.type, projectRoot) === void 0) {
|
|
50898
51040
|
throw unknownProvider(provider.type, environment);
|
|
50899
51041
|
}
|
|
50900
51042
|
}
|
|
50901
51043
|
}
|
|
51044
|
+
function localExtensions(projectRoot) {
|
|
51045
|
+
let text;
|
|
51046
|
+
try {
|
|
51047
|
+
text = (0, import_node_fs3.readFileSync)(localExtensionsFile(projectRoot), "utf8");
|
|
51048
|
+
} catch {
|
|
51049
|
+
return [];
|
|
51050
|
+
}
|
|
51051
|
+
return parseLocalExtensions(text);
|
|
51052
|
+
}
|
|
51053
|
+
function isCi(value2) {
|
|
51054
|
+
return value2 !== void 0 && value2 !== "" && value2 !== "0" && value2.toLowerCase() !== "false";
|
|
51055
|
+
}
|
|
51056
|
+
function localExtensionInCi(type, environment) {
|
|
51057
|
+
return new PenvError(
|
|
51058
|
+
"LOCAL_EXTENSION_IN_CI",
|
|
51059
|
+
`The provider \`${type}\` for environment ${environment} is a local extension, and this is CI`,
|
|
51060
|
+
`${LOCAL_EXTENSIONS_PATH} records it as a package this project develops, so nothing pins the bytes CI would run. Publish it and run \`penv add ${type}\` to pin a release.`
|
|
51061
|
+
);
|
|
51062
|
+
}
|
|
50902
51063
|
function resolvePlugin(specifier, fromDir) {
|
|
50903
51064
|
try {
|
|
50904
51065
|
const require2 = (0, import_node_module.createRequire)((0, import_node_path3.resolve)(fromDir, "noop.js"));
|
|
@@ -50936,7 +51097,7 @@ function unknownProvider(type, environment) {
|
|
|
50936
51097
|
return new PenvError(
|
|
50937
51098
|
"UNKNOWN_PROVIDER",
|
|
50938
51099
|
`The provider \`${type}\`${where} in penv.config.ts is not installed in this project`,
|
|
50939
|
-
`
|
|
51100
|
+
`A provider's \`type\` is the package penv imports, so it has to resolve from this project: install it with \`npm i ${type}\`, or \u2014 if this repository is the one that builds it \u2014 run \`penv add --local ${type}\` once it is a dependency of the root. The CLI ships ${preinstalled} pre-installed.`
|
|
50940
51101
|
);
|
|
50941
51102
|
}
|
|
50942
51103
|
|
|
@@ -50966,10 +51127,10 @@ function localTree(project) {
|
|
|
50966
51127
|
}
|
|
50967
51128
|
function selfContainedSchemaModule(root, schemaFile) {
|
|
50968
51129
|
const file2 = (0, import_node_path4.join)(root, ...schemaFile.split("/"));
|
|
50969
|
-
if (!(0,
|
|
51130
|
+
if (!(0, import_node_fs4.existsSync)(file2)) {
|
|
50970
51131
|
return void 0;
|
|
50971
51132
|
}
|
|
50972
|
-
const source = (0,
|
|
51133
|
+
const source = (0, import_node_fs4.readFileSync)(file2, "utf8");
|
|
50973
51134
|
return source.includes("PenvSchemaShape") || source.includes("z.object") ? schemaFile : void 0;
|
|
50974
51135
|
}
|
|
50975
51136
|
function schemaShapeFileOf(project) {
|
|
@@ -51206,10 +51367,7 @@ function writeError(lines) {
|
|
|
51206
51367
|
}
|
|
51207
51368
|
function reportError(error51) {
|
|
51208
51369
|
if (error51 instanceof PenvError) {
|
|
51209
|
-
|
|
51210
|
-
${error51.remedy}`;
|
|
51211
|
-
const message = suffix !== void 0 && error51.message.endsWith(suffix) ? error51.message.slice(0, -suffix.length) : error51.message;
|
|
51212
|
-
process.stderr.write(`${err.red(CROSS)} ${message}
|
|
51370
|
+
process.stderr.write(`${err.red(CROSS)} ${error51.summary}
|
|
51213
51371
|
`);
|
|
51214
51372
|
if (error51.remedy !== void 0) {
|
|
51215
51373
|
process.stderr.write(` ${err.cyan("\u2192")} ${error51.remedy}
|
|
@@ -51240,13 +51398,13 @@ async function guard(run) {
|
|
|
51240
51398
|
|
|
51241
51399
|
// src/commands/run.ts
|
|
51242
51400
|
init_cjs_shims();
|
|
51243
|
-
var
|
|
51401
|
+
var import_node_fs6 = require("fs");
|
|
51244
51402
|
var import_node_module2 = require("module");
|
|
51245
51403
|
var import_node_path6 = require("path");
|
|
51246
51404
|
|
|
51247
51405
|
// src/dotenv-files.ts
|
|
51248
51406
|
init_cjs_shims();
|
|
51249
|
-
var
|
|
51407
|
+
var import_node_fs5 = require("fs");
|
|
51250
51408
|
var SHARED = ".env";
|
|
51251
51409
|
var LOCAL2 = "local";
|
|
51252
51410
|
var NOT_ENVIRONMENTS = [
|
|
@@ -51305,7 +51463,7 @@ function order(file2) {
|
|
|
51305
51463
|
function discoverDotenvFiles(root) {
|
|
51306
51464
|
let entries;
|
|
51307
51465
|
try {
|
|
51308
|
-
entries = (0,
|
|
51466
|
+
entries = (0, import_node_fs5.readdirSync)(root, { withFileTypes: true }).filter((entry) => entry.isFile()).map((entry) => entry.name);
|
|
51309
51467
|
} catch {
|
|
51310
51468
|
return [];
|
|
51311
51469
|
}
|
|
@@ -52040,9 +52198,9 @@ function packageManifest(specifier, root) {
|
|
|
52040
52198
|
}
|
|
52041
52199
|
for (; ; ) {
|
|
52042
52200
|
const file2 = (0, import_node_path6.join)(directory, "package.json");
|
|
52043
|
-
if ((0,
|
|
52201
|
+
if ((0, import_node_fs6.existsSync)(file2)) {
|
|
52044
52202
|
try {
|
|
52045
|
-
const parsed = JSON.parse((0,
|
|
52203
|
+
const parsed = JSON.parse((0, import_node_fs6.readFileSync)(file2, "utf8"));
|
|
52046
52204
|
if (isPlainObject4(parsed) && parsed.name === specifier) {
|
|
52047
52205
|
return parsed;
|
|
52048
52206
|
}
|
|
@@ -52115,7 +52273,7 @@ function snapshotPath(host) {
|
|
|
52115
52273
|
}
|
|
52116
52274
|
function readSnapshot(path) {
|
|
52117
52275
|
try {
|
|
52118
|
-
return (0,
|
|
52276
|
+
return (0, import_node_fs6.readFileSync)(path, "utf8");
|
|
52119
52277
|
} catch {
|
|
52120
52278
|
throw new PenvError(
|
|
52121
52279
|
"RUN_SNAPSHOT_MISSING",
|
|
@@ -52194,11 +52352,11 @@ function watchProject(project, onChange) {
|
|
|
52194
52352
|
timer = setTimeout(onChange, DEBOUNCE_MS);
|
|
52195
52353
|
};
|
|
52196
52354
|
const add = (target, recursive, only) => {
|
|
52197
|
-
if (!(0,
|
|
52355
|
+
if (!(0, import_node_fs6.existsSync)(target)) {
|
|
52198
52356
|
return;
|
|
52199
52357
|
}
|
|
52200
52358
|
try {
|
|
52201
|
-
const watcher = (0,
|
|
52359
|
+
const watcher = (0, import_node_fs6.watch)(target, { recursive }, (_event, filename) => {
|
|
52202
52360
|
if (only !== void 0 && (filename === null || (0, import_node_path6.basename)(filename) !== only)) {
|
|
52203
52361
|
return;
|
|
52204
52362
|
}
|
|
@@ -52461,8 +52619,8 @@ ${lines}`,
|
|
|
52461
52619
|
keySource: keySourceIdentifier(project.config, environment),
|
|
52462
52620
|
values
|
|
52463
52621
|
};
|
|
52464
|
-
(0,
|
|
52465
|
-
(0,
|
|
52622
|
+
(0, import_node_fs7.mkdirSync)((0, import_node_path7.dirname)(file2), { recursive: true });
|
|
52623
|
+
(0, import_node_fs7.writeFileSync)(file2, serializeArtifact(artifact), "utf8");
|
|
52466
52624
|
const inside = (0, import_node_path7.relative)(project.root, file2);
|
|
52467
52625
|
return {
|
|
52468
52626
|
file: file2,
|
|
@@ -52532,7 +52690,7 @@ init_cjs_shims();
|
|
|
52532
52690
|
|
|
52533
52691
|
// src/cutover.ts
|
|
52534
52692
|
init_cjs_shims();
|
|
52535
|
-
var
|
|
52693
|
+
var import_node_fs8 = require("fs");
|
|
52536
52694
|
var import_node_path8 = require("path");
|
|
52537
52695
|
var CUTOVER_FORMAT = 1;
|
|
52538
52696
|
function fileFor(root, relativePosix) {
|
|
@@ -52550,7 +52708,7 @@ function cutoverRoot(cwd) {
|
|
|
52550
52708
|
}
|
|
52551
52709
|
function bundledFiles(root) {
|
|
52552
52710
|
try {
|
|
52553
|
-
return (0,
|
|
52711
|
+
return (0, import_node_fs8.readdirSync)(bundleDir(root)).sort();
|
|
52554
52712
|
} catch {
|
|
52555
52713
|
return [];
|
|
52556
52714
|
}
|
|
@@ -52560,32 +52718,32 @@ function bundleUnresolved(root) {
|
|
|
52560
52718
|
}
|
|
52561
52719
|
function readCutover(root) {
|
|
52562
52720
|
const file2 = cutoverFile(root);
|
|
52563
|
-
if (!(0,
|
|
52721
|
+
if (!(0, import_node_fs8.existsSync)(file2)) {
|
|
52564
52722
|
return void 0;
|
|
52565
52723
|
}
|
|
52566
52724
|
let parsed;
|
|
52567
52725
|
try {
|
|
52568
|
-
parsed = JSON.parse((0,
|
|
52726
|
+
parsed = JSON.parse((0, import_node_fs8.readFileSync)(file2, "utf8"));
|
|
52569
52727
|
} catch {
|
|
52570
52728
|
throw unreadable("it is not JSON");
|
|
52571
52729
|
}
|
|
52572
52730
|
if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
52573
52731
|
throw unreadable("it is not an object");
|
|
52574
52732
|
}
|
|
52575
|
-
const
|
|
52576
|
-
if (
|
|
52733
|
+
const record3 = parsed;
|
|
52734
|
+
if (record3.format !== CUTOVER_FORMAT) {
|
|
52577
52735
|
throw unreadable(
|
|
52578
|
-
`it is format ${JSON.stringify(
|
|
52736
|
+
`it is format ${JSON.stringify(record3.format)}, and penv reads format ${CUTOVER_FORMAT}`
|
|
52579
52737
|
);
|
|
52580
52738
|
}
|
|
52581
|
-
const files =
|
|
52739
|
+
const files = record3.files;
|
|
52582
52740
|
if (!Array.isArray(files) || files.some((name) => typeof name !== "string")) {
|
|
52583
52741
|
throw unreadable("it lists no filenames");
|
|
52584
52742
|
}
|
|
52585
|
-
const environments = Array.isArray(
|
|
52743
|
+
const environments = Array.isArray(record3.environments) ? record3.environments.filter((name) => typeof name === "string") : [];
|
|
52586
52744
|
return {
|
|
52587
52745
|
format: CUTOVER_FORMAT,
|
|
52588
|
-
movedAt: typeof
|
|
52746
|
+
movedAt: typeof record3.movedAt === "string" ? record3.movedAt : "",
|
|
52589
52747
|
files,
|
|
52590
52748
|
environments
|
|
52591
52749
|
};
|
|
@@ -52618,12 +52776,12 @@ function bundleDotenvFiles(root, files, environments, now = /* @__PURE__ */ new
|
|
|
52618
52776
|
environments: [...environments]
|
|
52619
52777
|
};
|
|
52620
52778
|
const file2 = cutoverFile(root);
|
|
52621
|
-
(0,
|
|
52622
|
-
(0,
|
|
52779
|
+
(0, import_node_fs8.mkdirSync)((0, import_node_path8.dirname)(file2), { recursive: true });
|
|
52780
|
+
(0, import_node_fs8.writeFileSync)(file2, serializeCutover(cutover), "utf8");
|
|
52623
52781
|
const bundle = bundleDir(root);
|
|
52624
|
-
(0,
|
|
52782
|
+
(0, import_node_fs8.mkdirSync)(bundle, { recursive: true });
|
|
52625
52783
|
for (const name of files) {
|
|
52626
|
-
(0,
|
|
52784
|
+
(0, import_node_fs8.renameSync)((0, import_node_path8.join)(root, name), (0, import_node_path8.join)(bundle, name));
|
|
52627
52785
|
}
|
|
52628
52786
|
return cutover;
|
|
52629
52787
|
}
|
|
@@ -52642,7 +52800,7 @@ function runUndo(options) {
|
|
|
52642
52800
|
const names = [...recorded, ...bundled.filter((name) => !recorded.includes(name))];
|
|
52643
52801
|
const bundle = bundleDir(root);
|
|
52644
52802
|
const held = new Set(bundled);
|
|
52645
|
-
const occupied2 = names.filter((name) => held.has(name) && (0,
|
|
52803
|
+
const occupied2 = names.filter((name) => held.has(name) && (0, import_node_fs8.existsSync)((0, import_node_path8.join)(root, name)));
|
|
52646
52804
|
if (occupied2.length > 0) {
|
|
52647
52805
|
const listed = occupied2.join(", ");
|
|
52648
52806
|
const many = occupied2.length > 1;
|
|
@@ -52657,9 +52815,9 @@ function runUndo(options) {
|
|
|
52657
52815
|
const missing = [];
|
|
52658
52816
|
for (const name of names) {
|
|
52659
52817
|
if (held.has(name)) {
|
|
52660
|
-
(0,
|
|
52818
|
+
(0, import_node_fs8.renameSync)((0, import_node_path8.join)(bundle, name), (0, import_node_path8.join)(root, name));
|
|
52661
52819
|
restored.push(name);
|
|
52662
|
-
} else if ((0,
|
|
52820
|
+
} else if ((0, import_node_fs8.existsSync)((0, import_node_path8.join)(root, name))) {
|
|
52663
52821
|
alreadyBack.push(name);
|
|
52664
52822
|
} else {
|
|
52665
52823
|
missing.push(name);
|
|
@@ -52671,13 +52829,13 @@ function runUndo(options) {
|
|
|
52671
52829
|
function runCleanup(options) {
|
|
52672
52830
|
const root = cutoverRoot(options.cwd);
|
|
52673
52831
|
const held = bundledFiles(root);
|
|
52674
|
-
const cleaned = held.length > 0 || (0,
|
|
52832
|
+
const cleaned = held.length > 0 || (0, import_node_fs8.existsSync)(cutoverFile(root)) || (0, import_node_fs8.existsSync)(fileFor(root, ROLLBACK_PATH));
|
|
52675
52833
|
removeBundle(root);
|
|
52676
52834
|
return { root, removed: held, cleaned };
|
|
52677
52835
|
}
|
|
52678
52836
|
function removeBundle(root) {
|
|
52679
|
-
(0,
|
|
52680
|
-
(0,
|
|
52837
|
+
(0, import_node_fs8.rmSync)(fileFor(root, ROLLBACK_PATH), { recursive: true, force: true });
|
|
52838
|
+
(0, import_node_fs8.rmSync)(cutoverFile(root), { force: true });
|
|
52681
52839
|
}
|
|
52682
52840
|
|
|
52683
52841
|
// src/commands/cleanup.ts
|
|
@@ -52713,7 +52871,7 @@ var cleanupCommand = defineCommand({
|
|
|
52713
52871
|
|
|
52714
52872
|
// src/commands/doctor.ts
|
|
52715
52873
|
init_cjs_shims();
|
|
52716
|
-
var
|
|
52874
|
+
var import_node_fs9 = require("fs");
|
|
52717
52875
|
var import_node_path9 = require("path");
|
|
52718
52876
|
|
|
52719
52877
|
// src/commands/push.ts
|
|
@@ -53157,6 +53315,7 @@ async function runDoctor(options) {
|
|
|
53157
53315
|
findings.push(...unusedFindings(drift));
|
|
53158
53316
|
}
|
|
53159
53317
|
findings.push(...fallbackFindings(subjects, environment));
|
|
53318
|
+
findings.push(...secrecyFindings(subjects, environment));
|
|
53160
53319
|
findings.push(...plaintextSecretFindings(subjects, environment));
|
|
53161
53320
|
findings.push(...publicSecretFindings(subjects, environment, project.config));
|
|
53162
53321
|
findings.push(...encryptionFindings(subjects, environment));
|
|
@@ -53169,6 +53328,7 @@ async function runDoctor(options) {
|
|
|
53169
53328
|
}
|
|
53170
53329
|
findings.push(...await providerDriftFindings(project, environment, options.source));
|
|
53171
53330
|
findings.push(...await projectionFindings(project, environment, options.projection));
|
|
53331
|
+
findings.push(...localExtensionFindings(project));
|
|
53172
53332
|
findings.push(...artifactFindings(project));
|
|
53173
53333
|
findings.push({
|
|
53174
53334
|
check: "provider",
|
|
@@ -53306,6 +53466,31 @@ function fallbackFindings(subjects, environment) {
|
|
|
53306
53466
|
}
|
|
53307
53467
|
];
|
|
53308
53468
|
}
|
|
53469
|
+
function secrecyFindings(subjects, environment) {
|
|
53470
|
+
const undeclared = subjects.filter(
|
|
53471
|
+
({ meta: meta3 }) => effectiveMeta(meta3, environment).secret === void 0
|
|
53472
|
+
);
|
|
53473
|
+
if (undeclared.length === 0) {
|
|
53474
|
+
return [
|
|
53475
|
+
{
|
|
53476
|
+
check: "secrecy-undeclared",
|
|
53477
|
+
severity: "pass",
|
|
53478
|
+
label: "Secrecy policy",
|
|
53479
|
+
subject: subjects.length === 0 ? `no parameter resolves for ${environment}` : `every parameter declares whether it is secret for ${environment}`
|
|
53480
|
+
}
|
|
53481
|
+
];
|
|
53482
|
+
}
|
|
53483
|
+
return [
|
|
53484
|
+
{
|
|
53485
|
+
check: "secrecy-undeclared",
|
|
53486
|
+
severity: "unknown",
|
|
53487
|
+
label: "Secrecy policy",
|
|
53488
|
+
subject: `${undeclared.length} of ${subjects.length} declare neither way for ${environment}`,
|
|
53489
|
+
detail: "penv was never told which of these values must be encrypted",
|
|
53490
|
+
remedy: `declare \`"secret": true\` or \`"secret": false\` in a parameter's meta file, ${RECORDS_PATH2}/<name>.json`
|
|
53491
|
+
}
|
|
53492
|
+
];
|
|
53493
|
+
}
|
|
53309
53494
|
function plaintextSecretFindings(subjects, environment) {
|
|
53310
53495
|
const secrets = subjects.filter(({ meta: meta3 }) => isSecret(meta3, environment));
|
|
53311
53496
|
const findings = [];
|
|
@@ -53609,7 +53794,7 @@ function looksLikeArtifact(text) {
|
|
|
53609
53794
|
function scannableFiles(directory, out2) {
|
|
53610
53795
|
let entries;
|
|
53611
53796
|
try {
|
|
53612
|
-
entries = (0,
|
|
53797
|
+
entries = (0, import_node_fs9.readdirSync)(directory, { withFileTypes: true });
|
|
53613
53798
|
} catch {
|
|
53614
53799
|
return;
|
|
53615
53800
|
}
|
|
@@ -53626,6 +53811,29 @@ function scannableFiles(directory, out2) {
|
|
|
53626
53811
|
}
|
|
53627
53812
|
}
|
|
53628
53813
|
}
|
|
53814
|
+
function localExtensionFindings(project) {
|
|
53815
|
+
const names = localExtensions(project.root);
|
|
53816
|
+
if (names.length === 0) {
|
|
53817
|
+
return [
|
|
53818
|
+
{
|
|
53819
|
+
check: "local-extension",
|
|
53820
|
+
severity: "pass",
|
|
53821
|
+
label: "Extensions",
|
|
53822
|
+
subject: "every extension this project names is pinned"
|
|
53823
|
+
}
|
|
53824
|
+
];
|
|
53825
|
+
}
|
|
53826
|
+
return [
|
|
53827
|
+
{
|
|
53828
|
+
check: "local-extension",
|
|
53829
|
+
severity: "unknown",
|
|
53830
|
+
label: "Extensions",
|
|
53831
|
+
subject: names.join(", "),
|
|
53832
|
+
detail: "resolved from this project's node_modules \u2014 no release, no pinned bytes",
|
|
53833
|
+
remedy: `publish it and run \`penv add ${names[0]}\` when this stops being a development path`
|
|
53834
|
+
}
|
|
53835
|
+
];
|
|
53836
|
+
}
|
|
53629
53837
|
function artifactFindings(project) {
|
|
53630
53838
|
const files = [];
|
|
53631
53839
|
scannableFiles(project.root, files);
|
|
@@ -53633,10 +53841,10 @@ function artifactFindings(project) {
|
|
|
53633
53841
|
for (const file2 of files) {
|
|
53634
53842
|
let text;
|
|
53635
53843
|
try {
|
|
53636
|
-
if ((0,
|
|
53844
|
+
if ((0, import_node_fs9.statSync)(file2).size > ARTIFACT_SCAN_LIMIT) {
|
|
53637
53845
|
continue;
|
|
53638
53846
|
}
|
|
53639
|
-
text = (0,
|
|
53847
|
+
text = (0, import_node_fs9.readFileSync)(file2, "utf8");
|
|
53640
53848
|
} catch {
|
|
53641
53849
|
continue;
|
|
53642
53850
|
}
|
|
@@ -54394,7 +54602,7 @@ var fillCommand = defineCommand({
|
|
|
54394
54602
|
|
|
54395
54603
|
// src/commands/generate.ts
|
|
54396
54604
|
init_cjs_shims();
|
|
54397
|
-
var
|
|
54605
|
+
var import_node_fs10 = require("fs");
|
|
54398
54606
|
var import_node_path10 = require("path");
|
|
54399
54607
|
var DEFAULT_OUTPUT = ".env";
|
|
54400
54608
|
function entriesFor(project, environment, allowDecrypt) {
|
|
@@ -54441,7 +54649,7 @@ function runGenerate(options) {
|
|
|
54441
54649
|
const environment = targetEnvironment(project, options.environment, options.envFlags);
|
|
54442
54650
|
const { entries, decrypted } = entriesFor(project, environment, options.allowDecrypt === true);
|
|
54443
54651
|
const file2 = options.out === void 0 ? (0, import_node_path10.resolve)(project.root, DEFAULT_OUTPUT) : (0, import_node_path10.isAbsolute)(options.out) ? options.out : (0, import_node_path10.resolve)(options.cwd, options.out);
|
|
54444
|
-
(0,
|
|
54652
|
+
(0, import_node_fs10.writeFileSync)(file2, serializeDotenv(entries), "utf8");
|
|
54445
54653
|
return { file: file2, environment, entries: entries.length, decrypted };
|
|
54446
54654
|
}
|
|
54447
54655
|
function displayPath2(cwd, file2) {
|
|
@@ -54579,8 +54787,8 @@ var getCommand = defineCommand({
|
|
|
54579
54787
|
|
|
54580
54788
|
// src/commands/import.ts
|
|
54581
54789
|
init_cjs_shims();
|
|
54582
|
-
var
|
|
54583
|
-
var
|
|
54790
|
+
var import_node_fs14 = require("fs");
|
|
54791
|
+
var import_node_path14 = require("path");
|
|
54584
54792
|
|
|
54585
54793
|
// src/adopt.ts
|
|
54586
54794
|
init_cjs_shims();
|
|
@@ -54649,7 +54857,7 @@ function writeEntries(tree, entries, refs, scope) {
|
|
|
54649
54857
|
|
|
54650
54858
|
// src/detect.ts
|
|
54651
54859
|
init_cjs_shims();
|
|
54652
|
-
var
|
|
54860
|
+
var import_node_fs11 = require("fs");
|
|
54653
54861
|
var import_node_path11 = require("path");
|
|
54654
54862
|
var SIGNATURES = [
|
|
54655
54863
|
{ name: "Next.js", packages: ["next"], publicPrefixes: ["NEXT_PUBLIC_"] },
|
|
@@ -54666,7 +54874,7 @@ var SIGNATURES = [
|
|
|
54666
54874
|
function exportsSchema(file2) {
|
|
54667
54875
|
let source;
|
|
54668
54876
|
try {
|
|
54669
|
-
source = (0,
|
|
54877
|
+
source = (0, import_node_fs11.readFileSync)(file2, "utf8");
|
|
54670
54878
|
} catch {
|
|
54671
54879
|
return false;
|
|
54672
54880
|
}
|
|
@@ -54678,7 +54886,7 @@ function exportsSchema(file2) {
|
|
|
54678
54886
|
}
|
|
54679
54887
|
function occupied(cwd, relative5) {
|
|
54680
54888
|
const file2 = (0, import_node_path11.join)(cwd, ...relative5.split("/"));
|
|
54681
|
-
return (0,
|
|
54889
|
+
return (0, import_node_fs11.existsSync)(file2) && !exportsSchema(file2);
|
|
54682
54890
|
}
|
|
54683
54891
|
function schemaFileFor(cwd) {
|
|
54684
54892
|
const dir = srcPrefix(cwd);
|
|
@@ -54693,7 +54901,7 @@ function schemaFileFor(cwd) {
|
|
|
54693
54901
|
return { file: DEFAULT_SCHEMA_FILE, displaced: preferred };
|
|
54694
54902
|
}
|
|
54695
54903
|
function srcPrefix(cwd) {
|
|
54696
|
-
return (0,
|
|
54904
|
+
return (0, import_node_fs11.existsSync)((0, import_node_path11.join)(cwd, "src")) ? "src/" : "";
|
|
54697
54905
|
}
|
|
54698
54906
|
function dependenciesOf(cwd) {
|
|
54699
54907
|
const manifest = manifestOf2(cwd);
|
|
@@ -54713,12 +54921,12 @@ function dependenciesOf(cwd) {
|
|
|
54713
54921
|
}
|
|
54714
54922
|
function manifestOf2(cwd) {
|
|
54715
54923
|
const file2 = (0, import_node_path11.join)(cwd, "package.json");
|
|
54716
|
-
if (!(0,
|
|
54924
|
+
if (!(0, import_node_fs11.existsSync)(file2)) {
|
|
54717
54925
|
return void 0;
|
|
54718
54926
|
}
|
|
54719
54927
|
let manifest;
|
|
54720
54928
|
try {
|
|
54721
|
-
manifest = JSON.parse((0,
|
|
54929
|
+
manifest = JSON.parse((0, import_node_fs11.readFileSync)(file2, "utf8"));
|
|
54722
54930
|
} catch {
|
|
54723
54931
|
return void 0;
|
|
54724
54932
|
}
|
|
@@ -54734,7 +54942,7 @@ function detectFramework(cwd) {
|
|
|
54734
54942
|
return detectedFrom(cwd, signature.name, signature.publicPrefixes);
|
|
54735
54943
|
}
|
|
54736
54944
|
}
|
|
54737
|
-
if ((0,
|
|
54945
|
+
if ((0, import_node_fs11.existsSync)((0, import_node_path11.join)(cwd, "bunfig.toml")) || dependencies.has("bun-types")) {
|
|
54738
54946
|
return detectedFrom(cwd, "Bun", []);
|
|
54739
54947
|
}
|
|
54740
54948
|
return void 0;
|
|
@@ -54814,10 +55022,93 @@ function draftFieldsAcross(sources, environments) {
|
|
|
54814
55022
|
|
|
54815
55023
|
// src/commands/init.ts
|
|
54816
55024
|
init_cjs_shims();
|
|
54817
|
-
var
|
|
54818
|
-
var
|
|
55025
|
+
var import_node_fs13 = require("fs");
|
|
55026
|
+
var import_node_path13 = require("path");
|
|
54819
55027
|
var import_promises = require("readline/promises");
|
|
54820
55028
|
|
|
55029
|
+
// src/scaffold-undo.ts
|
|
55030
|
+
init_cjs_shims();
|
|
55031
|
+
var import_node_fs12 = require("fs");
|
|
55032
|
+
var import_node_path12 = require("path");
|
|
55033
|
+
function record2(path, files, dirs) {
|
|
55034
|
+
let stats;
|
|
55035
|
+
try {
|
|
55036
|
+
stats = (0, import_node_fs12.statSync)(path);
|
|
55037
|
+
} catch {
|
|
55038
|
+
return;
|
|
55039
|
+
}
|
|
55040
|
+
if (stats.isDirectory()) {
|
|
55041
|
+
dirs.add(path);
|
|
55042
|
+
for (const entry of (0, import_node_fs12.readdirSync)(path)) {
|
|
55043
|
+
record2((0, import_node_path12.join)(path, entry), files, dirs);
|
|
55044
|
+
}
|
|
55045
|
+
return;
|
|
55046
|
+
}
|
|
55047
|
+
if (stats.isFile()) {
|
|
55048
|
+
files.set(path, (0, import_node_fs12.readFileSync)(path));
|
|
55049
|
+
}
|
|
55050
|
+
}
|
|
55051
|
+
function captureScaffold(root, paths) {
|
|
55052
|
+
const files = /* @__PURE__ */ new Map();
|
|
55053
|
+
const dirs = /* @__PURE__ */ new Set();
|
|
55054
|
+
for (const path of paths) {
|
|
55055
|
+
for (let dir = (0, import_node_path12.dirname)(path); dir.startsWith(root) && dir !== root; dir = (0, import_node_path12.dirname)(dir)) {
|
|
55056
|
+
if ((0, import_node_fs12.existsSync)(dir)) {
|
|
55057
|
+
dirs.add(dir);
|
|
55058
|
+
}
|
|
55059
|
+
}
|
|
55060
|
+
record2(path, files, dirs);
|
|
55061
|
+
}
|
|
55062
|
+
return { root, paths: [...paths], files, dirs };
|
|
55063
|
+
}
|
|
55064
|
+
function restoreScaffold(undo) {
|
|
55065
|
+
for (const path of undo.paths) {
|
|
55066
|
+
removeAdded(path, undo);
|
|
55067
|
+
}
|
|
55068
|
+
for (const path of undo.paths) {
|
|
55069
|
+
pruneAncestors(path, undo);
|
|
55070
|
+
}
|
|
55071
|
+
for (const [file2, contents] of undo.files) {
|
|
55072
|
+
(0, import_node_fs12.mkdirSync)((0, import_node_path12.dirname)(file2), { recursive: true });
|
|
55073
|
+
(0, import_node_fs12.writeFileSync)(file2, contents);
|
|
55074
|
+
}
|
|
55075
|
+
}
|
|
55076
|
+
function removeAdded(path, undo) {
|
|
55077
|
+
let stats;
|
|
55078
|
+
try {
|
|
55079
|
+
stats = (0, import_node_fs12.statSync)(path);
|
|
55080
|
+
} catch {
|
|
55081
|
+
return;
|
|
55082
|
+
}
|
|
55083
|
+
if (stats.isFile()) {
|
|
55084
|
+
if (!undo.files.has(path)) {
|
|
55085
|
+
(0, import_node_fs12.unlinkSync)(path);
|
|
55086
|
+
}
|
|
55087
|
+
return;
|
|
55088
|
+
}
|
|
55089
|
+
if (!stats.isDirectory()) {
|
|
55090
|
+
return;
|
|
55091
|
+
}
|
|
55092
|
+
for (const entry of (0, import_node_fs12.readdirSync)(path)) {
|
|
55093
|
+
removeAdded((0, import_node_path12.join)(path, entry), undo);
|
|
55094
|
+
}
|
|
55095
|
+
if (!undo.dirs.has(path) && (0, import_node_fs12.readdirSync)(path).length === 0) {
|
|
55096
|
+
(0, import_node_fs12.rmdirSync)(path);
|
|
55097
|
+
}
|
|
55098
|
+
}
|
|
55099
|
+
function pruneAncestors(path, undo) {
|
|
55100
|
+
for (let dir = (0, import_node_path12.dirname)(path); dir.startsWith(undo.root) && dir !== undo.root; dir = (0, import_node_path12.dirname)(dir)) {
|
|
55101
|
+
if (undo.dirs.has(dir)) {
|
|
55102
|
+
return;
|
|
55103
|
+
}
|
|
55104
|
+
try {
|
|
55105
|
+
(0, import_node_fs12.rmdirSync)(dir);
|
|
55106
|
+
} catch {
|
|
55107
|
+
return;
|
|
55108
|
+
}
|
|
55109
|
+
}
|
|
55110
|
+
}
|
|
55111
|
+
|
|
54821
55112
|
// src/seams.ts
|
|
54822
55113
|
init_cjs_shims();
|
|
54823
55114
|
function nextjs({ alias, srcDir }) {
|
|
@@ -54974,7 +55265,7 @@ var NOT_ENVIRONMENTS2 = [...RESERVED_TOKENS, "example", "sample", "template"];
|
|
|
54974
55265
|
function suggestEnvironments(root) {
|
|
54975
55266
|
let entries;
|
|
54976
55267
|
try {
|
|
54977
|
-
entries = (0,
|
|
55268
|
+
entries = (0, import_node_fs13.readdirSync)(root);
|
|
54978
55269
|
} catch {
|
|
54979
55270
|
return [];
|
|
54980
55271
|
}
|
|
@@ -55018,8 +55309,8 @@ function configOf(decisions) {
|
|
|
55018
55309
|
return { environments: decisions.environments, providers: {}, schemaFile: decisions.schemaFile };
|
|
55019
55310
|
}
|
|
55020
55311
|
function declaredIn(root) {
|
|
55021
|
-
const file2 = (0,
|
|
55022
|
-
if (!(0,
|
|
55312
|
+
const file2 = (0, import_node_path13.join)(root, CONFIG_FILE);
|
|
55313
|
+
if (!(0, import_node_fs13.existsSync)(file2)) {
|
|
55023
55314
|
return void 0;
|
|
55024
55315
|
}
|
|
55025
55316
|
return loadConfigFrom(file2);
|
|
@@ -55461,16 +55752,16 @@ function renderTsconfig(target, alias) {
|
|
|
55461
55752
|
`;
|
|
55462
55753
|
}
|
|
55463
55754
|
function ensurePenvDir(root) {
|
|
55464
|
-
const dir = (0,
|
|
55465
|
-
if ((0,
|
|
55755
|
+
const dir = (0, import_node_path13.resolve)(root, PENV_DIR);
|
|
55756
|
+
if ((0, import_node_fs13.existsSync)(dir)) {
|
|
55466
55757
|
return { target: "penv-dir", action: "kept", text: `Found ${PENV_DIR}/` };
|
|
55467
55758
|
}
|
|
55468
|
-
(0,
|
|
55759
|
+
(0, import_node_fs13.mkdirSync)(dir, { recursive: true });
|
|
55469
55760
|
return { target: "penv-dir", action: "created", text: `Created ${PENV_DIR}/` };
|
|
55470
55761
|
}
|
|
55471
55762
|
function writeSchemaShapeFile(root, fields, draft, decisions = DEFAULT_DECISIONS) {
|
|
55472
|
-
const file2 = (0,
|
|
55473
|
-
if ((0,
|
|
55763
|
+
const file2 = (0, import_node_path13.join)(root, SCHEMA_SHAPE_FILE);
|
|
55764
|
+
if ((0, import_node_fs13.existsSync)(file2)) {
|
|
55474
55765
|
return {
|
|
55475
55766
|
target: "schema",
|
|
55476
55767
|
action: "kept",
|
|
@@ -55487,7 +55778,7 @@ function writeSchemaShapeFile(root, fields, draft, decisions = DEFAULT_DECISIONS
|
|
|
55487
55778
|
note: `(the shape lives there, from before the ${SCHEMA_SHAPE_FILE} split \u2014 penv did not add a second one. To adopt the split: move the \`z.object\` (and any \`declare module\` block) into ${SCHEMA_SHAPE_FILE}, leaving ${oldLayout} importing \`schema\` from it and calling \`load\`.)`
|
|
55488
55779
|
};
|
|
55489
55780
|
}
|
|
55490
|
-
(0,
|
|
55781
|
+
(0, import_node_fs13.writeFileSync)(file2, renderSchemaShapeModule(fields, draft), "utf8");
|
|
55491
55782
|
return {
|
|
55492
55783
|
target: "schema",
|
|
55493
55784
|
action: "created",
|
|
@@ -55496,8 +55787,8 @@ function writeSchemaShapeFile(root, fields, draft, decisions = DEFAULT_DECISIONS
|
|
|
55496
55787
|
};
|
|
55497
55788
|
}
|
|
55498
55789
|
function writeEnvFile(root, decisions = DEFAULT_DECISIONS) {
|
|
55499
|
-
const file2 = (0,
|
|
55500
|
-
if ((0,
|
|
55790
|
+
const file2 = (0, import_node_path13.join)(root, ...decisions.schemaFile.split("/"));
|
|
55791
|
+
if ((0, import_node_fs13.existsSync)(file2)) {
|
|
55501
55792
|
return {
|
|
55502
55793
|
target: "env",
|
|
55503
55794
|
action: "kept",
|
|
@@ -55505,8 +55796,8 @@ function writeEnvFile(root, decisions = DEFAULT_DECISIONS) {
|
|
|
55505
55796
|
note: "(yours \u2014 penv never regenerates it)"
|
|
55506
55797
|
};
|
|
55507
55798
|
}
|
|
55508
|
-
(0,
|
|
55509
|
-
(0,
|
|
55799
|
+
(0, import_node_fs13.mkdirSync)((0, import_node_path13.dirname)(file2), { recursive: true });
|
|
55800
|
+
(0, import_node_fs13.writeFileSync)(file2, renderEnvModule(decisions.schemaFile, decisions.inject), "utf8");
|
|
55510
55801
|
return {
|
|
55511
55802
|
target: "env",
|
|
55512
55803
|
action: "created",
|
|
@@ -55515,19 +55806,19 @@ function writeEnvFile(root, decisions = DEFAULT_DECISIONS) {
|
|
|
55515
55806
|
};
|
|
55516
55807
|
}
|
|
55517
55808
|
function writeConfigFile(root, decisions = DEFAULT_DECISIONS) {
|
|
55518
|
-
const file2 = (0,
|
|
55519
|
-
if ((0,
|
|
55809
|
+
const file2 = (0, import_node_path13.join)(root, CONFIG_FILE);
|
|
55810
|
+
if ((0, import_node_fs13.existsSync)(file2)) {
|
|
55520
55811
|
return { target: "config", action: "kept", text: `Kept ${CONFIG_FILE}` };
|
|
55521
55812
|
}
|
|
55522
|
-
(0,
|
|
55813
|
+
(0, import_node_fs13.writeFileSync)(file2, renderConfigModule(decisions), "utf8");
|
|
55523
55814
|
return { target: "config", action: "created", text: `Generated ${CONFIG_FILE}` };
|
|
55524
55815
|
}
|
|
55525
55816
|
function writeTsconfigAlias(root, decisions = DEFAULT_DECISIONS) {
|
|
55526
55817
|
const alias = decisions.alias;
|
|
55527
55818
|
const imports = alias.startsWith(IMPORTS_PREFIX);
|
|
55528
|
-
const file2 = (0,
|
|
55819
|
+
const file2 = (0, import_node_path13.join)(root, imports ? PACKAGE_FILE : TSCONFIG_FILE);
|
|
55529
55820
|
const where = imports ? PACKAGE_FILE : TSCONFIG_FILE;
|
|
55530
|
-
if (!(0,
|
|
55821
|
+
if (!(0, import_node_fs13.existsSync)(file2)) {
|
|
55531
55822
|
if (imports) {
|
|
55532
55823
|
return {
|
|
55533
55824
|
target: "tsconfig",
|
|
@@ -55536,14 +55827,14 @@ function writeTsconfigAlias(root, decisions = DEFAULT_DECISIONS) {
|
|
|
55536
55827
|
note: `(run \`npm init\` first, or use \`--alias @env\` to alias through ${TSCONFIG_FILE})`
|
|
55537
55828
|
};
|
|
55538
55829
|
}
|
|
55539
|
-
(0,
|
|
55830
|
+
(0, import_node_fs13.writeFileSync)(file2, renderTsconfig(decisions.schemaFile, alias), "utf8");
|
|
55540
55831
|
return {
|
|
55541
55832
|
target: "tsconfig",
|
|
55542
55833
|
action: "created",
|
|
55543
55834
|
text: `Created ${TSCONFIG_FILE} with the ${alias} path alias`
|
|
55544
55835
|
};
|
|
55545
55836
|
}
|
|
55546
|
-
const source = (0,
|
|
55837
|
+
const source = (0, import_node_fs13.readFileSync)(file2, "utf8");
|
|
55547
55838
|
const edit = imports ? insertImportsAlias(source, decisions.schemaFile, alias) : insertEnvAlias(source, decisions.schemaFile, alias);
|
|
55548
55839
|
if (edit.conflict !== void 0) {
|
|
55549
55840
|
return {
|
|
@@ -55560,7 +55851,7 @@ function writeTsconfigAlias(root, decisions = DEFAULT_DECISIONS) {
|
|
|
55560
55851
|
text: `Kept the ${alias} alias in ${where}`
|
|
55561
55852
|
};
|
|
55562
55853
|
}
|
|
55563
|
-
(0,
|
|
55854
|
+
(0, import_node_fs13.writeFileSync)(file2, edit.source, "utf8");
|
|
55564
55855
|
return {
|
|
55565
55856
|
target: "tsconfig",
|
|
55566
55857
|
action: "updated",
|
|
@@ -55568,14 +55859,14 @@ function writeTsconfigAlias(root, decisions = DEFAULT_DECISIONS) {
|
|
|
55568
55859
|
};
|
|
55569
55860
|
}
|
|
55570
55861
|
function writeGitignore(root, decisions = DEFAULT_DECISIONS) {
|
|
55571
|
-
const file2 = (0,
|
|
55862
|
+
const file2 = (0, import_node_path13.join)(root, ...STATE_GITIGNORE_PATH.split("/"));
|
|
55572
55863
|
const wanted = renderStateGitignore(configOf(decisions));
|
|
55573
|
-
const existing = (0,
|
|
55864
|
+
const existing = (0, import_node_fs13.existsSync)(file2) ? (0, import_node_fs13.readFileSync)(file2, "utf8") : void 0;
|
|
55574
55865
|
if (existing === wanted) {
|
|
55575
55866
|
return { target: "gitignore", action: "kept", text: `Kept ${STATE_GITIGNORE_PATH}` };
|
|
55576
55867
|
}
|
|
55577
|
-
(0,
|
|
55578
|
-
(0,
|
|
55868
|
+
(0, import_node_fs13.mkdirSync)((0, import_node_path13.dirname)(file2), { recursive: true });
|
|
55869
|
+
(0, import_node_fs13.writeFileSync)(file2, wanted, "utf8");
|
|
55579
55870
|
return {
|
|
55580
55871
|
target: "gitignore",
|
|
55581
55872
|
action: existing === void 0 ? "created" : "updated",
|
|
@@ -55591,12 +55882,12 @@ function outdatedRuntimeWarning(root) {
|
|
|
55591
55882
|
return `Injection needs @penvhq/penv ${INJECT_MIN_VERSION}+ \u2014 this project has ${version2}, whose \`load\` ignores \`{ inject: true }\`. Upgrade, or process.env stays empty.`;
|
|
55592
55883
|
}
|
|
55593
55884
|
function installedPenvVersion(root) {
|
|
55594
|
-
const file2 = (0,
|
|
55595
|
-
if (!(0,
|
|
55885
|
+
const file2 = (0, import_node_path13.join)(root, "node_modules", "@penvhq", "penv", "package.json");
|
|
55886
|
+
if (!(0, import_node_fs13.existsSync)(file2)) {
|
|
55596
55887
|
return void 0;
|
|
55597
55888
|
}
|
|
55598
55889
|
try {
|
|
55599
|
-
const version2 = JSON.parse((0,
|
|
55890
|
+
const version2 = JSON.parse((0, import_node_fs13.readFileSync)(file2, "utf8")).version;
|
|
55600
55891
|
return typeof version2 === "string" ? version2 : void 0;
|
|
55601
55892
|
} catch {
|
|
55602
55893
|
return void 0;
|
|
@@ -55636,11 +55927,11 @@ function writeSeam(root, decisions = DEFAULT_DECISIONS, framework = detectFramew
|
|
|
55636
55927
|
};
|
|
55637
55928
|
}
|
|
55638
55929
|
const alsoNote = writeAlso(root, seam.also);
|
|
55639
|
-
const file2 = (0,
|
|
55930
|
+
const file2 = (0, import_node_path13.join)(root, ...seam.file.split("/"));
|
|
55640
55931
|
const baseNotes = [...seam.notes, ...alsoNote === void 0 ? [] : [alsoNote]];
|
|
55641
55932
|
const notes = baseNotes.length === 0 ? "" : `
|
|
55642
55933
|
${baseNotes.map((n) => ` ${n}`).join("\n")}`;
|
|
55643
|
-
if ((0,
|
|
55934
|
+
if ((0, import_node_fs13.existsSync)(file2)) {
|
|
55644
55935
|
return {
|
|
55645
55936
|
target: "seam",
|
|
55646
55937
|
action: "info",
|
|
@@ -55648,8 +55939,8 @@ ${baseNotes.map((n) => ` ${n}`).join("\n")}`;
|
|
|
55648
55939
|
note: withWarning(`${seam.ifPresent}${notes}`, outdated)
|
|
55649
55940
|
};
|
|
55650
55941
|
}
|
|
55651
|
-
(0,
|
|
55652
|
-
(0,
|
|
55942
|
+
(0, import_node_fs13.mkdirSync)((0, import_node_path13.dirname)(file2), { recursive: true });
|
|
55943
|
+
(0, import_node_fs13.writeFileSync)(file2, seam.content, "utf8");
|
|
55653
55944
|
return {
|
|
55654
55945
|
target: "seam",
|
|
55655
55946
|
action: outdated === void 0 ? "created" : "info",
|
|
@@ -55661,12 +55952,12 @@ function writeAlso(root, also) {
|
|
|
55661
55952
|
if (also === void 0) {
|
|
55662
55953
|
return void 0;
|
|
55663
55954
|
}
|
|
55664
|
-
const file2 = (0,
|
|
55665
|
-
if ((0,
|
|
55955
|
+
const file2 = (0, import_node_path13.join)(root, ...also.file.split("/"));
|
|
55956
|
+
if ((0, import_node_fs13.existsSync)(file2)) {
|
|
55666
55957
|
return also.ifPresent;
|
|
55667
55958
|
}
|
|
55668
|
-
(0,
|
|
55669
|
-
(0,
|
|
55959
|
+
(0, import_node_fs13.mkdirSync)((0, import_node_path13.dirname)(file2), { recursive: true });
|
|
55960
|
+
(0, import_node_fs13.writeFileSync)(file2, also.content, "utf8");
|
|
55670
55961
|
return `Wrote ${also.file} to register it.`;
|
|
55671
55962
|
}
|
|
55672
55963
|
function withWarning(note, warning) {
|
|
@@ -55691,6 +55982,23 @@ function scaffold(root, fields, draft, decisions = DEFAULT_DECISIONS, framework
|
|
|
55691
55982
|
const seam = writeSeam(root, decisions, framework);
|
|
55692
55983
|
return seam === void 0 ? steps : [...steps, seam];
|
|
55693
55984
|
}
|
|
55985
|
+
function scaffoldPaths(root, decisions = DEFAULT_DECISIONS, framework = detectFramework(root)?.name) {
|
|
55986
|
+
const fileAt = (relative5) => (0, import_node_path13.join)(root, ...relative5.split("/"));
|
|
55987
|
+
const seam = decisions.inject ? seamFor(framework, {
|
|
55988
|
+
alias: decisions.alias,
|
|
55989
|
+
srcDir: srcPrefix(root),
|
|
55990
|
+
schemaFile: decisions.schemaFile
|
|
55991
|
+
}) : void 0;
|
|
55992
|
+
return [
|
|
55993
|
+
fileAt(PENV_DIR),
|
|
55994
|
+
fileAt(SCHEMA_SHAPE_FILE),
|
|
55995
|
+
fileAt(decisions.schemaFile),
|
|
55996
|
+
fileAt(CONFIG_FILE),
|
|
55997
|
+
fileAt(TSCONFIG_FILE),
|
|
55998
|
+
fileAt(PACKAGE_FILE),
|
|
55999
|
+
...seam?.kind === "scaffold" ? [fileAt(seam.file), ...seam.also === void 0 ? [] : [fileAt(seam.also.file)]] : []
|
|
56000
|
+
];
|
|
56001
|
+
}
|
|
55694
56002
|
var DEVELOPMENT = "development";
|
|
55695
56003
|
var LOCAL_PROVIDER = "@penvhq/provider-filesystem";
|
|
55696
56004
|
function planAdoption(root) {
|
|
@@ -55753,7 +56061,7 @@ function planCutover(input) {
|
|
|
55753
56061
|
const diagnostics = [];
|
|
55754
56062
|
let variables = 0;
|
|
55755
56063
|
for (const file2 of selected) {
|
|
55756
|
-
const parsed = parseDotenv((0,
|
|
56064
|
+
const parsed = parseDotenv((0, import_node_fs13.readFileSync)((0, import_node_path13.join)(root, file2.name), "utf8"));
|
|
55757
56065
|
const fileRefs = refsForEntries(parsed.entries, file2.name, config2);
|
|
55758
56066
|
adopted.push({ file: file2, entries: parsed.entries, refs: fileRefs, scope: scopeOf(file2) });
|
|
55759
56067
|
refs.push(...fileRefs);
|
|
@@ -55864,17 +56172,27 @@ async function applyCutover(plan2, options = {}) {
|
|
|
55864
56172
|
if (!plan2.install.satisfied) {
|
|
55865
56173
|
await (options.install ?? installWithPackageManager)(plan2.install);
|
|
55866
56174
|
}
|
|
55867
|
-
const
|
|
55868
|
-
|
|
55869
|
-
|
|
55870
|
-
|
|
55871
|
-
|
|
55872
|
-
|
|
55873
|
-
|
|
55874
|
-
|
|
55875
|
-
if (!check2.result.ok) {
|
|
55876
|
-
throw invalidAfterImport(check2.result);
|
|
56175
|
+
const undo = captureScaffold(plan2.root, scaffoldPaths(plan2.root, plan2.decisions, plan2.framework));
|
|
56176
|
+
let steps;
|
|
56177
|
+
try {
|
|
56178
|
+
steps = scaffold(plan2.root, plan2.fields, true, plan2.decisions, plan2.framework);
|
|
56179
|
+
const project = openProject(plan2.root);
|
|
56180
|
+
const tree = localTree(project);
|
|
56181
|
+
for (const adopted of plan2.adopted) {
|
|
56182
|
+
writeEntries(tree, adopted.entries, adopted.refs, adopted.scope);
|
|
55877
56183
|
}
|
|
56184
|
+
for (const environment of plan2.adopting) {
|
|
56185
|
+
const check2 = await checkEnvironment(project, environment);
|
|
56186
|
+
if (check2.schema === void 0) {
|
|
56187
|
+
throw draftNotLoaded(check2.result);
|
|
56188
|
+
}
|
|
56189
|
+
if (!check2.result.ok) {
|
|
56190
|
+
throw invalidAfterImport(check2.result);
|
|
56191
|
+
}
|
|
56192
|
+
}
|
|
56193
|
+
} catch (error51) {
|
|
56194
|
+
restoreScaffold(undo);
|
|
56195
|
+
throw error51;
|
|
55878
56196
|
}
|
|
55879
56197
|
const cutover = bundleDotenvFiles(
|
|
55880
56198
|
plan2.root,
|
|
@@ -55883,13 +56201,24 @@ async function applyCutover(plan2, options = {}) {
|
|
|
55883
56201
|
);
|
|
55884
56202
|
return { plan: plan2, steps, moved: cutover.files, validated: plan2.adopting };
|
|
55885
56203
|
}
|
|
56204
|
+
function issueLines(result2) {
|
|
56205
|
+
return result2.issues.map((issue2) => ` ${issue2.subject}: ${issue2.message}`).join("\n");
|
|
56206
|
+
}
|
|
56207
|
+
var SCAFFOLD_ROLLED_BACK = "penv put the project back as it found it \u2014 your dotenv files and everything else are exactly where they were.";
|
|
55886
56208
|
function invalidAfterImport(result2) {
|
|
55887
|
-
const lines = result2.issues.map((issue2) => ` ${issue2.subject}: ${issue2.message}`).join("\n");
|
|
55888
56209
|
return new PenvError(
|
|
55889
56210
|
"INIT_CUTOVER_INVALID",
|
|
55890
|
-
`The imported values do not satisfy the draft schema for ${result2.environment}
|
|
55891
|
-
${
|
|
55892
|
-
`Correct
|
|
56211
|
+
`The imported values do not satisfy the draft schema for ${result2.environment}:
|
|
56212
|
+
${issueLines(result2)}`,
|
|
56213
|
+
`Correct the values above, then run \`penv init\` again. ${SCAFFOLD_ROLLED_BACK}`
|
|
56214
|
+
);
|
|
56215
|
+
}
|
|
56216
|
+
function draftNotLoaded(result2) {
|
|
56217
|
+
return new PenvError(
|
|
56218
|
+
"INIT_DRAFT_NOT_LOADED",
|
|
56219
|
+
`penv could not load the schema it drafted for ${result2.environment}, so nothing was checked against it:
|
|
56220
|
+
${issueLines(result2)}`,
|
|
56221
|
+
`Fix the error above, then run \`penv init\` again. ${SCAFFOLD_ROLLED_BACK}`
|
|
55893
56222
|
);
|
|
55894
56223
|
}
|
|
55895
56224
|
function renderSelection(plan2, selected = plan2.preselected) {
|
|
@@ -55952,7 +56281,7 @@ function renderCutover(result2) {
|
|
|
55952
56281
|
const glyph = step.action === "conflicted" ? WARN : step.action === "info" ? "\u2192" : CHECK;
|
|
55953
56282
|
return step.note === void 0 ? { glyph, text: step.text } : { glyph, text: step.text, note: step.note };
|
|
55954
56283
|
}),
|
|
55955
|
-
...plan2.install.
|
|
56284
|
+
...plan2.install.packages.filter((entry) => !entry.satisfied).map((entry) => ({ glyph: CHECK, text: `Installed ${entry.name}`, note: entry.version })),
|
|
55956
56285
|
{
|
|
55957
56286
|
glyph: CHECK,
|
|
55958
56287
|
text: `Imported ${plan2.fields.length} parameters`,
|
|
@@ -55976,12 +56305,12 @@ function dailyCommand(root) {
|
|
|
55976
56305
|
return `penv run -- ${detectPackageManager(root)} ${devScript(root)}`;
|
|
55977
56306
|
}
|
|
55978
56307
|
function devScript(root) {
|
|
55979
|
-
const file2 = (0,
|
|
55980
|
-
if (!(0,
|
|
56308
|
+
const file2 = (0, import_node_path13.join)(root, PACKAGE_FILE);
|
|
56309
|
+
if (!(0, import_node_fs13.existsSync)(file2)) {
|
|
55981
56310
|
return "dev";
|
|
55982
56311
|
}
|
|
55983
56312
|
try {
|
|
55984
|
-
const scripts = JSON.parse((0,
|
|
56313
|
+
const scripts = JSON.parse((0, import_node_fs13.readFileSync)(file2, "utf8")).scripts;
|
|
55985
56314
|
if (scripts !== null && typeof scripts === "object" && !Array.isArray(scripts)) {
|
|
55986
56315
|
const named = Object.keys(scripts);
|
|
55987
56316
|
return ["dev", "start"].find((script) => named.includes(script)) ?? named[0] ?? "dev";
|
|
@@ -55991,7 +56320,7 @@ function devScript(root) {
|
|
|
55991
56320
|
return "dev";
|
|
55992
56321
|
}
|
|
55993
56322
|
function runInit(options) {
|
|
55994
|
-
const root = (0,
|
|
56323
|
+
const root = (0, import_node_path13.resolve)(options.cwd);
|
|
55995
56324
|
const decisions = options.decisions ?? planInit(root).decisions;
|
|
55996
56325
|
return { root, decisions, steps: scaffold(root, [], false, decisions, options.framework) };
|
|
55997
56326
|
}
|
|
@@ -56154,7 +56483,7 @@ var initCommand = defineCommand({
|
|
|
56154
56483
|
},
|
|
56155
56484
|
run({ args }) {
|
|
56156
56485
|
return guard(async () => {
|
|
56157
|
-
const root = (0,
|
|
56486
|
+
const root = (0, import_node_path13.resolve)(process.cwd());
|
|
56158
56487
|
if (args.action !== void 0) {
|
|
56159
56488
|
runUndoAction(root, String(args.action));
|
|
56160
56489
|
return;
|
|
@@ -56230,7 +56559,7 @@ function assertDeclared(segment, config2) {
|
|
|
56230
56559
|
throw new UnknownEnvironmentError(segment, config2.environments);
|
|
56231
56560
|
}
|
|
56232
56561
|
function scopeFromFilename(file2, config2) {
|
|
56233
|
-
const name = (0,
|
|
56562
|
+
const name = (0, import_node_path14.basename)(file2);
|
|
56234
56563
|
const segments = name.split(".");
|
|
56235
56564
|
const start = segments.indexOf(DOTENV_SEGMENT);
|
|
56236
56565
|
if (start === -1) {
|
|
@@ -56314,7 +56643,7 @@ function environmentNamed(file2, explicit) {
|
|
|
56314
56643
|
if (explicit !== void 0 && explicit.trim().length > 0) {
|
|
56315
56644
|
return explicit.trim();
|
|
56316
56645
|
}
|
|
56317
|
-
const segments = (0,
|
|
56646
|
+
const segments = (0, import_node_path14.basename)(file2).split(".");
|
|
56318
56647
|
const start = segments.indexOf(DOTENV_SEGMENT);
|
|
56319
56648
|
if (start === -1) {
|
|
56320
56649
|
return void 0;
|
|
@@ -56348,16 +56677,16 @@ function configInEffect(cwd, environment) {
|
|
|
56348
56677
|
return { config: openProject(cwd).config, decisions };
|
|
56349
56678
|
}
|
|
56350
56679
|
function importDotenv(options) {
|
|
56351
|
-
const cwd = (0,
|
|
56352
|
-
const file2 = (0,
|
|
56353
|
-
if (!(0,
|
|
56680
|
+
const cwd = (0, import_node_path14.resolve)(options.cwd);
|
|
56681
|
+
const file2 = (0, import_node_path14.isAbsolute)(options.file) ? options.file : (0, import_node_path14.resolve)(cwd, options.file);
|
|
56682
|
+
if (!(0, import_node_fs14.existsSync)(file2)) {
|
|
56354
56683
|
throw new PenvError(
|
|
56355
56684
|
"IMPORT_FILE_MISSING",
|
|
56356
56685
|
`There is no file at ${file2} to import`,
|
|
56357
56686
|
"Point `penv import` at an existing dotenv file, e.g. `penv import .env`."
|
|
56358
56687
|
);
|
|
56359
56688
|
}
|
|
56360
|
-
const parsed = parseDotenv((0,
|
|
56689
|
+
const parsed = parseDotenv((0, import_node_fs14.readFileSync)(file2, "utf8"));
|
|
56361
56690
|
const { config: config2, decisions } = configInEffect(cwd, environmentNamed(file2, options.environment));
|
|
56362
56691
|
const source = displayPath3(cwd, file2);
|
|
56363
56692
|
const named = scopeFromFilename(file2, config2);
|
|
@@ -56373,7 +56702,7 @@ function importDotenv(options) {
|
|
|
56373
56702
|
const tree = localTree(project);
|
|
56374
56703
|
writeEntries(tree, parsed.entries, refs, scope);
|
|
56375
56704
|
const backup = `${file2}${BACKUP_SUFFIX}`;
|
|
56376
|
-
(0,
|
|
56705
|
+
(0, import_node_fs14.copyFileSync)(file2, backup);
|
|
56377
56706
|
return {
|
|
56378
56707
|
root: project.root,
|
|
56379
56708
|
file: file2,
|
|
@@ -56387,7 +56716,7 @@ function importDotenv(options) {
|
|
|
56387
56716
|
};
|
|
56388
56717
|
}
|
|
56389
56718
|
function displayPath3(root, file2) {
|
|
56390
|
-
const rel = (0,
|
|
56719
|
+
const rel = (0, import_node_path14.relative)(root, file2);
|
|
56391
56720
|
return rel === "" || rel.startsWith("..") ? file2 : rel.split("\\").join("/");
|
|
56392
56721
|
}
|
|
56393
56722
|
function keptSchemaStep(step, variables) {
|
|
@@ -56706,28 +57035,28 @@ var listCommand = defineCommand({
|
|
|
56706
57035
|
|
|
56707
57036
|
// src/commands/migrate.ts
|
|
56708
57037
|
init_cjs_shims();
|
|
56709
|
-
var
|
|
56710
|
-
var
|
|
57038
|
+
var import_node_fs15 = require("fs");
|
|
57039
|
+
var import_node_path15 = require("path");
|
|
56711
57040
|
var import_promises2 = require("readline/promises");
|
|
56712
57041
|
var OLD_GITIGNORE = `${PENV_DIR}/.gitignore`;
|
|
56713
57042
|
function planMigrate(cwd) {
|
|
56714
57043
|
const { config: config2, file: file2 } = loadConfig(cwd);
|
|
56715
|
-
const root = (0,
|
|
57044
|
+
const root = (0, import_node_path15.dirname)(file2);
|
|
56716
57045
|
const entries = oldLayoutEntries(root, config2);
|
|
56717
57046
|
const tree = recordsDir(root);
|
|
56718
57047
|
const collisions = collidingEntries(entries, tree);
|
|
56719
57048
|
if (collisions.length > 0) {
|
|
56720
57049
|
throw new PenvError(
|
|
56721
57050
|
"HALF_MIGRATED",
|
|
56722
|
-
`${
|
|
57051
|
+
`${describe5(collisions)} in both \`${PENV_DIR}/\` and \`${RECORDS_PATH2}/\`, and penv cannot tell which copy is current`,
|
|
56723
57052
|
`Move what is left under \`${PENV_DIR}/\` into \`${RECORDS_PATH2}/\` yourself, keeping the copy you want, then run \`penv validate\`.`
|
|
56724
57053
|
);
|
|
56725
57054
|
}
|
|
56726
57055
|
const creates = [];
|
|
56727
|
-
if (entries.length > 0 && !(0,
|
|
57056
|
+
if (entries.length > 0 && !(0, import_node_fs15.existsSync)(tree)) {
|
|
56728
57057
|
creates.push(`${RECORDS_PATH2}/`);
|
|
56729
57058
|
}
|
|
56730
|
-
if (readIfPresent((0,
|
|
57059
|
+
if (readIfPresent((0, import_node_path15.join)(root, ...STATE_GITIGNORE_PATH.split("/"))) !== renderStateGitignore(config2)) {
|
|
56731
57060
|
creates.push(STATE_GITIGNORE_PATH);
|
|
56732
57061
|
}
|
|
56733
57062
|
return {
|
|
@@ -56737,23 +57066,23 @@ function planMigrate(cwd) {
|
|
|
56737
57066
|
to: `${RECORDS_PATH2}/${entry}`
|
|
56738
57067
|
})),
|
|
56739
57068
|
creates,
|
|
56740
|
-
removes: (0,
|
|
57069
|
+
removes: (0, import_node_fs15.existsSync)((0, import_node_path15.join)(root, ...OLD_GITIGNORE.split("/"))) ? [OLD_GITIGNORE] : []
|
|
56741
57070
|
};
|
|
56742
57071
|
}
|
|
56743
57072
|
function readIfPresent(file2) {
|
|
56744
|
-
return (0,
|
|
57073
|
+
return (0, import_node_fs15.existsSync)(file2) ? (0, import_node_fs15.readFileSync)(file2, "utf8") : void 0;
|
|
56745
57074
|
}
|
|
56746
57075
|
function collidingEntries(entries, tree) {
|
|
56747
57076
|
let held;
|
|
56748
57077
|
try {
|
|
56749
|
-
held = (0,
|
|
57078
|
+
held = (0, import_node_fs15.readdirSync)(tree);
|
|
56750
57079
|
} catch {
|
|
56751
57080
|
return [];
|
|
56752
57081
|
}
|
|
56753
57082
|
const taken = new Set(held.map((name) => name.toLowerCase()));
|
|
56754
57083
|
return entries.filter((entry) => taken.has(entry.toLowerCase())).sort();
|
|
56755
57084
|
}
|
|
56756
|
-
function
|
|
57085
|
+
function describe5(names) {
|
|
56757
57086
|
return names.length === 1 ? `\`${names[0]}\` is` : `${names.map((name) => `\`${name}\``).join(", ")} are`;
|
|
56758
57087
|
}
|
|
56759
57088
|
function isNoop(plan2) {
|
|
@@ -56765,18 +57094,18 @@ function applyMigrate(plan2) {
|
|
|
56765
57094
|
}
|
|
56766
57095
|
const { config: config2 } = loadConfig(plan2.root);
|
|
56767
57096
|
if (plan2.moves.length > 0) {
|
|
56768
|
-
(0,
|
|
57097
|
+
(0, import_node_fs15.mkdirSync)(recordsDir(plan2.root), { recursive: true });
|
|
56769
57098
|
for (const move of plan2.moves) {
|
|
56770
|
-
(0,
|
|
57099
|
+
(0, import_node_fs15.renameSync)((0, import_node_path15.join)(plan2.root, ...move.from.split("/")), (0, import_node_path15.join)(plan2.root, ...move.to.split("/")));
|
|
56771
57100
|
}
|
|
56772
57101
|
}
|
|
56773
57102
|
if (plan2.creates.includes(STATE_GITIGNORE_PATH)) {
|
|
56774
|
-
const ignore = (0,
|
|
56775
|
-
(0,
|
|
56776
|
-
(0,
|
|
57103
|
+
const ignore = (0, import_node_path15.join)(plan2.root, ...STATE_GITIGNORE_PATH.split("/"));
|
|
57104
|
+
(0, import_node_fs15.mkdirSync)((0, import_node_path15.dirname)(ignore), { recursive: true });
|
|
57105
|
+
(0, import_node_fs15.writeFileSync)(ignore, renderStateGitignore(config2), "utf8");
|
|
56777
57106
|
}
|
|
56778
57107
|
for (const removed of plan2.removes) {
|
|
56779
|
-
(0,
|
|
57108
|
+
(0, import_node_fs15.rmSync)((0, import_node_path15.join)(plan2.root, ...removed.split("/")), { force: true });
|
|
56780
57109
|
}
|
|
56781
57110
|
return { ...plan2, status: "migrated" };
|
|
56782
57111
|
}
|
|
@@ -57253,12 +57582,12 @@ var rotateCommand = defineCommand({
|
|
|
57253
57582
|
|
|
57254
57583
|
// src/commands/watch.ts
|
|
57255
57584
|
init_cjs_shims();
|
|
57256
|
-
var
|
|
57257
|
-
var
|
|
57585
|
+
var import_node_fs16 = require("fs");
|
|
57586
|
+
var import_node_path16 = require("path");
|
|
57258
57587
|
var DEBOUNCE_MS2 = 100;
|
|
57259
57588
|
function runWatch(options) {
|
|
57260
57589
|
const project = openProject(options.cwd);
|
|
57261
|
-
const configFile = (0,
|
|
57590
|
+
const configFile = (0, import_node_path16.basename)(project.configFile);
|
|
57262
57591
|
const debounceMs = options.debounceMs ?? DEBOUNCE_MS2;
|
|
57263
57592
|
const watchers = /* @__PURE__ */ new Set();
|
|
57264
57593
|
let timer;
|
|
@@ -57311,22 +57640,22 @@ function runWatch(options) {
|
|
|
57311
57640
|
watcher.close();
|
|
57312
57641
|
}
|
|
57313
57642
|
function armRecovery(target, recursive, only) {
|
|
57314
|
-
const parent = (0,
|
|
57315
|
-
const name = (0,
|
|
57643
|
+
const parent = (0, import_node_path16.dirname)(target);
|
|
57644
|
+
const name = (0, import_node_path16.basename)(target);
|
|
57316
57645
|
let recovery;
|
|
57317
57646
|
try {
|
|
57318
|
-
recovery = (0,
|
|
57647
|
+
recovery = (0, import_node_fs16.watch)(parent, { recursive: false }, (_event, filename) => {
|
|
57319
57648
|
if (closed || recovery === void 0) {
|
|
57320
57649
|
return;
|
|
57321
57650
|
}
|
|
57322
|
-
if (!(0,
|
|
57651
|
+
if (!(0, import_node_fs16.existsSync)(parent)) {
|
|
57323
57652
|
stop2(recovery);
|
|
57324
57653
|
return;
|
|
57325
57654
|
}
|
|
57326
|
-
if (filename !== null && (0,
|
|
57655
|
+
if (filename !== null && (0, import_node_path16.basename)(filename) !== name) {
|
|
57327
57656
|
return;
|
|
57328
57657
|
}
|
|
57329
|
-
if (!(0,
|
|
57658
|
+
if (!(0, import_node_fs16.existsSync)(target)) {
|
|
57330
57659
|
return;
|
|
57331
57660
|
}
|
|
57332
57661
|
stop2(recovery);
|
|
@@ -57346,11 +57675,11 @@ function runWatch(options) {
|
|
|
57346
57675
|
}
|
|
57347
57676
|
function addWatcher(target, recursive, only) {
|
|
57348
57677
|
let watcher;
|
|
57349
|
-
const listen = (useRecursive) => (0,
|
|
57678
|
+
const listen = (useRecursive) => (0, import_node_fs16.watch)(target, { recursive: useRecursive }, (_event, filename) => {
|
|
57350
57679
|
if (closed) {
|
|
57351
57680
|
return;
|
|
57352
57681
|
}
|
|
57353
|
-
if (!(0,
|
|
57682
|
+
if (!(0, import_node_fs16.existsSync)(target)) {
|
|
57354
57683
|
if (watcher !== void 0) {
|
|
57355
57684
|
stop2(watcher);
|
|
57356
57685
|
}
|
|
@@ -57358,7 +57687,7 @@ function runWatch(options) {
|
|
|
57358
57687
|
schedule();
|
|
57359
57688
|
return;
|
|
57360
57689
|
}
|
|
57361
|
-
if (only !== void 0 && (filename === null || (0,
|
|
57690
|
+
if (only !== void 0 && (filename === null || (0, import_node_path16.basename)(filename) !== only)) {
|
|
57362
57691
|
return;
|
|
57363
57692
|
}
|
|
57364
57693
|
schedule();
|
|
@@ -57385,11 +57714,11 @@ function runWatch(options) {
|
|
|
57385
57714
|
watchers.add(watcher);
|
|
57386
57715
|
}
|
|
57387
57716
|
addWatcher(project.recordsDir, true);
|
|
57388
|
-
addWatcher((0,
|
|
57717
|
+
addWatcher((0, import_node_path16.dirname)(project.configFile), false, configFile);
|
|
57389
57718
|
addWatcher(project.root, false, SCHEMA_SHAPE_FILE);
|
|
57390
57719
|
if (schemaInsideTree(project.config) === void 0) {
|
|
57391
|
-
const schemaFile = (0,
|
|
57392
|
-
addWatcher((0,
|
|
57720
|
+
const schemaFile = (0, import_node_path16.resolve)(project.root, schemaFileOf(project.config));
|
|
57721
|
+
addWatcher((0, import_node_path16.dirname)(schemaFile), false, (0, import_node_path16.basename)(schemaFile));
|
|
57393
57722
|
}
|
|
57394
57723
|
void validate();
|
|
57395
57724
|
return {
|