@geekmidas/cli 10.0.0-alpha.76 → 10.0.0-alpha.77
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/{add-j2yI3cbS.cjs → add-DCsgtvDk.cjs} +7 -7
- package/dist/{add-j2yI3cbS.cjs.map → add-DCsgtvDk.cjs.map} +1 -1
- package/dist/{add-B7IMXzou.mjs → add-EPQO-_dt.mjs} +2 -2
- package/dist/{add-B7IMXzou.mjs.map → add-EPQO-_dt.mjs.map} +1 -1
- package/dist/{bundler-Cf6OgaOe.cjs → bundler-5spPyduN.cjs} +3 -3
- package/dist/{bundler-Cf6OgaOe.cjs.map → bundler-5spPyduN.cjs.map} +1 -1
- package/dist/{bundler-DO6bHhnb.mjs → bundler-DgO_EMVs.mjs} +3 -3
- package/dist/{bundler-DO6bHhnb.mjs.map → bundler-DgO_EMVs.mjs.map} +1 -1
- package/dist/{cli-BCPOHmg9.mjs → cli-B74Ru-V1.mjs} +3 -3
- package/dist/{cli-BCPOHmg9.mjs.map → cli-B74Ru-V1.mjs.map} +1 -1
- package/dist/{cli-CNanUB7a.cjs → cli-ZpFTMbGw.cjs} +4 -4
- package/dist/{cli-CNanUB7a.cjs.map → cli-ZpFTMbGw.cjs.map} +1 -1
- package/dist/{compose-h_6oNnHC.cjs → compose-CePlrbUw.cjs} +66 -59
- package/dist/{compose-h_6oNnHC.cjs.map → compose-CePlrbUw.cjs.map} +1 -1
- package/dist/{compose-Dq4VCtu5.mjs → compose-IUuxRW0J.mjs} +16 -9
- package/dist/{compose-Dq4VCtu5.mjs.map → compose-IUuxRW0J.mjs.map} +1 -1
- package/dist/{config-CqAvPP-f.d.mts → config-Ckmoj56i.d.mts} +3 -3
- package/dist/{config-CWyhLSY1.d.cts.map → config-Ckmoj56i.d.mts.map} +1 -1
- package/dist/{config-CWyhLSY1.d.cts → config-aAeLXH86.d.cts} +3 -3
- package/dist/{config-CqAvPP-f.d.mts.map → config-aAeLXH86.d.cts.map} +1 -1
- package/dist/config.d.cts +3 -3
- package/dist/config.d.mts +3 -3
- package/dist/deploy/public.cjs +11 -11
- package/dist/deploy/public.d.cts +3 -3
- package/dist/deploy/public.d.cts.map +1 -1
- package/dist/deploy/public.d.mts +3 -3
- package/dist/deploy/public.d.mts.map +1 -1
- package/dist/deploy/public.mjs +5 -5
- package/dist/{deploy-CVXEx7Nm.mjs → deploy-Q6X6RXRG.mjs} +3 -3
- package/dist/{deploy-CVXEx7Nm.mjs.map → deploy-Q6X6RXRG.mjs.map} +1 -1
- package/dist/{deploy-CT3R9de9.cjs → deploy-XHXi-_tL.cjs} +9 -9
- package/dist/{deploy-CT3R9de9.cjs.map → deploy-XHXi-_tL.cjs.map} +1 -1
- package/dist/{dokploy-CYm2ozFs.mjs → dokploy-BtP5XSrS.mjs} +2 -2
- package/dist/{dokploy-CYm2ozFs.mjs.map → dokploy-BtP5XSrS.mjs.map} +1 -1
- package/dist/{dokploy-eSGmlhhj.cjs → dokploy-MSsPBO-t.cjs} +2 -2
- package/dist/{dokploy-eSGmlhhj.cjs.map → dokploy-MSsPBO-t.cjs.map} +1 -1
- package/dist/{encryption-DC0rsR1W.mjs → encryption-D4Ykywfr.mjs} +2 -2
- package/dist/{encryption-DC0rsR1W.mjs.map → encryption-D4Ykywfr.mjs.map} +1 -1
- package/dist/{encryption-vS3Qzw73.cjs → encryption-DY0na43R.cjs} +5 -5
- package/dist/{encryption-vS3Qzw73.cjs.map → encryption-DY0na43R.cjs.map} +1 -1
- package/dist/{engine-BOO5TWZd.mjs → engine-BI2xjCKt.mjs} +7 -2
- package/dist/{engine-BOO5TWZd.mjs.map → engine-BI2xjCKt.mjs.map} +1 -1
- package/dist/{engine-C0N2d1i5.cjs → engine-y53kE_3H.cjs} +71 -66
- package/dist/{engine-C0N2d1i5.cjs.map → engine-y53kE_3H.cjs.map} +1 -1
- package/dist/{github-CEaFDL6t.mjs → github-BBIqk1Jv.mjs} +2 -2
- package/dist/{github-CEaFDL6t.mjs.map → github-BBIqk1Jv.mjs.map} +1 -1
- package/dist/{github-ClkdCOL9.cjs → github-Bmb45xUQ.cjs} +6 -6
- package/dist/{github-ClkdCOL9.cjs.map → github-Bmb45xUQ.cjs.map} +1 -1
- package/dist/{index-DOxmDKqv.d.mts → index-C7Tma2m1.d.cts} +2 -2
- package/dist/{index-Ccu0f_2m.d.cts.map → index-C7Tma2m1.d.cts.map} +1 -1
- package/dist/{index-Ccu0f_2m.d.cts → index-CNdSRwar.d.mts} +2 -2
- package/dist/{index-DOxmDKqv.d.mts.map → index-CNdSRwar.d.mts.map} +1 -1
- package/dist/index.cjs +175 -215
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +103 -143
- package/dist/index.mjs.map +1 -1
- package/dist/{migrate-BRbYtFXG.cjs → migrate-31JXUOaG.cjs} +4 -4
- package/dist/{migrate-BRbYtFXG.cjs.map → migrate-31JXUOaG.cjs.map} +1 -1
- package/dist/{migrate-DrO2p9Rl.mjs → migrate-BUBsUiM3.mjs} +2 -2
- package/dist/{migrate-DrO2p9Rl.mjs.map → migrate-BUBsUiM3.mjs.map} +1 -1
- package/dist/{migrate-D3NAT7Ns.mjs → migrate-DWVl5PQK.mjs} +2 -2
- package/dist/{migrate-D3NAT7Ns.mjs.map → migrate-DWVl5PQK.mjs.map} +1 -1
- package/dist/{migrate-D5_-ylI1.cjs → migrate-sny0NjKe.cjs} +7 -7
- package/dist/{migrate-D5_-ylI1.cjs.map → migrate-sny0NjKe.cjs.map} +1 -1
- package/dist/openapi.d.cts +1 -1
- package/dist/openapi.d.mts +1 -1
- package/dist/reconcile/public.d.cts +1 -1
- package/dist/reconcile/public.d.mts +1 -1
- package/dist/{resolve-C1muFos5.mjs → resolve-BF1ICosS.mjs} +3 -3
- package/dist/{resolve-C1muFos5.mjs.map → resolve-BF1ICosS.mjs.map} +1 -1
- package/dist/{resolve-Fa1Ii0BK.cjs → resolve-DokLtTUb.cjs} +3 -3
- package/dist/{resolve-Fa1Ii0BK.cjs.map → resolve-DokLtTUb.cjs.map} +1 -1
- package/dist/{rollback-C9N5lKVf.cjs → rollback-CpOWRR9H.cjs} +5 -5
- package/dist/{rollback-C9N5lKVf.cjs.map → rollback-CpOWRR9H.cjs.map} +1 -1
- package/dist/{rollback-DeQzbRqM.mjs → rollback-sg0ZhKGG.mjs} +3 -3
- package/dist/{rollback-DeQzbRqM.mjs.map → rollback-sg0ZhKGG.mjs.map} +1 -1
- package/dist/{runtime-BSvzPqXW.d.mts → runtime-B5bYom9w.d.mts} +2 -2
- package/dist/{runtime-BSvzPqXW.d.mts.map → runtime-B5bYom9w.d.mts.map} +1 -1
- package/dist/{runtime-Cm7QA53H.d.cts → runtime-BozOkPtG.d.cts} +2 -2
- package/dist/{runtime-Cm7QA53H.d.cts.map → runtime-BozOkPtG.d.cts.map} +1 -1
- package/dist/{state-CUecOCNJ.mjs → stale-DGzpiN5S.mjs} +103 -23
- package/dist/stale-DGzpiN5S.mjs.map +1 -0
- package/dist/{state-C2qi0iQw.cjs → stale-yu2FkH3G.cjs} +108 -22
- package/dist/stale-yu2FkH3G.cjs.map +1 -0
- package/dist/target/public.cjs +1 -1
- package/dist/target/public.d.cts +2 -2
- package/dist/target/public.d.mts +2 -2
- package/dist/target/public.mjs +1 -1
- package/dist/{types-OxE0OAn2.d.mts → types-B9yWJAis.d.mts} +1 -3
- package/dist/types-B9yWJAis.d.mts.map +1 -0
- package/dist/{types-BdptGBFS.d.cts → types-ct7pdQRf.d.cts} +1 -3
- package/dist/types-ct7pdQRf.d.cts.map +1 -0
- package/dist/workspace/index.d.cts +2 -2
- package/dist/workspace/index.d.mts +2 -2
- package/package.json +15 -15
- package/dist/state-C2qi0iQw.cjs.map +0 -1
- package/dist/state-CUecOCNJ.mjs.map +0 -1
- package/dist/types-BdptGBFS.d.cts.map +0 -1
- package/dist/types-OxE0OAn2.d.mts.map +0 -1
package/dist/index.cjs
CHANGED
|
@@ -7,7 +7,7 @@ const require_discover = require("./discover-D1It5r_h.cjs");
|
|
|
7
7
|
const require_derive = require("./derive-DAbo49sm.cjs");
|
|
8
8
|
const require_workspace = require("./workspace-DOm81oUo.cjs");
|
|
9
9
|
const require_config = require("./config.cjs");
|
|
10
|
-
const
|
|
10
|
+
const require_stale = require("./stale-yu2FkH3G.cjs");
|
|
11
11
|
const require_EndpointGenerator = require("./EndpointGenerator-CP6sBvQV.cjs");
|
|
12
12
|
const require_openapi = require("./openapi.cjs");
|
|
13
13
|
const require_SubscriberGenerator = require("./SubscriberGenerator-CajwOa5W.cjs");
|
|
@@ -15,8 +15,8 @@ const require_appPorts = require("./appPorts-Cu79hJF6.cjs");
|
|
|
15
15
|
const require_drivers = require("./drivers-BdvtCKc7.cjs");
|
|
16
16
|
const require_emit = require("./emit-Dmc1nvdS.cjs");
|
|
17
17
|
const require_sniffer = require("./sniffer-Y6GQOCXB.cjs");
|
|
18
|
-
const require_deploy = require("./deploy-
|
|
19
|
-
const require_compose = require("./compose-
|
|
18
|
+
const require_deploy = require("./deploy-XHXi-_tL.cjs");
|
|
19
|
+
const require_compose = require("./compose-CePlrbUw.cjs");
|
|
20
20
|
const require_credentialSchemas = require("./credentialSchemas-DCR4Wd1W.cjs");
|
|
21
21
|
const require_LocalStateStore = require("./LocalStateStore-B0NCde8Z.cjs");
|
|
22
22
|
const require_utils = require("./utils-D2Nk1Nv2.cjs");
|
|
@@ -53,7 +53,7 @@ crypto = require_rolldown_runtime.__toESM(crypto, 1);
|
|
|
53
53
|
let _geekmidas_constructs_functions = require("@geekmidas/constructs/functions");
|
|
54
54
|
let _geekmidas_constructs_topic = require("@geekmidas/constructs/topic");
|
|
55
55
|
//#region package.json
|
|
56
|
-
var version = "10.0.0-alpha.
|
|
56
|
+
var version = "10.0.0-alpha.77";
|
|
57
57
|
//#endregion
|
|
58
58
|
//#region src/prompt.ts
|
|
59
59
|
/**
|
|
@@ -304,7 +304,7 @@ function installation(platform, certificate) {
|
|
|
304
304
|
*/
|
|
305
305
|
async function trustCommand(options = {}) {
|
|
306
306
|
const { workspace } = await require_config.loadWorkspaceConfig();
|
|
307
|
-
const certificate = (0, node_path.join)(workspace.root,
|
|
307
|
+
const certificate = (0, node_path.join)(workspace.root, require_stale.LOCAL_CA_PATH);
|
|
308
308
|
if (!(0, node_fs.existsSync)(certificate)) throw new NoLocalAuthority(certificate);
|
|
309
309
|
const { describe, asks, steps } = installation(process.platform, certificate);
|
|
310
310
|
logger$7.log(`\n🔐 Trusting the local authority in ${describe}`);
|
|
@@ -1488,7 +1488,7 @@ async function serveFakes(fakes, ports) {
|
|
|
1488
1488
|
const served = [];
|
|
1489
1489
|
for (const [id, local] of Object.entries(fakes)) {
|
|
1490
1490
|
if (local.image) continue;
|
|
1491
|
-
const port = ports[
|
|
1491
|
+
const port = ports[require_stale.fakeKey(id)];
|
|
1492
1492
|
if (port === void 0) continue;
|
|
1493
1493
|
const { handler } = (await import((0, node_url.pathToFileURL)(local.file).href)).default;
|
|
1494
1494
|
const server = serve({
|
|
@@ -1531,16 +1531,16 @@ var NoCommandSpecified = class extends Error {
|
|
|
1531
1531
|
async function execCommand(commandArgs, options = {}) {
|
|
1532
1532
|
const cwd = options.cwd ?? process.cwd();
|
|
1533
1533
|
if (!commandArgs[0]) throw new NoCommandSpecified();
|
|
1534
|
-
const defaultEnv =
|
|
1534
|
+
const defaultEnv = require_stale.loadEnvFiles(".env");
|
|
1535
1535
|
if (defaultEnv.loaded.length > 0) logger$6.log(`📦 Loaded env: ${defaultEnv.loaded.join(", ")}`);
|
|
1536
|
-
const { credentials, secretsJsonPath, appName } =
|
|
1536
|
+
const { credentials, secretsJsonPath, appName } = require_stale.isImageBuild() ? await imageBuildEntry(cwd) : await require_stale.prepareEntryCredentials({ cwd });
|
|
1537
1537
|
if (appName) logger$6.log(`📦 App: ${appName}`);
|
|
1538
1538
|
const secretCount = Object.keys(credentials).filter((k) => k !== "PORT").length;
|
|
1539
|
-
if (secretCount > 0 && !
|
|
1539
|
+
if (secretCount > 0 && !require_stale.isImageBuild()) logger$6.log(`🔐 Loaded ${secretCount} secret(s)`);
|
|
1540
1540
|
const preloadDir = (0, node_path.join)(cwd, ".gkm");
|
|
1541
1541
|
await (0, node_fs_promises.mkdir)(preloadDir, { recursive: true });
|
|
1542
1542
|
const preloadPath = (0, node_path.join)(preloadDir, "credentials-preload.mjs");
|
|
1543
|
-
await
|
|
1543
|
+
await require_stale.createCredentialsPreload(preloadPath, secretsJsonPath);
|
|
1544
1544
|
const [cmd, ...args] = commandArgs;
|
|
1545
1545
|
logger$6.log(`🚀 Running: ${[cmd, ...args].join(" ")}`);
|
|
1546
1546
|
const nodeOptions = [(process.env.NODE_OPTIONS ?? "").replace(/--import[= ]\S+/g, "").trim(), `--import=${preloadPath}`].filter(Boolean).join(" ");
|
|
@@ -1568,7 +1568,7 @@ async function execCommand(commandArgs, options = {}) {
|
|
|
1568
1568
|
* secret read and no address resolved.
|
|
1569
1569
|
*/
|
|
1570
1570
|
async function imageBuildEntry(cwd) {
|
|
1571
|
-
const credentials =
|
|
1571
|
+
const credentials = require_stale.imageBuildCredentials();
|
|
1572
1572
|
logger$6.log(`🐳 Image build: ${Object.keys(credentials).length} public value(s) from the build args`);
|
|
1573
1573
|
const dir = (0, node_path.join)(cwd, ".gkm");
|
|
1574
1574
|
await (0, node_fs_promises.mkdir)(dir, { recursive: true });
|
|
@@ -1649,7 +1649,7 @@ const SUBSCRIBERS_ENV = "GKM_SUBSCRIBERS";
|
|
|
1649
1649
|
async function devCommand(options) {
|
|
1650
1650
|
if (options.subscribers === false) process.env[SUBSCRIBERS_ENV] = "off";
|
|
1651
1651
|
if (options.entry) return entryDevCommand(options);
|
|
1652
|
-
const defaultEnv =
|
|
1652
|
+
const defaultEnv = require_stale.loadEnvFiles(".env");
|
|
1653
1653
|
if (defaultEnv.loaded.length > 0) logger$5.log(`📦 Loaded env: ${defaultEnv.loaded.join(", ")}`);
|
|
1654
1654
|
const appConfig = await require_config.loadAppConfig().catch((error) => {
|
|
1655
1655
|
if (error instanceof require_config.NotInAnApp || error instanceof require_config.NotABackendApp) return;
|
|
@@ -1665,7 +1665,7 @@ async function devCommand(options) {
|
|
|
1665
1665
|
const secretsRoot = appConfig.workspaceRoot;
|
|
1666
1666
|
const workspaceAppName = appConfig.appName;
|
|
1667
1667
|
const assigned = await require_appPorts.assignAppPorts(appConfig.workspace, [workspaceAppName], {
|
|
1668
|
-
free:
|
|
1668
|
+
free: require_stale.isPortAvailable,
|
|
1669
1669
|
holder: require_appPorts.holderOf
|
|
1670
1670
|
});
|
|
1671
1671
|
if (assigned.running.length > 0) throw new WorkspacePortsInUse(assigned.running);
|
|
@@ -1683,7 +1683,7 @@ async function devCommand(options) {
|
|
|
1683
1683
|
});
|
|
1684
1684
|
}
|
|
1685
1685
|
if (config.env) {
|
|
1686
|
-
const { loaded, missing } =
|
|
1686
|
+
const { loaded, missing } = require_stale.loadEnvFiles(config.env, appRoot);
|
|
1687
1687
|
if (loaded.length > 0) logger$5.log(`📦 Loaded env: ${loaded.join(", ")}`);
|
|
1688
1688
|
if (missing.length > 0) logger$5.warn(`⚠️ Missing env files: ${missing.join(", ")}`);
|
|
1689
1689
|
}
|
|
@@ -1696,8 +1696,8 @@ async function devCommand(options) {
|
|
|
1696
1696
|
appRoot,
|
|
1697
1697
|
target: "server",
|
|
1698
1698
|
enableOpenApi,
|
|
1699
|
-
cacheBackend:
|
|
1700
|
-
eventsBackend:
|
|
1699
|
+
cacheBackend: require_stale.cacheBackendFor(require_stale.providerOf(workspace ?? config)),
|
|
1700
|
+
eventsBackend: require_stale.eventsBackendFor(require_stale.providerOf(workspace ?? config)),
|
|
1701
1701
|
telescope,
|
|
1702
1702
|
databaseApi: true,
|
|
1703
1703
|
hooks,
|
|
@@ -1711,16 +1711,16 @@ async function devCommand(options) {
|
|
|
1711
1711
|
let secretsJsonPath;
|
|
1712
1712
|
let publicUrl;
|
|
1713
1713
|
let manifest;
|
|
1714
|
-
const appSecrets = await
|
|
1714
|
+
const appSecrets = await require_stale.loadSecretsForApp(workspace ? await require_stale.secretsStoreFor(workspace, config.stages.local) : new require_stale.FileSecretsStore(secretsRoot), config.stages.local);
|
|
1715
1715
|
if (workspace) {
|
|
1716
|
-
const reconciled = await
|
|
1716
|
+
const reconciled = await require_stale.reconcileWorkspace(workspace, {
|
|
1717
1717
|
stage: workspace.stages.local,
|
|
1718
1718
|
...options.fake ? { fake: true } : {},
|
|
1719
1719
|
progress: (message) => logger$5.log(message)
|
|
1720
1720
|
});
|
|
1721
1721
|
if (reconciled.services.length > 0) {
|
|
1722
1722
|
logger$5.log("🐳 Services");
|
|
1723
|
-
for (const line of
|
|
1723
|
+
for (const line of require_stale.describeServices(reconciled.services)) logger$5.log(line);
|
|
1724
1724
|
}
|
|
1725
1725
|
Object.assign(appSecrets, reconciled.env);
|
|
1726
1726
|
const own = reconciled.plan.resources.find((r) => (r.kind === "rest-api" || r.kind === "site") && require_derive.appKey(r.id) === workspaceAppName);
|
|
@@ -1999,8 +1999,8 @@ async function validateFrontendApps(workspace) {
|
|
|
1999
1999
|
async function loadDevSecrets(workspace) {
|
|
2000
2000
|
if (!workspace.secrets.enabled) return {};
|
|
2001
2001
|
const stage = workspace.stages.local;
|
|
2002
|
-
const secrets = await (await
|
|
2003
|
-
if (secrets) return
|
|
2002
|
+
const secrets = await (await require_stale.secretsStoreFor(workspace, stage)).read(stage);
|
|
2003
|
+
if (secrets) return require_stale.toEmbeddableSecrets(secrets);
|
|
2004
2004
|
return {};
|
|
2005
2005
|
}
|
|
2006
2006
|
/**
|
|
@@ -2015,7 +2015,7 @@ async function loadDevSecrets(workspace) {
|
|
|
2015
2015
|
async function workspaceDevCommand(configured, options) {
|
|
2016
2016
|
const scoped = options.app ? [options.app] : options.filter ? [] : Object.keys(configured.apps);
|
|
2017
2017
|
const assigned = await require_appPorts.assignAppPorts(configured, scoped, {
|
|
2018
|
-
free:
|
|
2018
|
+
free: require_stale.isPortAvailable,
|
|
2019
2019
|
holder: require_appPorts.holderOf
|
|
2020
2020
|
});
|
|
2021
2021
|
if (assigned.running.length > 0) throw new WorkspacePortsInUse(assigned.running);
|
|
@@ -2042,14 +2042,14 @@ async function workspaceDevCommand(configured, options) {
|
|
|
2042
2042
|
if (hasErrors) throw new Error("Frontend app validation failed. Fix the issues above and try again.");
|
|
2043
2043
|
}
|
|
2044
2044
|
const rawSecrets = await loadDevSecrets(workspace);
|
|
2045
|
-
const reconciled = await
|
|
2045
|
+
const reconciled = await require_stale.reconcileWorkspace(workspace, {
|
|
2046
2046
|
stage: workspace.stages.local,
|
|
2047
2047
|
...options.fake ? { fake: true } : {},
|
|
2048
2048
|
progress: (message) => logger$5.log(message)
|
|
2049
2049
|
});
|
|
2050
2050
|
if (reconciled.services.length > 0) {
|
|
2051
2051
|
logger$5.log("🐳 Services");
|
|
2052
|
-
for (const line of
|
|
2052
|
+
for (const line of require_stale.describeServices(reconciled.services)) logger$5.log(line);
|
|
2053
2053
|
}
|
|
2054
2054
|
const secretsEnv = {
|
|
2055
2055
|
...rawSecrets,
|
|
@@ -2059,9 +2059,9 @@ async function workspaceDevCommand(configured, options) {
|
|
|
2059
2059
|
for (const { id, port } of fakes) logger$5.log(`🎭 ${id} fake: http://localhost:${port}`);
|
|
2060
2060
|
logger$5.log(options.migrate || options.seed ? "🗄️ Migrating the databases" : "🗄️ Checking for pending migrations");
|
|
2061
2061
|
if (options.migrate || options.seed) {
|
|
2062
|
-
const { prepareDevDatabases } = await Promise.resolve().then(() => require("./migrate-
|
|
2062
|
+
const { prepareDevDatabases } = await Promise.resolve().then(() => require("./migrate-sny0NjKe.cjs"));
|
|
2063
2063
|
await prepareDevDatabases(workspace, reconciled.env, { seed: !!options.seed });
|
|
2064
|
-
} else await Promise.resolve().then(() => require("./migrate-
|
|
2064
|
+
} else await Promise.resolve().then(() => require("./migrate-sny0NjKe.cjs")).then(({ reportPendingMigrations }) => reportPendingMigrations(workspace, reconciled.env)).catch((error) => {
|
|
2065
2065
|
logger$5.log(`⚠️ Could not check for pending migrations: ${error instanceof Error ? error.message : String(error)}`);
|
|
2066
2066
|
});
|
|
2067
2067
|
const appUrls = {};
|
|
@@ -2147,7 +2147,7 @@ async function workspaceDevCommand(configured, options) {
|
|
|
2147
2147
|
...secretsEnv,
|
|
2148
2148
|
NODE_ENV: "development",
|
|
2149
2149
|
...configPath ? { GKM_CONFIG_PATH: configPath } : {},
|
|
2150
|
-
...options.fake ? { [
|
|
2150
|
+
...options.fake ? { [require_stale.FAKE_ENV]: "1" } : {},
|
|
2151
2151
|
[DISCOVERY_QUIET_ENV]: "1"
|
|
2152
2152
|
};
|
|
2153
2153
|
logger$5.log(`🚀 Starting ${appCount} app(s) — each builds before it answers, and says so when it is ready`);
|
|
@@ -2210,16 +2210,16 @@ async function entryDevCommand(options) {
|
|
|
2210
2210
|
if (!entry) throw new Error("--entry requires a file path");
|
|
2211
2211
|
const entryPath = (0, node_path.resolve)(process.cwd(), entry);
|
|
2212
2212
|
if (!(0, node_fs.existsSync)(entryPath)) throw new Error(`Entry file not found: ${entryPath}`);
|
|
2213
|
-
const defaultEnv =
|
|
2213
|
+
const defaultEnv = require_stale.loadEnvFiles(".env");
|
|
2214
2214
|
if (defaultEnv.loaded.length > 0) logger$5.log(`📦 Loaded env: ${defaultEnv.loaded.join(", ")}`);
|
|
2215
|
-
const { credentials, resolvedPort, secretsJsonPath, appName } = await
|
|
2215
|
+
const { credentials, resolvedPort, secretsJsonPath, appName } = await require_stale.prepareEntryCredentials({ explicitPort: options.portExplicit ? options.port : void 0 });
|
|
2216
2216
|
if (appName) logger$5.log(`📦 App: ${appName} (port ${resolvedPort})`);
|
|
2217
2217
|
logger$5.log(`🚀 Starting entry file: ${entry} on port ${resolvedPort}`);
|
|
2218
2218
|
if (Object.keys(credentials).length > 1) logger$5.log(`🔐 Loaded ${Object.keys(credentials).length - 1} secret(s) + PORT`);
|
|
2219
2219
|
const wrapperDir = (0, node_path.join)(process.cwd(), ".gkm");
|
|
2220
2220
|
await (0, node_fs_promises.mkdir)(wrapperDir, { recursive: true });
|
|
2221
2221
|
const wrapperPath = (0, node_path.join)(wrapperDir, "entry-wrapper.ts");
|
|
2222
|
-
await
|
|
2222
|
+
await require_stale.createEntryWrapper(wrapperPath, entryPath, secretsJsonPath);
|
|
2223
2223
|
const runner = new EntryRunner(wrapperPath, entryPath, watch, resolvedPort);
|
|
2224
2224
|
await runner.start();
|
|
2225
2225
|
let isShuttingDown = false;
|
|
@@ -2528,10 +2528,10 @@ var DevServer = class {
|
|
|
2528
2528
|
this.startTime = Date.now();
|
|
2529
2529
|
if (this.isRunning) await this.stop();
|
|
2530
2530
|
if (this.portExplicit) {
|
|
2531
|
-
if (!await
|
|
2531
|
+
if (!await require_stale.isPortAvailable(this.requestedPort)) throw new DevPortInUse(this.requestedPort, listenerOn(this.requestedPort));
|
|
2532
2532
|
this.actualPort = this.requestedPort;
|
|
2533
2533
|
} else {
|
|
2534
|
-
this.actualPort = await
|
|
2534
|
+
this.actualPort = await require_stale.findAvailablePort(this.requestedPort);
|
|
2535
2535
|
if (this.actualPort !== this.requestedPort) logger$5.log(`ℹ️ Port ${this.requestedPort} was in use, using port ${this.actualPort} instead`);
|
|
2536
2536
|
}
|
|
2537
2537
|
const serverEntryPath = (0, node_path.join)(this.appRoot, ".gkm", "server", "server.ts");
|
|
@@ -2602,7 +2602,7 @@ var DevServer = class {
|
|
|
2602
2602
|
await this.stop();
|
|
2603
2603
|
let attempts = 0;
|
|
2604
2604
|
while (attempts < 30) {
|
|
2605
|
-
if (await
|
|
2605
|
+
if (await require_stale.isPortAvailable(portToReuse)) break;
|
|
2606
2606
|
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
2607
2607
|
attempts++;
|
|
2608
2608
|
}
|
|
@@ -2943,7 +2943,7 @@ async function buildCommand(options) {
|
|
|
2943
2943
|
}
|
|
2944
2944
|
}
|
|
2945
2945
|
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;
|
|
2946
|
-
const target = options.provider ??
|
|
2946
|
+
const target = options.provider ?? require_stale.providerOf(loadedConfig.workspace);
|
|
2947
2947
|
const workspaceRoot = loadedConfig.workspace.root;
|
|
2948
2948
|
const appRoot = process.cwd();
|
|
2949
2949
|
const output = await buildOneApp({
|
|
@@ -2975,15 +2975,15 @@ async function declaredIn(config, cwd) {
|
|
|
2975
2975
|
*/
|
|
2976
2976
|
function backendsOf(workspace) {
|
|
2977
2977
|
return {
|
|
2978
|
-
cache:
|
|
2978
|
+
cache: require_stale.cacheBackendFor(require_stale.providerOf(workspace)),
|
|
2979
2979
|
email: "ses"
|
|
2980
2980
|
};
|
|
2981
2981
|
}
|
|
2982
2982
|
/** One app's build, from its config and the command's options. */
|
|
2983
2983
|
async function buildOneApp(input) {
|
|
2984
2984
|
const { config, options, workspace, appRoot, target } = input;
|
|
2985
|
-
const cacheBackend = options.cache ??
|
|
2986
|
-
const eventsBackend =
|
|
2985
|
+
const cacheBackend = options.cache ?? require_stale.cacheBackendFor(require_stale.providerOf(workspace));
|
|
2986
|
+
const eventsBackend = require_stale.eventsBackendFor(require_stale.providerOf(workspace));
|
|
2987
2987
|
const production = normalizeProductionConfig(options.production ?? false);
|
|
2988
2988
|
if (production) logger$4.log(`🏭 Building for PRODUCTION`);
|
|
2989
2989
|
logger$4.log(`Building for ${target}`);
|
|
@@ -3069,7 +3069,7 @@ async function buildApp(input) {
|
|
|
3069
3069
|
if (production?.bundle && !input.skipBundle) {
|
|
3070
3070
|
const outputDir = (0, node_path.join)(appRoot, ".gkm", "server");
|
|
3071
3071
|
const entryPoint = await writeSurfaceServer(outputDir, production);
|
|
3072
|
-
const { bundleServer } = await Promise.resolve().then(() => require("./bundler-
|
|
3072
|
+
const { bundleServer } = await Promise.resolve().then(() => require("./bundler-5spPyduN.cjs"));
|
|
3073
3073
|
await bundleServer({
|
|
3074
3074
|
entryPoint,
|
|
3075
3075
|
outputDir: (0, node_path.join)(outputDir, "dist"),
|
|
@@ -3113,9 +3113,9 @@ async function buildApp(input) {
|
|
|
3113
3113
|
};
|
|
3114
3114
|
const endpointGenerator = new require_EndpointGenerator.EndpointGenerator();
|
|
3115
3115
|
const functionGenerator = new FunctionGenerator();
|
|
3116
|
-
const cronGenerator = new
|
|
3116
|
+
const cronGenerator = new require_stale.CronGenerator();
|
|
3117
3117
|
const subscriberGenerator = new require_SubscriberGenerator.SubscriberGenerator();
|
|
3118
|
-
const queueGenerator = new
|
|
3118
|
+
const queueGenerator = new require_stale.QueueGenerator();
|
|
3119
3119
|
const topicGenerator = new TopicGenerator();
|
|
3120
3120
|
const code = constructGlobs;
|
|
3121
3121
|
const [loadedEndpoints, allFunctions, allCrons, allSubscribers, allQueues, allTopics] = await Promise.all([
|
|
@@ -3154,7 +3154,7 @@ async function buildApp(input) {
|
|
|
3154
3154
|
const appName = Object.entries(input.workspace.apps).find(([, app]) => (0, node_path.resolve)(input.workspace.root, app.path) === (0, node_path.resolve)(appRoot))?.[0];
|
|
3155
3155
|
await buildWorkers({
|
|
3156
3156
|
context: buildContext,
|
|
3157
|
-
workers:
|
|
3157
|
+
workers: require_stale.workerUnits(input.workspace, declared, background).filter((unit) => unit.app === appName),
|
|
3158
3158
|
serverDir: (0, node_path.join)(appRoot, ".gkm", "server"),
|
|
3159
3159
|
crons: allCrons,
|
|
3160
3160
|
queues: allQueues,
|
|
@@ -3177,7 +3177,7 @@ async function buildApp(input) {
|
|
|
3177
3177
|
* runnables built from that worker, and nothing built from another.
|
|
3178
3178
|
*/
|
|
3179
3179
|
async function buildWorkers(input) {
|
|
3180
|
-
const generator = new
|
|
3180
|
+
const generator = new require_stale.WorkerGenerator();
|
|
3181
3181
|
for (const worker of input.workers) {
|
|
3182
3182
|
const owned = (list) => list.filter(({ construct }) => construct.owner === worker.id);
|
|
3183
3183
|
const crons = owned(input.crons);
|
|
@@ -3186,15 +3186,15 @@ async function buildWorkers(input) {
|
|
|
3186
3186
|
const entryPoint = await generator.build({
|
|
3187
3187
|
context: input.context,
|
|
3188
3188
|
workerId: worker.id,
|
|
3189
|
-
outputDir:
|
|
3189
|
+
outputDir: require_stale.workerEntryDir(input.serverDir, worker.id),
|
|
3190
3190
|
crons,
|
|
3191
3191
|
queues,
|
|
3192
3192
|
subscribers
|
|
3193
3193
|
});
|
|
3194
3194
|
logger$4.log(`Generated worker ${worker.id}: ${crons.length} crons, ${queues.length} queues, ${subscribers.length} subscribers`);
|
|
3195
3195
|
if (!input.bundle) continue;
|
|
3196
|
-
const { bundleServer } = await Promise.resolve().then(() => require("./bundler-
|
|
3197
|
-
const outfile =
|
|
3196
|
+
const { bundleServer } = await Promise.resolve().then(() => require("./bundler-5spPyduN.cjs"));
|
|
3197
|
+
const outfile = require_stale.workerBundleName(worker.id);
|
|
3198
3198
|
await bundleServer({
|
|
3199
3199
|
entryPoint,
|
|
3200
3200
|
outputDir: (0, node_path.join)(input.serverDir, "dist"),
|
|
@@ -3263,7 +3263,7 @@ async function buildForTarget(target, context, appRoot, workspaceRoot, endpointG
|
|
|
3263
3263
|
let masterKey;
|
|
3264
3264
|
if (context.production?.bundle && !skipBundle) {
|
|
3265
3265
|
logger$4.log(`\n📦 Bundling production server...`);
|
|
3266
|
-
const { bundleServer } = await Promise.resolve().then(() => require("./bundler-
|
|
3266
|
+
const { bundleServer } = await Promise.resolve().then(() => require("./bundler-5spPyduN.cjs"));
|
|
3267
3267
|
const allConstructs = [
|
|
3268
3268
|
...endpoints.map((e) => e.construct),
|
|
3269
3269
|
...functions.map((f) => f.construct),
|
|
@@ -3394,7 +3394,7 @@ async function workspaceBuildCommand(workspace, options) {
|
|
|
3394
3394
|
const buildOrder = require_workspace.getAppBuildOrder(workspace);
|
|
3395
3395
|
logger$4.log(` Build order: ${buildOrder.join(" → ")}`);
|
|
3396
3396
|
try {
|
|
3397
|
-
const target = options.provider ??
|
|
3397
|
+
const target = options.provider ?? require_stale.providerOf(workspace);
|
|
3398
3398
|
const builds = [];
|
|
3399
3399
|
for (const appName of buildOrder) {
|
|
3400
3400
|
const app = workspace.apps[appName];
|
|
@@ -3517,14 +3517,14 @@ async function composeCommand(options, deps = {}) {
|
|
|
3517
3517
|
if (options.push && !options.build) throw new require_compose.ComposePushNeedsBuild();
|
|
3518
3518
|
const pulls = !options.build && (options.pull || options.tag !== void 0);
|
|
3519
3519
|
if (options.digestsFile && !options.push && !pulls) throw new require_compose.ComposePinNeedsPull();
|
|
3520
|
-
const allowDevServices =
|
|
3520
|
+
const allowDevServices = require_stale.parseDevServices(options.allowDevServices);
|
|
3521
3521
|
const cwd = (0, node_path.resolve)(options.cwd ?? process.cwd());
|
|
3522
3522
|
const { workspace } = await require_config.loadWorkspaceConfig(cwd);
|
|
3523
3523
|
const { stage } = options;
|
|
3524
3524
|
if (options.down) {
|
|
3525
3525
|
const override = require_compose.stackOverrideFile(workspace.root, stage);
|
|
3526
3526
|
const ref = {
|
|
3527
|
-
project: require_compose.composeProject(
|
|
3527
|
+
project: require_compose.composeProject(require_stale.deployIdentity(workspace, stage)),
|
|
3528
3528
|
file: (0, node_path.join)(workspace.root, require_compose.stackDir(stage), "docker-compose.yml"),
|
|
3529
3529
|
...(0, node_fs.existsSync)(override) ? { overrides: [override] } : {},
|
|
3530
3530
|
cwd: workspace.root
|
|
@@ -4033,13 +4033,6 @@ const SERVICE_DEFAULTS = {
|
|
|
4033
4033
|
region: "us-east-1"
|
|
4034
4034
|
}
|
|
4035
4035
|
};
|
|
4036
|
-
/** Default credentials for pgboss (not a Docker service, reuses postgres) */
|
|
4037
|
-
const PGBOSS_DEFAULTS = {
|
|
4038
|
-
host: "localhost",
|
|
4039
|
-
port: 5432,
|
|
4040
|
-
username: "pgboss",
|
|
4041
|
-
database: "app"
|
|
4042
|
-
};
|
|
4043
4036
|
/**
|
|
4044
4037
|
* Generate credentials for a specific service.
|
|
4045
4038
|
*/
|
|
@@ -4079,14 +4072,6 @@ function generateMinioEndpoint(creds) {
|
|
|
4079
4072
|
return `http://${host}:${port}`;
|
|
4080
4073
|
}
|
|
4081
4074
|
/**
|
|
4082
|
-
* Generate connection URL for pg-boss (uses PostgreSQL protocol).
|
|
4083
|
-
* Format: pgboss://user:pass@host:port/db?schema=pgboss
|
|
4084
|
-
*/
|
|
4085
|
-
function generatePgBossUrl(creds) {
|
|
4086
|
-
const { username, password, host, port, database } = creds;
|
|
4087
|
-
return `pgboss://${username}:${encodeURIComponent(password)}@${host}:${port}/${database}?schema=pgboss`;
|
|
4088
|
-
}
|
|
4089
|
-
/**
|
|
4090
4075
|
* Generate connection URLs from service credentials.
|
|
4091
4076
|
*/
|
|
4092
4077
|
function generateConnectionUrls(services) {
|
|
@@ -4094,7 +4079,6 @@ function generateConnectionUrls(services) {
|
|
|
4094
4079
|
if (services.postgres) urls.DATABASE_URL = generatePostgresUrl(services.postgres);
|
|
4095
4080
|
if (services.redis) urls.REDIS_URL = generateRedisUrl(services.redis);
|
|
4096
4081
|
if (services.minio) urls.STORAGE_ENDPOINT = generateMinioEndpoint(services.minio);
|
|
4097
|
-
if (services.pgboss) urls.EVENT_PUBLISHER_CONNECTION_STRING = generatePgBossUrl(services.pgboss);
|
|
4098
4082
|
if (services.mailpit) {
|
|
4099
4083
|
urls.SMTP_HOST = services.mailpit.host;
|
|
4100
4084
|
urls.SMTP_PORT = String(services.mailpit.port);
|
|
@@ -4118,13 +4102,6 @@ function createStageSecrets(stage, services, options) {
|
|
|
4118
4102
|
serviceCredentials.minio.username = options.projectName;
|
|
4119
4103
|
}
|
|
4120
4104
|
}
|
|
4121
|
-
if (serviceCredentials.postgres && !serviceCredentials.pgboss) serviceCredentials.pgboss = {
|
|
4122
|
-
...PGBOSS_DEFAULTS,
|
|
4123
|
-
password: generateSecurePassword(),
|
|
4124
|
-
host: serviceCredentials.postgres.host,
|
|
4125
|
-
port: serviceCredentials.postgres.port,
|
|
4126
|
-
database: serviceCredentials.postgres.database
|
|
4127
|
-
};
|
|
4128
4105
|
return {
|
|
4129
4106
|
stage,
|
|
4130
4107
|
createdAt: now,
|
|
@@ -4987,25 +4964,25 @@ function loadPackageJson() {
|
|
|
4987
4964
|
* Run: pnpm --filter @geekmidas/cli sync-versions
|
|
4988
4965
|
*/
|
|
4989
4966
|
const GEEKMIDAS_VERSIONS = {
|
|
4990
|
-
"@geekmidas/audit": "~10.0.0-alpha.
|
|
4991
|
-
"@geekmidas/auth": "~10.0.0-alpha.
|
|
4992
|
-
"@geekmidas/cache": "~10.0.0-alpha.
|
|
4993
|
-
"@geekmidas/client": "~10.0.0-alpha.
|
|
4994
|
-
"@geekmidas/cloud": "~10.0.0-alpha.
|
|
4995
|
-
"@geekmidas/constructs": "~10.0.0-alpha.
|
|
4996
|
-
"@geekmidas/db": "~10.0.0-alpha.
|
|
4997
|
-
"@geekmidas/emailkit": "~10.0.0-alpha.
|
|
4998
|
-
"@geekmidas/envkit": "~10.0.0-alpha.
|
|
4999
|
-
"@geekmidas/errors": "~10.0.0-alpha.
|
|
5000
|
-
"@geekmidas/events": "~10.0.0-alpha.
|
|
5001
|
-
"@geekmidas/logger": "~10.0.0-alpha.
|
|
5002
|
-
"@geekmidas/manifest": "~10.0.0-alpha.
|
|
5003
|
-
"@geekmidas/rate-limit": "~10.0.0-alpha.
|
|
5004
|
-
"@geekmidas/schema": "~10.0.0-alpha.
|
|
5005
|
-
"@geekmidas/services": "~10.0.0-alpha.
|
|
5006
|
-
"@geekmidas/storage": "~10.0.0-alpha.
|
|
5007
|
-
"@geekmidas/telescope": "~10.0.0-alpha.
|
|
5008
|
-
"@geekmidas/testkit": "~10.0.0-alpha.
|
|
4967
|
+
"@geekmidas/audit": "~10.0.0-alpha.77",
|
|
4968
|
+
"@geekmidas/auth": "~10.0.0-alpha.77",
|
|
4969
|
+
"@geekmidas/cache": "~10.0.0-alpha.77",
|
|
4970
|
+
"@geekmidas/client": "~10.0.0-alpha.77",
|
|
4971
|
+
"@geekmidas/cloud": "~10.0.0-alpha.77",
|
|
4972
|
+
"@geekmidas/constructs": "~10.0.0-alpha.77",
|
|
4973
|
+
"@geekmidas/db": "~10.0.0-alpha.77",
|
|
4974
|
+
"@geekmidas/emailkit": "~10.0.0-alpha.77",
|
|
4975
|
+
"@geekmidas/envkit": "~10.0.0-alpha.77",
|
|
4976
|
+
"@geekmidas/errors": "~10.0.0-alpha.77",
|
|
4977
|
+
"@geekmidas/events": "~10.0.0-alpha.77",
|
|
4978
|
+
"@geekmidas/logger": "~10.0.0-alpha.77",
|
|
4979
|
+
"@geekmidas/manifest": "~10.0.0-alpha.77",
|
|
4980
|
+
"@geekmidas/rate-limit": "~10.0.0-alpha.77",
|
|
4981
|
+
"@geekmidas/schema": "~10.0.0-alpha.77",
|
|
4982
|
+
"@geekmidas/services": "~10.0.0-alpha.77",
|
|
4983
|
+
"@geekmidas/storage": "~10.0.0-alpha.77",
|
|
4984
|
+
"@geekmidas/telescope": "~10.0.0-alpha.77",
|
|
4985
|
+
"@geekmidas/testkit": "~10.0.0-alpha.77",
|
|
5009
4986
|
"@geekmidas/cli": `~${loadPackageJson().version}`
|
|
5010
4987
|
};
|
|
5011
4988
|
//#endregion
|
|
@@ -5588,7 +5565,7 @@ function deploy(options) {
|
|
|
5588
5565
|
role-to-assume: \${{ vars.AWS_ROLE_ARN }}
|
|
5589
5566
|
aws-region: ${options.region}
|
|
5590
5567
|
` : "";
|
|
5591
|
-
const keyDir = `~/.gkm/keys/${
|
|
5568
|
+
const keyDir = `~/.gkm/keys/${require_stale.projectKey({ name: options.name })}`;
|
|
5592
5569
|
const stageSecrets = sst ? credentials : `
|
|
5593
5570
|
# The stage's secrets are kept in the encrypted .gkm/secrets/<stage>.json,
|
|
5594
5571
|
# and each environment holds its key as GKM_SECRETS_KEY. .gkm/ is
|
|
@@ -6850,7 +6827,6 @@ docker-compose.constructs.yml
|
|
|
6850
6827
|
.env
|
|
6851
6828
|
.env.local
|
|
6852
6829
|
.env.*.local
|
|
6853
|
-
docker/.env
|
|
6854
6830
|
|
|
6855
6831
|
# IDE
|
|
6856
6832
|
.idea/
|
|
@@ -9919,18 +9895,17 @@ async function initCommand(projectName, options = {}) {
|
|
|
9919
9895
|
};
|
|
9920
9896
|
if (isFullstack) {
|
|
9921
9897
|
customSecrets.AUTH_PORT = "3002";
|
|
9922
|
-
customSecrets.AUTH_URL = "http://localhost:3002";
|
|
9923
9898
|
customSecrets.BETTER_AUTH_SECRET = `better-auth-${Date.now()}-${Math.random().toString(36).slice(2)}`;
|
|
9924
9899
|
customSecrets.BETTER_AUTH_URL = "http://localhost:3002";
|
|
9925
9900
|
customSecrets.BETTER_AUTH_TRUSTED_ORIGINS = "http://localhost:3000,http://localhost:3001";
|
|
9926
9901
|
}
|
|
9927
9902
|
devSecrets.custom = customSecrets;
|
|
9928
9903
|
const keys = {
|
|
9929
|
-
key:
|
|
9904
|
+
key: require_stale.projectKey({ name }),
|
|
9930
9905
|
legacy: [(0, node_path.basename)(targetDir)]
|
|
9931
9906
|
};
|
|
9932
|
-
await new
|
|
9933
|
-
const keyPath =
|
|
9907
|
+
await new require_stale.FileSecretsStore(targetDir, keys).write(local, devSecrets);
|
|
9908
|
+
const keyPath = require_stale.getKeyPath(local, keys);
|
|
9934
9909
|
console.log(` Secrets: .gkm/secrets/${local}.json (encrypted)`);
|
|
9935
9910
|
console.log(` Key: ${keyPath}\n`);
|
|
9936
9911
|
if (!options.skipInstall) {
|
|
@@ -10083,27 +10058,18 @@ var NotAnAwsRegion = class extends Error {
|
|
|
10083
10058
|
//#endregion
|
|
10084
10059
|
//#region src/setup/fullstack-secrets.ts
|
|
10085
10060
|
/**
|
|
10086
|
-
* Generate a secure random password for database users.
|
|
10087
|
-
* Uses a combination of timestamp and random bytes for uniqueness.
|
|
10088
|
-
*/
|
|
10089
|
-
function generateDbPassword() {
|
|
10090
|
-
return `${Date.now().toString(36)}${Math.random().toString(36).slice(2)}${Math.random().toString(36).slice(2)}`;
|
|
10091
|
-
}
|
|
10092
|
-
/**
|
|
10093
|
-
* Generate database URL for an app.
|
|
10094
|
-
* All apps connect to the same database, but use different users/schemas.
|
|
10095
|
-
*/
|
|
10096
|
-
function generateDbUrl(appName, password, projectName, host = "localhost", port = 5432) {
|
|
10097
|
-
return `postgresql://${appName.replace(/-/g, "_")}:${password}@${host}:${port}/${`${projectName.replace(/-/g, "_")}_dev`}`;
|
|
10098
|
-
}
|
|
10099
|
-
/**
|
|
10100
10061
|
* Generate fullstack-aware custom secrets for a workspace.
|
|
10101
10062
|
*
|
|
10102
10063
|
* Generates:
|
|
10103
10064
|
* - Common secrets: PORT, LOG_LEVEL, JWT_SECRET (no `NODE_ENV` — the command
|
|
10104
10065
|
* decides that; see `gkm init`)
|
|
10105
|
-
* - Per-app database passwords and URLs for backend apps with db service
|
|
10106
10066
|
* - Better-auth secrets for apps using the better-auth framework
|
|
10067
|
+
*
|
|
10068
|
+
* No address of anything a construct declares — a database's or a tenant's
|
|
10069
|
+
* URL, a surface's or a site's. Those are derived from the construct, with
|
|
10070
|
+
* passwords from the stage, and one stored here would be a value set by hand,
|
|
10071
|
+
* which wins over the derived one: a `localhost` URL handed to a container,
|
|
10072
|
+
* with a password no role has.
|
|
10107
10073
|
*/
|
|
10108
10074
|
function generateFullstackCustomSecrets(workspace, containers = []) {
|
|
10109
10075
|
const hasDb = containers.includes("postgres");
|
|
@@ -10113,22 +10079,10 @@ function generateFullstackCustomSecrets(workspace, containers = []) {
|
|
|
10113
10079
|
JWT_SECRET: `dev-${Date.now()}-${Math.random().toString(36).slice(2)}`
|
|
10114
10080
|
};
|
|
10115
10081
|
if (!hasDb) return customs;
|
|
10116
|
-
const
|
|
10117
|
-
|
|
10118
|
-
if (appConfig.type === "web") {
|
|
10119
|
-
frontendPorts.push(appConfig.port);
|
|
10120
|
-
const upperName = appName.toUpperCase();
|
|
10121
|
-
customs[`${upperName}_URL`] = `http://localhost:${appConfig.port}`;
|
|
10122
|
-
continue;
|
|
10123
|
-
}
|
|
10124
|
-
if (appConfig.type === "mobile") continue;
|
|
10125
|
-
const password = generateDbPassword();
|
|
10126
|
-
const upperName = appName.toUpperCase();
|
|
10127
|
-
customs[`${upperName}_DATABASE_URL`] = generateDbUrl(appName, password, workspace.name);
|
|
10128
|
-
customs[`${upperName}_DB_PASSWORD`] = password;
|
|
10082
|
+
for (const appConfig of Object.values(workspace.apps)) {
|
|
10083
|
+
if (appConfig.type === "web" || appConfig.type === "mobile") continue;
|
|
10129
10084
|
if (appConfig.framework === "better-auth") {
|
|
10130
10085
|
customs.AUTH_PORT = String(appConfig.port);
|
|
10131
|
-
customs.AUTH_URL = `http://localhost:${appConfig.port}`;
|
|
10132
10086
|
customs.BETTER_AUTH_SECRET = `better-auth-${Date.now()}-${generateSecurePassword(16)}`;
|
|
10133
10087
|
customs.BETTER_AUTH_URL = `http://localhost:${appConfig.port}`;
|
|
10134
10088
|
}
|
|
@@ -10136,25 +10090,6 @@ function generateFullstackCustomSecrets(workspace, containers = []) {
|
|
|
10136
10090
|
if (customs.BETTER_AUTH_SECRET) customs.BETTER_AUTH_TRUSTED_ORIGINS = Object.values(workspace.apps).map((a) => a.port).map((p) => `http://localhost:${p}`).join(",");
|
|
10137
10091
|
return customs;
|
|
10138
10092
|
}
|
|
10139
|
-
/**
|
|
10140
|
-
* Extract *_DB_PASSWORD keys from secrets and write docker/.env.
|
|
10141
|
-
*
|
|
10142
|
-
* The docker/.env file contains database passwords that the PostgreSQL
|
|
10143
|
-
* init script reads to create per-app database users.
|
|
10144
|
-
*/
|
|
10145
|
-
async function writeDockerEnvFromSecrets(secrets, workspaceRoot) {
|
|
10146
|
-
const dbPasswordEntries = Object.entries(secrets.custom).filter(([key]) => key.endsWith("_DB_PASSWORD"));
|
|
10147
|
-
if (secrets.services.pgboss && !dbPasswordEntries.some(([key]) => key === "PGBOSS_DB_PASSWORD")) dbPasswordEntries.push(["PGBOSS_DB_PASSWORD", secrets.services.pgboss.password]);
|
|
10148
|
-
if (dbPasswordEntries.length === 0) return;
|
|
10149
|
-
const envContent = `# Auto-generated docker environment file
|
|
10150
|
-
# Contains database passwords for docker-compose postgres init
|
|
10151
|
-
# This file is gitignored - do not commit to version control
|
|
10152
|
-
${dbPasswordEntries.map(([key, value]) => `${key}=${value}`).join("\n")}
|
|
10153
|
-
`;
|
|
10154
|
-
const envPath = (0, node_path.join)(workspaceRoot, "docker", ".env");
|
|
10155
|
-
await (0, node_fs_promises.mkdir)((0, node_path.dirname)(envPath), { recursive: true });
|
|
10156
|
-
await (0, node_fs_promises.writeFile)(envPath, envContent);
|
|
10157
|
-
}
|
|
10158
10093
|
//#endregion
|
|
10159
10094
|
//#region src/secrets/index.ts
|
|
10160
10095
|
const logger$2 = console;
|
|
@@ -10165,9 +10100,9 @@ const logger$2 = console;
|
|
|
10165
10100
|
*/
|
|
10166
10101
|
async function storeFor(stage) {
|
|
10167
10102
|
try {
|
|
10168
|
-
return await
|
|
10103
|
+
return await require_stale.secretsStoreFor(await require_config.loadWorkspaceSettings(), stage);
|
|
10169
10104
|
} catch (error) {
|
|
10170
|
-
if (error instanceof require_config.ConfigNotFound) return new
|
|
10105
|
+
if (error instanceof require_config.ConfigNotFound) return new require_stale.FileSecretsStore(process.cwd());
|
|
10171
10106
|
throw error;
|
|
10172
10107
|
}
|
|
10173
10108
|
}
|
|
@@ -10238,9 +10173,50 @@ async function secretsSetCommand(key, value, options) {
|
|
|
10238
10173
|
process.exit(1);
|
|
10239
10174
|
}
|
|
10240
10175
|
await assertCredentialValue(key, secretValue, stage);
|
|
10241
|
-
await store.write(stage,
|
|
10176
|
+
await store.write(stage, require_stale.withCustomSecret(secrets, key, secretValue));
|
|
10242
10177
|
logger$2.log(`\n✓ Secret "${key}" set for stage "${stage}" (${store.name})`);
|
|
10243
10178
|
}
|
|
10179
|
+
/** `gkm secrets:unset` for a key the stage does not hold. */
|
|
10180
|
+
var SecretNotSet = class extends Error {
|
|
10181
|
+
key;
|
|
10182
|
+
stage;
|
|
10183
|
+
constructor(key, stage) {
|
|
10184
|
+
super(`The stage '${stage}' holds no secret '${key}'. List what it holds with gkm secrets:show --stage ${stage}.`);
|
|
10185
|
+
this.key = key;
|
|
10186
|
+
this.stage = stage;
|
|
10187
|
+
this.name = "SecretNotSet";
|
|
10188
|
+
}
|
|
10189
|
+
};
|
|
10190
|
+
/** `gkm secrets:unset` on a stage that has no secrets at all. */
|
|
10191
|
+
var StageSecretsNotFound = class extends Error {
|
|
10192
|
+
stage;
|
|
10193
|
+
constructor(stage) {
|
|
10194
|
+
super(`The stage '${stage}' has no secrets, so there is nothing to remove.`);
|
|
10195
|
+
this.stage = stage;
|
|
10196
|
+
this.name = "StageSecretsNotFound";
|
|
10197
|
+
}
|
|
10198
|
+
};
|
|
10199
|
+
/**
|
|
10200
|
+
* Remove a custom secret from a stage, in the stage's own store — the file,
|
|
10201
|
+
* SSM or Secrets Manager. The rest of the stage is written back as it was.
|
|
10202
|
+
*
|
|
10203
|
+
* @throws {StageSecretsNotFound} when the stage holds no secrets
|
|
10204
|
+
* @throws {SecretNotSet} when it holds none by that key
|
|
10205
|
+
*/
|
|
10206
|
+
async function secretsUnsetCommand(key, options) {
|
|
10207
|
+
const { stage } = options;
|
|
10208
|
+
const store = await storeFor(stage);
|
|
10209
|
+
const secrets = await store.read(stage);
|
|
10210
|
+
if (!secrets) throw new StageSecretsNotFound(stage);
|
|
10211
|
+
if (!(key in secrets.custom)) throw new SecretNotSet(key, stage);
|
|
10212
|
+
const { [key]: _removed, ...custom } = secrets.custom;
|
|
10213
|
+
await store.write(stage, {
|
|
10214
|
+
...secrets,
|
|
10215
|
+
updatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
10216
|
+
custom
|
|
10217
|
+
});
|
|
10218
|
+
logger$2.log(`\n✓ Secret "${key}" removed from stage "${stage}" (${store.name})`);
|
|
10219
|
+
}
|
|
10244
10220
|
/**
|
|
10245
10221
|
* A third party's credentials, checked against the schema of the construct
|
|
10246
10222
|
* that reads them before they are stored — what the app would otherwise
|
|
@@ -10260,7 +10236,7 @@ async function assertCredentialValue(key, value, stage) {
|
|
|
10260
10236
|
}
|
|
10261
10237
|
const check = await (await require_credentialSchemas.loadCredentialSchemas({
|
|
10262
10238
|
root: workspace.root,
|
|
10263
|
-
patterns:
|
|
10239
|
+
patterns: require_stale.constructGlobs(workspace)
|
|
10264
10240
|
})).check(key, value);
|
|
10265
10241
|
if (!check.ok) throw new require_credentialSchemas.CredentialsInvalid(stage, [{
|
|
10266
10242
|
key,
|
|
@@ -10286,7 +10262,7 @@ async function secretsShowCommand(options) {
|
|
|
10286
10262
|
logger$2.log(` host: ${creds.host}`);
|
|
10287
10263
|
logger$2.log(` port: ${creds.port}`);
|
|
10288
10264
|
logger$2.log(` username: ${creds.username}`);
|
|
10289
|
-
logger$2.log(` password: ${reveal ? creds.password :
|
|
10265
|
+
logger$2.log(` password: ${reveal ? creds.password : require_stale.maskPassword(creds.password)}`);
|
|
10290
10266
|
if (creds.database) logger$2.log(` database: ${creds.database}`);
|
|
10291
10267
|
if (creds.bucket) logger$2.log(` bucket: ${creds.bucket}`);
|
|
10292
10268
|
}
|
|
@@ -10296,7 +10272,7 @@ async function secretsShowCommand(options) {
|
|
|
10296
10272
|
if (secrets.urls.STORAGE_ENDPOINT) logger$2.log(` STORAGE_ENDPOINT: ${secrets.urls.STORAGE_ENDPOINT}`);
|
|
10297
10273
|
if (Object.keys(secrets.custom).length > 0) {
|
|
10298
10274
|
logger$2.log("\nCustom Secrets:");
|
|
10299
|
-
for (const [key, value] of Object.entries(secrets.custom)) logger$2.log(` ${key}: ${reveal ? value :
|
|
10275
|
+
for (const [key, value] of Object.entries(secrets.custom)) logger$2.log(` ${key}: ${reveal ? value : require_stale.maskPassword(value)}`);
|
|
10300
10276
|
}
|
|
10301
10277
|
if (!reveal) logger$2.log("\nUse --reveal to show actual values");
|
|
10302
10278
|
}
|
|
@@ -10376,7 +10352,7 @@ async function secretsImportCommand(file, options) {
|
|
|
10376
10352
|
function maskUrl(url) {
|
|
10377
10353
|
try {
|
|
10378
10354
|
const parsed = new URL(url);
|
|
10379
|
-
if (parsed.password) parsed.password =
|
|
10355
|
+
if (parsed.password) parsed.password = require_stale.maskPassword(parsed.password);
|
|
10380
10356
|
return parsed.toString();
|
|
10381
10357
|
} catch {
|
|
10382
10358
|
return url;
|
|
@@ -10397,8 +10373,7 @@ const logger$1 = console;
|
|
|
10397
10373
|
* Orchestrates:
|
|
10398
10374
|
* 1. Load workspace config
|
|
10399
10375
|
* 2. Resolve secrets (local → the stage's store → generate fresh)
|
|
10400
|
-
* 3.
|
|
10401
|
-
* 4. Start Docker services
|
|
10376
|
+
* 3. Start Docker services
|
|
10402
10377
|
*/
|
|
10403
10378
|
async function setupCommand(options = {}) {
|
|
10404
10379
|
logger$1.log("\n🔧 Setting up the local environment...\n");
|
|
@@ -10411,20 +10386,13 @@ async function setupCommand(options = {}) {
|
|
|
10411
10386
|
}
|
|
10412
10387
|
const stage = options.stage ?? loadedConfig.workspace.stages.local;
|
|
10413
10388
|
const { workspace } = loadedConfig;
|
|
10414
|
-
const isMultiApp = Object.keys(workspace.apps).length > 1;
|
|
10415
10389
|
logger$1.log(`📦 Workspace: ${workspace.name}`);
|
|
10416
10390
|
logger$1.log(`📱 Apps: ${Object.keys(workspace.apps).join(", ")}`);
|
|
10417
10391
|
logger$1.log(`🔑 Stage: ${stage}\n`);
|
|
10418
|
-
|
|
10419
|
-
if (!secrets) {
|
|
10392
|
+
if (!await resolveSecrets(stage, workspace, options)) {
|
|
10420
10393
|
logger$1.error("❌ Failed to resolve secrets. Exiting.");
|
|
10421
10394
|
process.exit(1);
|
|
10422
10395
|
}
|
|
10423
|
-
const containers = await require_state.derivedContainers(workspace, stage);
|
|
10424
|
-
if (isMultiApp && containers.includes("postgres")) {
|
|
10425
|
-
await writeDockerEnvFromSecrets(secrets, workspace.root);
|
|
10426
|
-
logger$1.log("📄 Generated docker/.env with database passwords");
|
|
10427
|
-
}
|
|
10428
10396
|
if (!options.skipDocker) {
|
|
10429
10397
|
logger$1.log("");
|
|
10430
10398
|
await reconcileLocal(workspace, stage, options);
|
|
@@ -10439,7 +10407,7 @@ async function setupCommand(options = {}) {
|
|
|
10439
10407
|
* free and quiet.
|
|
10440
10408
|
*/
|
|
10441
10409
|
async function reconcileLocal(workspace, stage, options) {
|
|
10442
|
-
const result = await
|
|
10410
|
+
const result = await require_stale.reconcileWorkspace(workspace, { stage });
|
|
10443
10411
|
if (result.plan.containers.length === 0) {
|
|
10444
10412
|
logger$1.log("🐳 No containers declared");
|
|
10445
10413
|
return;
|
|
@@ -10449,7 +10417,7 @@ async function reconcileLocal(workspace, stage, options) {
|
|
|
10449
10417
|
return;
|
|
10450
10418
|
}
|
|
10451
10419
|
logger$1.log("🐳 Services");
|
|
10452
|
-
for (const line of
|
|
10420
|
+
for (const line of require_stale.describeServices(result.services)) logger$1.log(line);
|
|
10453
10421
|
const url = result.plan.resources.filter((r) => r.kind === "rest-api" || r.kind === "site" || r.kind === "file-server").map((r) => result.env[r.envKey]).find((address) => address?.startsWith("https://"));
|
|
10454
10422
|
if (url) await ensureTrusted(workspace.root, url, { ...options.yes ? { assumeYes: true } : {} });
|
|
10455
10423
|
}
|
|
@@ -10466,11 +10434,11 @@ async function resolveSecrets(stage, workspace, options) {
|
|
|
10466
10434
|
logger$1.log("🔐 Generating fresh secrets (--force)...");
|
|
10467
10435
|
return generateFreshSecrets(stage, workspace);
|
|
10468
10436
|
}
|
|
10469
|
-
const store = await
|
|
10437
|
+
const store = await require_stale.secretsStoreFor(workspace, stage);
|
|
10470
10438
|
const secrets = await store.read(stage);
|
|
10471
10439
|
if (secrets) {
|
|
10472
10440
|
logger$1.log("🔐 Using existing secrets");
|
|
10473
|
-
const reconciled = reconcileSecrets(secrets, workspace, await
|
|
10441
|
+
const reconciled = reconcileSecrets(secrets, workspace, await require_stale.derivedContainers(workspace, stage));
|
|
10474
10442
|
if (reconciled) await store.write(stage, reconciled);
|
|
10475
10443
|
return reconciled ?? secrets;
|
|
10476
10444
|
}
|
|
@@ -10521,24 +10489,6 @@ function reconcileSecrets(secrets, workspace, containers = []) {
|
|
|
10521
10489
|
logger$1.log(` 🔄 Adding missing service credentials: ${name}`);
|
|
10522
10490
|
changed = true;
|
|
10523
10491
|
}
|
|
10524
|
-
if (result.services.postgres && !result.services.pgboss) {
|
|
10525
|
-
result = {
|
|
10526
|
-
...result,
|
|
10527
|
-
services: {
|
|
10528
|
-
...result.services,
|
|
10529
|
-
pgboss: {
|
|
10530
|
-
host: result.services.postgres.host,
|
|
10531
|
-
port: result.services.postgres.port,
|
|
10532
|
-
username: "pgboss",
|
|
10533
|
-
password: generateSecurePassword(),
|
|
10534
|
-
database: result.services.postgres.database ?? "app"
|
|
10535
|
-
}
|
|
10536
|
-
}
|
|
10537
|
-
};
|
|
10538
|
-
result.urls = generateConnectionUrls(result.services);
|
|
10539
|
-
logger$1.log(" 🔄 Adding missing service credentials: pgboss");
|
|
10540
|
-
changed = true;
|
|
10541
|
-
}
|
|
10542
10492
|
if (Object.keys(workspace.apps).length > 1) {
|
|
10543
10493
|
const expected = generateFullstackCustomSecrets(workspace, containers);
|
|
10544
10494
|
const missing = {};
|
|
@@ -10590,9 +10540,9 @@ function createFreshWorkspaceSecrets(stage, workspace, containers = []) {
|
|
|
10590
10540
|
*/
|
|
10591
10541
|
async function ensureStageSecrets(stage, cwd = process.cwd()) {
|
|
10592
10542
|
const { workspace } = await require_config.loadWorkspaceConfig(cwd);
|
|
10593
|
-
const store = await
|
|
10543
|
+
const store = await require_stale.secretsStoreFor(workspace, stage);
|
|
10594
10544
|
if (await store.read(stage)) return false;
|
|
10595
|
-
const secrets = createFreshWorkspaceSecrets(stage, workspace, await
|
|
10545
|
+
const secrets = createFreshWorkspaceSecrets(stage, workspace, await require_stale.derivedContainers(workspace, stage));
|
|
10596
10546
|
await store.write(stage, secrets);
|
|
10597
10547
|
return true;
|
|
10598
10548
|
}
|
|
@@ -10600,8 +10550,8 @@ async function ensureStageSecrets(stage, cwd = process.cwd()) {
|
|
|
10600
10550
|
* Generate fresh secrets for the workspace.
|
|
10601
10551
|
*/
|
|
10602
10552
|
async function generateFreshSecrets(stage, workspace) {
|
|
10603
|
-
const secrets = createFreshWorkspaceSecrets(stage, workspace, await
|
|
10604
|
-
const store = await
|
|
10553
|
+
const secrets = createFreshWorkspaceSecrets(stage, workspace, await require_stale.derivedContainers(workspace, stage));
|
|
10554
|
+
const store = await require_stale.secretsStoreFor(workspace, stage);
|
|
10605
10555
|
await store.write(stage, secrets);
|
|
10606
10556
|
logger$1.log(` Secrets written to the "${stage}" store (${store.name})`);
|
|
10607
10557
|
return secrets;
|
|
@@ -10641,7 +10591,7 @@ function printSummary(workspace, stage) {
|
|
|
10641
10591
|
* A no-op when nothing is recorded — no run yet, or one already torn down —
|
|
10642
10592
|
* so running it twice, or before a setup, is harmless.
|
|
10643
10593
|
*/
|
|
10644
|
-
async function dropTestDatabases(cwd, root, sql =
|
|
10594
|
+
async function dropTestDatabases(cwd, root, sql = require_stale.pgClient) {
|
|
10645
10595
|
const readyPath = (0, node_path.join)(cwd, require_ready.TEST_READY_FILE);
|
|
10646
10596
|
const ready = await readReady(readyPath);
|
|
10647
10597
|
const recorded = ready?.databases;
|
|
@@ -10649,9 +10599,9 @@ async function dropTestDatabases(cwd, root, sql = require_state.pgClient) {
|
|
|
10649
10599
|
const client = sql(recorded.port);
|
|
10650
10600
|
for (const name of recorded.names) {
|
|
10651
10601
|
if (!name.endsWith(`_test`)) throw new NotATestDatabase(name);
|
|
10652
|
-
await client.query(void 0, `DROP DATABASE IF EXISTS ${
|
|
10602
|
+
await client.query(void 0, `DROP DATABASE IF EXISTS ${require_stale.quoteIdentifier(name)} WITH (FORCE)`);
|
|
10653
10603
|
}
|
|
10654
|
-
await
|
|
10604
|
+
await require_stale.forgetState(root, require_workspace.TEST_STAGE);
|
|
10655
10605
|
const { databases: _dropped, ...rest } = ready;
|
|
10656
10606
|
await (0, node_fs_promises.writeFile)(readyPath, JSON.stringify(rest, null, 2));
|
|
10657
10607
|
return recorded.names;
|
|
@@ -10691,10 +10641,10 @@ async function testCommand(options = {}) {
|
|
|
10691
10641
|
const { ensureStageSecrets } = await Promise.resolve().then(() => setup_exports);
|
|
10692
10642
|
if (await ensureStageSecrets(stage, cwd)) console.log(` 🔐 Generated fresh ${stage} secrets (auto-setup)`);
|
|
10693
10643
|
}
|
|
10694
|
-
const defaultEnv =
|
|
10644
|
+
const defaultEnv = require_stale.loadEnvFiles(".env");
|
|
10695
10645
|
if (defaultEnv.loaded.length > 0) console.log(` 📦 Loaded env: ${defaultEnv.loaded.join(", ")}`);
|
|
10696
10646
|
if (!options.prepare) await teardown(cwd);
|
|
10697
|
-
const result = await
|
|
10647
|
+
const result = await require_stale.prepareEntryCredentials({
|
|
10698
10648
|
stage,
|
|
10699
10649
|
startDocker: !options.prepare,
|
|
10700
10650
|
secretsFileName: "test-secrets.json",
|
|
@@ -10715,14 +10665,14 @@ async function testCommand(options = {}) {
|
|
|
10715
10665
|
await (0, node_fs_promises.writeFile)(result.secretsJsonPath, JSON.stringify(finalCredentials, null, 2));
|
|
10716
10666
|
const gkmDir = (0, node_path.join)(cwd, ".gkm");
|
|
10717
10667
|
const preloadPath = (0, node_path.join)(gkmDir, "test-credentials-preload.ts");
|
|
10718
|
-
await
|
|
10668
|
+
await require_stale.createCredentialsPreload(preloadPath, result.secretsJsonPath);
|
|
10719
10669
|
const workspace = await require_config.loadWorkspaceConfig(cwd).then((loaded) => loaded.workspace).catch(() => void 0);
|
|
10720
10670
|
const manifestPath = workspace ? await require_ready.writeTestHarness({
|
|
10721
10671
|
root: workspace.root,
|
|
10722
10672
|
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))],
|
|
10723
|
-
patterns:
|
|
10724
|
-
cacheBackend:
|
|
10725
|
-
eventsBackend:
|
|
10673
|
+
patterns: require_stale.constructGlobs(workspace),
|
|
10674
|
+
cacheBackend: require_stale.backendsOf(workspace).cache,
|
|
10675
|
+
eventsBackend: require_stale.backendsOf(workspace).events,
|
|
10726
10676
|
stage: require_workspace.TEST_STAGE,
|
|
10727
10677
|
env: finalCredentials,
|
|
10728
10678
|
factories: (0, node_path.join)(workspace.root, workspace.test.factories ?? "test/factories")
|
|
@@ -10785,8 +10735,8 @@ async function teardown(cwd) {
|
|
|
10785
10735
|
* the plan provisions, on the port the shared container answers.
|
|
10786
10736
|
*/
|
|
10787
10737
|
function testDatabases(reconciled) {
|
|
10788
|
-
const port = reconciled?.ports[
|
|
10789
|
-
const names = reconciled ?
|
|
10738
|
+
const port = reconciled?.ports[require_stale.primaryPortKey("postgres")];
|
|
10739
|
+
const names = reconciled ? require_stale.postgresDatabaseNames(reconciled.plan) : [];
|
|
10790
10740
|
return port !== void 0 && names.length > 0 ? { databases: {
|
|
10791
10741
|
port,
|
|
10792
10742
|
names
|
|
@@ -10797,11 +10747,11 @@ function testDatabases(reconciled) {
|
|
|
10797
10747
|
* starts without the reference data the app needs.
|
|
10798
10748
|
*/
|
|
10799
10749
|
async function migrateTestStage(workspace, env) {
|
|
10800
|
-
const { migrateAndSeed } = await Promise.resolve().then(() => require("./migrate-
|
|
10750
|
+
const { migrateAndSeed } = await Promise.resolve().then(() => require("./migrate-sny0NjKe.cjs"));
|
|
10801
10751
|
const { discover } = await Promise.resolve().then(() => require("./discover-D1It5r_h.cjs")).then((n) => n.discover_exports);
|
|
10802
10752
|
const sources = {};
|
|
10803
10753
|
const manifest = await discover({
|
|
10804
|
-
patterns:
|
|
10754
|
+
patterns: require_stale.constructGlobs(workspace),
|
|
10805
10755
|
cwd: workspace.root,
|
|
10806
10756
|
sources
|
|
10807
10757
|
});
|
|
@@ -11230,7 +11180,7 @@ program.command("migrate").description("Apply each database construct's migratio
|
|
|
11230
11180
|
try {
|
|
11231
11181
|
const globalOptions = program.opts();
|
|
11232
11182
|
if (globalOptions.cwd) process.chdir(globalOptions.cwd);
|
|
11233
|
-
const { migrateCommand } = await Promise.resolve().then(() => require("./migrate-
|
|
11183
|
+
const { migrateCommand } = await Promise.resolve().then(() => require("./migrate-sny0NjKe.cjs"));
|
|
11234
11184
|
await migrateCommand({
|
|
11235
11185
|
...options,
|
|
11236
11186
|
...construct ? { construct } : {}
|
|
@@ -11244,7 +11194,7 @@ program.command("seed").description("Migrate, then run each database construct's
|
|
|
11244
11194
|
try {
|
|
11245
11195
|
const globalOptions = program.opts();
|
|
11246
11196
|
if (globalOptions.cwd) process.chdir(globalOptions.cwd);
|
|
11247
|
-
const { seedCommand } = await Promise.resolve().then(() => require("./migrate-
|
|
11197
|
+
const { seedCommand } = await Promise.resolve().then(() => require("./migrate-sny0NjKe.cjs"));
|
|
11248
11198
|
await seedCommand({
|
|
11249
11199
|
...options,
|
|
11250
11200
|
...construct ? { construct } : {}
|
|
@@ -11258,7 +11208,7 @@ program.command("migration").description("Write a construct's next migration: an
|
|
|
11258
11208
|
try {
|
|
11259
11209
|
const globalOptions = program.opts();
|
|
11260
11210
|
if (globalOptions.cwd) process.chdir(globalOptions.cwd);
|
|
11261
|
-
const { migrationCommand } = await Promise.resolve().then(() => require("./migrate-
|
|
11211
|
+
const { migrationCommand } = await Promise.resolve().then(() => require("./migrate-sny0NjKe.cjs"));
|
|
11262
11212
|
await migrationCommand({
|
|
11263
11213
|
construct,
|
|
11264
11214
|
...name ? { name } : {}
|
|
@@ -11297,7 +11247,7 @@ program.command("docker").description("Generate Docker deployment files").option
|
|
|
11297
11247
|
try {
|
|
11298
11248
|
const globalOptions = program.opts();
|
|
11299
11249
|
if (globalOptions.cwd) process.chdir(globalOptions.cwd);
|
|
11300
|
-
await
|
|
11250
|
+
await require_stale.dockerCommand(options);
|
|
11301
11251
|
} catch (error) {
|
|
11302
11252
|
console.error(formatError(error));
|
|
11303
11253
|
process.exit(1);
|
|
@@ -11317,7 +11267,7 @@ program.command("prepack").description("Generate Docker files for production dep
|
|
|
11317
11267
|
try {
|
|
11318
11268
|
const globalOptions = program.opts();
|
|
11319
11269
|
if (globalOptions.cwd) process.chdir(globalOptions.cwd);
|
|
11320
|
-
await
|
|
11270
|
+
await require_stale.dockerCommand({
|
|
11321
11271
|
build: options.build,
|
|
11322
11272
|
push: options.push,
|
|
11323
11273
|
tag: options.tag,
|
|
@@ -11348,11 +11298,21 @@ program.command("secrets:set").description("Set a custom secret for a stage").ar
|
|
|
11348
11298
|
process.exit(1);
|
|
11349
11299
|
}
|
|
11350
11300
|
});
|
|
11301
|
+
program.command("secrets:unset").description("Remove a custom secret from a stage").argument("<key>", "Secret key (e.g., API_KEY)").requiredOption("--stage <stage>", "Stage name").action(async (key, options) => {
|
|
11302
|
+
try {
|
|
11303
|
+
const globalOptions = program.opts();
|
|
11304
|
+
if (globalOptions.cwd) process.chdir(globalOptions.cwd);
|
|
11305
|
+
await secretsUnsetCommand(key, options);
|
|
11306
|
+
} catch (error) {
|
|
11307
|
+
console.error(formatError(error));
|
|
11308
|
+
process.exit(1);
|
|
11309
|
+
}
|
|
11310
|
+
});
|
|
11351
11311
|
program.command("secrets:add").description("Build the keys a stage must be given — buckets, mail, file servers, third parties' credentials — across every app").requiredOption("--stage <stage>", "Stage name").option("--missing", "Only the keys the stage has not set").option("--json", "Print the keys as JSON and ask nothing").action(async (options) => {
|
|
11352
11312
|
try {
|
|
11353
11313
|
const globalOptions = program.opts();
|
|
11354
11314
|
if (globalOptions.cwd) process.chdir(globalOptions.cwd);
|
|
11355
|
-
const { secretsAddCommand } = await Promise.resolve().then(() => require("./add-
|
|
11315
|
+
const { secretsAddCommand } = await Promise.resolve().then(() => require("./add-DCsgtvDk.cjs"));
|
|
11356
11316
|
await secretsAddCommand(options);
|
|
11357
11317
|
} catch (error) {
|
|
11358
11318
|
console.error(formatError(error));
|
|
@@ -11363,7 +11323,7 @@ program.command("encryption:rotate").description("Add a new current key to an En
|
|
|
11363
11323
|
try {
|
|
11364
11324
|
const globalOptions = program.opts();
|
|
11365
11325
|
if (globalOptions.cwd) process.chdir(globalOptions.cwd);
|
|
11366
|
-
const { encryptionRotateCommand } = await Promise.resolve().then(() => require("./encryption-
|
|
11326
|
+
const { encryptionRotateCommand } = await Promise.resolve().then(() => require("./encryption-DY0na43R.cjs"));
|
|
11367
11327
|
await encryptionRotateCommand(construct, options);
|
|
11368
11328
|
} catch (error) {
|
|
11369
11329
|
console.error(formatError(error));
|
|
@@ -11374,7 +11334,7 @@ program.command("encryption:retire").description("Remove an old key from an Encr
|
|
|
11374
11334
|
try {
|
|
11375
11335
|
const globalOptions = program.opts();
|
|
11376
11336
|
if (globalOptions.cwd) process.chdir(globalOptions.cwd);
|
|
11377
|
-
const { encryptionRetireCommand } = await Promise.resolve().then(() => require("./encryption-
|
|
11337
|
+
const { encryptionRetireCommand } = await Promise.resolve().then(() => require("./encryption-DY0na43R.cjs"));
|
|
11378
11338
|
await encryptionRetireCommand(construct, key, options);
|
|
11379
11339
|
} catch (error) {
|
|
11380
11340
|
console.error(formatError(error));
|
|
@@ -11417,7 +11377,7 @@ program.command("secrets:reconcile").description("Backfill missing custom secret
|
|
|
11417
11377
|
if (globalOptions.cwd) process.chdir(globalOptions.cwd);
|
|
11418
11378
|
const { loadWorkspaceConfig } = await Promise.resolve().then(() => require("./config.cjs"));
|
|
11419
11379
|
const { reconcileMissingSecrets } = await Promise.resolve().then(() => require("./reconcile-CuCQBa5-.cjs"));
|
|
11420
|
-
const { secretsStoreFor } = await Promise.resolve().then(() => require("./
|
|
11380
|
+
const { secretsStoreFor } = await Promise.resolve().then(() => require("./stale-yu2FkH3G.cjs")).then((n) => n.store_exports);
|
|
11421
11381
|
const { workspace } = await loadWorkspaceConfig();
|
|
11422
11382
|
const stage = options.stage ?? workspace.stages.local;
|
|
11423
11383
|
const store = await secretsStoreFor(workspace, stage);
|
|
@@ -11426,7 +11386,7 @@ program.command("secrets:reconcile").description("Backfill missing custom secret
|
|
|
11426
11386
|
console.error(`No secrets found for stage "${stage}". Run "gkm secrets:init --stage ${stage}" first.`);
|
|
11427
11387
|
process.exit(1);
|
|
11428
11388
|
}
|
|
11429
|
-
const { derivedContainers } = await Promise.resolve().then(() => require("./
|
|
11389
|
+
const { derivedContainers } = await Promise.resolve().then(() => require("./stale-yu2FkH3G.cjs")).then((n) => n.workspace_exports);
|
|
11430
11390
|
const result = reconcileMissingSecrets(secrets, workspace, await derivedContainers(workspace, stage));
|
|
11431
11391
|
if (!result) {
|
|
11432
11392
|
console.log(`\n✓ Secrets for stage "${stage}" are up-to-date`);
|
|
@@ -11444,7 +11404,7 @@ program.command("secrets:migrate").description("Copy a deployed stage's secrets
|
|
|
11444
11404
|
try {
|
|
11445
11405
|
const globalOptions = program.opts();
|
|
11446
11406
|
if (globalOptions.cwd) process.chdir(globalOptions.cwd);
|
|
11447
|
-
const { secretsMigrateCommand } = await Promise.resolve().then(() => require("./migrate-
|
|
11407
|
+
const { secretsMigrateCommand } = await Promise.resolve().then(() => require("./migrate-31JXUOaG.cjs"));
|
|
11448
11408
|
await secretsMigrateCommand(options);
|
|
11449
11409
|
} catch (error) {
|
|
11450
11410
|
console.error(formatError(error));
|
|
@@ -11452,7 +11412,7 @@ program.command("secrets:migrate").description("Copy a deployed stage's secrets
|
|
|
11452
11412
|
}
|
|
11453
11413
|
});
|
|
11454
11414
|
program.command("deploy").description("Deploy a stage through its target").option("--target <name>", "Deploy target: dokploy, compose, sst, or one named in deploy.targets (default: deploy.default)").option("--provider <provider>", "[DEPRECATED] Use --target instead").requiredOption("--stage <stage>", "Deployment stage (e.g., production, staging)").option("--tag <tag>", "Image tag (default: stage-timestamp; compose: the commit). Compose pulls a given tag").option("--skip-push", "Skip pushing image to registry").option("--skip-build", "Skip build step (use existing build)").option("--json", "Write events as JSON lines instead of progress; never prompts").option("--dry-run", "Show what would be created or reused; change, build and push nothing").option("--atomic", "If the release fails, roll back every app it released, not only the failed ones").option("--allow-dev-services <list>", "Server targets: run MinIO and/or Mailpit (minio,mailpit) for mail and buckets the stage's secrets don't configure. Not production-grade").action(async (options) => {
|
|
11455
|
-
const { deployCli } = await Promise.resolve().then(() => require("./cli-
|
|
11415
|
+
const { deployCli } = await Promise.resolve().then(() => require("./cli-ZpFTMbGw.cjs"));
|
|
11456
11416
|
const globalOptions = program.opts();
|
|
11457
11417
|
const code = await deployCli({
|
|
11458
11418
|
cwd: (0, node_path.resolve)(globalOptions.cwd ?? process.cwd()),
|
|
@@ -11469,7 +11429,7 @@ program.command("deploy").description("Deploy a stage through its target").optio
|
|
|
11469
11429
|
});
|
|
11470
11430
|
program.command("deploy:rollback").description("Put a stage's app back on its previous release (Dokploy): one app with --app, every app with --atomic").requiredOption("--stage <stage>", "A deployed stage").option("--app <app>", "The app to roll back").option("--atomic", "Roll back every app that has an earlier release").action(async (options) => {
|
|
11471
11431
|
try {
|
|
11472
|
-
const { rollbackStage } = await Promise.resolve().then(() => require("./rollback-
|
|
11432
|
+
const { rollbackStage } = await Promise.resolve().then(() => require("./rollback-CpOWRR9H.cjs")).then((n) => n.rollback_exports);
|
|
11473
11433
|
const { terminalCredentials } = await Promise.resolve().then(() => require("./terminal-BL5E0xbR.cjs"));
|
|
11474
11434
|
const globalOptions = program.opts();
|
|
11475
11435
|
await rollbackStage({
|
|
@@ -11505,7 +11465,7 @@ program.command("deploy:github").description("Let GitHub Actions deploy a stage:
|
|
|
11505
11465
|
try {
|
|
11506
11466
|
const globalOptions = program.opts();
|
|
11507
11467
|
if (globalOptions.cwd) process.chdir(globalOptions.cwd);
|
|
11508
|
-
const { deployGithubCommand } = await Promise.resolve().then(() => require("./github-
|
|
11468
|
+
const { deployGithubCommand } = await Promise.resolve().then(() => require("./github-Bmb45xUQ.cjs"));
|
|
11509
11469
|
await deployGithubCommand(options);
|
|
11510
11470
|
} catch (error) {
|
|
11511
11471
|
console.error(formatError(error));
|