@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.
Files changed (157) hide show
  1. package/dist/{LegacyStateStore-BFnXUFlx.cjs → LegacyStateStore-DwngfJxr.cjs} +2 -2
  2. package/dist/{LegacyStateStore-BFnXUFlx.cjs.map → LegacyStateStore-DwngfJxr.cjs.map} +1 -1
  3. package/dist/{LegacyStateStore-cpt3K1vx.mjs → LegacyStateStore-dyq07_Ir.mjs} +2 -2
  4. package/dist/{LegacyStateStore-cpt3K1vx.mjs.map → LegacyStateStore-dyq07_Ir.mjs.map} +1 -1
  5. package/dist/{LocalStateStore-zQGZ9b4J.cjs → LocalStateStore-B0NCde8Z.cjs} +2 -2
  6. package/dist/{LocalStateStore-zQGZ9b4J.cjs.map → LocalStateStore-B0NCde8Z.cjs.map} +1 -1
  7. package/dist/{LocalStateStore-RH9F2ZEy.mjs → LocalStateStore-DLxCCatI.mjs} +2 -2
  8. package/dist/{LocalStateStore-RH9F2ZEy.mjs.map → LocalStateStore-DLxCCatI.mjs.map} +1 -1
  9. package/dist/{S3StateStore-CT-ZMlQY.cjs → S3StateStore-BOenb-3o.cjs} +2 -2
  10. package/dist/{S3StateStore-CT-ZMlQY.cjs.map → S3StateStore-BOenb-3o.cjs.map} +1 -1
  11. package/dist/{S3StateStore-DBeBc0c0.mjs → S3StateStore-CGK_4hlo.mjs} +2 -2
  12. package/dist/{S3StateStore-DBeBc0c0.mjs.map → S3StateStore-CGK_4hlo.mjs.map} +1 -1
  13. package/dist/{SSMStateStore-rnzNfOaV.mjs → SSMStateStore-B_5_RqY-.mjs} +2 -2
  14. package/dist/{SSMStateStore-rnzNfOaV.mjs.map → SSMStateStore-B_5_RqY-.mjs.map} +1 -1
  15. package/dist/{SSMStateStore-HmsH3c4v.cjs → SSMStateStore-DYeD__7p.cjs} +2 -2
  16. package/dist/{SSMStateStore-HmsH3c4v.cjs.map → SSMStateStore-DYeD__7p.cjs.map} +1 -1
  17. package/dist/{add-CHBin8TF.cjs → add-DCsgtvDk.cjs} +8 -8
  18. package/dist/{add-CHBin8TF.cjs.map → add-DCsgtvDk.cjs.map} +1 -1
  19. package/dist/{add-Cvzdw8cf.mjs → add-EPQO-_dt.mjs} +3 -3
  20. package/dist/{add-Cvzdw8cf.mjs.map → add-EPQO-_dt.mjs.map} +1 -1
  21. package/dist/{aws-DojzQnLd.mjs → aws-Bja4zGSs.mjs} +13 -9
  22. package/dist/aws-Bja4zGSs.mjs.map +1 -0
  23. package/dist/{aws-DkHdTV-p.cjs → aws-CQAuluiu.cjs} +13 -9
  24. package/dist/aws-CQAuluiu.cjs.map +1 -0
  25. package/dist/awsStore-7VmS_cZR.cjs +54 -0
  26. package/dist/awsStore-7VmS_cZR.cjs.map +1 -0
  27. package/dist/awsStore-B529csle.mjs +43 -0
  28. package/dist/awsStore-B529csle.mjs.map +1 -0
  29. package/dist/{bundler-_8AEZhrs.cjs → bundler-5spPyduN.cjs} +5 -5
  30. package/dist/bundler-5spPyduN.cjs.map +1 -0
  31. package/dist/{bundler-xjp5RwRS.mjs → bundler-DgO_EMVs.mjs} +5 -5
  32. package/dist/bundler-DgO_EMVs.mjs.map +1 -0
  33. package/dist/{cli-BTGfA0B7.mjs → cli-B74Ru-V1.mjs} +3 -3
  34. package/dist/{cli-BTGfA0B7.mjs.map → cli-B74Ru-V1.mjs.map} +1 -1
  35. package/dist/{cli-B4ktxAsM.cjs → cli-ZpFTMbGw.cjs} +4 -4
  36. package/dist/{cli-B4ktxAsM.cjs.map → cli-ZpFTMbGw.cjs.map} +1 -1
  37. package/dist/{compose-UKyv_1yU.cjs → compose-CePlrbUw.cjs} +68 -60
  38. package/dist/compose-CePlrbUw.cjs.map +1 -0
  39. package/dist/{compose-DdH2JQJD.mjs → compose-IUuxRW0J.mjs} +18 -10
  40. package/dist/compose-IUuxRW0J.mjs.map +1 -0
  41. package/dist/{config-DA0kRTQe.d.mts → config-Ckmoj56i.d.mts} +3 -3
  42. package/dist/{config-B38YWicj.d.cts.map → config-Ckmoj56i.d.mts.map} +1 -1
  43. package/dist/{config-B38YWicj.d.cts → config-aAeLXH86.d.cts} +3 -3
  44. package/dist/{config-DA0kRTQe.d.mts.map → config-aAeLXH86.d.cts.map} +1 -1
  45. package/dist/config.cjs +1 -1
  46. package/dist/config.d.cts +3 -3
  47. package/dist/config.d.mts +3 -3
  48. package/dist/config.mjs +1 -1
  49. package/dist/deploy/public.cjs +12 -12
  50. package/dist/deploy/public.d.cts +3 -3
  51. package/dist/deploy/public.d.cts.map +1 -1
  52. package/dist/deploy/public.d.mts +3 -3
  53. package/dist/deploy/public.d.mts.map +1 -1
  54. package/dist/deploy/public.mjs +6 -6
  55. package/dist/{deploy-CuSsiFIc.mjs → deploy-Q6X6RXRG.mjs} +5 -5
  56. package/dist/{deploy-CuSsiFIc.mjs.map → deploy-Q6X6RXRG.mjs.map} +1 -1
  57. package/dist/{deploy-XUZoA1us.cjs → deploy-XHXi-_tL.cjs} +11 -11
  58. package/dist/{deploy-XUZoA1us.cjs.map → deploy-XHXi-_tL.cjs.map} +1 -1
  59. package/dist/{dokploy-DZXTQX10.mjs → dokploy-BtP5XSrS.mjs} +2 -2
  60. package/dist/{dokploy-DZXTQX10.mjs.map → dokploy-BtP5XSrS.mjs.map} +1 -1
  61. package/dist/{dokploy-Cvgg_pID.cjs → dokploy-MSsPBO-t.cjs} +2 -2
  62. package/dist/{dokploy-Cvgg_pID.cjs.map → dokploy-MSsPBO-t.cjs.map} +1 -1
  63. package/dist/{encryption-JkeMPugf.mjs → encryption-D4Ykywfr.mjs} +3 -3
  64. package/dist/{encryption-JkeMPugf.mjs.map → encryption-D4Ykywfr.mjs.map} +1 -1
  65. package/dist/{encryption-w-Ehh9DW.cjs → encryption-DY0na43R.cjs} +6 -6
  66. package/dist/{encryption-w-Ehh9DW.cjs.map → encryption-DY0na43R.cjs.map} +1 -1
  67. package/dist/{engine-CmozkHxq.mjs → engine-BI2xjCKt.mjs} +9 -4
  68. package/dist/{engine-CmozkHxq.mjs.map → engine-BI2xjCKt.mjs.map} +1 -1
  69. package/dist/{engine-zpWBMsQq.cjs → engine-y53kE_3H.cjs} +73 -68
  70. package/dist/{engine-zpWBMsQq.cjs.map → engine-y53kE_3H.cjs.map} +1 -1
  71. package/dist/{github-BNngHoId.mjs → github-BBIqk1Jv.mjs} +6 -6
  72. package/dist/github-BBIqk1Jv.mjs.map +1 -0
  73. package/dist/{github-BGdJ-Lnm.cjs → github-Bmb45xUQ.cjs} +10 -10
  74. package/dist/github-Bmb45xUQ.cjs.map +1 -0
  75. package/dist/{index-vMidfqhU.d.cts → index-C7Tma2m1.d.cts} +2 -2
  76. package/dist/{index-B-1lLGzy.d.mts.map → index-C7Tma2m1.d.cts.map} +1 -1
  77. package/dist/{index-B-1lLGzy.d.mts → index-CNdSRwar.d.mts} +2 -2
  78. package/dist/{index-vMidfqhU.d.cts.map → index-CNdSRwar.d.mts.map} +1 -1
  79. package/dist/index.cjs +210 -221
  80. package/dist/index.cjs.map +1 -1
  81. package/dist/index.mjs +141 -152
  82. package/dist/index.mjs.map +1 -1
  83. package/dist/migrate-31JXUOaG.cjs +93 -0
  84. package/dist/migrate-31JXUOaG.cjs.map +1 -0
  85. package/dist/{migrate-BLL1RTAj.mjs → migrate-BUBsUiM3.mjs} +3 -3
  86. package/dist/{migrate-BLL1RTAj.mjs.map → migrate-BUBsUiM3.mjs.map} +1 -1
  87. package/dist/migrate-DWVl5PQK.mjs +93 -0
  88. package/dist/migrate-DWVl5PQK.mjs.map +1 -0
  89. package/dist/{migrate-CgjlYeun.cjs → migrate-sny0NjKe.cjs} +8 -8
  90. package/dist/{migrate-CgjlYeun.cjs.map → migrate-sny0NjKe.cjs.map} +1 -1
  91. package/dist/openapi.cjs +16 -6
  92. package/dist/openapi.cjs.map +1 -1
  93. package/dist/openapi.d.cts +1 -1
  94. package/dist/openapi.d.cts.map +1 -1
  95. package/dist/openapi.d.mts +1 -1
  96. package/dist/openapi.d.mts.map +1 -1
  97. package/dist/openapi.mjs +16 -6
  98. package/dist/openapi.mjs.map +1 -1
  99. package/dist/reconcile/public.d.cts +1 -1
  100. package/dist/reconcile/public.d.mts +1 -1
  101. package/dist/{resolve-DZNx7rLy.mjs → resolve-BF1ICosS.mjs} +3 -3
  102. package/dist/{resolve-DZNx7rLy.mjs.map → resolve-BF1ICosS.mjs.map} +1 -1
  103. package/dist/{resolve-fevXn-wZ.cjs → resolve-DokLtTUb.cjs} +3 -3
  104. package/dist/{resolve-fevXn-wZ.cjs.map → resolve-DokLtTUb.cjs.map} +1 -1
  105. package/dist/{rollback-Dw-FW3X2.cjs → rollback-CpOWRR9H.cjs} +7 -7
  106. package/dist/{rollback-Dw-FW3X2.cjs.map → rollback-CpOWRR9H.cjs.map} +1 -1
  107. package/dist/{rollback-CLi5Pln_.mjs → rollback-sg0ZhKGG.mjs} +5 -5
  108. package/dist/{rollback-CLi5Pln_.mjs.map → rollback-sg0ZhKGG.mjs.map} +1 -1
  109. package/dist/{runtime-BzZD5HHi.d.cts → runtime-B5bYom9w.d.mts} +2 -2
  110. package/dist/{runtime-BzZD5HHi.d.cts.map → runtime-B5bYom9w.d.mts.map} +1 -1
  111. package/dist/{runtime-Cm6J6L7n.d.mts → runtime-BozOkPtG.d.cts} +2 -2
  112. package/dist/{runtime-Cm6J6L7n.d.mts.map → runtime-BozOkPtG.d.cts.map} +1 -1
  113. package/dist/secretsManager-DUXW3fQt.cjs +70 -0
  114. package/dist/secretsManager-DUXW3fQt.cjs.map +1 -0
  115. package/dist/secretsManager-Ti0oZwsS.mjs +70 -0
  116. package/dist/secretsManager-Ti0oZwsS.mjs.map +1 -0
  117. package/dist/{sniffer-BmCvVyhq.mjs → sniffer-DR8AlRCk.mjs} +17 -17
  118. package/dist/sniffer-DR8AlRCk.mjs.map +1 -0
  119. package/dist/{sniffer-bMzrX4cO.cjs → sniffer-Y6GQOCXB.cjs} +17 -17
  120. package/dist/sniffer-Y6GQOCXB.cjs.map +1 -0
  121. package/dist/{state-BrWIOce_.mjs → stale-DGzpiN5S.mjs} +270 -45
  122. package/dist/stale-DGzpiN5S.mjs.map +1 -0
  123. package/dist/{state-kA4Fkufx.cjs → stale-yu2FkH3G.cjs} +293 -44
  124. package/dist/stale-yu2FkH3G.cjs.map +1 -0
  125. package/dist/target/public.cjs +1 -1
  126. package/dist/target/public.d.cts +2 -2
  127. package/dist/target/public.d.mts +2 -2
  128. package/dist/target/public.mjs +1 -1
  129. package/dist/{types-TzCChNrA.d.cts → types-B9yWJAis.d.mts} +59 -9
  130. package/dist/types-B9yWJAis.d.mts.map +1 -0
  131. package/dist/{types-Dp9lgx_S.d.mts → types-ct7pdQRf.d.cts} +60 -8
  132. package/dist/types-ct7pdQRf.d.cts.map +1 -0
  133. package/dist/workspace/index.cjs +1 -1
  134. package/dist/workspace/index.d.cts +2 -2
  135. package/dist/workspace/index.d.mts +2 -2
  136. package/dist/workspace/index.mjs +1 -1
  137. package/dist/{workspace-vdrcRI-m.cjs → workspace-DOm81oUo.cjs} +54 -1
  138. package/dist/workspace-DOm81oUo.cjs.map +1 -0
  139. package/dist/{workspace-C7NqCsQF.mjs → workspace-QUTqYmVy.mjs} +43 -2
  140. package/dist/workspace-QUTqYmVy.mjs.map +1 -0
  141. package/package.json +16 -15
  142. package/dist/aws-DkHdTV-p.cjs.map +0 -1
  143. package/dist/aws-DojzQnLd.mjs.map +0 -1
  144. package/dist/bundler-_8AEZhrs.cjs.map +0 -1
  145. package/dist/bundler-xjp5RwRS.mjs.map +0 -1
  146. package/dist/compose-DdH2JQJD.mjs.map +0 -1
  147. package/dist/compose-UKyv_1yU.cjs.map +0 -1
  148. package/dist/github-BGdJ-Lnm.cjs.map +0 -1
  149. package/dist/github-BNngHoId.mjs.map +0 -1
  150. package/dist/sniffer-BmCvVyhq.mjs.map +0 -1
  151. package/dist/sniffer-bMzrX4cO.cjs.map +0 -1
  152. package/dist/state-BrWIOce_.mjs.map +0 -1
  153. package/dist/state-kA4Fkufx.cjs.map +0 -1
  154. package/dist/types-Dp9lgx_S.d.mts.map +0 -1
  155. package/dist/types-TzCChNrA.d.cts.map +0 -1
  156. package/dist/workspace-C7NqCsQF.mjs.map +0 -1
  157. 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-vdrcRI-m.cjs");
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-fevXn-wZ.cjs");
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
- if (configured.provider !== "ssm") return configured.provider;
545
- const { AwsSecretsStore } = await Promise.resolve().then(() => require("./aws-DkHdTV-p.cjs"));
546
- return new AwsSecretsStore({
547
- project: workspace.name,
548
- region: configured.region,
549
- ...options.profile ? { profile: options.profile } : {}
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 secrets for an app from encrypted storage.
638
- * For workspace app: maps {APP}_DATABASE_URL → DATABASE_URL.
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, appName) {
642
- let secrets = {};
669
+ async function loadSecretsForApp(store, stage) {
643
670
  const stageSecrets = await store.read(stage);
644
- if (stageSecrets) {
645
- logger$1.log(`🔐 Loading secrets from stage: ${stage}`);
646
- secrets = toEmbeddableSecrets(stageSecrets);
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, appName) : {};
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 '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)}')" && node "$GKM_BIN" ${args}`;
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, turboPackage, publicUrlArgs = ["NEXT_PUBLIC_API_URL", "NEXT_PUBLIC_AUTH_URL"] } = options;
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
- RUN ${turbo} run build --filter='${turboPackage}'
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, turboPackage } = options;
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
- RUN ${turbo} run build --filter='${turboPackage}'
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, turboPackage } = options;
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
- RUN ${turbo} run build --filter='${turboPackage}'
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=state-kA4Fkufx.cjs.map
7309
+ //# sourceMappingURL=stale-yu2FkH3G.cjs.map