@geekmidas/cli 10.0.0-alpha.25 → 10.0.0-alpha.27
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/{config-Dn9DW2Fz.cjs → config-7R_-WyHq.cjs} +24 -3
- package/dist/{config-Dn9DW2Fz.cjs.map → config-7R_-WyHq.cjs.map} +1 -1
- package/dist/{config-DBGpRTUy.mjs → config-DXrrYvob.mjs} +19 -4
- package/dist/{config-DBGpRTUy.mjs.map → config-DXrrYvob.mjs.map} +1 -1
- package/dist/config.cjs +3 -2
- package/dist/config.d.cts +12 -1
- package/dist/config.d.cts.map +1 -1
- package/dist/config.d.mts +12 -1
- package/dist/config.d.mts.map +1 -1
- package/dist/config.mjs +3 -3
- package/dist/{github-BOaa3kQR.mjs → github-Ba5kXEJo.mjs} +4 -4
- package/dist/{github-BOaa3kQR.mjs.map → github-Ba5kXEJo.mjs.map} +1 -1
- package/dist/{github-CUjW3G91.cjs → github-CQflOKKV.cjs} +4 -4
- package/dist/{github-CUjW3G91.cjs.map → github-CQflOKKV.cjs.map} +1 -1
- package/dist/{index-RCUizGxL.d.cts → index-BPN7kghQ.d.cts} +2 -12
- package/dist/{index-B4H4XF7A.d.mts.map → index-BPN7kghQ.d.cts.map} +1 -1
- package/dist/{index-B4H4XF7A.d.mts → index-BqWKWRm0.d.mts} +2 -12
- package/dist/{index-RCUizGxL.d.cts.map → index-BqWKWRm0.d.mts.map} +1 -1
- package/dist/index.cjs +170 -169
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +123 -122
- package/dist/index.mjs.map +1 -1
- package/dist/{openapi-DHQlstv6.mjs → openapi-3NLVvtz-.mjs} +2 -2
- package/dist/{openapi-DHQlstv6.mjs.map → openapi-3NLVvtz-.mjs.map} +1 -1
- package/dist/{openapi-BAKQLho-.cjs → openapi-rhJdy2GC.cjs} +2 -2
- package/dist/{openapi-BAKQLho-.cjs.map → openapi-rhJdy2GC.cjs.map} +1 -1
- package/dist/openapi.cjs +1 -1
- package/dist/openapi.mjs +1 -1
- package/dist/{generator-LfZU7NlU.mjs → reconcile-DhbCvh4K.mjs} +111 -2
- package/dist/reconcile-DhbCvh4K.mjs.map +1 -0
- package/dist/{generator-Wdfp0jCS.cjs → reconcile-szmJw_Sb.cjs} +130 -3
- package/dist/reconcile-szmJw_Sb.cjs.map +1 -0
- package/dist/{transfer-B88fTvnh.mjs → transfer-BV00TxZv.mjs} +4 -4
- package/dist/{transfer-B88fTvnh.mjs.map → transfer-BV00TxZv.mjs.map} +1 -1
- package/dist/{transfer-D59M4aaR.cjs → transfer-BYIn7z8m.cjs} +4 -4
- package/dist/{transfer-D59M4aaR.cjs.map → transfer-BYIn7z8m.cjs.map} +1 -1
- package/dist/workspace/index.cjs +1 -2
- package/dist/workspace/index.d.cts +2 -2
- package/dist/workspace/index.d.mts +2 -2
- package/dist/workspace/index.mjs +2 -2
- package/dist/{workspace-CRD9YinV.cjs → workspace-Bav3TVrP.cjs} +47 -78
- package/dist/workspace-Bav3TVrP.cjs.map +1 -0
- package/dist/{credentials-BpoOUa74.mjs → workspace-CUmR_k4J.mjs} +228 -492
- package/dist/workspace-CUmR_k4J.mjs.map +1 -0
- package/dist/{credentials-Dbyccl3A.cjs → workspace-DgeVgxmm.cjs} +229 -517
- package/dist/workspace-DgeVgxmm.cjs.map +1 -0
- package/dist/{workspace-Bu3xNCej.mjs → workspace-T4IVGSoB.mjs} +48 -73
- package/dist/workspace-T4IVGSoB.mjs.map +1 -0
- package/package.json +14 -14
- package/dist/credentials-BpoOUa74.mjs.map +0 -1
- package/dist/credentials-Dbyccl3A.cjs.map +0 -1
- package/dist/generator-LfZU7NlU.mjs.map +0 -1
- package/dist/generator-Wdfp0jCS.cjs.map +0 -1
- package/dist/reconcile-gb1lz1Dk.mjs +0 -113
- package/dist/reconcile-gb1lz1Dk.mjs.map +0 -1
- package/dist/reconcile-hx_vBvux.cjs +0 -136
- package/dist/reconcile-hx_vBvux.cjs.map +0 -1
- package/dist/workspace-Bu3xNCej.mjs.map +0 -1
- package/dist/workspace-CRD9YinV.cjs.map +0 -1
package/dist/index.cjs
CHANGED
|
@@ -2,15 +2,14 @@
|
|
|
2
2
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
3
|
const require_rolldown_runtime = require("./rolldown-runtime-C0BPl7ul.cjs");
|
|
4
4
|
const require_discover = require("./discover-B_HtYJCr.cjs");
|
|
5
|
-
const require_config = require("./config-
|
|
6
|
-
const require_workspace = require("./workspace-
|
|
7
|
-
const require_credentials = require("./credentials-Dbyccl3A.cjs");
|
|
8
|
-
const require_generator = require("./generator-Wdfp0jCS.cjs");
|
|
5
|
+
const require_config = require("./config-7R_-WyHq.cjs");
|
|
6
|
+
const require_workspace = require("./workspace-Bav3TVrP.cjs");
|
|
9
7
|
const require_storage = require("./storage-DgypfSD6.cjs");
|
|
10
|
-
const
|
|
8
|
+
const require_workspace$1 = require("./workspace-DgeVgxmm.cjs");
|
|
9
|
+
const require_openapi = require("./openapi-rhJdy2GC.cjs");
|
|
11
10
|
const require_emit = require("./emit-BdoPFjZf.cjs");
|
|
12
|
-
const require_reconcile = require("./reconcile-
|
|
13
|
-
const require_transfer = require("./transfer-
|
|
11
|
+
const require_reconcile = require("./reconcile-szmJw_Sb.cjs");
|
|
12
|
+
const require_transfer = require("./transfer-BYIn7z8m.cjs");
|
|
14
13
|
let commander = require("commander");
|
|
15
14
|
let node_process = require("node:process");
|
|
16
15
|
let node_readline_promises = require("node:readline/promises");
|
|
@@ -25,13 +24,13 @@ let fast_glob = require("fast-glob");
|
|
|
25
24
|
fast_glob = require_rolldown_runtime.__toESM(fast_glob, 1);
|
|
26
25
|
let chokidar = require("chokidar");
|
|
27
26
|
chokidar = require_rolldown_runtime.__toESM(chokidar, 1);
|
|
28
|
-
let yaml = require("yaml");
|
|
29
27
|
let node_crypto = require("node:crypto");
|
|
28
|
+
let node_url = require("node:url");
|
|
30
29
|
let _geekmidas_db_pg_roles = require("@geekmidas/db/pg/roles");
|
|
31
30
|
let pg = require("pg");
|
|
31
|
+
let yaml = require("yaml");
|
|
32
32
|
let node_util = require("node:util");
|
|
33
33
|
let _geekmidas_cache_postgres = require("@geekmidas/cache/postgres");
|
|
34
|
-
let node_url = require("node:url");
|
|
35
34
|
let _geekmidas_constructs_crons = require("@geekmidas/constructs/crons");
|
|
36
35
|
let _geekmidas_constructs_functions = require("@geekmidas/constructs/functions");
|
|
37
36
|
let _geekmidas_constructs_queue = require("@geekmidas/constructs/queue");
|
|
@@ -44,7 +43,7 @@ prompts = require_rolldown_runtime.__toESM(prompts, 1);
|
|
|
44
43
|
let _geekmidas_envkit = require("@geekmidas/envkit");
|
|
45
44
|
let _geekmidas_services = require("@geekmidas/services");
|
|
46
45
|
//#region package.json
|
|
47
|
-
var version = "10.0.0-alpha.
|
|
46
|
+
var version = "10.0.0-alpha.27";
|
|
48
47
|
//#endregion
|
|
49
48
|
//#region src/auth/credentials.ts
|
|
50
49
|
/**
|
|
@@ -434,19 +433,16 @@ var NoCommandSpecified = class extends Error {
|
|
|
434
433
|
async function execCommand(commandArgs, options = {}) {
|
|
435
434
|
const cwd = options.cwd ?? process.cwd();
|
|
436
435
|
if (!commandArgs[0]) throw new NoCommandSpecified();
|
|
437
|
-
const defaultEnv =
|
|
436
|
+
const defaultEnv = require_workspace$1.loadEnvFiles(".env");
|
|
438
437
|
if (defaultEnv.loaded.length > 0) logger$12.log(`📦 Loaded env: ${defaultEnv.loaded.join(", ")}`);
|
|
439
|
-
const { credentials, secretsJsonPath, appName } = await
|
|
440
|
-
cwd,
|
|
441
|
-
resolveDockerPorts: "readonly"
|
|
442
|
-
});
|
|
438
|
+
const { credentials, secretsJsonPath, appName } = await require_workspace$1.prepareEntryCredentials({ cwd });
|
|
443
439
|
if (appName) logger$12.log(`📦 App: ${appName}`);
|
|
444
440
|
const secretCount = Object.keys(credentials).filter((k) => k !== "PORT").length;
|
|
445
441
|
if (secretCount > 0) logger$12.log(`🔐 Loaded ${secretCount} secret(s)`);
|
|
446
442
|
const preloadDir = (0, node_path.join)(cwd, ".gkm");
|
|
447
443
|
await (0, node_fs_promises.mkdir)(preloadDir, { recursive: true });
|
|
448
444
|
const preloadPath = (0, node_path.join)(preloadDir, "credentials-preload.mjs");
|
|
449
|
-
await
|
|
445
|
+
await require_workspace$1.createCredentialsPreload(preloadPath, secretsJsonPath);
|
|
450
446
|
const [cmd, ...args] = commandArgs;
|
|
451
447
|
logger$12.log(`🚀 Running: ${[cmd, ...args].join(" ")}`);
|
|
452
448
|
const nodeOptions = [(process.env.NODE_OPTIONS ?? "").replace(/--import[= ]\S+/g, "").trim(), `--import=${preloadPath}`].filter(Boolean).join(" ");
|
|
@@ -563,7 +559,7 @@ function getProductionConfigFromGkm(config) {
|
|
|
563
559
|
}
|
|
564
560
|
async function devCommand(options) {
|
|
565
561
|
if (options.entry) return entryDevCommand(options);
|
|
566
|
-
const defaultEnv =
|
|
562
|
+
const defaultEnv = require_workspace$1.loadEnvFiles(".env");
|
|
567
563
|
if (defaultEnv.loaded.length > 0) logger$11.log(`📦 Loaded env: ${defaultEnv.loaded.join(", ")}`);
|
|
568
564
|
const appName = require_config.getAppNameFromCwd();
|
|
569
565
|
let config;
|
|
@@ -597,6 +593,7 @@ async function devCommand(options) {
|
|
|
597
593
|
return workspaceDevCommand(loadedConfig.workspace, options);
|
|
598
594
|
}
|
|
599
595
|
config = loadedConfig.raw;
|
|
596
|
+
workspace = loadedConfig.workspace;
|
|
600
597
|
}
|
|
601
598
|
else {
|
|
602
599
|
const loadedConfig = await require_config.loadWorkspaceConfig();
|
|
@@ -608,7 +605,7 @@ async function devCommand(options) {
|
|
|
608
605
|
workspace = loadedConfig.workspace;
|
|
609
606
|
}
|
|
610
607
|
if (config.env) {
|
|
611
|
-
const { loaded, missing } =
|
|
608
|
+
const { loaded, missing } = require_workspace$1.loadEnvFiles(config.env, appRoot);
|
|
612
609
|
if (loaded.length > 0) logger$11.log(`📦 Loaded env: ${loaded.join(", ")}`);
|
|
613
610
|
if (missing.length > 0) logger$11.warn(`⚠️ Missing env files: ${missing.join(", ")}`);
|
|
614
611
|
}
|
|
@@ -629,7 +626,7 @@ async function devCommand(options) {
|
|
|
629
626
|
appRoot,
|
|
630
627
|
providers: ["server"],
|
|
631
628
|
enableOpenApi,
|
|
632
|
-
cacheBackend:
|
|
629
|
+
cacheBackend: require_workspace$1.cacheBackendFor(require_workspace$1.providerOf(workspace ?? config)),
|
|
633
630
|
telescope,
|
|
634
631
|
studio,
|
|
635
632
|
hooks,
|
|
@@ -640,25 +637,14 @@ async function devCommand(options) {
|
|
|
640
637
|
const initial = await build();
|
|
641
638
|
const runtime = config.runtime ?? "node";
|
|
642
639
|
let secretsJsonPath;
|
|
643
|
-
const appSecrets = await
|
|
644
|
-
if (workspace
|
|
645
|
-
const reconciled = await
|
|
640
|
+
const appSecrets = await require_workspace$1.loadSecretsForApp(secretsRoot, config.stages.local, workspaceAppName);
|
|
641
|
+
if (workspace) {
|
|
642
|
+
const reconciled = await require_workspace$1.reconcileWorkspace(workspace, { stage: workspace.stages.local });
|
|
646
643
|
if (reconciled.changed && reconciled.plan.containers.length > 0) {
|
|
647
644
|
logger$11.log(`🐳 Services: ${reconciled.plan.containers.join(", ")}`);
|
|
648
645
|
for (const [container, address] of Object.entries(reconciled.addresses)) logger$11.log(` ${container}: ${address}`);
|
|
649
646
|
}
|
|
650
647
|
Object.assign(appSecrets, reconciled.env);
|
|
651
|
-
} else {
|
|
652
|
-
const resolvedPorts = await require_credentials.resolveServicePorts(secretsRoot);
|
|
653
|
-
if (Object.keys(resolvedPorts.ports).length > 0) {
|
|
654
|
-
const rewritten = require_credentials.rewriteUrlsWithPorts(appSecrets, resolvedPorts);
|
|
655
|
-
Object.assign(appSecrets, rewritten);
|
|
656
|
-
logger$11.log(`🔌 Applied ${Object.keys(resolvedPorts.ports).length} port mapping(s)`);
|
|
657
|
-
}
|
|
658
|
-
}
|
|
659
|
-
if (workspace && workspaceAppName) {
|
|
660
|
-
const depEnv = require_workspace.getDependencyEnvVars(workspace, workspaceAppName);
|
|
661
|
-
Object.assign(appSecrets, depEnv);
|
|
662
648
|
}
|
|
663
649
|
if (Object.keys(appSecrets).length > 0) {
|
|
664
650
|
const secretsDir = (0, node_path.join)(secretsRoot, ".gkm");
|
|
@@ -668,7 +654,7 @@ async function devCommand(options) {
|
|
|
668
654
|
await (0, node_fs_promises.writeFile)(secretsJsonPath, JSON.stringify(appSecrets, null, 2));
|
|
669
655
|
logger$11.log(`🔐 Loaded ${Object.keys(appSecrets).length} secret(s)`);
|
|
670
656
|
}
|
|
671
|
-
const devServer = new DevServer(resolved.providers[0], options.port ?? workspaceAppPort ?? 3e3, options.portExplicit ??
|
|
657
|
+
const devServer = new DevServer(resolved.providers[0], options.port ?? workspaceAppPort ?? 3e3, options.portExplicit ?? workspaceAppPort !== void 0, enableOpenApi, telescope, studio, runtime, appRoot, secretsJsonPath, initial.selfServing !== void 0);
|
|
672
658
|
await devServer.start();
|
|
673
659
|
const hooksFile = (config.hooks?.server?.split("#"))?.[0];
|
|
674
660
|
const normalizedPatterns = [config.constructs, ...hooksFile ? [hooksFile.endsWith(".ts") ? hooksFile : `${hooksFile}.ts`] : []].flat().filter((p) => typeof p === "string").map((p) => p.startsWith("./") ? p.slice(2) : p);
|
|
@@ -727,19 +713,6 @@ async function devCommand(options) {
|
|
|
727
713
|
process.on("SIGTERM", shutdown);
|
|
728
714
|
}
|
|
729
715
|
/**
|
|
730
|
-
* Generate all dependency environment variables for all apps.
|
|
731
|
-
* Returns a flat object with all {APP_NAME}_URL variables.
|
|
732
|
-
* @internal Exported for testing
|
|
733
|
-
*/
|
|
734
|
-
function generateAllDependencyEnvVars(workspace, urlPrefix = "http://localhost") {
|
|
735
|
-
const env = {};
|
|
736
|
-
for (const appName of Object.keys(workspace.apps)) {
|
|
737
|
-
const appEnv = require_workspace.getDependencyEnvVars(workspace, appName, urlPrefix);
|
|
738
|
-
Object.assign(env, appEnv);
|
|
739
|
-
}
|
|
740
|
-
return env;
|
|
741
|
-
}
|
|
742
|
-
/**
|
|
743
716
|
* Check for port conflicts across all apps.
|
|
744
717
|
* Returns list of conflicts if any ports are duplicated.
|
|
745
718
|
* @internal Exported for testing
|
|
@@ -964,27 +937,25 @@ async function workspaceDevCommand(workspace, options) {
|
|
|
964
937
|
logger$11.log("✅ Frontend apps validated");
|
|
965
938
|
}
|
|
966
939
|
const rawSecrets = await loadDevSecrets(workspace);
|
|
967
|
-
|
|
968
|
-
if (
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
const
|
|
980
|
-
|
|
981
|
-
secretsEnv = require_credentials.rewriteUrlsWithPorts(rawSecrets, resolvedPorts);
|
|
940
|
+
const reconciled = await require_workspace$1.reconcileWorkspace(workspace, { stage: workspace.stages.local });
|
|
941
|
+
if (reconciled.changed && reconciled.plan.containers.length > 0) {
|
|
942
|
+
logger$11.log(`🐳 Services: ${reconciled.plan.containers.join(", ")}`);
|
|
943
|
+
for (const [container, address] of Object.entries(reconciled.addresses)) logger$11.log(` ${container}: ${address}`);
|
|
944
|
+
}
|
|
945
|
+
const secretsEnv = {
|
|
946
|
+
...rawSecrets,
|
|
947
|
+
...reconciled.env
|
|
948
|
+
};
|
|
949
|
+
const appUrls = {};
|
|
950
|
+
for (const resource of reconciled.plan.resources) {
|
|
951
|
+
if (resource.kind !== "rest-api" && resource.kind !== "site") continue;
|
|
952
|
+
const address = reconciled.env[resource.envKey];
|
|
953
|
+
if (address) appUrls[resource.id] = address;
|
|
982
954
|
}
|
|
983
955
|
if (Object.keys(secretsEnv).length > 0) logger$11.log(` Loaded ${Object.keys(secretsEnv).length} secret(s)`);
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
logger$11.log(
|
|
987
|
-
for (const [key, value] of Object.entries(dependencyEnv)) logger$11.log(` ${key}=${value}`);
|
|
956
|
+
if (Object.keys(appUrls).length > 0) {
|
|
957
|
+
logger$11.log("🔒 App URLs:");
|
|
958
|
+
for (const [id, address] of Object.entries(appUrls)) logger$11.log(` ${id}: ${address}`);
|
|
988
959
|
}
|
|
989
960
|
let turboFilter = [];
|
|
990
961
|
if (options.app) {
|
|
@@ -1028,10 +999,20 @@ async function workspaceDevCommand(workspace, options) {
|
|
|
1028
999
|
const turboEnv = {
|
|
1029
1000
|
...process.env,
|
|
1030
1001
|
...secretsEnv,
|
|
1031
|
-
...dependencyEnv,
|
|
1032
1002
|
NODE_ENV: "development",
|
|
1033
1003
|
...configPath ? { GKM_CONFIG_PATH: configPath } : {}
|
|
1034
1004
|
};
|
|
1005
|
+
const scoped = options.app ? [options.app] : options.filter ? [] : Object.keys(workspace.apps);
|
|
1006
|
+
const held = [];
|
|
1007
|
+
for (const appName of scoped) {
|
|
1008
|
+
const port = workspace.apps[appName]?.port;
|
|
1009
|
+
if (port && !await require_workspace$1.isPortAvailable(port)) held.push({
|
|
1010
|
+
app: appName,
|
|
1011
|
+
port,
|
|
1012
|
+
holder: listenerOn(port)
|
|
1013
|
+
});
|
|
1014
|
+
}
|
|
1015
|
+
if (held.length > 0) throw new WorkspacePortsInUse(held);
|
|
1035
1016
|
logger$11.log("\n🏃 Starting turbo run dev...\n");
|
|
1036
1017
|
const turboProcess = (0, node_child_process.spawn)("pnpm", [
|
|
1037
1018
|
"turbo",
|
|
@@ -1090,16 +1071,16 @@ async function entryDevCommand(options) {
|
|
|
1090
1071
|
if (!entry) throw new Error("--entry requires a file path");
|
|
1091
1072
|
const entryPath = (0, node_path.resolve)(process.cwd(), entry);
|
|
1092
1073
|
if (!(0, node_fs.existsSync)(entryPath)) throw new Error(`Entry file not found: ${entryPath}`);
|
|
1093
|
-
const defaultEnv =
|
|
1074
|
+
const defaultEnv = require_workspace$1.loadEnvFiles(".env");
|
|
1094
1075
|
if (defaultEnv.loaded.length > 0) logger$11.log(`📦 Loaded env: ${defaultEnv.loaded.join(", ")}`);
|
|
1095
|
-
const { credentials, resolvedPort, secretsJsonPath, appName } = await
|
|
1076
|
+
const { credentials, resolvedPort, secretsJsonPath, appName } = await require_workspace$1.prepareEntryCredentials({ explicitPort: options.portExplicit ? options.port : void 0 });
|
|
1096
1077
|
if (appName) logger$11.log(`📦 App: ${appName} (port ${resolvedPort})`);
|
|
1097
1078
|
logger$11.log(`🚀 Starting entry file: ${entry} on port ${resolvedPort}`);
|
|
1098
1079
|
if (Object.keys(credentials).length > 1) logger$11.log(`🔐 Loaded ${Object.keys(credentials).length - 1} secret(s) + PORT`);
|
|
1099
1080
|
const wrapperDir = (0, node_path.join)(process.cwd(), ".gkm");
|
|
1100
1081
|
await (0, node_fs_promises.mkdir)(wrapperDir, { recursive: true });
|
|
1101
1082
|
const wrapperPath = (0, node_path.join)(wrapperDir, "entry-wrapper.ts");
|
|
1102
|
-
await
|
|
1083
|
+
await require_workspace$1.createEntryWrapper(wrapperPath, entryPath, secretsJsonPath);
|
|
1103
1084
|
const runner = new EntryRunner(wrapperPath, entryPath, watch, resolvedPort);
|
|
1104
1085
|
await runner.start();
|
|
1105
1086
|
let isShuttingDown = false;
|
|
@@ -1209,6 +1190,19 @@ var EntryRunner = class {
|
|
|
1209
1190
|
*/
|
|
1210
1191
|
function generateServerEntryContent(options) {
|
|
1211
1192
|
const { secretsJsonPath, runtime = "node", enableOpenApi = false, appImportPath = "./app.js", selfServing = false } = options;
|
|
1193
|
+
const parentWatch = `// Exit when the gkm dev that started this server is gone.
|
|
1194
|
+
const __gkmDevPid = Number(process.env.GKM_DEV_PID);
|
|
1195
|
+
if (__gkmDevPid) {
|
|
1196
|
+
setInterval(() => {
|
|
1197
|
+
try {
|
|
1198
|
+
process.kill(__gkmDevPid, 0);
|
|
1199
|
+
} catch {
|
|
1200
|
+
process.exit(0);
|
|
1201
|
+
}
|
|
1202
|
+
}, 1000).unref();
|
|
1203
|
+
}
|
|
1204
|
+
|
|
1205
|
+
`;
|
|
1212
1206
|
const credentialsInjection = secretsJsonPath ? `import { existsSync, readFileSync } from 'node:fs';
|
|
1213
1207
|
|
|
1214
1208
|
// Inject dev secrets via globalThis (must happen before app import)
|
|
@@ -1239,8 +1233,7 @@ if (existsSync(secretsPath)) {
|
|
|
1239
1233
|
* Development server entry point for a surface that serves itself
|
|
1240
1234
|
* This file is auto-generated by 'gkm dev'
|
|
1241
1235
|
*/
|
|
1242
|
-
${credentialsInjection}
|
|
1243
|
-
const port = process.argv.includes('--port')
|
|
1236
|
+
${credentialsInjection}${parentWatch}const port = process.argv.includes('--port')
|
|
1244
1237
|
? Number.parseInt(process.argv[process.argv.indexOf('--port') + 1])
|
|
1245
1238
|
: 3000;
|
|
1246
1239
|
|
|
@@ -1255,8 +1248,7 @@ console.log(\`Server started on port \${port}\`);
|
|
|
1255
1248
|
* Development server entry point
|
|
1256
1249
|
* This file is auto-generated by 'gkm dev'
|
|
1257
1250
|
*/
|
|
1258
|
-
${credentialsInjection}
|
|
1259
|
-
const port = process.argv.includes('--port')
|
|
1251
|
+
${credentialsInjection}${parentWatch}const port = process.argv.includes('--port')
|
|
1260
1252
|
? Number.parseInt(process.argv[process.argv.indexOf('--port') + 1])
|
|
1261
1253
|
: 3000;
|
|
1262
1254
|
|
|
@@ -1278,6 +1270,44 @@ start({
|
|
|
1278
1270
|
});
|
|
1279
1271
|
`;
|
|
1280
1272
|
}
|
|
1273
|
+
/** A port this app must serve on is held by something else. */
|
|
1274
|
+
var DevPortInUse = class extends Error {
|
|
1275
|
+
port;
|
|
1276
|
+
holder;
|
|
1277
|
+
constructor(port, holder) {
|
|
1278
|
+
super(`Port ${port} is already in use${holder ? ` by ${holder}` : ""}. It is the port this app is provisioned on — the one every other app and its CORS origins point at — so dev will not move off it. Stop what is holding it (often a dev server a previous run left behind), or pass -p/--port to run this app somewhere else.`);
|
|
1279
|
+
this.port = port;
|
|
1280
|
+
this.holder = holder;
|
|
1281
|
+
this.name = "DevPortInUse";
|
|
1282
|
+
}
|
|
1283
|
+
};
|
|
1284
|
+
/** Apps whose provisioned ports are held before the workspace starts. */
|
|
1285
|
+
var WorkspacePortsInUse = class extends Error {
|
|
1286
|
+
held;
|
|
1287
|
+
constructor(held) {
|
|
1288
|
+
super(`Ports this workspace's apps are provisioned on are already in use:\n${held.map(({ app, port, holder }) => ` ${app}: ${port}${holder ? ` — held by ${holder}` : ""}`).join("\n")}\nStop what is holding them (often dev servers a previous run left behind) and start again. Nothing was started.`);
|
|
1289
|
+
this.held = held;
|
|
1290
|
+
this.name = "WorkspacePortsInUse";
|
|
1291
|
+
}
|
|
1292
|
+
};
|
|
1293
|
+
/** What is listening on a port, as `command (pid N)`, if `lsof` can tell. */
|
|
1294
|
+
function listenerOn(port) {
|
|
1295
|
+
try {
|
|
1296
|
+
const out = (0, node_child_process.execSync)(`lsof -nP -iTCP:${port} -sTCP:LISTEN -Fpc`, {
|
|
1297
|
+
encoding: "utf8",
|
|
1298
|
+
stdio: [
|
|
1299
|
+
"ignore",
|
|
1300
|
+
"pipe",
|
|
1301
|
+
"ignore"
|
|
1302
|
+
]
|
|
1303
|
+
});
|
|
1304
|
+
const pid = out.match(/^p(\d+)/m)?.[1];
|
|
1305
|
+
const command = out.match(/^c(.+)$/m)?.[1];
|
|
1306
|
+
return pid ? `${command ?? "a process"} (pid ${pid})` : void 0;
|
|
1307
|
+
} catch {
|
|
1308
|
+
return;
|
|
1309
|
+
}
|
|
1310
|
+
}
|
|
1281
1311
|
var DevServer = class {
|
|
1282
1312
|
provider;
|
|
1283
1313
|
requestedPort;
|
|
@@ -1310,10 +1340,10 @@ var DevServer = class {
|
|
|
1310
1340
|
this.startTime = Date.now();
|
|
1311
1341
|
if (this.isRunning) await this.stop();
|
|
1312
1342
|
if (this.portExplicit) {
|
|
1313
|
-
if (!await
|
|
1343
|
+
if (!await require_workspace$1.isPortAvailable(this.requestedPort)) throw new DevPortInUse(this.requestedPort, listenerOn(this.requestedPort));
|
|
1314
1344
|
this.actualPort = this.requestedPort;
|
|
1315
1345
|
} else {
|
|
1316
|
-
this.actualPort = await
|
|
1346
|
+
this.actualPort = await require_workspace$1.findAvailablePort(this.requestedPort);
|
|
1317
1347
|
if (this.actualPort !== this.requestedPort) logger$11.log(`ℹ️ Port ${this.requestedPort} was in use, using port ${this.actualPort} instead`);
|
|
1318
1348
|
}
|
|
1319
1349
|
const serverEntryPath = (0, node_path.join)(this.appRoot, ".gkm", this.provider, "server.ts");
|
|
@@ -1328,7 +1358,8 @@ var DevServer = class {
|
|
|
1328
1358
|
stdio: "inherit",
|
|
1329
1359
|
env: {
|
|
1330
1360
|
...process.env,
|
|
1331
|
-
NODE_ENV: "development"
|
|
1361
|
+
NODE_ENV: "development",
|
|
1362
|
+
GKM_DEV_PID: String(process.pid)
|
|
1332
1363
|
},
|
|
1333
1364
|
detached: true
|
|
1334
1365
|
});
|
|
@@ -1385,7 +1416,7 @@ var DevServer = class {
|
|
|
1385
1416
|
await this.stop();
|
|
1386
1417
|
let attempts = 0;
|
|
1387
1418
|
while (attempts < 30) {
|
|
1388
|
-
if (await
|
|
1419
|
+
if (await require_workspace$1.isPortAvailable(portToReuse)) break;
|
|
1389
1420
|
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
1390
1421
|
attempts++;
|
|
1391
1422
|
}
|
|
@@ -2561,7 +2592,7 @@ async function buildCommand(options) {
|
|
|
2561
2592
|
}
|
|
2562
2593
|
const config = loadedConfig.type !== "workspace" ? await require_config.loadConfig() : (0, node_path.resolve)(process.cwd()) === (0, node_path.resolve)(loadedConfig.workspace.root) ? rootGkmConfig(loadedConfig.workspace) : (await require_config.loadAppConfig()).gkmConfig;
|
|
2563
2594
|
const resolved = resolveProviders(config, options);
|
|
2564
|
-
const cacheBackend =
|
|
2595
|
+
const cacheBackend = require_workspace$1.cacheBackendFor(require_workspace$1.providerOf(loadedConfig.workspace));
|
|
2565
2596
|
const productionConfigFromGkm = getProductionConfigFromGkm(config);
|
|
2566
2597
|
const production = normalizeProductionConfig(options.production ?? false, productionConfigFromGkm);
|
|
2567
2598
|
if (production) logger$9.log(`🏭 Building for PRODUCTION`);
|
|
@@ -2995,7 +3026,7 @@ const PROVISIONERS = {
|
|
|
2995
3026
|
*/
|
|
2996
3027
|
database: async (declaration, context) => {
|
|
2997
3028
|
if (declaration.kind !== "database") throw new WrongKind(declaration.kind);
|
|
2998
|
-
const name =
|
|
3029
|
+
const name = require_workspace$1.resourceName(declaration.id, declaration.kind, context.stage);
|
|
2999
3030
|
const { postgres } = await context.api.findOrCreatePostgres(serviceName({
|
|
3000
3031
|
stage: context.stage,
|
|
3001
3032
|
app: context.project
|
|
@@ -3031,7 +3062,7 @@ const PROVISIONERS = {
|
|
|
3031
3062
|
if (declaration.kind !== "database-schema") throw new WrongKind(declaration.kind);
|
|
3032
3063
|
const parent = context.provisioned[declaration.of];
|
|
3033
3064
|
if (!parent) throw new UnresolvedParent(declaration.id, declaration.of);
|
|
3034
|
-
const runtime =
|
|
3065
|
+
const runtime = require_workspace$1.resourceName(declaration.id, declaration.kind, context.stage);
|
|
3035
3066
|
const owner = (0, _geekmidas_db_pg_roles.ownerRole)(runtime);
|
|
3036
3067
|
const reads = readsFrom(context.manifest, declaration.id);
|
|
3037
3068
|
const parentUrl = new URL(parent.provides[(0, _geekmidas_manifest.provideKey)(declaration.of, "url")] ?? "");
|
|
@@ -3133,7 +3164,7 @@ const PROVISIONERS = {
|
|
|
3133
3164
|
stage: context.stage,
|
|
3134
3165
|
app: context.project
|
|
3135
3166
|
}, declaration.id);
|
|
3136
|
-
const bucket =
|
|
3167
|
+
const bucket = require_workspace$1.resourceName(declaration.id, declaration.kind, context.stage);
|
|
3137
3168
|
const user = `${bucket}-root`;
|
|
3138
3169
|
const password = derivedPassword(context, `objects:${declaration.id}`);
|
|
3139
3170
|
const { compose } = await context.api.findOrCreateCompose(service, context.projectId, context.environmentId, minioCompose({
|
|
@@ -3501,10 +3532,6 @@ var UnprovisionableBucket = class extends Error {
|
|
|
3501
3532
|
*/
|
|
3502
3533
|
/**
|
|
3503
3534
|
* Provision everything the workspace declares, and return what it resolved.
|
|
3504
|
-
*
|
|
3505
|
-
* Nothing happens for a project that has not adopted the model: `usesConstructs`
|
|
3506
|
-
* is the same hard switch reconcile reads, so an existing deploy is untouched
|
|
3507
|
-
* until it declares something.
|
|
3508
3535
|
*/
|
|
3509
3536
|
async function provisionDeclared(options) {
|
|
3510
3537
|
const { workspace } = options;
|
|
@@ -3514,9 +3541,8 @@ async function provisionDeclared(options) {
|
|
|
3514
3541
|
provisioned: {},
|
|
3515
3542
|
clusters: {}
|
|
3516
3543
|
};
|
|
3517
|
-
if (!require_credentials.usesConstructs(workspace)) return empty;
|
|
3518
3544
|
const manifest = options.manifest ?? await require_discover.discover({
|
|
3519
|
-
patterns:
|
|
3545
|
+
patterns: require_workspace$1.constructGlobs(workspace),
|
|
3520
3546
|
cwd: workspace.root
|
|
3521
3547
|
});
|
|
3522
3548
|
if (Object.keys(manifest).length === 0) return empty;
|
|
@@ -3528,9 +3554,9 @@ async function provisionDeclared(options) {
|
|
|
3528
3554
|
environmentId: options.environmentId,
|
|
3529
3555
|
stage: options.stage,
|
|
3530
3556
|
project: workspace.name,
|
|
3531
|
-
cache:
|
|
3532
|
-
events:
|
|
3533
|
-
storage:
|
|
3557
|
+
cache: require_workspace$1.cacheBackendFor(require_workspace$1.providerOf(workspace)),
|
|
3558
|
+
events: require_workspace$1.eventsBackendFor(require_workspace$1.providerOf(workspace)),
|
|
3559
|
+
storage: require_workspace$1.storageBackendFor(require_workspace$1.providerOf(workspace)),
|
|
3534
3560
|
addresses: surfaceAddresses(workspace, manifest, options.appUrls),
|
|
3535
3561
|
...options.secrets ? { secrets: options.secrets } : {},
|
|
3536
3562
|
deferred: [],
|
|
@@ -3567,7 +3593,7 @@ async function provisionDeclared(options) {
|
|
|
3567
3593
|
* run again.
|
|
3568
3594
|
*/
|
|
3569
3595
|
async function applyDeclared(client, statements) {
|
|
3570
|
-
return (await
|
|
3596
|
+
return (await require_workspace$1.applyPostgres(client, statements)).filter((entry) => entry.created).length;
|
|
3571
3597
|
}
|
|
3572
3598
|
/**
|
|
3573
3599
|
* The provisioning order, with queues and topics moved to the end.
|
|
@@ -5257,7 +5283,7 @@ async function workspaceDockerCommand(workspace) {
|
|
|
5257
5283
|
await (0, node_fs_promises.writeFile)(dockerignorePath, dockerignore);
|
|
5258
5284
|
logger$7.log(`\n Generated: .dockerignore (workspace root)`);
|
|
5259
5285
|
const composePath = await writeConstructsCompose(workspace);
|
|
5260
|
-
logger$7.log(`\n✅ Generated ${results.length} Dockerfile(s) + ${
|
|
5286
|
+
logger$7.log(`\n✅ Generated ${results.length} Dockerfile(s) + ${require_workspace$1.COMPOSE_PATH}`);
|
|
5261
5287
|
logger$7.log("\n📋 Build commands:");
|
|
5262
5288
|
for (const result of results) {
|
|
5263
5289
|
const icon = result.type === "backend" ? "⚙️" : result.type === "mobile" ? "📱" : "🌐";
|
|
@@ -5278,18 +5304,18 @@ async function workspaceDockerCommand(workspace) {
|
|
|
5278
5304
|
* describes and what `gkm dev` runs cannot disagree. Nothing is started.
|
|
5279
5305
|
*/
|
|
5280
5306
|
async function writeConstructsCompose(workspace) {
|
|
5281
|
-
await
|
|
5307
|
+
await require_workspace$1.reconcileWorkspace(workspace, {
|
|
5282
5308
|
stage: workspace.stages.local,
|
|
5283
5309
|
start: false
|
|
5284
5310
|
});
|
|
5285
|
-
logger$7.log(` Generated: ${
|
|
5286
|
-
return (0, node_path.join)(workspace.root,
|
|
5311
|
+
logger$7.log(` Generated: ${require_workspace$1.COMPOSE_PATH} (project root)`);
|
|
5312
|
+
return (0, node_path.join)(workspace.root, require_workspace$1.COMPOSE_PATH);
|
|
5287
5313
|
}
|
|
5288
5314
|
function printRunInstructions(workspace) {
|
|
5289
5315
|
const project = (0, node_fs.existsSync)((0, node_path.join)(workspace.root, "docker-compose.yml")) ? " -f docker-compose.yml" : "";
|
|
5290
5316
|
logger$7.log("\n📋 Run everything (the apps sit behind the \"apps\" profile):");
|
|
5291
5317
|
logger$7.log(" gkm setup # starts the containers and creates what they hold");
|
|
5292
|
-
logger$7.log(` docker compose -f ${
|
|
5318
|
+
logger$7.log(` docker compose -f ${require_workspace$1.COMPOSE_PATH}${project} --profile apps up --build`);
|
|
5293
5319
|
}
|
|
5294
5320
|
//#endregion
|
|
5295
5321
|
//#region src/deploy/docker.ts
|
|
@@ -6972,7 +6998,7 @@ function requiredOf(requirements) {
|
|
|
6972
6998
|
async function workspaceDeployCommand(configured, options) {
|
|
6973
6999
|
const { provider, stage, tag, apps: selectedApps } = options;
|
|
6974
7000
|
const manifest = await require_discover.discover({
|
|
6975
|
-
patterns:
|
|
7001
|
+
patterns: require_workspace$1.constructGlobs(configured),
|
|
6976
7002
|
cwd: configured.root
|
|
6977
7003
|
});
|
|
6978
7004
|
const units = deployUnits(manifest, configured);
|
|
@@ -8526,26 +8552,26 @@ function loadPackageJson() {
|
|
|
8526
8552
|
* Run: pnpm --filter @geekmidas/cli sync-versions
|
|
8527
8553
|
*/
|
|
8528
8554
|
const GEEKMIDAS_VERSIONS = {
|
|
8529
|
-
"@geekmidas/audit": "~10.0.0-alpha.
|
|
8530
|
-
"@geekmidas/auth": "~10.0.0-alpha.
|
|
8531
|
-
"@geekmidas/cache": "~10.0.0-alpha.
|
|
8532
|
-
"@geekmidas/client": "~10.0.0-alpha.
|
|
8533
|
-
"@geekmidas/cloud": "~10.0.0-alpha.
|
|
8534
|
-
"@geekmidas/constructs": "~10.0.0-alpha.
|
|
8535
|
-
"@geekmidas/db": "~10.0.0-alpha.
|
|
8536
|
-
"@geekmidas/emailkit": "~10.0.0-alpha.
|
|
8537
|
-
"@geekmidas/envkit": "~10.0.0-alpha.
|
|
8538
|
-
"@geekmidas/errors": "~10.0.0-alpha.
|
|
8539
|
-
"@geekmidas/events": "~10.0.0-alpha.
|
|
8540
|
-
"@geekmidas/logger": "~10.0.0-alpha.
|
|
8541
|
-
"@geekmidas/manifest": "~10.0.0-alpha.
|
|
8542
|
-
"@geekmidas/rate-limit": "~10.0.0-alpha.
|
|
8543
|
-
"@geekmidas/schema": "~10.0.0-alpha.
|
|
8544
|
-
"@geekmidas/services": "~10.0.0-alpha.
|
|
8545
|
-
"@geekmidas/storage": "~10.0.0-alpha.
|
|
8546
|
-
"@geekmidas/studio": "~10.0.0-alpha.
|
|
8547
|
-
"@geekmidas/telescope": "~10.0.0-alpha.
|
|
8548
|
-
"@geekmidas/testkit": "~10.0.0-alpha.
|
|
8555
|
+
"@geekmidas/audit": "~10.0.0-alpha.27",
|
|
8556
|
+
"@geekmidas/auth": "~10.0.0-alpha.27",
|
|
8557
|
+
"@geekmidas/cache": "~10.0.0-alpha.27",
|
|
8558
|
+
"@geekmidas/client": "~10.0.0-alpha.27",
|
|
8559
|
+
"@geekmidas/cloud": "~10.0.0-alpha.27",
|
|
8560
|
+
"@geekmidas/constructs": "~10.0.0-alpha.27",
|
|
8561
|
+
"@geekmidas/db": "~10.0.0-alpha.27",
|
|
8562
|
+
"@geekmidas/emailkit": "~10.0.0-alpha.27",
|
|
8563
|
+
"@geekmidas/envkit": "~10.0.0-alpha.27",
|
|
8564
|
+
"@geekmidas/errors": "~10.0.0-alpha.27",
|
|
8565
|
+
"@geekmidas/events": "~10.0.0-alpha.27",
|
|
8566
|
+
"@geekmidas/logger": "~10.0.0-alpha.27",
|
|
8567
|
+
"@geekmidas/manifest": "~10.0.0-alpha.27",
|
|
8568
|
+
"@geekmidas/rate-limit": "~10.0.0-alpha.27",
|
|
8569
|
+
"@geekmidas/schema": "~10.0.0-alpha.27",
|
|
8570
|
+
"@geekmidas/services": "~10.0.0-alpha.27",
|
|
8571
|
+
"@geekmidas/storage": "~10.0.0-alpha.27",
|
|
8572
|
+
"@geekmidas/studio": "~10.0.0-alpha.27",
|
|
8573
|
+
"@geekmidas/telescope": "~10.0.0-alpha.27",
|
|
8574
|
+
"@geekmidas/testkit": "~10.0.0-alpha.27",
|
|
8549
8575
|
"@geekmidas/cli": `~${loadPackageJson().version}`
|
|
8550
8576
|
};
|
|
8551
8577
|
//#endregion
|
|
@@ -14460,7 +14486,7 @@ async function initCommand(projectName, options = {}) {
|
|
|
14460
14486
|
}
|
|
14461
14487
|
console.log("🔐 Initializing encrypted secrets...\n");
|
|
14462
14488
|
const local = templateOptions.stages.local;
|
|
14463
|
-
const devSecrets =
|
|
14489
|
+
const devSecrets = require_reconcile.createStageSecrets(local, [], { projectName: name });
|
|
14464
14490
|
const customSecrets = {
|
|
14465
14491
|
PORT: "3000",
|
|
14466
14492
|
LOG_LEVEL: "debug",
|
|
@@ -14645,7 +14671,7 @@ async function secretsInitCommand(options) {
|
|
|
14645
14671
|
logger$3.log(" Detected workspace mode — generating per-app secrets");
|
|
14646
14672
|
}
|
|
14647
14673
|
} catch {}
|
|
14648
|
-
const secrets =
|
|
14674
|
+
const secrets = require_reconcile.createStageSecrets(stage, [], { projectName });
|
|
14649
14675
|
if (workspaceSecrets) secrets.custom = workspaceSecrets;
|
|
14650
14676
|
await require_storage.writeStageSecrets(secrets);
|
|
14651
14677
|
logger$3.log(`\n✓ Secrets initialized for stage "${stage}"`);
|
|
@@ -14743,13 +14769,13 @@ async function secretsRotateCommand(options) {
|
|
|
14743
14769
|
logger$3.error(`Service "${service}" not configured in stage "${stage}"`);
|
|
14744
14770
|
process.exit(1);
|
|
14745
14771
|
}
|
|
14746
|
-
const updated =
|
|
14772
|
+
const updated = require_reconcile.rotateServicePassword(secrets, service);
|
|
14747
14773
|
await require_storage.writeStageSecrets(updated);
|
|
14748
14774
|
logger$3.log(`\n✓ Password rotated for ${service} in stage "${stage}"`);
|
|
14749
14775
|
} else {
|
|
14750
14776
|
let updated = secrets;
|
|
14751
14777
|
const services = Object.keys(secrets.services);
|
|
14752
|
-
for (const svc of services) updated =
|
|
14778
|
+
for (const svc of services) updated = require_reconcile.rotateServicePassword(updated, svc);
|
|
14753
14779
|
await require_storage.writeStageSecrets(updated);
|
|
14754
14780
|
logger$3.log(`\n✓ Passwords rotated for all services in stage "${stage}": ${services.join(", ")}`);
|
|
14755
14781
|
}
|
|
@@ -14873,7 +14899,7 @@ function installation(platform, certificate) {
|
|
|
14873
14899
|
*/
|
|
14874
14900
|
async function trustCommand(options = {}) {
|
|
14875
14901
|
const { workspace } = await require_config.loadWorkspaceConfig();
|
|
14876
|
-
const certificate = (0, node_path.join)(workspace.root,
|
|
14902
|
+
const certificate = (0, node_path.join)(workspace.root, require_workspace$1.LOCAL_CA_PATH);
|
|
14877
14903
|
if (!(0, node_fs.existsSync)(certificate)) throw new NoLocalAuthority(certificate);
|
|
14878
14904
|
const { describe, steps } = installation(process.platform, certificate);
|
|
14879
14905
|
logger$2.log(`\n🔐 Trusting the local authority in ${describe}`);
|
|
@@ -15016,7 +15042,7 @@ async function setupCommand(options = {}) {
|
|
|
15016
15042
|
logger$1.error("❌ Failed to resolve secrets. Exiting.");
|
|
15017
15043
|
process.exit(1);
|
|
15018
15044
|
}
|
|
15019
|
-
const containers = await
|
|
15045
|
+
const containers = await require_workspace$1.derivedContainers(workspace, stage);
|
|
15020
15046
|
if (isMultiApp && containers.includes("postgres")) {
|
|
15021
15047
|
await require_reconcile.writeDockerEnvFromSecrets(secrets, workspace.root);
|
|
15022
15048
|
logger$1.log("📄 Generated docker/.env with database passwords");
|
|
@@ -15035,7 +15061,7 @@ async function setupCommand(options = {}) {
|
|
|
15035
15061
|
* free and quiet.
|
|
15036
15062
|
*/
|
|
15037
15063
|
async function reconcileLocal(workspace, stage, options) {
|
|
15038
|
-
const result = await
|
|
15064
|
+
const result = await require_workspace$1.reconcileWorkspace(workspace, { stage });
|
|
15039
15065
|
if (result.plan.containers.length === 0) {
|
|
15040
15066
|
logger$1.log("🐳 No containers declared");
|
|
15041
15067
|
return;
|
|
@@ -15067,7 +15093,7 @@ async function resolveSecrets(stage, workspace, options) {
|
|
|
15067
15093
|
logger$1.log("🔐 Using existing local secrets");
|
|
15068
15094
|
const secrets = await require_storage.readStageSecrets(stage, workspace.root);
|
|
15069
15095
|
if (secrets) {
|
|
15070
|
-
const reconciled = reconcileSecrets(secrets, workspace, await
|
|
15096
|
+
const reconciled = reconcileSecrets(secrets, workspace, await require_workspace$1.derivedContainers(workspace, stage));
|
|
15071
15097
|
if (reconciled) await require_storage.writeStageSecrets(reconciled, workspace.root);
|
|
15072
15098
|
return reconciled ?? secrets;
|
|
15073
15099
|
}
|
|
@@ -15115,7 +15141,7 @@ function reconcileSecrets(secrets, workspace, containers = []) {
|
|
|
15115
15141
|
let changed = false;
|
|
15116
15142
|
let result = { ...secrets };
|
|
15117
15143
|
for (const name of credentialedServices(containers)) if (!result.services[name]) {
|
|
15118
|
-
const creds =
|
|
15144
|
+
const creds = require_reconcile.generateServiceCredentials(name);
|
|
15119
15145
|
if (name === "minio") {
|
|
15120
15146
|
creds.bucket = workspace.name;
|
|
15121
15147
|
creds.username = workspace.name;
|
|
@@ -15127,7 +15153,7 @@ function reconcileSecrets(secrets, workspace, containers = []) {
|
|
|
15127
15153
|
[name]: creds
|
|
15128
15154
|
}
|
|
15129
15155
|
};
|
|
15130
|
-
result.urls =
|
|
15156
|
+
result.urls = require_reconcile.generateConnectionUrls(result.services, result.eventsBackend);
|
|
15131
15157
|
logger$1.log(` 🔄 Adding missing service credentials: ${name}`);
|
|
15132
15158
|
changed = true;
|
|
15133
15159
|
}
|
|
@@ -15140,12 +15166,12 @@ function reconcileSecrets(secrets, workspace, containers = []) {
|
|
|
15140
15166
|
host: result.services.postgres.host,
|
|
15141
15167
|
port: result.services.postgres.port,
|
|
15142
15168
|
username: "pgboss",
|
|
15143
|
-
password:
|
|
15169
|
+
password: require_reconcile.generateSecurePassword(),
|
|
15144
15170
|
database: result.services.postgres.database ?? "app"
|
|
15145
15171
|
}
|
|
15146
15172
|
}
|
|
15147
15173
|
};
|
|
15148
|
-
result.urls =
|
|
15174
|
+
result.urls = require_reconcile.generateConnectionUrls(result.services, result.eventsBackend);
|
|
15149
15175
|
logger$1.log(" 🔄 Adding missing service credentials: pgboss");
|
|
15150
15176
|
changed = true;
|
|
15151
15177
|
}
|
|
@@ -15180,7 +15206,7 @@ function reconcileSecrets(secrets, workspace, containers = []) {
|
|
|
15180
15206
|
*/
|
|
15181
15207
|
function createFreshWorkspaceSecrets(stage, workspace, containers = []) {
|
|
15182
15208
|
const serviceNames = credentialedServices(containers);
|
|
15183
|
-
const secrets =
|
|
15209
|
+
const secrets = require_reconcile.createStageSecrets(stage, serviceNames, { projectName: workspace.name });
|
|
15184
15210
|
if (Object.keys(workspace.apps).length > 1) secrets.custom = require_reconcile.generateFullstackCustomSecrets(workspace, containers);
|
|
15185
15211
|
else secrets.custom = {
|
|
15186
15212
|
PORT: "3000",
|
|
@@ -15202,7 +15228,7 @@ function createFreshWorkspaceSecrets(stage, workspace, containers = []) {
|
|
|
15202
15228
|
async function ensureStageSecrets(stage, cwd = process.cwd()) {
|
|
15203
15229
|
const { workspace } = await require_config.loadWorkspaceConfig(cwd);
|
|
15204
15230
|
if (require_storage.secretsExist(stage, workspace.root)) return false;
|
|
15205
|
-
const secrets = createFreshWorkspaceSecrets(stage, workspace, await
|
|
15231
|
+
const secrets = createFreshWorkspaceSecrets(stage, workspace, await require_workspace$1.derivedContainers(workspace, stage));
|
|
15206
15232
|
await require_storage.writeStageSecrets(secrets, workspace.root);
|
|
15207
15233
|
return true;
|
|
15208
15234
|
}
|
|
@@ -15210,7 +15236,7 @@ async function ensureStageSecrets(stage, cwd = process.cwd()) {
|
|
|
15210
15236
|
* Generate fresh secrets for the workspace.
|
|
15211
15237
|
*/
|
|
15212
15238
|
async function generateFreshSecrets(stage, workspace, options) {
|
|
15213
|
-
const secrets = createFreshWorkspaceSecrets(stage, workspace, await
|
|
15239
|
+
const secrets = createFreshWorkspaceSecrets(stage, workspace, await require_workspace$1.derivedContainers(workspace, stage));
|
|
15214
15240
|
await require_storage.writeStageSecrets(secrets, workspace.root);
|
|
15215
15241
|
logger$1.log(` Secrets written to .gkm/secrets/${stage}.json`);
|
|
15216
15242
|
if (require_transfer.isRemoteStore(workspace, stage) && !options.yes) {
|
|
@@ -15485,13 +15511,12 @@ async function testCommand(options = {}) {
|
|
|
15485
15511
|
const { ensureStageSecrets } = await Promise.resolve().then(() => setup_exports);
|
|
15486
15512
|
if (await ensureStageSecrets(stage, cwd)) console.log(` 🔐 Generated fresh ${stage} secrets (auto-setup)`);
|
|
15487
15513
|
}
|
|
15488
|
-
const defaultEnv =
|
|
15514
|
+
const defaultEnv = require_workspace$1.loadEnvFiles(".env");
|
|
15489
15515
|
if (defaultEnv.loaded.length > 0) console.log(` 📦 Loaded env: ${defaultEnv.loaded.join(", ")}`);
|
|
15490
|
-
const result = await
|
|
15516
|
+
const result = await require_workspace$1.prepareEntryCredentials({
|
|
15491
15517
|
stage,
|
|
15492
15518
|
startDocker: !options.prepare,
|
|
15493
15519
|
secretsFileName: "test-secrets.json",
|
|
15494
|
-
resolveDockerPorts: "full",
|
|
15495
15520
|
reconcileStage: "test"
|
|
15496
15521
|
});
|
|
15497
15522
|
let finalCredentials = { ...result.credentials };
|
|
@@ -15505,18 +15530,17 @@ async function testCommand(options = {}) {
|
|
|
15505
15530
|
console.log(` 🔍 Sniffed ${sniffed.requiredEnvVars.length} required env var(s)` + (result.declaredKeys.length > 0 ? `, kept ${result.declaredKeys.length} declared` : ""));
|
|
15506
15531
|
}
|
|
15507
15532
|
}
|
|
15508
|
-
finalCredentials = rewriteDatabaseUrlForTests(finalCredentials);
|
|
15509
15533
|
console.log("");
|
|
15510
15534
|
await (0, node_fs_promises.writeFile)(result.secretsJsonPath, JSON.stringify(finalCredentials, null, 2));
|
|
15511
15535
|
const gkmDir = (0, node_path.join)(cwd, ".gkm");
|
|
15512
15536
|
const preloadPath = (0, node_path.join)(gkmDir, "test-credentials-preload.ts");
|
|
15513
|
-
await
|
|
15537
|
+
await require_workspace$1.createCredentialsPreload(preloadPath, result.secretsJsonPath);
|
|
15514
15538
|
const workspace = await require_config.loadWorkspaceConfig(cwd).then((loaded) => loaded.workspace).catch(() => void 0);
|
|
15515
|
-
const manifestPath = workspace
|
|
15539
|
+
const manifestPath = workspace ? await writeTestHarness({
|
|
15516
15540
|
root: workspace.root,
|
|
15517
15541
|
targets: [workspace.root, ...Object.values(workspace.apps).map((app) => (0, node_path.isAbsolute)(app.path) ? app.path : (0, node_path.join)(workspace.root, app.path))],
|
|
15518
|
-
patterns:
|
|
15519
|
-
cacheBackend:
|
|
15542
|
+
patterns: require_workspace$1.constructGlobs(workspace),
|
|
15543
|
+
cacheBackend: require_workspace$1.backendsOf(workspace).cache,
|
|
15520
15544
|
stage: require_workspace.TEST_STAGE,
|
|
15521
15545
|
env: finalCredentials
|
|
15522
15546
|
}) : void 0;
|
|
@@ -15556,29 +15580,6 @@ async function testCommand(options = {}) {
|
|
|
15556
15580
|
});
|
|
15557
15581
|
});
|
|
15558
15582
|
}
|
|
15559
|
-
const TEST_DB_SUFFIX = "_test";
|
|
15560
|
-
/**
|
|
15561
|
-
* Rewrite DATABASE_URL to point to a separate test database.
|
|
15562
|
-
* Appends `_test` to the database name (e.g., `app` -> `app_test`).
|
|
15563
|
-
* @internal Exported for testing
|
|
15564
|
-
*/
|
|
15565
|
-
function rewriteDatabaseUrlForTests(env) {
|
|
15566
|
-
const result = { ...env };
|
|
15567
|
-
for (const key of Object.keys(result)) {
|
|
15568
|
-
if (!key.includes("DATABASE_URL")) continue;
|
|
15569
|
-
const value = result[key];
|
|
15570
|
-
try {
|
|
15571
|
-
const url = new URL(value);
|
|
15572
|
-
const dbName = url.pathname.slice(1);
|
|
15573
|
-
if (dbName && !dbName.endsWith(TEST_DB_SUFFIX)) {
|
|
15574
|
-
url.pathname = `/${dbName}${TEST_DB_SUFFIX}`;
|
|
15575
|
-
result[key] = url.toString();
|
|
15576
|
-
console.log(` 🧪 ${key}: using test database "${dbName}${TEST_DB_SUFFIX}"`);
|
|
15577
|
-
}
|
|
15578
|
-
} catch {}
|
|
15579
|
-
}
|
|
15580
|
-
return result;
|
|
15581
|
-
}
|
|
15582
15583
|
/** `gkm test` outside a project that declares stages, with none named. */
|
|
15583
15584
|
var NoStageToTest = class extends Error {
|
|
15584
15585
|
constructor() {
|
|
@@ -16119,7 +16120,7 @@ program.command("secrets:push").description("Send a deployed stage's secrets to
|
|
|
16119
16120
|
const globalOptions = program.opts();
|
|
16120
16121
|
if (globalOptions.cwd) process.chdir(globalOptions.cwd);
|
|
16121
16122
|
const { loadWorkspaceConfig } = await Promise.resolve().then(() => require("./config.cjs"));
|
|
16122
|
-
const { pushStageSecrets } = await Promise.resolve().then(() => require("./transfer-
|
|
16123
|
+
const { pushStageSecrets } = await Promise.resolve().then(() => require("./transfer-BYIn7z8m.cjs")).then((n) => n.transfer_exports);
|
|
16123
16124
|
const { workspace } = await loadWorkspaceConfig();
|
|
16124
16125
|
const { addedKeys } = await pushStageSecrets(workspace, options.stage, { profile: options.profile });
|
|
16125
16126
|
for (const key of addedKeys) console.log(` + ${key} (reconciled)`);
|
|
@@ -16134,7 +16135,7 @@ program.command("secrets:pull").description("Bring a deployed stage's secrets fr
|
|
|
16134
16135
|
const globalOptions = program.opts();
|
|
16135
16136
|
if (globalOptions.cwd) process.chdir(globalOptions.cwd);
|
|
16136
16137
|
const { loadWorkspaceConfig } = await Promise.resolve().then(() => require("./config.cjs"));
|
|
16137
|
-
const { pullStageSecrets } = await Promise.resolve().then(() => require("./transfer-
|
|
16138
|
+
const { pullStageSecrets } = await Promise.resolve().then(() => require("./transfer-BYIn7z8m.cjs")).then((n) => n.transfer_exports);
|
|
16138
16139
|
const { workspace } = await loadWorkspaceConfig();
|
|
16139
16140
|
const { addedKeys } = await pullStageSecrets(workspace, options.stage, { profile: options.profile });
|
|
16140
16141
|
for (const key of addedKeys) console.log(` + ${key} (reconciled)`);
|
|
@@ -16149,7 +16150,7 @@ program.command("secrets:reconcile").description("Backfill missing custom secret
|
|
|
16149
16150
|
const globalOptions = program.opts();
|
|
16150
16151
|
if (globalOptions.cwd) process.chdir(globalOptions.cwd);
|
|
16151
16152
|
const { loadWorkspaceConfig } = await Promise.resolve().then(() => require("./config.cjs"));
|
|
16152
|
-
const { reconcileMissingSecrets } = await Promise.resolve().then(() => require("./reconcile-
|
|
16153
|
+
const { reconcileMissingSecrets } = await Promise.resolve().then(() => require("./reconcile-szmJw_Sb.cjs")).then((n) => n.reconcile_exports);
|
|
16153
16154
|
const { readStageSecrets, writeStageSecrets } = await Promise.resolve().then(() => require("./storage-DgypfSD6.cjs")).then((n) => n.storage_exports);
|
|
16154
16155
|
const { workspace } = await loadWorkspaceConfig();
|
|
16155
16156
|
const stage = options.stage ?? workspace.stages.local;
|
|
@@ -16158,7 +16159,7 @@ program.command("secrets:reconcile").description("Backfill missing custom secret
|
|
|
16158
16159
|
console.error(`No secrets found for stage "${stage}". Run "gkm secrets:init --stage ${stage}" first.`);
|
|
16159
16160
|
process.exit(1);
|
|
16160
16161
|
}
|
|
16161
|
-
const { derivedContainers } = await Promise.resolve().then(() => require("./
|
|
16162
|
+
const { derivedContainers } = await Promise.resolve().then(() => require("./workspace-DgeVgxmm.cjs")).then((n) => n.workspace_exports);
|
|
16162
16163
|
const result = reconcileMissingSecrets(secrets, workspace, await derivedContainers(workspace, stage));
|
|
16163
16164
|
if (!result) {
|
|
16164
16165
|
console.log(`\n✓ Secrets for stage "${stage}" are up-to-date`);
|
|
@@ -16217,7 +16218,7 @@ program.command("deploy:github").description("Let GitHub Actions deploy a stage:
|
|
|
16217
16218
|
try {
|
|
16218
16219
|
const globalOptions = program.opts();
|
|
16219
16220
|
if (globalOptions.cwd) process.chdir(globalOptions.cwd);
|
|
16220
|
-
const { deployGithubCommand } = await Promise.resolve().then(() => require("./github-
|
|
16221
|
+
const { deployGithubCommand } = await Promise.resolve().then(() => require("./github-CQflOKKV.cjs"));
|
|
16221
16222
|
await deployGithubCommand(options);
|
|
16222
16223
|
} catch (error) {
|
|
16223
16224
|
console.error(formatError(error));
|