@geekmidas/cli 10.0.0-alpha.75 → 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/{LegacyStateStore-BFnXUFlx.cjs → LegacyStateStore-DwngfJxr.cjs} +2 -2
- package/dist/{LegacyStateStore-BFnXUFlx.cjs.map → LegacyStateStore-DwngfJxr.cjs.map} +1 -1
- package/dist/{LegacyStateStore-cpt3K1vx.mjs → LegacyStateStore-dyq07_Ir.mjs} +2 -2
- package/dist/{LegacyStateStore-cpt3K1vx.mjs.map → LegacyStateStore-dyq07_Ir.mjs.map} +1 -1
- package/dist/{LocalStateStore-zQGZ9b4J.cjs → LocalStateStore-B0NCde8Z.cjs} +2 -2
- package/dist/{LocalStateStore-zQGZ9b4J.cjs.map → LocalStateStore-B0NCde8Z.cjs.map} +1 -1
- package/dist/{LocalStateStore-RH9F2ZEy.mjs → LocalStateStore-DLxCCatI.mjs} +2 -2
- package/dist/{LocalStateStore-RH9F2ZEy.mjs.map → LocalStateStore-DLxCCatI.mjs.map} +1 -1
- package/dist/{S3StateStore-CT-ZMlQY.cjs → S3StateStore-BOenb-3o.cjs} +2 -2
- package/dist/{S3StateStore-CT-ZMlQY.cjs.map → S3StateStore-BOenb-3o.cjs.map} +1 -1
- package/dist/{S3StateStore-DBeBc0c0.mjs → S3StateStore-CGK_4hlo.mjs} +2 -2
- package/dist/{S3StateStore-DBeBc0c0.mjs.map → S3StateStore-CGK_4hlo.mjs.map} +1 -1
- package/dist/{SSMStateStore-rnzNfOaV.mjs → SSMStateStore-B_5_RqY-.mjs} +2 -2
- package/dist/{SSMStateStore-rnzNfOaV.mjs.map → SSMStateStore-B_5_RqY-.mjs.map} +1 -1
- package/dist/{SSMStateStore-HmsH3c4v.cjs → SSMStateStore-DYeD__7p.cjs} +2 -2
- package/dist/{SSMStateStore-HmsH3c4v.cjs.map → SSMStateStore-DYeD__7p.cjs.map} +1 -1
- package/dist/{add-CHBin8TF.cjs → add-DCsgtvDk.cjs} +8 -8
- package/dist/{add-CHBin8TF.cjs.map → add-DCsgtvDk.cjs.map} +1 -1
- package/dist/{add-Cvzdw8cf.mjs → add-EPQO-_dt.mjs} +3 -3
- package/dist/{add-Cvzdw8cf.mjs.map → add-EPQO-_dt.mjs.map} +1 -1
- package/dist/{aws-DojzQnLd.mjs → aws-Bja4zGSs.mjs} +13 -9
- package/dist/aws-Bja4zGSs.mjs.map +1 -0
- package/dist/{aws-DkHdTV-p.cjs → aws-CQAuluiu.cjs} +13 -9
- package/dist/aws-CQAuluiu.cjs.map +1 -0
- package/dist/awsStore-7VmS_cZR.cjs +54 -0
- package/dist/awsStore-7VmS_cZR.cjs.map +1 -0
- package/dist/awsStore-B529csle.mjs +43 -0
- package/dist/awsStore-B529csle.mjs.map +1 -0
- package/dist/{bundler-_8AEZhrs.cjs → bundler-5spPyduN.cjs} +5 -5
- package/dist/bundler-5spPyduN.cjs.map +1 -0
- package/dist/{bundler-xjp5RwRS.mjs → bundler-DgO_EMVs.mjs} +5 -5
- package/dist/bundler-DgO_EMVs.mjs.map +1 -0
- package/dist/{cli-BTGfA0B7.mjs → cli-B74Ru-V1.mjs} +3 -3
- package/dist/{cli-BTGfA0B7.mjs.map → cli-B74Ru-V1.mjs.map} +1 -1
- package/dist/{cli-B4ktxAsM.cjs → cli-ZpFTMbGw.cjs} +4 -4
- package/dist/{cli-B4ktxAsM.cjs.map → cli-ZpFTMbGw.cjs.map} +1 -1
- package/dist/{compose-UKyv_1yU.cjs → compose-CePlrbUw.cjs} +68 -60
- package/dist/compose-CePlrbUw.cjs.map +1 -0
- package/dist/{compose-DdH2JQJD.mjs → compose-IUuxRW0J.mjs} +18 -10
- package/dist/compose-IUuxRW0J.mjs.map +1 -0
- package/dist/{config-DA0kRTQe.d.mts → config-Ckmoj56i.d.mts} +3 -3
- package/dist/{config-B38YWicj.d.cts.map → config-Ckmoj56i.d.mts.map} +1 -1
- package/dist/{config-B38YWicj.d.cts → config-aAeLXH86.d.cts} +3 -3
- package/dist/{config-DA0kRTQe.d.mts.map → config-aAeLXH86.d.cts.map} +1 -1
- package/dist/config.cjs +1 -1
- package/dist/config.d.cts +3 -3
- package/dist/config.d.mts +3 -3
- package/dist/config.mjs +1 -1
- package/dist/deploy/public.cjs +12 -12
- 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 +6 -6
- package/dist/{deploy-CuSsiFIc.mjs → deploy-Q6X6RXRG.mjs} +5 -5
- package/dist/{deploy-CuSsiFIc.mjs.map → deploy-Q6X6RXRG.mjs.map} +1 -1
- package/dist/{deploy-XUZoA1us.cjs → deploy-XHXi-_tL.cjs} +11 -11
- package/dist/{deploy-XUZoA1us.cjs.map → deploy-XHXi-_tL.cjs.map} +1 -1
- package/dist/{dokploy-DZXTQX10.mjs → dokploy-BtP5XSrS.mjs} +2 -2
- package/dist/{dokploy-DZXTQX10.mjs.map → dokploy-BtP5XSrS.mjs.map} +1 -1
- package/dist/{dokploy-Cvgg_pID.cjs → dokploy-MSsPBO-t.cjs} +2 -2
- package/dist/{dokploy-Cvgg_pID.cjs.map → dokploy-MSsPBO-t.cjs.map} +1 -1
- package/dist/{encryption-JkeMPugf.mjs → encryption-D4Ykywfr.mjs} +3 -3
- package/dist/{encryption-JkeMPugf.mjs.map → encryption-D4Ykywfr.mjs.map} +1 -1
- package/dist/{encryption-w-Ehh9DW.cjs → encryption-DY0na43R.cjs} +6 -6
- package/dist/{encryption-w-Ehh9DW.cjs.map → encryption-DY0na43R.cjs.map} +1 -1
- package/dist/{engine-CmozkHxq.mjs → engine-BI2xjCKt.mjs} +9 -4
- package/dist/{engine-CmozkHxq.mjs.map → engine-BI2xjCKt.mjs.map} +1 -1
- package/dist/{engine-zpWBMsQq.cjs → engine-y53kE_3H.cjs} +73 -68
- package/dist/{engine-zpWBMsQq.cjs.map → engine-y53kE_3H.cjs.map} +1 -1
- package/dist/{github-BNngHoId.mjs → github-BBIqk1Jv.mjs} +6 -6
- package/dist/github-BBIqk1Jv.mjs.map +1 -0
- package/dist/{github-BGdJ-Lnm.cjs → github-Bmb45xUQ.cjs} +10 -10
- package/dist/github-Bmb45xUQ.cjs.map +1 -0
- package/dist/{index-vMidfqhU.d.cts → index-C7Tma2m1.d.cts} +2 -2
- package/dist/{index-B-1lLGzy.d.mts.map → index-C7Tma2m1.d.cts.map} +1 -1
- package/dist/{index-B-1lLGzy.d.mts → index-CNdSRwar.d.mts} +2 -2
- package/dist/{index-vMidfqhU.d.cts.map → index-CNdSRwar.d.mts.map} +1 -1
- package/dist/index.cjs +210 -221
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +141 -152
- package/dist/index.mjs.map +1 -1
- package/dist/migrate-31JXUOaG.cjs +93 -0
- package/dist/migrate-31JXUOaG.cjs.map +1 -0
- package/dist/{migrate-BLL1RTAj.mjs → migrate-BUBsUiM3.mjs} +3 -3
- package/dist/{migrate-BLL1RTAj.mjs.map → migrate-BUBsUiM3.mjs.map} +1 -1
- package/dist/migrate-DWVl5PQK.mjs +93 -0
- package/dist/migrate-DWVl5PQK.mjs.map +1 -0
- package/dist/{migrate-CgjlYeun.cjs → migrate-sny0NjKe.cjs} +8 -8
- package/dist/{migrate-CgjlYeun.cjs.map → migrate-sny0NjKe.cjs.map} +1 -1
- package/dist/openapi.cjs +16 -6
- package/dist/openapi.cjs.map +1 -1
- package/dist/openapi.d.cts +1 -1
- package/dist/openapi.d.cts.map +1 -1
- package/dist/openapi.d.mts +1 -1
- package/dist/openapi.d.mts.map +1 -1
- package/dist/openapi.mjs +16 -6
- package/dist/openapi.mjs.map +1 -1
- package/dist/reconcile/public.d.cts +1 -1
- package/dist/reconcile/public.d.mts +1 -1
- package/dist/{resolve-DZNx7rLy.mjs → resolve-BF1ICosS.mjs} +3 -3
- package/dist/{resolve-DZNx7rLy.mjs.map → resolve-BF1ICosS.mjs.map} +1 -1
- package/dist/{resolve-fevXn-wZ.cjs → resolve-DokLtTUb.cjs} +3 -3
- package/dist/{resolve-fevXn-wZ.cjs.map → resolve-DokLtTUb.cjs.map} +1 -1
- package/dist/{rollback-Dw-FW3X2.cjs → rollback-CpOWRR9H.cjs} +7 -7
- package/dist/{rollback-Dw-FW3X2.cjs.map → rollback-CpOWRR9H.cjs.map} +1 -1
- package/dist/{rollback-CLi5Pln_.mjs → rollback-sg0ZhKGG.mjs} +5 -5
- package/dist/{rollback-CLi5Pln_.mjs.map → rollback-sg0ZhKGG.mjs.map} +1 -1
- package/dist/{runtime-BzZD5HHi.d.cts → runtime-B5bYom9w.d.mts} +2 -2
- package/dist/{runtime-BzZD5HHi.d.cts.map → runtime-B5bYom9w.d.mts.map} +1 -1
- package/dist/{runtime-Cm6J6L7n.d.mts → runtime-BozOkPtG.d.cts} +2 -2
- package/dist/{runtime-Cm6J6L7n.d.mts.map → runtime-BozOkPtG.d.cts.map} +1 -1
- package/dist/secretsManager-DUXW3fQt.cjs +70 -0
- package/dist/secretsManager-DUXW3fQt.cjs.map +1 -0
- package/dist/secretsManager-Ti0oZwsS.mjs +70 -0
- package/dist/secretsManager-Ti0oZwsS.mjs.map +1 -0
- package/dist/{sniffer-BmCvVyhq.mjs → sniffer-DR8AlRCk.mjs} +17 -17
- package/dist/sniffer-DR8AlRCk.mjs.map +1 -0
- package/dist/{sniffer-bMzrX4cO.cjs → sniffer-Y6GQOCXB.cjs} +17 -17
- package/dist/sniffer-Y6GQOCXB.cjs.map +1 -0
- package/dist/{state-BrWIOce_.mjs → stale-DGzpiN5S.mjs} +270 -45
- package/dist/stale-DGzpiN5S.mjs.map +1 -0
- package/dist/{state-kA4Fkufx.cjs → stale-yu2FkH3G.cjs} +293 -44
- 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-TzCChNrA.d.cts → types-B9yWJAis.d.mts} +59 -9
- package/dist/types-B9yWJAis.d.mts.map +1 -0
- package/dist/{types-Dp9lgx_S.d.mts → types-ct7pdQRf.d.cts} +60 -8
- package/dist/types-ct7pdQRf.d.cts.map +1 -0
- package/dist/workspace/index.cjs +1 -1
- package/dist/workspace/index.d.cts +2 -2
- package/dist/workspace/index.d.mts +2 -2
- package/dist/workspace/index.mjs +1 -1
- package/dist/{workspace-vdrcRI-m.cjs → workspace-DOm81oUo.cjs} +54 -1
- package/dist/workspace-DOm81oUo.cjs.map +1 -0
- package/dist/{workspace-C7NqCsQF.mjs → workspace-QUTqYmVy.mjs} +43 -2
- package/dist/workspace-QUTqYmVy.mjs.map +1 -0
- package/package.json +16 -15
- package/dist/aws-DkHdTV-p.cjs.map +0 -1
- package/dist/aws-DojzQnLd.mjs.map +0 -1
- package/dist/bundler-_8AEZhrs.cjs.map +0 -1
- package/dist/bundler-xjp5RwRS.mjs.map +0 -1
- package/dist/compose-DdH2JQJD.mjs.map +0 -1
- package/dist/compose-UKyv_1yU.cjs.map +0 -1
- package/dist/github-BGdJ-Lnm.cjs.map +0 -1
- package/dist/github-BNngHoId.mjs.map +0 -1
- package/dist/sniffer-BmCvVyhq.mjs.map +0 -1
- package/dist/sniffer-bMzrX4cO.cjs.map +0 -1
- package/dist/state-BrWIOce_.mjs.map +0 -1
- package/dist/state-kA4Fkufx.cjs.map +0 -1
- package/dist/types-Dp9lgx_S.d.mts.map +0 -1
- package/dist/types-TzCChNrA.d.cts.map +0 -1
- package/dist/workspace-C7NqCsQF.mjs.map +0 -1
- package/dist/workspace-vdrcRI-m.cjs.map +0 -1
|
@@ -2,10 +2,10 @@ const require_rolldown_runtime = require("./rolldown-runtime-C0BPl7ul.cjs");
|
|
|
2
2
|
const require_run = require("./run-fVZ-rLnc.cjs");
|
|
3
3
|
const require_discover = require("./discover-D1It5r_h.cjs");
|
|
4
4
|
const require_derive = require("./derive-DAbo49sm.cjs");
|
|
5
|
-
const require_workspace = require("./workspace-
|
|
5
|
+
const require_workspace = require("./workspace-DOm81oUo.cjs");
|
|
6
6
|
const require_config = require("./config.cjs");
|
|
7
7
|
const require_EndpointGenerator = require("./EndpointGenerator-CP6sBvQV.cjs");
|
|
8
|
-
const require_resolve = require("./resolve-
|
|
8
|
+
const require_resolve = require("./resolve-DokLtTUb.cjs");
|
|
9
9
|
const require_SubscriberGenerator = require("./SubscriberGenerator-CajwOa5W.cjs");
|
|
10
10
|
let node_path = require("node:path");
|
|
11
11
|
let node_fs = require("node:fs");
|
|
@@ -93,10 +93,6 @@ function toEmbeddableSecrets(secrets) {
|
|
|
93
93
|
AWS_SECRET_ACCESS_KEY: secrets.services.localstack.password,
|
|
94
94
|
AWS_REGION: secrets.services.localstack.region ?? "us-east-1",
|
|
95
95
|
AWS_ENDPOINT_URL: `http://${secrets.services.localstack.host}:${secrets.services.localstack.port}`
|
|
96
|
-
},
|
|
97
|
-
...secrets.services.pgboss && {
|
|
98
|
-
PGBOSS_DB_USER: secrets.services.pgboss.username,
|
|
99
|
-
PGBOSS_DB_PASSWORD: secrets.services.pgboss.password
|
|
100
96
|
}
|
|
101
97
|
};
|
|
102
98
|
}
|
|
@@ -529,7 +525,8 @@ function decrypt(data, keyHex) {
|
|
|
529
525
|
var store_exports = /* @__PURE__ */ require_rolldown_runtime.__exportAll({
|
|
530
526
|
FileSecretsStore: () => FileSecretsStore,
|
|
531
527
|
isRemoteStore: () => isRemoteStore,
|
|
532
|
-
secretsStoreFor: () => secretsStoreFor
|
|
528
|
+
secretsStoreFor: () => secretsStoreFor,
|
|
529
|
+
storeFromConfig: () => storeFromConfig
|
|
533
530
|
});
|
|
534
531
|
/**
|
|
535
532
|
* The store a stage's secrets are kept in — what every command reads and
|
|
@@ -541,13 +538,41 @@ var store_exports = /* @__PURE__ */ require_rolldown_runtime.__exportAll({
|
|
|
541
538
|
async function secretsStoreFor(workspace, stage, options = {}) {
|
|
542
539
|
const configured = workspace.secrets.store ?? "file";
|
|
543
540
|
if (stage === workspace.stages.local || configured === "file") return new FileSecretsStore(workspace.root, keystoreProject(workspace, options.home));
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
541
|
+
return storeFromConfig(workspace, configured, options);
|
|
542
|
+
}
|
|
543
|
+
/**
|
|
544
|
+
* The store a `secrets.store` value describes, for any stage — what
|
|
545
|
+
* {@link secretsStoreFor} answers for a deployed stage, and what
|
|
546
|
+
* `gkm secrets:migrate` builds for the store it copies to.
|
|
547
|
+
*/
|
|
548
|
+
async function storeFromConfig(workspace, config, options = {}) {
|
|
549
|
+
if (config === "file") return new FileSecretsStore(workspace.root, keystoreProject(workspace, options.home));
|
|
550
|
+
const profile = options.profile ? { profile: options.profile } : {};
|
|
551
|
+
switch (config.provider) {
|
|
552
|
+
case "ssm": {
|
|
553
|
+
const { AwsSecretsStore } = await Promise.resolve().then(() => require("./aws-CQAuluiu.cjs"));
|
|
554
|
+
return new AwsSecretsStore({
|
|
555
|
+
project: workspace.name,
|
|
556
|
+
region: config.region,
|
|
557
|
+
...profile
|
|
558
|
+
});
|
|
559
|
+
}
|
|
560
|
+
case "secrets-manager": {
|
|
561
|
+
const { kmsKeyId } = config;
|
|
562
|
+
const { SecretsManagerSecretsStore } = await Promise.resolve().then(() => require("./secretsManager-DUXW3fQt.cjs"));
|
|
563
|
+
return new SecretsManagerSecretsStore({
|
|
564
|
+
project: workspace.name,
|
|
565
|
+
region: config.region,
|
|
566
|
+
...kmsKeyId ? { kmsKeyId } : {},
|
|
567
|
+
...profile
|
|
568
|
+
});
|
|
569
|
+
}
|
|
570
|
+
default: {
|
|
571
|
+
const provider = config.provider;
|
|
572
|
+
if (typeof provider === "object" && provider !== null) return provider;
|
|
573
|
+
throw new require_workspace.UnknownSecretsStoreProvider(provider);
|
|
574
|
+
}
|
|
575
|
+
}
|
|
551
576
|
}
|
|
552
577
|
/** Whether a stage's secrets live somewhere other than this machine. */
|
|
553
578
|
function isRemoteStore(workspace, stage) {
|
|
@@ -634,24 +659,18 @@ async function savePortState(workspaceRoot, ports) {
|
|
|
634
659
|
await (0, node_fs_promises.writeFile)((0, node_path.join)(workspaceRoot, PORT_STATE_PATH), `${JSON.stringify(ports, null, 2)}\n`);
|
|
635
660
|
}
|
|
636
661
|
/**
|
|
637
|
-
* Load and flatten
|
|
638
|
-
*
|
|
662
|
+
* Load and flatten a stage's secrets from its store.
|
|
663
|
+
*
|
|
664
|
+
* Every key as stored — nothing renamed. An app's database URL is its
|
|
665
|
+
* construct's key, derived by reconcile, and never a stored per-app value
|
|
666
|
+
* mapped onto `DATABASE_URL`.
|
|
639
667
|
* @internal Exported for testing
|
|
640
668
|
*/
|
|
641
|
-
async function loadSecretsForApp(store, stage
|
|
642
|
-
let secrets = {};
|
|
669
|
+
async function loadSecretsForApp(store, stage) {
|
|
643
670
|
const stageSecrets = await store.read(stage);
|
|
644
|
-
if (stageSecrets) {
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
}
|
|
648
|
-
if (Object.keys(secrets).length === 0) return {};
|
|
649
|
-
if (!appName) return secrets;
|
|
650
|
-
const prefix = appName.toUpperCase();
|
|
651
|
-
const mapped = { ...secrets };
|
|
652
|
-
const appDbUrl = secrets[`${prefix}_DATABASE_URL`];
|
|
653
|
-
if (appDbUrl) mapped.DATABASE_URL = appDbUrl;
|
|
654
|
-
return mapped;
|
|
671
|
+
if (!stageSecrets) return {};
|
|
672
|
+
logger$1.log(`🔐 Loading secrets from stage: ${stage}`);
|
|
673
|
+
return toEmbeddableSecrets(stageSecrets);
|
|
655
674
|
}
|
|
656
675
|
/**
|
|
657
676
|
* Walk up the directory tree to find the root containing .gkm/secrets/.
|
|
@@ -759,7 +778,7 @@ async function prepareEntryCredentials(options) {
|
|
|
759
778
|
const resolvedPort = options.explicitPort ?? workspaceAppPort ?? 3e3;
|
|
760
779
|
const stage = options.stage ?? workspace?.stages.local;
|
|
761
780
|
const store = stage ? workspace ? await secretsStoreFor(workspace, stage) : new FileSecretsStore(secretsRoot) : void 0;
|
|
762
|
-
const credentials = store && stage ? await loadSecretsForApp(store, stage
|
|
781
|
+
const credentials = store && stage ? await loadSecretsForApp(store, stage) : {};
|
|
763
782
|
credentials.PORT = String(resolvedPort);
|
|
764
783
|
if (appInfo?.app.type === "mobile") credentials.RCT_METRO_PORT = String(resolvedPort);
|
|
765
784
|
const declaredKeys = [];
|
|
@@ -1024,6 +1043,36 @@ function eventsBackendFor(on) {
|
|
|
1024
1043
|
return require_SubscriberGenerator.DEFAULT_EVENTS[on];
|
|
1025
1044
|
}
|
|
1026
1045
|
//#endregion
|
|
1046
|
+
//#region src/exec/imageBuild.ts
|
|
1047
|
+
/**
|
|
1048
|
+
* Set by a site's Dockerfile in its builder stage: this process is building
|
|
1049
|
+
* an image.
|
|
1050
|
+
*
|
|
1051
|
+
* Inside an image there is no stage to load secrets for and no local
|
|
1052
|
+
* container to resolve an address from — the public URLs the bundle inlines
|
|
1053
|
+
* arrived as the Dockerfile's build args, already in the environment. So
|
|
1054
|
+
* `gkm exec -- next build` there injects exactly those, and never the
|
|
1055
|
+
* `localhost` addresses a workspace resolves on a developer's machine.
|
|
1056
|
+
*/
|
|
1057
|
+
const IMAGE_BUILD_ENV = "GKM_IMAGE_BUILD";
|
|
1058
|
+
/** Whether this process is building an image. */
|
|
1059
|
+
function isImageBuild(env = process.env) {
|
|
1060
|
+
return env[IMAGE_BUILD_ENV] === "1";
|
|
1061
|
+
}
|
|
1062
|
+
/**
|
|
1063
|
+
* What `gkm exec` injects inside an image build: the public values its build
|
|
1064
|
+
* args set — every `NEXT_PUBLIC_*`, `VITE_*` and `EXPO_PUBLIC_*` — and
|
|
1065
|
+
* nothing read from a secrets store, a file or a container.
|
|
1066
|
+
*/
|
|
1067
|
+
function imageBuildCredentials(env = process.env) {
|
|
1068
|
+
const credentials = {};
|
|
1069
|
+
for (const [key, value] of Object.entries(env)) {
|
|
1070
|
+
if (value === void 0) continue;
|
|
1071
|
+
if (require_workspace.PUBLIC_ENV_PREFIXES.some((prefix) => key.startsWith(prefix))) credentials[key] = value;
|
|
1072
|
+
}
|
|
1073
|
+
return credentials;
|
|
1074
|
+
}
|
|
1075
|
+
//#endregion
|
|
1027
1076
|
//#region src/docker/templates.ts
|
|
1028
1077
|
/**
|
|
1029
1078
|
* The turbo every image prunes and builds with when the build root resolves
|
|
@@ -1321,7 +1370,48 @@ function binPath(options) {
|
|
|
1321
1370
|
* were installed.
|
|
1322
1371
|
*/
|
|
1323
1372
|
function gkmCommand(args) {
|
|
1324
|
-
return `GKM_BIN="$(node -e '
|
|
1373
|
+
return `GKM_BIN="$(node -e '${FIND_GKM_BIN}')" && node "$GKM_BIN" ${args}`;
|
|
1374
|
+
}
|
|
1375
|
+
/** Prints the `bin/gkm.mjs` Node resolves from the cwd, or fails saying so. */
|
|
1376
|
+
const FIND_GKM_BIN = `let d=process.cwd();const{existsSync:e}=require("fs"),{dirname:u,join:j}=require("path");for(;;){const p=j(d,"node_modules/@geekmidas/cli/bin/gkm.mjs");if(e(p)){console.log(p);break}if(u(d)===d){console.error("@geekmidas/cli is not installed where the app can resolve it");process.exit(1)}d=u(d)}`;
|
|
1377
|
+
/**
|
|
1378
|
+
* What a site's builder does with the gkm workspace it carries, before its
|
|
1379
|
+
* framework builds it — all of it inside the image, nothing from the host:
|
|
1380
|
+
*
|
|
1381
|
+
* - `gkm` on the PATH: the CLI the workspace installs, so a build script that
|
|
1382
|
+
* is `gkm exec -- next build` runs. Resolved from the gkm root rather than
|
|
1383
|
+
* through `node_modules/.bin`, where a CLI that is a workspace package has
|
|
1384
|
+
* no bin linked.
|
|
1385
|
+
* - `GKM_IMAGE_BUILD`, which has `gkm exec` inject the build args above — the
|
|
1386
|
+
* stage's public URLs — and never load a secret or resolve a local address.
|
|
1387
|
+
* - each backend's typed client, generated from its endpoints at the
|
|
1388
|
+
* workspace root's `.gkm/client/`, where the site's tsconfig paths point.
|
|
1389
|
+
*/
|
|
1390
|
+
function siteWorkspaceSteps(options) {
|
|
1391
|
+
const { gkmRoot } = layout(options);
|
|
1392
|
+
const root = `/app/${gkmRoot}`.replace(/\/\.$/, "");
|
|
1393
|
+
const clients = options.clients ?? [];
|
|
1394
|
+
const generate = clients.length ? `
|
|
1395
|
+
|
|
1396
|
+
# The typed client of each API this site calls, generated from its endpoints
|
|
1397
|
+
# into ${gkmRoot === "." ? "" : `${gkmRoot}/`}.gkm/client/ — offline, with no secret and no container.
|
|
1398
|
+
RUN ${clients.map(({ app, path }) => `cd /app/${path} && gkm openapi --app ${app}`).join(" && \\\n ")}` : "";
|
|
1399
|
+
return `# The gkm CLI the workspace installs, as \`gkm\`
|
|
1400
|
+
RUN cd ${root} && GKM_BIN="$(node -e '${FIND_GKM_BIN}')" && \\
|
|
1401
|
+
{ echo '#!/bin/sh'; echo "exec node \\"$GKM_BIN\\" \\"\\$@\\""; } > /usr/local/bin/gkm && \\
|
|
1402
|
+
chmod +x /usr/local/bin/gkm
|
|
1403
|
+
|
|
1404
|
+
# \`gkm exec\` in this build injects the build args, never a stage's secrets
|
|
1405
|
+
ENV ${IMAGE_BUILD_ENV}=1${generate}`;
|
|
1406
|
+
}
|
|
1407
|
+
/**
|
|
1408
|
+
* Build the site with turbo. Loose env mode, so the task sees what the
|
|
1409
|
+
* Dockerfile set — the build args and `GKM_IMAGE_BUILD` — whatever the
|
|
1410
|
+
* project's turbo.json declares: the image's environment holds nothing else.
|
|
1411
|
+
*/
|
|
1412
|
+
function siteBuild(options) {
|
|
1413
|
+
const { turbo } = layout(options);
|
|
1414
|
+
return `RUN ${turbo} run build --filter='${options.turboPackage}' --env-mode=loose`;
|
|
1325
1415
|
}
|
|
1326
1416
|
/**
|
|
1327
1417
|
* The encrypted credentials, from a build secret — never an ARG, which is
|
|
@@ -1475,8 +1565,7 @@ HEALTHCHECK --interval=30s --timeout=10s --start-period=30s --retries=3 \\
|
|
|
1475
1565
|
* @internal Exported for testing
|
|
1476
1566
|
*/
|
|
1477
1567
|
function generateNextjsDockerfile(options) {
|
|
1478
|
-
const { port, appPath,
|
|
1479
|
-
const { turbo } = layout(options);
|
|
1568
|
+
const { port, appPath, publicUrlArgs = ["NEXT_PUBLIC_API_URL", "NEXT_PUBLIC_AUTH_URL"] } = options;
|
|
1480
1569
|
return `# syntax=docker/dockerfile:1
|
|
1481
1570
|
# Next.js standalone Dockerfile, built from a turbo-pruned slice
|
|
1482
1571
|
|
|
@@ -1486,13 +1575,15 @@ ${depsStage(options)}
|
|
|
1486
1575
|
|
|
1487
1576
|
${builderStage(options, { args: publicUrlArgs })}
|
|
1488
1577
|
|
|
1578
|
+
${siteWorkspaceSteps(options)}
|
|
1579
|
+
|
|
1489
1580
|
# Ensure public directory exists (may be empty for scaffolded projects)
|
|
1490
1581
|
RUN mkdir -p ${appPath}/public
|
|
1491
1582
|
|
|
1492
1583
|
ENV NEXT_TELEMETRY_DISABLED=1
|
|
1493
1584
|
|
|
1494
1585
|
# Build the application
|
|
1495
|
-
|
|
1586
|
+
${siteBuild(options)}
|
|
1496
1587
|
|
|
1497
1588
|
# The runner needs the standalone server; without it there is nothing to run.
|
|
1498
1589
|
RUN if [ ! -d ${appPath}/.next/standalone ]; then \\
|
|
@@ -1680,8 +1771,7 @@ CMD ["node", "index.mjs"]
|
|
|
1680
1771
|
* @internal Exported for testing
|
|
1681
1772
|
*/
|
|
1682
1773
|
function generateNodeWebDockerfile(options) {
|
|
1683
|
-
const { port, appPath
|
|
1684
|
-
const { turbo } = layout(options);
|
|
1774
|
+
const { port, appPath } = options;
|
|
1685
1775
|
return `# syntax=docker/dockerfile:1
|
|
1686
1776
|
# Node SSR web Dockerfile (TanStack Start / Remix), from a turbo-pruned slice
|
|
1687
1777
|
|
|
@@ -1690,7 +1780,10 @@ ${prunerStage(options)}
|
|
|
1690
1780
|
${depsStage(options)}
|
|
1691
1781
|
|
|
1692
1782
|
${builderStage(options, { args: options.publicUrlArgs ?? [] })}
|
|
1693
|
-
|
|
1783
|
+
|
|
1784
|
+
${siteWorkspaceSteps(options)}
|
|
1785
|
+
|
|
1786
|
+
${siteBuild(options)}
|
|
1694
1787
|
|
|
1695
1788
|
FROM ${options.baseImage} AS runner
|
|
1696
1789
|
WORKDIR /app
|
|
@@ -1724,8 +1817,7 @@ CMD ["sh", "-c", "cd ${appPath} && npm start"]
|
|
|
1724
1817
|
* @internal Exported for testing
|
|
1725
1818
|
*/
|
|
1726
1819
|
function generateViteStaticDockerfile(options) {
|
|
1727
|
-
const { port, appPath
|
|
1728
|
-
const { turbo } = layout(options);
|
|
1820
|
+
const { port, appPath } = options;
|
|
1729
1821
|
return `# syntax=docker/dockerfile:1
|
|
1730
1822
|
# Vite SPA Dockerfile — a turbo-pruned slice built to static files, served by Caddy
|
|
1731
1823
|
|
|
@@ -1734,7 +1826,10 @@ ${prunerStage(options)}
|
|
|
1734
1826
|
${depsStage(options)}
|
|
1735
1827
|
|
|
1736
1828
|
${builderStage(options, { args: options.publicUrlArgs ?? [] })}
|
|
1737
|
-
|
|
1829
|
+
|
|
1830
|
+
${siteWorkspaceSteps(options)}
|
|
1831
|
+
|
|
1832
|
+
${siteBuild(options)}
|
|
1738
1833
|
|
|
1739
1834
|
FROM ${STATIC_SITE_IMAGE} AS runner
|
|
1740
1835
|
|
|
@@ -1843,7 +1938,7 @@ function fromBuildRoot(layout, path) {
|
|
|
1843
1938
|
return joined === "" ? "." : joined;
|
|
1844
1939
|
}
|
|
1845
1940
|
/** Everything a template needs about one app, relative to the build root. */
|
|
1846
|
-
function appImageOptions(layout, appName, app, workspaceRoot) {
|
|
1941
|
+
function appImageOptions(layout, appName, app, workspaceRoot, apps = {}) {
|
|
1847
1942
|
const turboPackage = packageName((0, node_path.isAbsolute)(app.path) ? app.path : (0, node_path.join)(workspaceRoot, app.path)) ?? appName;
|
|
1848
1943
|
return {
|
|
1849
1944
|
imageName: appName,
|
|
@@ -1859,10 +1954,49 @@ function appImageOptions(layout, appName, app, workspaceRoot) {
|
|
|
1859
1954
|
...app.type === "backend" ? {
|
|
1860
1955
|
gkmPaths: layout.gkmPaths,
|
|
1861
1956
|
...layout.workspacePackage && layout.workspacePackage !== turboPackage ? { prunePackages: [layout.workspacePackage] } : {}
|
|
1862
|
-
} : {}
|
|
1957
|
+
} : app.type === "web" ? siteWorkspace(layout, app, apps, workspaceRoot, turboPackage) : {}
|
|
1863
1958
|
};
|
|
1864
1959
|
}
|
|
1865
1960
|
/**
|
|
1961
|
+
* What a site's image carries of the gkm workspace: its config and construct
|
|
1962
|
+
* directories, the workspace's own package where it is nested in a monorepo
|
|
1963
|
+
* (it holds the CLI), and each backend the site calls — whose endpoints its
|
|
1964
|
+
* client is generated from, and whose package their imports resolve in.
|
|
1965
|
+
*/
|
|
1966
|
+
function siteWorkspace(layout, site, apps, workspaceRoot, turboPackage) {
|
|
1967
|
+
const clients = siteClients(site, apps);
|
|
1968
|
+
const packages = /* @__PURE__ */ new Set();
|
|
1969
|
+
if (layout.workspacePackage) packages.add(layout.workspacePackage);
|
|
1970
|
+
for (const { app } of clients) {
|
|
1971
|
+
const backend = apps[app];
|
|
1972
|
+
const name = packageName((0, node_path.isAbsolute)(backend.path) ? backend.path : (0, node_path.join)(workspaceRoot, backend.path));
|
|
1973
|
+
if (name) packages.add(name);
|
|
1974
|
+
}
|
|
1975
|
+
packages.delete(turboPackage);
|
|
1976
|
+
return {
|
|
1977
|
+
gkmPaths: layout.gkmPaths,
|
|
1978
|
+
...packages.size > 0 ? { prunePackages: [...packages].sort() } : {},
|
|
1979
|
+
...clients.length > 0 ? { clients: clients.map(({ app }) => ({
|
|
1980
|
+
app,
|
|
1981
|
+
path: fromBuildRoot(layout, apps[app].path)
|
|
1982
|
+
})) } : {}
|
|
1983
|
+
};
|
|
1984
|
+
}
|
|
1985
|
+
/**
|
|
1986
|
+
* The backends whose clients a site imports: each it depends on that gkm
|
|
1987
|
+
* builds from endpoints — not one with an entry of its own, and not one that
|
|
1988
|
+
* turned OpenAPI off.
|
|
1989
|
+
*/
|
|
1990
|
+
function siteClients(site, apps) {
|
|
1991
|
+
return site.dependencies.filter((name) => {
|
|
1992
|
+
const app = apps[name];
|
|
1993
|
+
if (!app || app.type !== "backend" || app.entry) return false;
|
|
1994
|
+
if (app.openapi === false) return false;
|
|
1995
|
+
if (typeof app.openapi === "object" && app.openapi.enabled === false) return false;
|
|
1996
|
+
return true;
|
|
1997
|
+
}).sort().map((app) => ({ app }));
|
|
1998
|
+
}
|
|
1999
|
+
/**
|
|
1866
2000
|
* The directories the workspace's construct globs start in, relative to its
|
|
1867
2001
|
* root: `./constructs/**\/*.ts` reads from `constructs`.
|
|
1868
2002
|
*/
|
|
@@ -5885,6 +6019,7 @@ async function workspaceDockerCommand(workspace, manifest, imageNames = {}, back
|
|
|
5885
6019
|
const dockerfile = appDockerfile(appName, app, {
|
|
5886
6020
|
layout,
|
|
5887
6021
|
workspaceRoot: workspace.root,
|
|
6022
|
+
apps: workspace.apps,
|
|
5888
6023
|
...manifest ? { manifest } : {}
|
|
5889
6024
|
});
|
|
5890
6025
|
const path = dockerfileOf(appName, app.path);
|
|
@@ -5940,7 +6075,7 @@ async function workspaceDockerCommand(workspace, manifest, imageNames = {}, back
|
|
|
5940
6075
|
* framework. The one choice every builder of images makes.
|
|
5941
6076
|
*/
|
|
5942
6077
|
function appDockerfile(appName, app, options) {
|
|
5943
|
-
const image = appImageOptions(options.layout, appName, app, options.workspaceRoot);
|
|
6078
|
+
const image = appImageOptions(options.layout, appName, app, options.workspaceRoot, options.apps);
|
|
5944
6079
|
if (app.type === "web") return siteDockerfile(appName, app, {
|
|
5945
6080
|
image,
|
|
5946
6081
|
...options.manifest ? { manifest: options.manifest } : {},
|
|
@@ -6360,6 +6495,96 @@ function setPostgresBackupId(state, backupId) {
|
|
|
6360
6495
|
if (state.backups) state.backups.postgresBackupId = backupId;
|
|
6361
6496
|
}
|
|
6362
6497
|
//#endregion
|
|
6498
|
+
//#region src/secrets/stale.ts
|
|
6499
|
+
/**
|
|
6500
|
+
* Stored secrets an older gkm generated that now shadow a derived value.
|
|
6501
|
+
*
|
|
6502
|
+
* Before constructs, initialising a stage wrote an address for each app into
|
|
6503
|
+
* its custom secrets: `<APP>_DATABASE_URL` as a `postgresql://…@localhost`
|
|
6504
|
+
* URL with a password of its own, and `http://localhost:<port>` for a site or
|
|
6505
|
+
* an auth server. Those keys are now a construct's — `database.schema('AuthDatabase')`
|
|
6506
|
+
* provides `AUTH_DATABASE_URL`, `new BetterAuth('Auth')` provides `AUTH_URL`
|
|
6507
|
+
* — and a deploy derives them. A value the stage holds is a value set by hand,
|
|
6508
|
+
* and set by hand wins: the container is handed `localhost`, where nothing
|
|
6509
|
+
* answers, with a password no role has.
|
|
6510
|
+
*
|
|
6511
|
+
* So a deploy refuses such a stage rather than run it, naming each key and
|
|
6512
|
+
* the command that removes it. Nothing is deleted for the user: the value is
|
|
6513
|
+
* theirs, and only they can say it is stale. A URL that names a real host — a
|
|
6514
|
+
* managed database — is a deliberate choice and still wins.
|
|
6515
|
+
*/
|
|
6516
|
+
/** The kinds whose URL an older gkm wrote into a stage's secrets. */
|
|
6517
|
+
const ADDRESSED = /* @__PURE__ */ new Set([
|
|
6518
|
+
"database",
|
|
6519
|
+
"database-reader",
|
|
6520
|
+
"database-schema",
|
|
6521
|
+
"rest-api",
|
|
6522
|
+
"site"
|
|
6523
|
+
]);
|
|
6524
|
+
/** Hosts that are this machine — never anything, inside a container. */
|
|
6525
|
+
const LOOPBACK = /* @__PURE__ */ new Set([
|
|
6526
|
+
"localhost",
|
|
6527
|
+
"127.0.0.1",
|
|
6528
|
+
"[::1]",
|
|
6529
|
+
"::1"
|
|
6530
|
+
]);
|
|
6531
|
+
/**
|
|
6532
|
+
* A stage holds a construct's address as a custom secret, pointing at
|
|
6533
|
+
* `localhost` — what an older `gkm secrets:init`, `gkm setup` or `gkm init`
|
|
6534
|
+
* generated. Set by hand wins over derived, so the app would be handed it.
|
|
6535
|
+
*/
|
|
6536
|
+
var StaleStageSecrets = class extends Error {
|
|
6537
|
+
stage;
|
|
6538
|
+
stale;
|
|
6539
|
+
constructor(stage, stale) {
|
|
6540
|
+
const one = stale.length === 1;
|
|
6541
|
+
super(`The stage '${stage}' holds ${one ? "a value" : "values"} an older gkm generated for ${one ? "an address a construct" : "addresses constructs"} now ${one ? "provides" : "provide"}:\n` + stale.map((s) => ` ${s.key}: ${s.construct}'s, stored pointing at ${s.host}`).join("\n") + `
|
|
6542
|
+
A stored value wins over the derived one, so the app would be handed an address where nothing answers inside its container. Remove ${one ? "it" : "each"}, and the construct's own value is used:\n` + stale.map((s) => ` gkm secrets:unset ${s.key} --stage ${stage}`).join("\n") + "\nA managed service set with its real host is not affected.");
|
|
6543
|
+
this.stage = stage;
|
|
6544
|
+
this.stale = stale;
|
|
6545
|
+
this.name = "StaleStageSecrets";
|
|
6546
|
+
}
|
|
6547
|
+
};
|
|
6548
|
+
/** The host a stored value names, if it is a URL. */
|
|
6549
|
+
function hostOf(value) {
|
|
6550
|
+
try {
|
|
6551
|
+
return new URL(value).hostname;
|
|
6552
|
+
} catch {
|
|
6553
|
+
return;
|
|
6554
|
+
}
|
|
6555
|
+
}
|
|
6556
|
+
/**
|
|
6557
|
+
* Each stored key that a construct provides an address for, holding an
|
|
6558
|
+
* address on this machine.
|
|
6559
|
+
*/
|
|
6560
|
+
function staleStageSecrets(manifest, supplied) {
|
|
6561
|
+
const stale = [];
|
|
6562
|
+
for (const [id, declaration] of Object.entries(manifest)) {
|
|
6563
|
+
if (!ADDRESSED.has(declaration.kind)) continue;
|
|
6564
|
+
const key = (0, _geekmidas_manifest.providedKeyFor)(id, declaration.kind, "url");
|
|
6565
|
+
const value = supplied[key];
|
|
6566
|
+
if (value === void 0) continue;
|
|
6567
|
+
const host = hostOf(value);
|
|
6568
|
+
if (host === void 0 || !LOOPBACK.has(host)) continue;
|
|
6569
|
+
stale.push({
|
|
6570
|
+
key,
|
|
6571
|
+
construct: id,
|
|
6572
|
+
host
|
|
6573
|
+
});
|
|
6574
|
+
}
|
|
6575
|
+
return stale.sort((a, b) => a.key.localeCompare(b.key));
|
|
6576
|
+
}
|
|
6577
|
+
/**
|
|
6578
|
+
* Refuse a stage whose stored secrets would shadow a construct's address with
|
|
6579
|
+
* `localhost`.
|
|
6580
|
+
*
|
|
6581
|
+
* @throws {StaleStageSecrets} naming each key and the command removing it
|
|
6582
|
+
*/
|
|
6583
|
+
function assertNoStaleSecrets(options) {
|
|
6584
|
+
const stale = staleStageSecrets(options.manifest, options.supplied);
|
|
6585
|
+
if (stale.length > 0) throw new StaleStageSecrets(options.stage, stale);
|
|
6586
|
+
}
|
|
6587
|
+
//#endregion
|
|
6363
6588
|
Object.defineProperty(exports, "CronGenerator", {
|
|
6364
6589
|
enumerable: true,
|
|
6365
6590
|
get: function() {
|
|
@@ -6510,6 +6735,12 @@ Object.defineProperty(exports, "assertExternalServices", {
|
|
|
6510
6735
|
return assertExternalServices;
|
|
6511
6736
|
}
|
|
6512
6737
|
});
|
|
6738
|
+
Object.defineProperty(exports, "assertNoStaleSecrets", {
|
|
6739
|
+
enumerable: true,
|
|
6740
|
+
get: function() {
|
|
6741
|
+
return assertNoStaleSecrets;
|
|
6742
|
+
}
|
|
6743
|
+
});
|
|
6513
6744
|
Object.defineProperty(exports, "backendsOf", {
|
|
6514
6745
|
enumerable: true,
|
|
6515
6746
|
get: function() {
|
|
@@ -6684,6 +6915,12 @@ Object.defineProperty(exports, "hostFor", {
|
|
|
6684
6915
|
return hostFor;
|
|
6685
6916
|
}
|
|
6686
6917
|
});
|
|
6918
|
+
Object.defineProperty(exports, "imageBuildCredentials", {
|
|
6919
|
+
enumerable: true,
|
|
6920
|
+
get: function() {
|
|
6921
|
+
return imageBuildCredentials;
|
|
6922
|
+
}
|
|
6923
|
+
});
|
|
6687
6924
|
Object.defineProperty(exports, "imageLayout", {
|
|
6688
6925
|
enumerable: true,
|
|
6689
6926
|
get: function() {
|
|
@@ -6714,6 +6951,12 @@ Object.defineProperty(exports, "isDnsVerified", {
|
|
|
6714
6951
|
return isDnsVerified;
|
|
6715
6952
|
}
|
|
6716
6953
|
});
|
|
6954
|
+
Object.defineProperty(exports, "isImageBuild", {
|
|
6955
|
+
enumerable: true,
|
|
6956
|
+
get: function() {
|
|
6957
|
+
return isImageBuild;
|
|
6958
|
+
}
|
|
6959
|
+
});
|
|
6717
6960
|
Object.defineProperty(exports, "isMainFrontendApp", {
|
|
6718
6961
|
enumerable: true,
|
|
6719
6962
|
get: function() {
|
|
@@ -6978,6 +7221,12 @@ Object.defineProperty(exports, "storage_exports", {
|
|
|
6978
7221
|
return storage_exports;
|
|
6979
7222
|
}
|
|
6980
7223
|
});
|
|
7224
|
+
Object.defineProperty(exports, "storeFromConfig", {
|
|
7225
|
+
enumerable: true,
|
|
7226
|
+
get: function() {
|
|
7227
|
+
return storeFromConfig;
|
|
7228
|
+
}
|
|
7229
|
+
});
|
|
6981
7230
|
Object.defineProperty(exports, "store_exports", {
|
|
6982
7231
|
enumerable: true,
|
|
6983
7232
|
get: function() {
|
|
@@ -7057,4 +7306,4 @@ Object.defineProperty(exports, "workspace_exports", {
|
|
|
7057
7306
|
}
|
|
7058
7307
|
});
|
|
7059
7308
|
|
|
7060
|
-
//# sourceMappingURL=
|
|
7309
|
+
//# sourceMappingURL=stale-yu2FkH3G.cjs.map
|