@penvhq/cli 0.9.4 → 0.10.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 +682 -172
- package/dist/bin.cjs.map +1 -1
- package/dist/index.cjs +254 -133
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +241 -106
- package/dist/index.js.map +1 -1
- package/package.json +7 -7
package/dist/index.cjs
CHANGED
|
@@ -69,7 +69,7 @@ var import_core35 = require("@penvhq/core");
|
|
|
69
69
|
var import_citty22 = require("citty");
|
|
70
70
|
|
|
71
71
|
// src/commands/artifact.ts
|
|
72
|
-
var
|
|
72
|
+
var import_node_fs7 = require("fs");
|
|
73
73
|
var import_node_path7 = require("path");
|
|
74
74
|
var import_core12 = require("@penvhq/core");
|
|
75
75
|
var import_runtime2 = require("@penvhq/runtime");
|
|
@@ -381,7 +381,7 @@ function installFailed(plan2) {
|
|
|
381
381
|
}
|
|
382
382
|
|
|
383
383
|
// src/project.ts
|
|
384
|
-
var
|
|
384
|
+
var import_node_fs4 = require("fs");
|
|
385
385
|
var import_node_path4 = require("path");
|
|
386
386
|
var import_core5 = require("@penvhq/core");
|
|
387
387
|
var import_provider_filesystem2 = require("@penvhq/provider-filesystem");
|
|
@@ -445,6 +445,7 @@ function environmentFromShorthand(config, candidates, explicit) {
|
|
|
445
445
|
}
|
|
446
446
|
|
|
447
447
|
// src/registry.ts
|
|
448
|
+
var import_node_fs3 = require("fs");
|
|
448
449
|
var import_node_module = require("module");
|
|
449
450
|
var import_node_path3 = require("path");
|
|
450
451
|
var import_node_url = require("url");
|
|
@@ -491,19 +492,12 @@ async function createSourceProvider(type, context) {
|
|
|
491
492
|
return loadPluginProvider(type, context);
|
|
492
493
|
}
|
|
493
494
|
async function loadPluginProvider(type, context) {
|
|
494
|
-
const
|
|
495
|
-
if (resolved === void 0) {
|
|
496
|
-
throw unknownProvider(type, context.environment);
|
|
497
|
-
}
|
|
495
|
+
const path = resolveExtension(type, context.root, context.environment);
|
|
498
496
|
let mod;
|
|
499
497
|
try {
|
|
500
|
-
mod = await importPlugin(
|
|
501
|
-
} catch {
|
|
502
|
-
throw
|
|
503
|
-
"PROVIDER_PLUGIN_LOAD",
|
|
504
|
-
`The provider package \`${type}\` failed to load`,
|
|
505
|
-
"It resolved but threw while importing. Check it builds and its dependencies are installed."
|
|
506
|
-
);
|
|
498
|
+
mod = await importPlugin(path);
|
|
499
|
+
} catch (cause) {
|
|
500
|
+
throw providerLoadFailed(type, path, cause);
|
|
507
501
|
}
|
|
508
502
|
const factory = mod[PLUGIN_FACTORY_EXPORT];
|
|
509
503
|
if (typeof factory !== "function") {
|
|
@@ -517,15 +511,71 @@ async function loadPluginProvider(type, context) {
|
|
|
517
511
|
assertSatisfiesContract(provider, type);
|
|
518
512
|
return provider;
|
|
519
513
|
}
|
|
520
|
-
function assertProvidersRegistered(config, projectRoot) {
|
|
514
|
+
function assertProvidersRegistered(config, projectRoot, options) {
|
|
515
|
+
const local = localExtensions(projectRoot);
|
|
516
|
+
const ci = options?.ci ?? isCi(process.env.CI);
|
|
521
517
|
for (const [environment, provider] of Object.entries(config.providers)) {
|
|
522
518
|
if (isProviderRegistered(provider.type)) {
|
|
523
519
|
continue;
|
|
524
520
|
}
|
|
525
|
-
if (
|
|
526
|
-
throw
|
|
521
|
+
if (ci && local.includes(provider.type)) {
|
|
522
|
+
throw localExtensionInCi(provider.type, environment);
|
|
523
|
+
}
|
|
524
|
+
resolveExtension(provider.type, projectRoot, environment, local);
|
|
525
|
+
}
|
|
526
|
+
}
|
|
527
|
+
function resolveExtension(type, projectRoot, environment, local = localExtensions(projectRoot)) {
|
|
528
|
+
const fromProject = resolvePlugin(type, projectRoot);
|
|
529
|
+
if (local.includes(type)) {
|
|
530
|
+
if (fromProject === void 0) {
|
|
531
|
+
throw localExtensionUnresolved(type, projectRoot, environment);
|
|
527
532
|
}
|
|
533
|
+
return fromProject;
|
|
534
|
+
}
|
|
535
|
+
if (fromProject !== void 0) {
|
|
536
|
+
return fromProject;
|
|
537
|
+
}
|
|
538
|
+
const version = pinnedVersion(type, projectRoot);
|
|
539
|
+
if (version === void 0) {
|
|
540
|
+
throw unknownProvider(type, environment);
|
|
541
|
+
}
|
|
542
|
+
const stored = storedExtension(type, version);
|
|
543
|
+
if (stored === void 0) {
|
|
544
|
+
throw extensionNotInstalled(type, version, environment);
|
|
545
|
+
}
|
|
546
|
+
return stored;
|
|
547
|
+
}
|
|
548
|
+
function pinnedVersion(type, projectRoot) {
|
|
549
|
+
let manifest;
|
|
550
|
+
try {
|
|
551
|
+
manifest = (0, import_core4.parseManifest)((0, import_node_fs3.readFileSync)((0, import_node_path3.join)(projectRoot, ...import_core4.MANIFEST_PATH.split("/")), "utf8"));
|
|
552
|
+
} catch {
|
|
553
|
+
return void 0;
|
|
528
554
|
}
|
|
555
|
+
return manifest.extensions[type]?.version;
|
|
556
|
+
}
|
|
557
|
+
function storedExtension(type, version) {
|
|
558
|
+
const entry = (0, import_core4.packageEntry)((0, import_core4.packageDir)((0, import_core4.penvHome)(process.env), "extensions", type, version));
|
|
559
|
+
return entry?.file;
|
|
560
|
+
}
|
|
561
|
+
function localExtensions(projectRoot) {
|
|
562
|
+
let text;
|
|
563
|
+
try {
|
|
564
|
+
text = (0, import_node_fs3.readFileSync)((0, import_core4.localExtensionsFile)(projectRoot), "utf8");
|
|
565
|
+
} catch {
|
|
566
|
+
return [];
|
|
567
|
+
}
|
|
568
|
+
return (0, import_core4.parseLocalExtensions)(text);
|
|
569
|
+
}
|
|
570
|
+
function isCi(value) {
|
|
571
|
+
return value !== void 0 && value !== "" && value !== "0" && value.toLowerCase() !== "false";
|
|
572
|
+
}
|
|
573
|
+
function localExtensionInCi(type, environment) {
|
|
574
|
+
return new import_core4.PenvError(
|
|
575
|
+
"LOCAL_EXTENSION_IN_CI",
|
|
576
|
+
`The provider \`${type}\` for environment ${environment} is a local extension, and this is CI`,
|
|
577
|
+
`${import_core4.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.`
|
|
578
|
+
);
|
|
529
579
|
}
|
|
530
580
|
function resolvePlugin(specifier, fromDir) {
|
|
531
581
|
try {
|
|
@@ -558,13 +608,37 @@ function assertSatisfiesContract(provider, specifier) {
|
|
|
558
608
|
}
|
|
559
609
|
}
|
|
560
610
|
}
|
|
611
|
+
function where(environment) {
|
|
612
|
+
return environment === void 0 ? "" : ` for environment ${environment}`;
|
|
613
|
+
}
|
|
561
614
|
function unknownProvider(type, environment) {
|
|
562
615
|
const preinstalled = [...REGISTRY.keys()].map((name) => `\`${name}\``).join(", ");
|
|
563
|
-
const where = environment === void 0 ? "" : ` for environment ${environment}`;
|
|
564
616
|
return new import_core4.PenvError(
|
|
565
617
|
"UNKNOWN_PROVIDER",
|
|
566
|
-
`The provider \`${type}\`${where} in penv.config.ts is
|
|
567
|
-
`
|
|
618
|
+
`The provider \`${type}\`${where(environment)} in penv.config.ts is nowhere penv looks for it`,
|
|
619
|
+
`Run \`penv add ${type}\` to pin a release, or \`penv add --local ${type}\` if this repository is the one that builds it. penv looks in ${import_core4.LOCAL_EXTENSIONS_PATH}, this project's node_modules, and then $PENV_HOME at the version ${import_core4.MANIFEST_PATH} pins. The CLI ships ${preinstalled} pre-installed.`
|
|
620
|
+
);
|
|
621
|
+
}
|
|
622
|
+
function extensionNotInstalled(type, version, environment) {
|
|
623
|
+
return new import_core4.PenvError(
|
|
624
|
+
"EXTENSION_NOT_INSTALLED",
|
|
625
|
+
`${import_core4.MANIFEST_PATH} pins \`${type}\` ${version}${where(environment)}, and it is not installed in ${(0, import_core4.penvHome)(process.env)}`,
|
|
626
|
+
"Run `penv install` \u2014 it downloads and verifies every version the manifest pins, extensions included."
|
|
627
|
+
);
|
|
628
|
+
}
|
|
629
|
+
function localExtensionUnresolved(type, projectRoot, environment) {
|
|
630
|
+
return new import_core4.PenvError(
|
|
631
|
+
"LOCAL_EXTENSION_UNRESOLVED",
|
|
632
|
+
`${import_core4.LOCAL_EXTENSIONS_PATH} records \`${type}\`${where(environment)} as a package this project develops, and it does not resolve from ${projectRoot}`,
|
|
633
|
+
`Add it as a dependency of the root (a workspace link is one) and run \`pnpm install\`, or drop the name from ${import_core4.LOCAL_EXTENSIONS_PATH} if this project no longer builds it.`
|
|
634
|
+
);
|
|
635
|
+
}
|
|
636
|
+
function providerLoadFailed(type, path, cause) {
|
|
637
|
+
const detail = cause instanceof Error ? cause.message : String(cause);
|
|
638
|
+
return new import_core4.PenvError(
|
|
639
|
+
"PROVIDER_PLUGIN_LOAD",
|
|
640
|
+
`The provider package \`${type}\` failed to load from ${path}: ${detail}`,
|
|
641
|
+
"penv imports that file exactly as it stands, with no transform, so it has to be built JavaScript with its dependencies installed."
|
|
568
642
|
);
|
|
569
643
|
}
|
|
570
644
|
|
|
@@ -594,10 +668,10 @@ function localTree(project) {
|
|
|
594
668
|
}
|
|
595
669
|
function selfContainedSchemaModule(root, schemaFile) {
|
|
596
670
|
const file = (0, import_node_path4.join)(root, ...schemaFile.split("/"));
|
|
597
|
-
if (!(0,
|
|
671
|
+
if (!(0, import_node_fs4.existsSync)(file)) {
|
|
598
672
|
return void 0;
|
|
599
673
|
}
|
|
600
|
-
const source = (0,
|
|
674
|
+
const source = (0, import_node_fs4.readFileSync)(file, "utf8");
|
|
601
675
|
return source.includes("PenvSchemaShape") || source.includes("z.object") ? schemaFile : void 0;
|
|
602
676
|
}
|
|
603
677
|
function schemaShapeFileOf(project) {
|
|
@@ -833,10 +907,7 @@ function writeError(lines) {
|
|
|
833
907
|
}
|
|
834
908
|
function reportError(error) {
|
|
835
909
|
if (error instanceof import_core6.PenvError) {
|
|
836
|
-
|
|
837
|
-
${error.remedy}`;
|
|
838
|
-
const message = suffix !== void 0 && error.message.endsWith(suffix) ? error.message.slice(0, -suffix.length) : error.message;
|
|
839
|
-
process.stderr.write(`${err.red(CROSS)} ${message}
|
|
910
|
+
process.stderr.write(`${err.red(CROSS)} ${error.summary}
|
|
840
911
|
`);
|
|
841
912
|
if (error.remedy !== void 0) {
|
|
842
913
|
process.stderr.write(` ${err.cyan("\u2192")} ${error.remedy}
|
|
@@ -866,7 +937,7 @@ async function guard(run) {
|
|
|
866
937
|
}
|
|
867
938
|
|
|
868
939
|
// src/commands/run.ts
|
|
869
|
-
var
|
|
940
|
+
var import_node_fs6 = require("fs");
|
|
870
941
|
var import_node_module2 = require("module");
|
|
871
942
|
var import_node_path6 = require("path");
|
|
872
943
|
var import_core11 = require("@penvhq/core");
|
|
@@ -874,7 +945,7 @@ var import_runtime = require("@penvhq/runtime");
|
|
|
874
945
|
var import_citty3 = require("citty");
|
|
875
946
|
|
|
876
947
|
// src/dotenv-files.ts
|
|
877
|
-
var
|
|
948
|
+
var import_node_fs5 = require("fs");
|
|
878
949
|
var import_core7 = require("@penvhq/core");
|
|
879
950
|
var SHARED = ".env";
|
|
880
951
|
var LOCAL = "local";
|
|
@@ -934,7 +1005,7 @@ function order(file) {
|
|
|
934
1005
|
function discoverDotenvFiles(root) {
|
|
935
1006
|
let entries;
|
|
936
1007
|
try {
|
|
937
|
-
entries = (0,
|
|
1008
|
+
entries = (0, import_node_fs5.readdirSync)(root, { withFileTypes: true }).filter((entry) => entry.isFile()).map((entry) => entry.name);
|
|
938
1009
|
} catch {
|
|
939
1010
|
return [];
|
|
940
1011
|
}
|
|
@@ -1671,9 +1742,9 @@ function packageManifest(specifier, root) {
|
|
|
1671
1742
|
}
|
|
1672
1743
|
for (; ; ) {
|
|
1673
1744
|
const file = (0, import_node_path6.join)(directory, "package.json");
|
|
1674
|
-
if ((0,
|
|
1745
|
+
if ((0, import_node_fs6.existsSync)(file)) {
|
|
1675
1746
|
try {
|
|
1676
|
-
const parsed = JSON.parse((0,
|
|
1747
|
+
const parsed = JSON.parse((0, import_node_fs6.readFileSync)(file, "utf8"));
|
|
1677
1748
|
if (isPlainObject(parsed) && parsed.name === specifier) {
|
|
1678
1749
|
return parsed;
|
|
1679
1750
|
}
|
|
@@ -1746,7 +1817,7 @@ function snapshotPath(host) {
|
|
|
1746
1817
|
}
|
|
1747
1818
|
function readSnapshot(path) {
|
|
1748
1819
|
try {
|
|
1749
|
-
return (0,
|
|
1820
|
+
return (0, import_node_fs6.readFileSync)(path, "utf8");
|
|
1750
1821
|
} catch {
|
|
1751
1822
|
throw new import_core11.PenvError(
|
|
1752
1823
|
"RUN_SNAPSHOT_MISSING",
|
|
@@ -1825,11 +1896,11 @@ function watchProject(project, onChange) {
|
|
|
1825
1896
|
timer = setTimeout(onChange, DEBOUNCE_MS);
|
|
1826
1897
|
};
|
|
1827
1898
|
const add = (target, recursive, only) => {
|
|
1828
|
-
if (!(0,
|
|
1899
|
+
if (!(0, import_node_fs6.existsSync)(target)) {
|
|
1829
1900
|
return;
|
|
1830
1901
|
}
|
|
1831
1902
|
try {
|
|
1832
|
-
const watcher = (0,
|
|
1903
|
+
const watcher = (0, import_node_fs6.watch)(target, { recursive }, (_event, filename) => {
|
|
1833
1904
|
if (only !== void 0 && (filename === null || (0, import_node_path6.basename)(filename) !== only)) {
|
|
1834
1905
|
return;
|
|
1835
1906
|
}
|
|
@@ -2092,8 +2163,8 @@ ${lines}`,
|
|
|
2092
2163
|
keySource: (0, import_core12.keySourceIdentifier)(project.config, environment),
|
|
2093
2164
|
values
|
|
2094
2165
|
};
|
|
2095
|
-
(0,
|
|
2096
|
-
(0,
|
|
2166
|
+
(0, import_node_fs7.mkdirSync)((0, import_node_path7.dirname)(file), { recursive: true });
|
|
2167
|
+
(0, import_node_fs7.writeFileSync)(file, (0, import_core12.serializeArtifact)(artifact), "utf8");
|
|
2097
2168
|
const inside = (0, import_node_path7.relative)(project.root, file);
|
|
2098
2169
|
return {
|
|
2099
2170
|
file,
|
|
@@ -2163,7 +2234,7 @@ var import_core14 = require("@penvhq/core");
|
|
|
2163
2234
|
var import_citty5 = require("citty");
|
|
2164
2235
|
|
|
2165
2236
|
// src/cutover.ts
|
|
2166
|
-
var
|
|
2237
|
+
var import_node_fs8 = require("fs");
|
|
2167
2238
|
var import_node_path8 = require("path");
|
|
2168
2239
|
var import_core13 = require("@penvhq/core");
|
|
2169
2240
|
var CUTOVER_FORMAT = 1;
|
|
@@ -2182,7 +2253,7 @@ function cutoverRoot(cwd) {
|
|
|
2182
2253
|
}
|
|
2183
2254
|
function bundledFiles(root) {
|
|
2184
2255
|
try {
|
|
2185
|
-
return (0,
|
|
2256
|
+
return (0, import_node_fs8.readdirSync)(bundleDir(root)).sort();
|
|
2186
2257
|
} catch {
|
|
2187
2258
|
return [];
|
|
2188
2259
|
}
|
|
@@ -2192,12 +2263,12 @@ function bundleUnresolved(root) {
|
|
|
2192
2263
|
}
|
|
2193
2264
|
function readCutover(root) {
|
|
2194
2265
|
const file = cutoverFile(root);
|
|
2195
|
-
if (!(0,
|
|
2266
|
+
if (!(0, import_node_fs8.existsSync)(file)) {
|
|
2196
2267
|
return void 0;
|
|
2197
2268
|
}
|
|
2198
2269
|
let parsed;
|
|
2199
2270
|
try {
|
|
2200
|
-
parsed = JSON.parse((0,
|
|
2271
|
+
parsed = JSON.parse((0, import_node_fs8.readFileSync)(file, "utf8"));
|
|
2201
2272
|
} catch {
|
|
2202
2273
|
throw unreadable("it is not JSON");
|
|
2203
2274
|
}
|
|
@@ -2250,12 +2321,12 @@ function bundleDotenvFiles(root, files, environments, now = /* @__PURE__ */ new
|
|
|
2250
2321
|
environments: [...environments]
|
|
2251
2322
|
};
|
|
2252
2323
|
const file = cutoverFile(root);
|
|
2253
|
-
(0,
|
|
2254
|
-
(0,
|
|
2324
|
+
(0, import_node_fs8.mkdirSync)((0, import_node_path8.dirname)(file), { recursive: true });
|
|
2325
|
+
(0, import_node_fs8.writeFileSync)(file, serializeCutover(cutover), "utf8");
|
|
2255
2326
|
const bundle = bundleDir(root);
|
|
2256
|
-
(0,
|
|
2327
|
+
(0, import_node_fs8.mkdirSync)(bundle, { recursive: true });
|
|
2257
2328
|
for (const name of files) {
|
|
2258
|
-
(0,
|
|
2329
|
+
(0, import_node_fs8.renameSync)((0, import_node_path8.join)(root, name), (0, import_node_path8.join)(bundle, name));
|
|
2259
2330
|
}
|
|
2260
2331
|
return cutover;
|
|
2261
2332
|
}
|
|
@@ -2274,7 +2345,7 @@ function runUndo(options) {
|
|
|
2274
2345
|
const names = [...recorded, ...bundled.filter((name) => !recorded.includes(name))];
|
|
2275
2346
|
const bundle = bundleDir(root);
|
|
2276
2347
|
const held = new Set(bundled);
|
|
2277
|
-
const occupied2 = names.filter((name) => held.has(name) && (0,
|
|
2348
|
+
const occupied2 = names.filter((name) => held.has(name) && (0, import_node_fs8.existsSync)((0, import_node_path8.join)(root, name)));
|
|
2278
2349
|
if (occupied2.length > 0) {
|
|
2279
2350
|
const listed = occupied2.join(", ");
|
|
2280
2351
|
const many = occupied2.length > 1;
|
|
@@ -2289,9 +2360,9 @@ function runUndo(options) {
|
|
|
2289
2360
|
const missing = [];
|
|
2290
2361
|
for (const name of names) {
|
|
2291
2362
|
if (held.has(name)) {
|
|
2292
|
-
(0,
|
|
2363
|
+
(0, import_node_fs8.renameSync)((0, import_node_path8.join)(bundle, name), (0, import_node_path8.join)(root, name));
|
|
2293
2364
|
restored.push(name);
|
|
2294
|
-
} else if ((0,
|
|
2365
|
+
} else if ((0, import_node_fs8.existsSync)((0, import_node_path8.join)(root, name))) {
|
|
2295
2366
|
alreadyBack.push(name);
|
|
2296
2367
|
} else {
|
|
2297
2368
|
missing.push(name);
|
|
@@ -2303,13 +2374,13 @@ function runUndo(options) {
|
|
|
2303
2374
|
function runCleanup(options) {
|
|
2304
2375
|
const root = cutoverRoot(options.cwd);
|
|
2305
2376
|
const held = bundledFiles(root);
|
|
2306
|
-
const cleaned = held.length > 0 || (0,
|
|
2377
|
+
const cleaned = held.length > 0 || (0, import_node_fs8.existsSync)(cutoverFile(root)) || (0, import_node_fs8.existsSync)(fileFor(root, import_core13.ROLLBACK_PATH));
|
|
2307
2378
|
removeBundle(root);
|
|
2308
2379
|
return { root, removed: held, cleaned };
|
|
2309
2380
|
}
|
|
2310
2381
|
function removeBundle(root) {
|
|
2311
|
-
(0,
|
|
2312
|
-
(0,
|
|
2382
|
+
(0, import_node_fs8.rmSync)(fileFor(root, import_core13.ROLLBACK_PATH), { recursive: true, force: true });
|
|
2383
|
+
(0, import_node_fs8.rmSync)(cutoverFile(root), { force: true });
|
|
2313
2384
|
}
|
|
2314
2385
|
|
|
2315
2386
|
// src/commands/cleanup.ts
|
|
@@ -2344,7 +2415,7 @@ var cleanupCommand = (0, import_citty5.defineCommand)({
|
|
|
2344
2415
|
});
|
|
2345
2416
|
|
|
2346
2417
|
// src/commands/doctor.ts
|
|
2347
|
-
var
|
|
2418
|
+
var import_node_fs9 = require("fs");
|
|
2348
2419
|
var import_node_path9 = require("path");
|
|
2349
2420
|
var import_core16 = require("@penvhq/core");
|
|
2350
2421
|
var import_citty7 = require("citty");
|
|
@@ -2790,6 +2861,7 @@ async function runDoctor(options) {
|
|
|
2790
2861
|
findings.push(...unusedFindings(drift));
|
|
2791
2862
|
}
|
|
2792
2863
|
findings.push(...fallbackFindings(subjects, environment));
|
|
2864
|
+
findings.push(...secrecyFindings(subjects, environment));
|
|
2793
2865
|
findings.push(...plaintextSecretFindings(subjects, environment));
|
|
2794
2866
|
findings.push(...publicSecretFindings(subjects, environment, project.config));
|
|
2795
2867
|
findings.push(...encryptionFindings(subjects, environment));
|
|
@@ -2802,6 +2874,7 @@ async function runDoctor(options) {
|
|
|
2802
2874
|
}
|
|
2803
2875
|
findings.push(...await providerDriftFindings(project, environment, options.source));
|
|
2804
2876
|
findings.push(...await projectionFindings(project, environment, options.projection));
|
|
2877
|
+
findings.push(...localExtensionFindings(project));
|
|
2805
2878
|
findings.push(...artifactFindings(project));
|
|
2806
2879
|
findings.push({
|
|
2807
2880
|
check: "provider",
|
|
@@ -2939,6 +3012,31 @@ function fallbackFindings(subjects, environment) {
|
|
|
2939
3012
|
}
|
|
2940
3013
|
];
|
|
2941
3014
|
}
|
|
3015
|
+
function secrecyFindings(subjects, environment) {
|
|
3016
|
+
const undeclared = subjects.filter(
|
|
3017
|
+
({ meta }) => (0, import_core16.effectiveMeta)(meta, environment).secret === void 0
|
|
3018
|
+
);
|
|
3019
|
+
if (undeclared.length === 0) {
|
|
3020
|
+
return [
|
|
3021
|
+
{
|
|
3022
|
+
check: "secrecy-undeclared",
|
|
3023
|
+
severity: "pass",
|
|
3024
|
+
label: "Secrecy policy",
|
|
3025
|
+
subject: subjects.length === 0 ? `no parameter resolves for ${environment}` : `every parameter declares whether it is secret for ${environment}`
|
|
3026
|
+
}
|
|
3027
|
+
];
|
|
3028
|
+
}
|
|
3029
|
+
return [
|
|
3030
|
+
{
|
|
3031
|
+
check: "secrecy-undeclared",
|
|
3032
|
+
severity: "unknown",
|
|
3033
|
+
label: "Secrecy policy",
|
|
3034
|
+
subject: `${undeclared.length} of ${subjects.length} declare neither way for ${environment}`,
|
|
3035
|
+
detail: "penv was never told which of these values must be encrypted",
|
|
3036
|
+
remedy: `declare \`"secret": true\` or \`"secret": false\` in a parameter's meta file, ${import_core16.RECORDS_PATH}/<name>.json`
|
|
3037
|
+
}
|
|
3038
|
+
];
|
|
3039
|
+
}
|
|
2942
3040
|
function plaintextSecretFindings(subjects, environment) {
|
|
2943
3041
|
const secrets = subjects.filter(({ meta }) => (0, import_core16.isSecret)(meta, environment));
|
|
2944
3042
|
const findings = [];
|
|
@@ -3242,7 +3340,7 @@ function looksLikeArtifact(text) {
|
|
|
3242
3340
|
function scannableFiles(directory, out2) {
|
|
3243
3341
|
let entries;
|
|
3244
3342
|
try {
|
|
3245
|
-
entries = (0,
|
|
3343
|
+
entries = (0, import_node_fs9.readdirSync)(directory, { withFileTypes: true });
|
|
3246
3344
|
} catch {
|
|
3247
3345
|
return;
|
|
3248
3346
|
}
|
|
@@ -3259,6 +3357,29 @@ function scannableFiles(directory, out2) {
|
|
|
3259
3357
|
}
|
|
3260
3358
|
}
|
|
3261
3359
|
}
|
|
3360
|
+
function localExtensionFindings(project) {
|
|
3361
|
+
const names = localExtensions(project.root);
|
|
3362
|
+
if (names.length === 0) {
|
|
3363
|
+
return [
|
|
3364
|
+
{
|
|
3365
|
+
check: "local-extension",
|
|
3366
|
+
severity: "pass",
|
|
3367
|
+
label: "Extensions",
|
|
3368
|
+
subject: "every extension this project names is pinned"
|
|
3369
|
+
}
|
|
3370
|
+
];
|
|
3371
|
+
}
|
|
3372
|
+
return [
|
|
3373
|
+
{
|
|
3374
|
+
check: "local-extension",
|
|
3375
|
+
severity: "unknown",
|
|
3376
|
+
label: "Extensions",
|
|
3377
|
+
subject: names.join(", "),
|
|
3378
|
+
detail: "resolved from this project's node_modules \u2014 no release, no pinned bytes",
|
|
3379
|
+
remedy: `publish it and run \`penv add ${names[0]}\` when this stops being a development path`
|
|
3380
|
+
}
|
|
3381
|
+
];
|
|
3382
|
+
}
|
|
3262
3383
|
function artifactFindings(project) {
|
|
3263
3384
|
const files = [];
|
|
3264
3385
|
scannableFiles(project.root, files);
|
|
@@ -3266,10 +3387,10 @@ function artifactFindings(project) {
|
|
|
3266
3387
|
for (const file of files) {
|
|
3267
3388
|
let text;
|
|
3268
3389
|
try {
|
|
3269
|
-
if ((0,
|
|
3390
|
+
if ((0, import_node_fs9.statSync)(file).size > ARTIFACT_SCAN_LIMIT) {
|
|
3270
3391
|
continue;
|
|
3271
3392
|
}
|
|
3272
|
-
text = (0,
|
|
3393
|
+
text = (0, import_node_fs9.readFileSync)(file, "utf8");
|
|
3273
3394
|
} catch {
|
|
3274
3395
|
continue;
|
|
3275
3396
|
}
|
|
@@ -4029,7 +4150,7 @@ var fillCommand = (0, import_citty10.defineCommand)({
|
|
|
4029
4150
|
});
|
|
4030
4151
|
|
|
4031
4152
|
// src/commands/generate.ts
|
|
4032
|
-
var
|
|
4153
|
+
var import_node_fs10 = require("fs");
|
|
4033
4154
|
var import_node_path10 = require("path");
|
|
4034
4155
|
var import_core20 = require("@penvhq/core");
|
|
4035
4156
|
var import_citty11 = require("citty");
|
|
@@ -4083,7 +4204,7 @@ function runGenerate(options) {
|
|
|
4083
4204
|
const environment = targetEnvironment(project, options.environment, options.envFlags);
|
|
4084
4205
|
const { entries, decrypted } = entriesFor(project, environment, options.allowDecrypt === true);
|
|
4085
4206
|
const file = 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);
|
|
4086
|
-
(0,
|
|
4207
|
+
(0, import_node_fs10.writeFileSync)(file, (0, import_core20.serializeDotenv)(entries), "utf8");
|
|
4087
4208
|
return { file, environment, entries: entries.length, decrypted };
|
|
4088
4209
|
}
|
|
4089
4210
|
function displayPath2(cwd, file) {
|
|
@@ -4221,7 +4342,7 @@ var getCommand = (0, import_citty12.defineCommand)({
|
|
|
4221
4342
|
});
|
|
4222
4343
|
|
|
4223
4344
|
// src/commands/import.ts
|
|
4224
|
-
var
|
|
4345
|
+
var import_node_fs14 = require("fs");
|
|
4225
4346
|
var import_node_path14 = require("path");
|
|
4226
4347
|
var import_core26 = require("@penvhq/core");
|
|
4227
4348
|
var import_citty14 = require("citty");
|
|
@@ -4238,9 +4359,9 @@ function assertImportable(ref, variable) {
|
|
|
4238
4359
|
`Filenames are split on \`.\`. Rename ${variable} in the source file, then import it again.`
|
|
4239
4360
|
);
|
|
4240
4361
|
}
|
|
4241
|
-
function assertNotReserved(ref, variable,
|
|
4362
|
+
function assertNotReserved(ref, variable, where2, config) {
|
|
4242
4363
|
if ((0, import_core22.isReservedToken)(ref.name, config)) {
|
|
4243
|
-
throw new import_core22.ReservedTokenError("parameter", variable,
|
|
4364
|
+
throw new import_core22.ReservedTokenError("parameter", variable, where2);
|
|
4244
4365
|
}
|
|
4245
4366
|
}
|
|
4246
4367
|
function assertRoundTrips(ref, variable, config) {
|
|
@@ -4257,12 +4378,12 @@ function assertRoundTrips(ref, variable, config) {
|
|
|
4257
4378
|
`\`penv generate\` would write ${generated}, so anything reading \`process.env["${variable}"]\` would read \`undefined\`. Declare the name you want in the \`override\` block of penv.config.ts \u2014 \`override: { "${ref.name}": "${variable}" }\` \u2014 then import it again. Nothing was imported.`
|
|
4258
4379
|
);
|
|
4259
4380
|
}
|
|
4260
|
-
function refsForEntries(entries,
|
|
4381
|
+
function refsForEntries(entries, where2, config) {
|
|
4261
4382
|
const refs = [];
|
|
4262
4383
|
for (const entry of entries) {
|
|
4263
4384
|
const ref = (0, import_core22.refFromVariable)(entry.key);
|
|
4264
4385
|
assertImportable(ref, entry.key);
|
|
4265
|
-
assertNotReserved(ref, entry.key,
|
|
4386
|
+
assertNotReserved(ref, entry.key, where2, config);
|
|
4266
4387
|
assertRoundTrips(ref, entry.key, config);
|
|
4267
4388
|
refs.push(ref);
|
|
4268
4389
|
}
|
|
@@ -4292,7 +4413,7 @@ function writeEntries(tree, entries, refs, scope) {
|
|
|
4292
4413
|
}
|
|
4293
4414
|
|
|
4294
4415
|
// src/detect.ts
|
|
4295
|
-
var
|
|
4416
|
+
var import_node_fs11 = require("fs");
|
|
4296
4417
|
var import_node_path11 = require("path");
|
|
4297
4418
|
var import_core23 = require("@penvhq/core");
|
|
4298
4419
|
var SIGNATURES = [
|
|
@@ -4310,7 +4431,7 @@ var SIGNATURES = [
|
|
|
4310
4431
|
function exportsSchema(file) {
|
|
4311
4432
|
let source;
|
|
4312
4433
|
try {
|
|
4313
|
-
source = (0,
|
|
4434
|
+
source = (0, import_node_fs11.readFileSync)(file, "utf8");
|
|
4314
4435
|
} catch {
|
|
4315
4436
|
return false;
|
|
4316
4437
|
}
|
|
@@ -4322,7 +4443,7 @@ function exportsSchema(file) {
|
|
|
4322
4443
|
}
|
|
4323
4444
|
function occupied(cwd, relative5) {
|
|
4324
4445
|
const file = (0, import_node_path11.join)(cwd, ...relative5.split("/"));
|
|
4325
|
-
return (0,
|
|
4446
|
+
return (0, import_node_fs11.existsSync)(file) && !exportsSchema(file);
|
|
4326
4447
|
}
|
|
4327
4448
|
function schemaFileFor(cwd) {
|
|
4328
4449
|
const dir = srcPrefix(cwd);
|
|
@@ -4337,7 +4458,7 @@ function schemaFileFor(cwd) {
|
|
|
4337
4458
|
return { file: import_core23.DEFAULT_SCHEMA_FILE, displaced: preferred };
|
|
4338
4459
|
}
|
|
4339
4460
|
function srcPrefix(cwd) {
|
|
4340
|
-
return (0,
|
|
4461
|
+
return (0, import_node_fs11.existsSync)((0, import_node_path11.join)(cwd, "src")) ? "src/" : "";
|
|
4341
4462
|
}
|
|
4342
4463
|
function dependenciesOf(cwd) {
|
|
4343
4464
|
const manifest = manifestOf2(cwd);
|
|
@@ -4357,12 +4478,12 @@ function dependenciesOf(cwd) {
|
|
|
4357
4478
|
}
|
|
4358
4479
|
function manifestOf2(cwd) {
|
|
4359
4480
|
const file = (0, import_node_path11.join)(cwd, "package.json");
|
|
4360
|
-
if (!(0,
|
|
4481
|
+
if (!(0, import_node_fs11.existsSync)(file)) {
|
|
4361
4482
|
return void 0;
|
|
4362
4483
|
}
|
|
4363
4484
|
let manifest;
|
|
4364
4485
|
try {
|
|
4365
|
-
manifest = JSON.parse((0,
|
|
4486
|
+
manifest = JSON.parse((0, import_node_fs11.readFileSync)(file, "utf8"));
|
|
4366
4487
|
} catch {
|
|
4367
4488
|
return void 0;
|
|
4368
4489
|
}
|
|
@@ -4378,7 +4499,7 @@ function detectFramework(cwd) {
|
|
|
4378
4499
|
return detectedFrom(cwd, signature.name, signature.publicPrefixes);
|
|
4379
4500
|
}
|
|
4380
4501
|
}
|
|
4381
|
-
if ((0,
|
|
4502
|
+
if ((0, import_node_fs11.existsSync)((0, import_node_path11.join)(cwd, "bunfig.toml")) || dependencies.has("bun-types")) {
|
|
4382
4503
|
return detectedFrom(cwd, "Bun", []);
|
|
4383
4504
|
}
|
|
4384
4505
|
return void 0;
|
|
@@ -4457,31 +4578,31 @@ function draftFieldsAcross(sources, environments) {
|
|
|
4457
4578
|
}
|
|
4458
4579
|
|
|
4459
4580
|
// src/commands/init.ts
|
|
4460
|
-
var
|
|
4581
|
+
var import_node_fs13 = require("fs");
|
|
4461
4582
|
var import_node_path13 = require("path");
|
|
4462
4583
|
var import_promises = require("readline/promises");
|
|
4463
4584
|
var import_core25 = require("@penvhq/core");
|
|
4464
4585
|
var import_citty13 = require("citty");
|
|
4465
4586
|
|
|
4466
4587
|
// src/scaffold-undo.ts
|
|
4467
|
-
var
|
|
4588
|
+
var import_node_fs12 = require("fs");
|
|
4468
4589
|
var import_node_path12 = require("path");
|
|
4469
4590
|
function record(path, files, dirs) {
|
|
4470
4591
|
let stats;
|
|
4471
4592
|
try {
|
|
4472
|
-
stats = (0,
|
|
4593
|
+
stats = (0, import_node_fs12.statSync)(path);
|
|
4473
4594
|
} catch {
|
|
4474
4595
|
return;
|
|
4475
4596
|
}
|
|
4476
4597
|
if (stats.isDirectory()) {
|
|
4477
4598
|
dirs.add(path);
|
|
4478
|
-
for (const entry of (0,
|
|
4599
|
+
for (const entry of (0, import_node_fs12.readdirSync)(path)) {
|
|
4479
4600
|
record((0, import_node_path12.join)(path, entry), files, dirs);
|
|
4480
4601
|
}
|
|
4481
4602
|
return;
|
|
4482
4603
|
}
|
|
4483
4604
|
if (stats.isFile()) {
|
|
4484
|
-
files.set(path, (0,
|
|
4605
|
+
files.set(path, (0, import_node_fs12.readFileSync)(path));
|
|
4485
4606
|
}
|
|
4486
4607
|
}
|
|
4487
4608
|
function captureScaffold(root, paths) {
|
|
@@ -4489,7 +4610,7 @@ function captureScaffold(root, paths) {
|
|
|
4489
4610
|
const dirs = /* @__PURE__ */ new Set();
|
|
4490
4611
|
for (const path of paths) {
|
|
4491
4612
|
for (let dir = (0, import_node_path12.dirname)(path); dir.startsWith(root) && dir !== root; dir = (0, import_node_path12.dirname)(dir)) {
|
|
4492
|
-
if ((0,
|
|
4613
|
+
if ((0, import_node_fs12.existsSync)(dir)) {
|
|
4493
4614
|
dirs.add(dir);
|
|
4494
4615
|
}
|
|
4495
4616
|
}
|
|
@@ -4505,31 +4626,31 @@ function restoreScaffold(undo) {
|
|
|
4505
4626
|
pruneAncestors(path, undo);
|
|
4506
4627
|
}
|
|
4507
4628
|
for (const [file, contents] of undo.files) {
|
|
4508
|
-
(0,
|
|
4509
|
-
(0,
|
|
4629
|
+
(0, import_node_fs12.mkdirSync)((0, import_node_path12.dirname)(file), { recursive: true });
|
|
4630
|
+
(0, import_node_fs12.writeFileSync)(file, contents);
|
|
4510
4631
|
}
|
|
4511
4632
|
}
|
|
4512
4633
|
function removeAdded(path, undo) {
|
|
4513
4634
|
let stats;
|
|
4514
4635
|
try {
|
|
4515
|
-
stats = (0,
|
|
4636
|
+
stats = (0, import_node_fs12.statSync)(path);
|
|
4516
4637
|
} catch {
|
|
4517
4638
|
return;
|
|
4518
4639
|
}
|
|
4519
4640
|
if (stats.isFile()) {
|
|
4520
4641
|
if (!undo.files.has(path)) {
|
|
4521
|
-
(0,
|
|
4642
|
+
(0, import_node_fs12.unlinkSync)(path);
|
|
4522
4643
|
}
|
|
4523
4644
|
return;
|
|
4524
4645
|
}
|
|
4525
4646
|
if (!stats.isDirectory()) {
|
|
4526
4647
|
return;
|
|
4527
4648
|
}
|
|
4528
|
-
for (const entry of (0,
|
|
4649
|
+
for (const entry of (0, import_node_fs12.readdirSync)(path)) {
|
|
4529
4650
|
removeAdded((0, import_node_path12.join)(path, entry), undo);
|
|
4530
4651
|
}
|
|
4531
|
-
if (!undo.dirs.has(path) && (0,
|
|
4532
|
-
(0,
|
|
4652
|
+
if (!undo.dirs.has(path) && (0, import_node_fs12.readdirSync)(path).length === 0) {
|
|
4653
|
+
(0, import_node_fs12.rmdirSync)(path);
|
|
4533
4654
|
}
|
|
4534
4655
|
}
|
|
4535
4656
|
function pruneAncestors(path, undo) {
|
|
@@ -4538,7 +4659,7 @@ function pruneAncestors(path, undo) {
|
|
|
4538
4659
|
return;
|
|
4539
4660
|
}
|
|
4540
4661
|
try {
|
|
4541
|
-
(0,
|
|
4662
|
+
(0, import_node_fs12.rmdirSync)(dir);
|
|
4542
4663
|
} catch {
|
|
4543
4664
|
return;
|
|
4544
4665
|
}
|
|
@@ -4700,7 +4821,7 @@ var NOT_ENVIRONMENTS2 = [...import_core25.RESERVED_TOKENS, "example", "sample",
|
|
|
4700
4821
|
function suggestEnvironments(root) {
|
|
4701
4822
|
let entries;
|
|
4702
4823
|
try {
|
|
4703
|
-
entries = (0,
|
|
4824
|
+
entries = (0, import_node_fs13.readdirSync)(root);
|
|
4704
4825
|
} catch {
|
|
4705
4826
|
return [];
|
|
4706
4827
|
}
|
|
@@ -4745,7 +4866,7 @@ function configOf(decisions) {
|
|
|
4745
4866
|
}
|
|
4746
4867
|
function declaredIn(root) {
|
|
4747
4868
|
const file = (0, import_node_path13.join)(root, CONFIG_FILE);
|
|
4748
|
-
if (!(0,
|
|
4869
|
+
if (!(0, import_node_fs13.existsSync)(file)) {
|
|
4749
4870
|
return void 0;
|
|
4750
4871
|
}
|
|
4751
4872
|
return (0, import_core25.loadConfigFrom)(file);
|
|
@@ -5188,15 +5309,15 @@ function renderTsconfig(target, alias) {
|
|
|
5188
5309
|
}
|
|
5189
5310
|
function ensurePenvDir(root) {
|
|
5190
5311
|
const dir = (0, import_node_path13.resolve)(root, import_core25.PENV_DIR);
|
|
5191
|
-
if ((0,
|
|
5312
|
+
if ((0, import_node_fs13.existsSync)(dir)) {
|
|
5192
5313
|
return { target: "penv-dir", action: "kept", text: `Found ${import_core25.PENV_DIR}/` };
|
|
5193
5314
|
}
|
|
5194
|
-
(0,
|
|
5315
|
+
(0, import_node_fs13.mkdirSync)(dir, { recursive: true });
|
|
5195
5316
|
return { target: "penv-dir", action: "created", text: `Created ${import_core25.PENV_DIR}/` };
|
|
5196
5317
|
}
|
|
5197
5318
|
function writeSchemaShapeFile(root, fields, draft, decisions = DEFAULT_DECISIONS) {
|
|
5198
5319
|
const file = (0, import_node_path13.join)(root, import_core25.SCHEMA_SHAPE_FILE);
|
|
5199
|
-
if ((0,
|
|
5320
|
+
if ((0, import_node_fs13.existsSync)(file)) {
|
|
5200
5321
|
return {
|
|
5201
5322
|
target: "schema",
|
|
5202
5323
|
action: "kept",
|
|
@@ -5213,7 +5334,7 @@ function writeSchemaShapeFile(root, fields, draft, decisions = DEFAULT_DECISIONS
|
|
|
5213
5334
|
note: `(the shape lives there, from before the ${import_core25.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 ${import_core25.SCHEMA_SHAPE_FILE}, leaving ${oldLayout} importing \`schema\` from it and calling \`load\`.)`
|
|
5214
5335
|
};
|
|
5215
5336
|
}
|
|
5216
|
-
(0,
|
|
5337
|
+
(0, import_node_fs13.writeFileSync)(file, renderSchemaShapeModule(fields, draft), "utf8");
|
|
5217
5338
|
return {
|
|
5218
5339
|
target: "schema",
|
|
5219
5340
|
action: "created",
|
|
@@ -5223,7 +5344,7 @@ function writeSchemaShapeFile(root, fields, draft, decisions = DEFAULT_DECISIONS
|
|
|
5223
5344
|
}
|
|
5224
5345
|
function writeEnvFile(root, decisions = DEFAULT_DECISIONS) {
|
|
5225
5346
|
const file = (0, import_node_path13.join)(root, ...decisions.schemaFile.split("/"));
|
|
5226
|
-
if ((0,
|
|
5347
|
+
if ((0, import_node_fs13.existsSync)(file)) {
|
|
5227
5348
|
return {
|
|
5228
5349
|
target: "env",
|
|
5229
5350
|
action: "kept",
|
|
@@ -5231,8 +5352,8 @@ function writeEnvFile(root, decisions = DEFAULT_DECISIONS) {
|
|
|
5231
5352
|
note: "(yours \u2014 penv never regenerates it)"
|
|
5232
5353
|
};
|
|
5233
5354
|
}
|
|
5234
|
-
(0,
|
|
5235
|
-
(0,
|
|
5355
|
+
(0, import_node_fs13.mkdirSync)((0, import_node_path13.dirname)(file), { recursive: true });
|
|
5356
|
+
(0, import_node_fs13.writeFileSync)(file, renderEnvModule(decisions.schemaFile, decisions.inject), "utf8");
|
|
5236
5357
|
return {
|
|
5237
5358
|
target: "env",
|
|
5238
5359
|
action: "created",
|
|
@@ -5242,18 +5363,18 @@ function writeEnvFile(root, decisions = DEFAULT_DECISIONS) {
|
|
|
5242
5363
|
}
|
|
5243
5364
|
function writeConfigFile(root, decisions = DEFAULT_DECISIONS) {
|
|
5244
5365
|
const file = (0, import_node_path13.join)(root, CONFIG_FILE);
|
|
5245
|
-
if ((0,
|
|
5366
|
+
if ((0, import_node_fs13.existsSync)(file)) {
|
|
5246
5367
|
return { target: "config", action: "kept", text: `Kept ${CONFIG_FILE}` };
|
|
5247
5368
|
}
|
|
5248
|
-
(0,
|
|
5369
|
+
(0, import_node_fs13.writeFileSync)(file, renderConfigModule(decisions), "utf8");
|
|
5249
5370
|
return { target: "config", action: "created", text: `Generated ${CONFIG_FILE}` };
|
|
5250
5371
|
}
|
|
5251
5372
|
function writeTsconfigAlias(root, decisions = DEFAULT_DECISIONS) {
|
|
5252
5373
|
const alias = decisions.alias;
|
|
5253
5374
|
const imports = alias.startsWith(IMPORTS_PREFIX);
|
|
5254
5375
|
const file = (0, import_node_path13.join)(root, imports ? PACKAGE_FILE : TSCONFIG_FILE);
|
|
5255
|
-
const
|
|
5256
|
-
if (!(0,
|
|
5376
|
+
const where2 = imports ? PACKAGE_FILE : TSCONFIG_FILE;
|
|
5377
|
+
if (!(0, import_node_fs13.existsSync)(file)) {
|
|
5257
5378
|
if (imports) {
|
|
5258
5379
|
return {
|
|
5259
5380
|
target: "tsconfig",
|
|
@@ -5262,20 +5383,20 @@ function writeTsconfigAlias(root, decisions = DEFAULT_DECISIONS) {
|
|
|
5262
5383
|
note: `(run \`npm init\` first, or use \`--alias @env\` to alias through ${TSCONFIG_FILE})`
|
|
5263
5384
|
};
|
|
5264
5385
|
}
|
|
5265
|
-
(0,
|
|
5386
|
+
(0, import_node_fs13.writeFileSync)(file, renderTsconfig(decisions.schemaFile, alias), "utf8");
|
|
5266
5387
|
return {
|
|
5267
5388
|
target: "tsconfig",
|
|
5268
5389
|
action: "created",
|
|
5269
5390
|
text: `Created ${TSCONFIG_FILE} with the ${alias} path alias`
|
|
5270
5391
|
};
|
|
5271
5392
|
}
|
|
5272
|
-
const source = (0,
|
|
5393
|
+
const source = (0, import_node_fs13.readFileSync)(file, "utf8");
|
|
5273
5394
|
const edit = imports ? insertImportsAlias(source, decisions.schemaFile, alias) : insertEnvAlias(source, decisions.schemaFile, alias);
|
|
5274
5395
|
if (edit.conflict !== void 0) {
|
|
5275
5396
|
return {
|
|
5276
5397
|
target: "tsconfig",
|
|
5277
5398
|
action: "conflicted",
|
|
5278
|
-
text: `${
|
|
5399
|
+
text: `${where2} already maps ${alias} to ${edit.conflict}`,
|
|
5279
5400
|
note: `(left alone \u2014 \`import { env } from "${alias}"\` will not reach ${decisions.schemaFile})`
|
|
5280
5401
|
};
|
|
5281
5402
|
}
|
|
@@ -5283,25 +5404,25 @@ function writeTsconfigAlias(root, decisions = DEFAULT_DECISIONS) {
|
|
|
5283
5404
|
return {
|
|
5284
5405
|
target: "tsconfig",
|
|
5285
5406
|
action: "kept",
|
|
5286
|
-
text: `Kept the ${alias} alias in ${
|
|
5407
|
+
text: `Kept the ${alias} alias in ${where2}`
|
|
5287
5408
|
};
|
|
5288
5409
|
}
|
|
5289
|
-
(0,
|
|
5410
|
+
(0, import_node_fs13.writeFileSync)(file, edit.source, "utf8");
|
|
5290
5411
|
return {
|
|
5291
5412
|
target: "tsconfig",
|
|
5292
5413
|
action: "updated",
|
|
5293
|
-
text: `Added ${alias} alias to ${
|
|
5414
|
+
text: `Added ${alias} alias to ${where2}`
|
|
5294
5415
|
};
|
|
5295
5416
|
}
|
|
5296
5417
|
function writeGitignore(root, decisions = DEFAULT_DECISIONS) {
|
|
5297
5418
|
const file = (0, import_node_path13.join)(root, ...import_core25.STATE_GITIGNORE_PATH.split("/"));
|
|
5298
5419
|
const wanted = (0, import_core25.renderStateGitignore)(configOf(decisions));
|
|
5299
|
-
const existing = (0,
|
|
5420
|
+
const existing = (0, import_node_fs13.existsSync)(file) ? (0, import_node_fs13.readFileSync)(file, "utf8") : void 0;
|
|
5300
5421
|
if (existing === wanted) {
|
|
5301
5422
|
return { target: "gitignore", action: "kept", text: `Kept ${import_core25.STATE_GITIGNORE_PATH}` };
|
|
5302
5423
|
}
|
|
5303
|
-
(0,
|
|
5304
|
-
(0,
|
|
5424
|
+
(0, import_node_fs13.mkdirSync)((0, import_node_path13.dirname)(file), { recursive: true });
|
|
5425
|
+
(0, import_node_fs13.writeFileSync)(file, wanted, "utf8");
|
|
5305
5426
|
return {
|
|
5306
5427
|
target: "gitignore",
|
|
5307
5428
|
action: existing === void 0 ? "created" : "updated",
|
|
@@ -5318,11 +5439,11 @@ function outdatedRuntimeWarning(root) {
|
|
|
5318
5439
|
}
|
|
5319
5440
|
function installedPenvVersion(root) {
|
|
5320
5441
|
const file = (0, import_node_path13.join)(root, "node_modules", "@penvhq", "penv", "package.json");
|
|
5321
|
-
if (!(0,
|
|
5442
|
+
if (!(0, import_node_fs13.existsSync)(file)) {
|
|
5322
5443
|
return void 0;
|
|
5323
5444
|
}
|
|
5324
5445
|
try {
|
|
5325
|
-
const version = JSON.parse((0,
|
|
5446
|
+
const version = JSON.parse((0, import_node_fs13.readFileSync)(file, "utf8")).version;
|
|
5326
5447
|
return typeof version === "string" ? version : void 0;
|
|
5327
5448
|
} catch {
|
|
5328
5449
|
return void 0;
|
|
@@ -5366,7 +5487,7 @@ function writeSeam(root, decisions = DEFAULT_DECISIONS, framework = detectFramew
|
|
|
5366
5487
|
const baseNotes = [...seam.notes, ...alsoNote === void 0 ? [] : [alsoNote]];
|
|
5367
5488
|
const notes = baseNotes.length === 0 ? "" : `
|
|
5368
5489
|
${baseNotes.map((n) => ` ${n}`).join("\n")}`;
|
|
5369
|
-
if ((0,
|
|
5490
|
+
if ((0, import_node_fs13.existsSync)(file)) {
|
|
5370
5491
|
return {
|
|
5371
5492
|
target: "seam",
|
|
5372
5493
|
action: "info",
|
|
@@ -5374,8 +5495,8 @@ ${baseNotes.map((n) => ` ${n}`).join("\n")}`;
|
|
|
5374
5495
|
note: withWarning(`${seam.ifPresent}${notes}`, outdated)
|
|
5375
5496
|
};
|
|
5376
5497
|
}
|
|
5377
|
-
(0,
|
|
5378
|
-
(0,
|
|
5498
|
+
(0, import_node_fs13.mkdirSync)((0, import_node_path13.dirname)(file), { recursive: true });
|
|
5499
|
+
(0, import_node_fs13.writeFileSync)(file, seam.content, "utf8");
|
|
5379
5500
|
return {
|
|
5380
5501
|
target: "seam",
|
|
5381
5502
|
action: outdated === void 0 ? "created" : "info",
|
|
@@ -5388,11 +5509,11 @@ function writeAlso(root, also) {
|
|
|
5388
5509
|
return void 0;
|
|
5389
5510
|
}
|
|
5390
5511
|
const file = (0, import_node_path13.join)(root, ...also.file.split("/"));
|
|
5391
|
-
if ((0,
|
|
5512
|
+
if ((0, import_node_fs13.existsSync)(file)) {
|
|
5392
5513
|
return also.ifPresent;
|
|
5393
5514
|
}
|
|
5394
|
-
(0,
|
|
5395
|
-
(0,
|
|
5515
|
+
(0, import_node_fs13.mkdirSync)((0, import_node_path13.dirname)(file), { recursive: true });
|
|
5516
|
+
(0, import_node_fs13.writeFileSync)(file, also.content, "utf8");
|
|
5396
5517
|
return `Wrote ${also.file} to register it.`;
|
|
5397
5518
|
}
|
|
5398
5519
|
function withWarning(note, warning) {
|
|
@@ -5496,7 +5617,7 @@ function planCutover(input) {
|
|
|
5496
5617
|
const diagnostics = [];
|
|
5497
5618
|
let variables = 0;
|
|
5498
5619
|
for (const file of selected) {
|
|
5499
|
-
const parsed = (0, import_core25.parseDotenv)((0,
|
|
5620
|
+
const parsed = (0, import_core25.parseDotenv)((0, import_node_fs13.readFileSync)((0, import_node_path13.join)(root, file.name), "utf8"));
|
|
5500
5621
|
const fileRefs = refsForEntries(parsed.entries, file.name, config);
|
|
5501
5622
|
adopted.push({ file, entries: parsed.entries, refs: fileRefs, scope: scopeOf(file) });
|
|
5502
5623
|
refs.push(...fileRefs);
|
|
@@ -5741,11 +5862,11 @@ function dailyCommand(root) {
|
|
|
5741
5862
|
}
|
|
5742
5863
|
function devScript(root) {
|
|
5743
5864
|
const file = (0, import_node_path13.join)(root, PACKAGE_FILE);
|
|
5744
|
-
if (!(0,
|
|
5865
|
+
if (!(0, import_node_fs13.existsSync)(file)) {
|
|
5745
5866
|
return "dev";
|
|
5746
5867
|
}
|
|
5747
5868
|
try {
|
|
5748
|
-
const scripts = JSON.parse((0,
|
|
5869
|
+
const scripts = JSON.parse((0, import_node_fs13.readFileSync)(file, "utf8")).scripts;
|
|
5749
5870
|
if (scripts !== null && typeof scripts === "object" && !Array.isArray(scripts)) {
|
|
5750
5871
|
const named = Object.keys(scripts);
|
|
5751
5872
|
return ["dev", "start"].find((script) => named.includes(script)) ?? named[0] ?? "dev";
|
|
@@ -6114,14 +6235,14 @@ function configInEffect(cwd, environment) {
|
|
|
6114
6235
|
function importDotenv(options) {
|
|
6115
6236
|
const cwd = (0, import_node_path14.resolve)(options.cwd);
|
|
6116
6237
|
const file = (0, import_node_path14.isAbsolute)(options.file) ? options.file : (0, import_node_path14.resolve)(cwd, options.file);
|
|
6117
|
-
if (!(0,
|
|
6238
|
+
if (!(0, import_node_fs14.existsSync)(file)) {
|
|
6118
6239
|
throw new import_core26.PenvError(
|
|
6119
6240
|
"IMPORT_FILE_MISSING",
|
|
6120
6241
|
`There is no file at ${file} to import`,
|
|
6121
6242
|
"Point `penv import` at an existing dotenv file, e.g. `penv import .env`."
|
|
6122
6243
|
);
|
|
6123
6244
|
}
|
|
6124
|
-
const parsed = (0, import_core26.parseDotenv)((0,
|
|
6245
|
+
const parsed = (0, import_core26.parseDotenv)((0, import_node_fs14.readFileSync)(file, "utf8"));
|
|
6125
6246
|
const { config, decisions } = configInEffect(cwd, environmentNamed(file, options.environment));
|
|
6126
6247
|
const source = displayPath3(cwd, file);
|
|
6127
6248
|
const named = scopeFromFilename(file, config);
|
|
@@ -6137,7 +6258,7 @@ function importDotenv(options) {
|
|
|
6137
6258
|
const tree = localTree(project);
|
|
6138
6259
|
writeEntries(tree, parsed.entries, refs, scope);
|
|
6139
6260
|
const backup = `${file}${BACKUP_SUFFIX}`;
|
|
6140
|
-
(0,
|
|
6261
|
+
(0, import_node_fs14.copyFileSync)(file, backup);
|
|
6141
6262
|
return {
|
|
6142
6263
|
root: project.root,
|
|
6143
6264
|
file,
|
|
@@ -6472,7 +6593,7 @@ var listCommand = (0, import_citty16.defineCommand)({
|
|
|
6472
6593
|
});
|
|
6473
6594
|
|
|
6474
6595
|
// src/commands/migrate.ts
|
|
6475
|
-
var
|
|
6596
|
+
var import_node_fs15 = require("fs");
|
|
6476
6597
|
var import_node_path15 = require("path");
|
|
6477
6598
|
var import_promises2 = require("readline/promises");
|
|
6478
6599
|
var import_core30 = require("@penvhq/core");
|
|
@@ -6492,7 +6613,7 @@ function planMigrate(cwd) {
|
|
|
6492
6613
|
);
|
|
6493
6614
|
}
|
|
6494
6615
|
const creates = [];
|
|
6495
|
-
if (entries.length > 0 && !(0,
|
|
6616
|
+
if (entries.length > 0 && !(0, import_node_fs15.existsSync)(tree)) {
|
|
6496
6617
|
creates.push(`${import_core30.RECORDS_PATH}/`);
|
|
6497
6618
|
}
|
|
6498
6619
|
if (readIfPresent((0, import_node_path15.join)(root, ...import_core30.STATE_GITIGNORE_PATH.split("/"))) !== (0, import_core30.renderStateGitignore)(config)) {
|
|
@@ -6505,16 +6626,16 @@ function planMigrate(cwd) {
|
|
|
6505
6626
|
to: `${import_core30.RECORDS_PATH}/${entry}`
|
|
6506
6627
|
})),
|
|
6507
6628
|
creates,
|
|
6508
|
-
removes: (0,
|
|
6629
|
+
removes: (0, import_node_fs15.existsSync)((0, import_node_path15.join)(root, ...OLD_GITIGNORE.split("/"))) ? [OLD_GITIGNORE] : []
|
|
6509
6630
|
};
|
|
6510
6631
|
}
|
|
6511
6632
|
function readIfPresent(file) {
|
|
6512
|
-
return (0,
|
|
6633
|
+
return (0, import_node_fs15.existsSync)(file) ? (0, import_node_fs15.readFileSync)(file, "utf8") : void 0;
|
|
6513
6634
|
}
|
|
6514
6635
|
function collidingEntries(entries, tree) {
|
|
6515
6636
|
let held;
|
|
6516
6637
|
try {
|
|
6517
|
-
held = (0,
|
|
6638
|
+
held = (0, import_node_fs15.readdirSync)(tree);
|
|
6518
6639
|
} catch {
|
|
6519
6640
|
return [];
|
|
6520
6641
|
}
|
|
@@ -6533,18 +6654,18 @@ function applyMigrate(plan2) {
|
|
|
6533
6654
|
}
|
|
6534
6655
|
const { config } = (0, import_core30.loadConfig)(plan2.root);
|
|
6535
6656
|
if (plan2.moves.length > 0) {
|
|
6536
|
-
(0,
|
|
6657
|
+
(0, import_node_fs15.mkdirSync)((0, import_core30.recordsDir)(plan2.root), { recursive: true });
|
|
6537
6658
|
for (const move of plan2.moves) {
|
|
6538
|
-
(0,
|
|
6659
|
+
(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("/")));
|
|
6539
6660
|
}
|
|
6540
6661
|
}
|
|
6541
6662
|
if (plan2.creates.includes(import_core30.STATE_GITIGNORE_PATH)) {
|
|
6542
6663
|
const ignore = (0, import_node_path15.join)(plan2.root, ...import_core30.STATE_GITIGNORE_PATH.split("/"));
|
|
6543
|
-
(0,
|
|
6544
|
-
(0,
|
|
6664
|
+
(0, import_node_fs15.mkdirSync)((0, import_node_path15.dirname)(ignore), { recursive: true });
|
|
6665
|
+
(0, import_node_fs15.writeFileSync)(ignore, (0, import_core30.renderStateGitignore)(config), "utf8");
|
|
6545
6666
|
}
|
|
6546
6667
|
for (const removed of plan2.removes) {
|
|
6547
|
-
(0,
|
|
6668
|
+
(0, import_node_fs15.rmSync)((0, import_node_path15.join)(plan2.root, ...removed.split("/")), { force: true });
|
|
6548
6669
|
}
|
|
6549
6670
|
return { ...plan2, status: "migrated" };
|
|
6550
6671
|
}
|
|
@@ -7030,7 +7151,7 @@ var rotateCommand = (0, import_citty20.defineCommand)({
|
|
|
7030
7151
|
});
|
|
7031
7152
|
|
|
7032
7153
|
// src/commands/watch.ts
|
|
7033
|
-
var
|
|
7154
|
+
var import_node_fs16 = require("fs");
|
|
7034
7155
|
var import_node_path16 = require("path");
|
|
7035
7156
|
var import_core34 = require("@penvhq/core");
|
|
7036
7157
|
var import_citty21 = require("citty");
|
|
@@ -7094,18 +7215,18 @@ function runWatch(options) {
|
|
|
7094
7215
|
const name = (0, import_node_path16.basename)(target);
|
|
7095
7216
|
let recovery;
|
|
7096
7217
|
try {
|
|
7097
|
-
recovery = (0,
|
|
7218
|
+
recovery = (0, import_node_fs16.watch)(parent, { recursive: false }, (_event, filename) => {
|
|
7098
7219
|
if (closed || recovery === void 0) {
|
|
7099
7220
|
return;
|
|
7100
7221
|
}
|
|
7101
|
-
if (!(0,
|
|
7222
|
+
if (!(0, import_node_fs16.existsSync)(parent)) {
|
|
7102
7223
|
stop2(recovery);
|
|
7103
7224
|
return;
|
|
7104
7225
|
}
|
|
7105
7226
|
if (filename !== null && (0, import_node_path16.basename)(filename) !== name) {
|
|
7106
7227
|
return;
|
|
7107
7228
|
}
|
|
7108
|
-
if (!(0,
|
|
7229
|
+
if (!(0, import_node_fs16.existsSync)(target)) {
|
|
7109
7230
|
return;
|
|
7110
7231
|
}
|
|
7111
7232
|
stop2(recovery);
|
|
@@ -7125,11 +7246,11 @@ function runWatch(options) {
|
|
|
7125
7246
|
}
|
|
7126
7247
|
function addWatcher(target, recursive, only) {
|
|
7127
7248
|
let watcher;
|
|
7128
|
-
const listen = (useRecursive) => (0,
|
|
7249
|
+
const listen = (useRecursive) => (0, import_node_fs16.watch)(target, { recursive: useRecursive }, (_event, filename) => {
|
|
7129
7250
|
if (closed) {
|
|
7130
7251
|
return;
|
|
7131
7252
|
}
|
|
7132
|
-
if (!(0,
|
|
7253
|
+
if (!(0, import_node_fs16.existsSync)(target)) {
|
|
7133
7254
|
if (watcher !== void 0) {
|
|
7134
7255
|
stop2(watcher);
|
|
7135
7256
|
}
|