@geekmidas/cli 10.0.0-alpha.93 → 10.0.0-alpha.95

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 (213) hide show
  1. package/dist/{GoDaddyProvider-Mi3vptSR.mjs → GoDaddyProvider-BwW51hPm.mjs} +3 -3
  2. package/dist/{GoDaddyProvider-Mi3vptSR.mjs.map → GoDaddyProvider-BwW51hPm.mjs.map} +1 -1
  3. package/dist/{GoDaddyProvider-BZb-V14e.cjs → GoDaddyProvider-C_DgIkMv.cjs} +3 -3
  4. package/dist/{GoDaddyProvider-BZb-V14e.cjs.map → GoDaddyProvider-C_DgIkMv.cjs.map} +1 -1
  5. package/dist/{HostingerProvider-1mqD6aG8.mjs → HostingerProvider-BNpS9aRJ.mjs} +9 -4
  6. package/dist/{HostingerProvider-1mqD6aG8.mjs.map → HostingerProvider-BNpS9aRJ.mjs.map} +1 -1
  7. package/dist/{HostingerProvider-C6t-PSNe.cjs → HostingerProvider-DR1iws1P.cjs} +9 -4
  8. package/dist/HostingerProvider-DR1iws1P.cjs.map +1 -0
  9. package/dist/{LegacyStateStore-BlYXQQSE.cjs → LegacyStateStore-BawjE_5n.cjs} +10 -9
  10. package/dist/{LegacyStateStore-BlYXQQSE.cjs.map → LegacyStateStore-BawjE_5n.cjs.map} +1 -1
  11. package/dist/{LegacyStateStore-CtwO7fwy.mjs → LegacyStateStore-D5DarNA2.mjs} +3 -2
  12. package/dist/{LegacyStateStore-CtwO7fwy.mjs.map → LegacyStateStore-D5DarNA2.mjs.map} +1 -1
  13. package/dist/{LocalStateStore-oX_zxj9V.cjs → LocalStateStore-D8fu5WiF.cjs} +8 -8
  14. package/dist/{LocalStateStore-oX_zxj9V.cjs.map → LocalStateStore-D8fu5WiF.cjs.map} +1 -1
  15. package/dist/{LocalStateStore-D40_SDmJ.mjs → LocalStateStore-YjIqlgAz.mjs} +2 -2
  16. package/dist/{LocalStateStore-D40_SDmJ.mjs.map → LocalStateStore-YjIqlgAz.mjs.map} +1 -1
  17. package/dist/{S3StateStore-BzS0IeSt.mjs → S3StateStore-CjTAVsWh.mjs} +2 -2
  18. package/dist/{S3StateStore-BzS0IeSt.mjs.map → S3StateStore-CjTAVsWh.mjs.map} +1 -1
  19. package/dist/{S3StateStore-DeI7jtvi.cjs → S3StateStore-Cm-v2IPI.cjs} +5 -5
  20. package/dist/{S3StateStore-DeI7jtvi.cjs.map → S3StateStore-Cm-v2IPI.cjs.map} +1 -1
  21. package/dist/{SSMStateStore-CaCtrzFL.cjs → SSMStateStore-BS4BiZCN.cjs} +9 -9
  22. package/dist/{SSMStateStore-CaCtrzFL.cjs.map → SSMStateStore-BS4BiZCN.cjs.map} +1 -1
  23. package/dist/{SSMStateStore-k_Ew7TWx.mjs → SSMStateStore-BhtM6jOh.mjs} +2 -2
  24. package/dist/{SSMStateStore-k_Ew7TWx.mjs.map → SSMStateStore-BhtM6jOh.mjs.map} +1 -1
  25. package/dist/{add-VcyJnsPX.cjs → add-D-3IKT7W.cjs} +24 -53
  26. package/dist/add-D-3IKT7W.cjs.map +1 -0
  27. package/dist/{add-CP1podDH.mjs → add-ylx8dejw.mjs} +23 -52
  28. package/dist/add-ylx8dejw.mjs.map +1 -0
  29. package/dist/{bundler-Dfsr6KXU.cjs → bundler-CI3elfZS.cjs} +5 -5
  30. package/dist/{bundler-Dfsr6KXU.cjs.map → bundler-CI3elfZS.cjs.map} +1 -1
  31. package/dist/{bundler-BWrh-AJH.mjs → bundler-ywR3C1B_.mjs} +5 -5
  32. package/dist/{bundler-BWrh-AJH.mjs.map → bundler-ywR3C1B_.mjs.map} +1 -1
  33. package/dist/{cli-B8otnZfX.mjs → cli-BCSuCfQk.mjs} +9 -5
  34. package/dist/cli-BCSuCfQk.mjs.map +1 -0
  35. package/dist/{cli-DL19w4OE.cjs → cli-Dewt2T21.cjs} +9 -5
  36. package/dist/cli-Dewt2T21.cjs.map +1 -0
  37. package/dist/{compose-DrEB_4F-.mjs → compose-C4js1JDv.mjs} +82 -47
  38. package/dist/compose-C4js1JDv.mjs.map +1 -0
  39. package/dist/{compose-BHVKLluX.cjs → compose-Dd0XphvF.cjs} +94 -59
  40. package/dist/compose-Dd0XphvF.cjs.map +1 -0
  41. package/dist/{config-DCCcrOSo.d.cts → config-4yirvxS8.d.cts} +4 -4
  42. package/dist/{config-CHX5GOo3.d.mts.map → config-4yirvxS8.d.cts.map} +1 -1
  43. package/dist/{config-CHX5GOo3.d.mts → config-C8NPCn1l.d.mts} +4 -4
  44. package/dist/{config-DCCcrOSo.d.cts.map → config-C8NPCn1l.d.mts.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/{credentials-C4KII3PD.mjs → credentials-B5N5yKk6.mjs} +12 -134
  50. package/dist/credentials-B5N5yKk6.mjs.map +1 -0
  51. package/dist/{credentials-QBu7VgaQ.cjs → credentials-Zqr3QQYB.cjs} +11 -175
  52. package/dist/credentials-Zqr3QQYB.cjs.map +1 -0
  53. package/dist/deploy/public.cjs +19 -18
  54. package/dist/deploy/public.cjs.map +1 -1
  55. package/dist/deploy/public.d.cts +24 -9
  56. package/dist/deploy/public.d.cts.map +1 -1
  57. package/dist/deploy/public.d.mts +24 -9
  58. package/dist/deploy/public.d.mts.map +1 -1
  59. package/dist/deploy/public.mjs +11 -10
  60. package/dist/deploy/public.mjs.map +1 -1
  61. package/dist/deploy-B0drCD6s.mjs +1854 -0
  62. package/dist/deploy-B0drCD6s.mjs.map +1 -0
  63. package/dist/deploy-Bw1FjX_x.cjs +1903 -0
  64. package/dist/deploy-Bw1FjX_x.cjs.map +1 -0
  65. package/dist/{discover-vk2r5giK.d.cts → discover-BtFofyQB.d.cts} +2 -2
  66. package/dist/{discover-DqwlBVyY.d.mts.map → discover-BtFofyQB.d.cts.map} +1 -1
  67. package/dist/{discover-DqwlBVyY.d.mts → discover-D-MdXZgm.d.mts} +2 -2
  68. package/dist/{discover-vk2r5giK.d.cts.map → discover-D-MdXZgm.d.mts.map} +1 -1
  69. package/dist/dns-Bmk7P9c2.cjs +663 -0
  70. package/dist/dns-Bmk7P9c2.cjs.map +1 -0
  71. package/dist/dns-CyMIq6to.cjs +55 -0
  72. package/dist/dns-CyMIq6to.cjs.map +1 -0
  73. package/dist/dns-X3oqEV4C.mjs +44 -0
  74. package/dist/dns-X3oqEV4C.mjs.map +1 -0
  75. package/dist/dns-idXfyCay.mjs +610 -0
  76. package/dist/dns-idXfyCay.mjs.map +1 -0
  77. package/dist/{dokploy-o4I6vb9W.mjs → dokploy-CZYxXeMa.mjs} +2 -2
  78. package/dist/{dokploy-o4I6vb9W.mjs.map → dokploy-CZYxXeMa.mjs.map} +1 -1
  79. package/dist/{dokploy-rivb1RFt.cjs → dokploy-DaT0mgLU.cjs} +2 -2
  80. package/dist/{dokploy-rivb1RFt.cjs.map → dokploy-DaT0mgLU.cjs.map} +1 -1
  81. package/dist/{encryption-B6ilrT7p.mjs → encryption-D0ucY4O7.mjs} +3 -3
  82. package/dist/{encryption-B6ilrT7p.mjs.map → encryption-D0ucY4O7.mjs.map} +1 -1
  83. package/dist/{encryption-D7zmwzWz.cjs → encryption-Dp0IvLVX.cjs} +3 -3
  84. package/dist/{encryption-D7zmwzWz.cjs.map → encryption-Dp0IvLVX.cjs.map} +1 -1
  85. package/dist/{engine-DjEcovm-.mjs → engine-BcuhnyQO.mjs} +14 -31
  86. package/dist/{engine-DjEcovm-.mjs.map → engine-BcuhnyQO.mjs.map} +1 -1
  87. package/dist/{engine-Cfx8fEZU.cjs → engine-WY6j_kvA.cjs} +18 -35
  88. package/dist/engine-WY6j_kvA.cjs.map +1 -0
  89. package/dist/{github-CzBbs43W.mjs → github-DUGA57du.mjs} +96 -6
  90. package/dist/github-DUGA57du.mjs.map +1 -0
  91. package/dist/{github-zneTMvnO.cjs → github-DgmW83OP.cjs} +96 -6
  92. package/dist/github-DgmW83OP.cjs.map +1 -0
  93. package/dist/{index-BiYU7cUl.d.mts → index-5eL8rM6H.d.mts} +2 -2
  94. package/dist/{index-BiYU7cUl.d.mts.map → index-5eL8rM6H.d.mts.map} +1 -1
  95. package/dist/{index-Dm6V9bwh.d.cts → index-Dz-gyjm_.d.cts} +2 -2
  96. package/dist/{index-Dm6V9bwh.d.cts.map → index-Dz-gyjm_.d.cts.map} +1 -1
  97. package/dist/index.cjs +150 -118
  98. package/dist/index.cjs.map +1 -1
  99. package/dist/index.mjs +144 -112
  100. package/dist/index.mjs.map +1 -1
  101. package/dist/{local-Otp74ak0.mjs → local-BwC2v2Y8.mjs} +2 -2
  102. package/dist/{local-Otp74ak0.mjs.map → local-BwC2v2Y8.mjs.map} +1 -1
  103. package/dist/{local-B61kUh0w.cjs → local-DNhnkugT.cjs} +3 -3
  104. package/dist/{local-B61kUh0w.cjs.map → local-DNhnkugT.cjs.map} +1 -1
  105. package/dist/{migrate-DFjbGnSr.cjs → migrate-BBcG1dhS.cjs} +3 -3
  106. package/dist/{migrate-DFjbGnSr.cjs.map → migrate-BBcG1dhS.cjs.map} +1 -1
  107. package/dist/{migrate-CsBZKALY.mjs → migrate-CZ-v5WV0.mjs} +3 -3
  108. package/dist/{migrate-CsBZKALY.mjs.map → migrate-CZ-v5WV0.mjs.map} +1 -1
  109. package/dist/{migrate-BaC4w0sb.mjs → migrate-D6PlNv2o.mjs} +3 -3
  110. package/dist/{migrate-BaC4w0sb.mjs.map → migrate-D6PlNv2o.mjs.map} +1 -1
  111. package/dist/{migrate-C8wTpakT.cjs → migrate-afgRL3Hg.cjs} +3 -3
  112. package/dist/{migrate-C8wTpakT.cjs.map → migrate-afgRL3Hg.cjs.map} +1 -1
  113. package/dist/openapi.cjs +1 -1
  114. package/dist/openapi.d.cts +1 -1
  115. package/dist/openapi.d.mts +1 -1
  116. package/dist/openapi.mjs +1 -1
  117. package/dist/reconcile/public.d.cts +2 -2
  118. package/dist/reconcile/public.d.mts +2 -2
  119. package/dist/{resolve-g8htuR80.cjs → resolve-CFb4Navi.cjs} +4 -4
  120. package/dist/{resolve-g8htuR80.cjs.map → resolve-CFb4Navi.cjs.map} +1 -1
  121. package/dist/{resolve-Ccjlpnd9.mjs → resolve-DakDhr6Z.mjs} +4 -4
  122. package/dist/{resolve-Ccjlpnd9.mjs.map → resolve-DakDhr6Z.mjs.map} +1 -1
  123. package/dist/{rollback--ympG9ss.cjs → rollback-B-1dPP0m.cjs} +9 -8
  124. package/dist/{rollback--ympG9ss.cjs.map → rollback-B-1dPP0m.cjs.map} +1 -1
  125. package/dist/{rollback-Drbg0OeR.mjs → rollback-B1TIpjdE.mjs} +7 -6
  126. package/dist/{rollback-Drbg0OeR.mjs.map → rollback-B1TIpjdE.mjs.map} +1 -1
  127. package/dist/run-BJLIerMM.mjs +133 -0
  128. package/dist/run-BJLIerMM.mjs.map +1 -0
  129. package/dist/run-fVZ-rLnc.cjs +174 -0
  130. package/dist/run-fVZ-rLnc.cjs.map +1 -0
  131. package/dist/{runtime-_wEVtshH.d.mts → runtime-DUQdM-mW.d.cts} +2 -2
  132. package/dist/{runtime-D_J3ExJn.d.cts.map → runtime-DUQdM-mW.d.cts.map} +1 -1
  133. package/dist/{runtime-D_J3ExJn.d.cts → runtime-Vr6mleo2.d.mts} +2 -2
  134. package/dist/{runtime-_wEVtshH.d.mts.map → runtime-Vr6mleo2.d.mts.map} +1 -1
  135. package/dist/{sandbox-CPJq1Kia.d.mts → sandbox-BbJmh2rI.d.cts} +2 -2
  136. package/dist/{sandbox-CPJq1Kia.d.mts.map → sandbox-BbJmh2rI.d.cts.map} +1 -1
  137. package/dist/{sandbox-JwuPAl7I.d.cts → sandbox-DGOsMPMf.d.mts} +2 -2
  138. package/dist/{sandbox-JwuPAl7I.d.cts.map → sandbox-DGOsMPMf.d.mts.map} +1 -1
  139. package/dist/{secrets-DJteijZo.cjs → secrets-CPM0Qffe.cjs} +3 -3
  140. package/dist/secrets-CPM0Qffe.cjs.map +1 -0
  141. package/dist/{secrets-DbPmAS4k.mjs → secrets-oI9ClAPR.mjs} +3 -3
  142. package/dist/secrets-oI9ClAPR.mjs.map +1 -0
  143. package/dist/{seeds-c-ByX9je.cjs → seeds-CnXkgKUv.cjs} +1339 -3594
  144. package/dist/seeds-CnXkgKUv.cjs.map +1 -0
  145. package/dist/{seeds-BSL55F6q.mjs → seeds-CoKkrSny.mjs} +1126 -3266
  146. package/dist/seeds-CoKkrSny.mjs.map +1 -0
  147. package/dist/{sniffer-BTtGAtm3.mjs → sniffer-CFRzIrby.mjs} +496 -5
  148. package/dist/sniffer-CFRzIrby.mjs.map +1 -0
  149. package/dist/{sniffer-Dq5BS98f.cjs → sniffer-vbiQ2Isn.cjs} +572 -3
  150. package/dist/sniffer-vbiQ2Isn.cjs.map +1 -0
  151. package/dist/{sst-BaRXp2Dd.mjs → sst-CGdjHn2A.mjs} +4 -3
  152. package/dist/{sst-BaRXp2Dd.mjs.map → sst-CGdjHn2A.mjs.map} +1 -1
  153. package/dist/{sst-CnKY-CSh.cjs → sst-DGuHDxVU.cjs} +5 -4
  154. package/dist/{sst-CnKY-CSh.cjs.map → sst-DGuHDxVU.cjs.map} +1 -1
  155. package/dist/{stack-1PeLJS2j.cjs → stack-1g57OfOw.cjs} +14 -52
  156. package/dist/stack-1g57OfOw.cjs.map +1 -0
  157. package/dist/{stack-Co4uZkAo.mjs → stack-B7O975TR.mjs} +14 -52
  158. package/dist/stack-B7O975TR.mjs.map +1 -0
  159. package/dist/{stages-DY-fQKmo.mjs → stages-Bt4OggMm.mjs} +17 -3
  160. package/dist/stages-Bt4OggMm.mjs.map +1 -0
  161. package/dist/{stages-BI8JvPzI.cjs → stages-BujUB4we.cjs} +17 -3
  162. package/dist/stages-BujUB4we.cjs.map +1 -0
  163. package/dist/target/public.cjs +1 -1
  164. package/dist/target/public.d.cts +2 -2
  165. package/dist/target/public.d.mts +2 -2
  166. package/dist/target/public.mjs +1 -1
  167. package/dist/{terminal-8XngdSTo.cjs → terminal-CPHuH4S1.cjs} +2 -2
  168. package/dist/{terminal-8XngdSTo.cjs.map → terminal-CPHuH4S1.cjs.map} +1 -1
  169. package/dist/{terminal-C4XRdwnU.mjs → terminal-iNmAXXjs.mjs} +2 -2
  170. package/dist/{terminal-C4XRdwnU.mjs.map → terminal-iNmAXXjs.mjs.map} +1 -1
  171. package/dist/{types-BibpiHKB.d.cts → types-bkqVscdN.d.mts} +43 -11
  172. package/dist/types-bkqVscdN.d.mts.map +1 -0
  173. package/dist/{types-B6lmD3en.d.mts → types-dipJRmKV.d.cts} +44 -10
  174. package/dist/types-dipJRmKV.d.cts.map +1 -0
  175. package/dist/workspace/index.cjs +1 -1
  176. package/dist/workspace/index.d.cts +2 -2
  177. package/dist/workspace/index.d.mts +2 -2
  178. package/dist/workspace/index.mjs +1 -1
  179. package/dist/{workspace-Bzw7Zs82.mjs → workspace-DWK1PTXP.mjs} +4 -4
  180. package/dist/workspace-DWK1PTXP.mjs.map +1 -0
  181. package/dist/{workspace-CHOB2Xg3.cjs → workspace-cSyi5nb1.cjs} +4 -4
  182. package/dist/workspace-cSyi5nb1.cjs.map +1 -0
  183. package/package.json +15 -15
  184. package/dist/HostingerProvider-C6t-PSNe.cjs.map +0 -1
  185. package/dist/add-CP1podDH.mjs.map +0 -1
  186. package/dist/add-VcyJnsPX.cjs.map +0 -1
  187. package/dist/cli-B8otnZfX.mjs.map +0 -1
  188. package/dist/cli-DL19w4OE.cjs.map +0 -1
  189. package/dist/compose-BHVKLluX.cjs.map +0 -1
  190. package/dist/compose-DrEB_4F-.mjs.map +0 -1
  191. package/dist/credentials-C4KII3PD.mjs.map +0 -1
  192. package/dist/credentials-QBu7VgaQ.cjs.map +0 -1
  193. package/dist/deploy-C3Mhnmus.cjs +0 -556
  194. package/dist/deploy-C3Mhnmus.cjs.map +0 -1
  195. package/dist/deploy-DYIyIUYd.mjs +0 -527
  196. package/dist/deploy-DYIyIUYd.mjs.map +0 -1
  197. package/dist/engine-Cfx8fEZU.cjs.map +0 -1
  198. package/dist/github-CzBbs43W.mjs.map +0 -1
  199. package/dist/github-zneTMvnO.cjs.map +0 -1
  200. package/dist/secrets-DJteijZo.cjs.map +0 -1
  201. package/dist/secrets-DbPmAS4k.mjs.map +0 -1
  202. package/dist/seeds-BSL55F6q.mjs.map +0 -1
  203. package/dist/seeds-c-ByX9je.cjs.map +0 -1
  204. package/dist/sniffer-BTtGAtm3.mjs.map +0 -1
  205. package/dist/sniffer-Dq5BS98f.cjs.map +0 -1
  206. package/dist/stack-1PeLJS2j.cjs.map +0 -1
  207. package/dist/stack-Co4uZkAo.mjs.map +0 -1
  208. package/dist/stages-BI8JvPzI.cjs.map +0 -1
  209. package/dist/stages-DY-fQKmo.mjs.map +0 -1
  210. package/dist/types-B6lmD3en.d.mts.map +0 -1
  211. package/dist/types-BibpiHKB.d.cts.map +0 -1
  212. package/dist/workspace-Bzw7Zs82.mjs.map +0 -1
  213. package/dist/workspace-CHOB2Xg3.cjs.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"bundler-Dfsr6KXU.cjs","names":["require","createRequire","join","dirname","mkdir","existsSync","readFileSync","spawnSync","writeFile"],"sources":["../src/build/bundler.ts"],"sourcesContent":["import { spawnSync } from 'node:child_process';\nimport { existsSync, readFileSync } from 'node:fs';\nimport { mkdir, writeFile } from 'node:fs/promises';\nimport { createRequire } from 'node:module';\nimport { dirname, join } from 'node:path';\nimport type { Construct } from '@geekmidas/constructs';\n\n/**\n * Banner to inject into ESM bundle for CJS compatibility.\n * Creates a `require` function using Node's createRequire for packages\n * that internally use CommonJS require() for Node builtins.\n */\nconst ESM_CJS_COMPAT_BANNER =\n\t'import { createRequire } from \"module\"; const require = createRequire(import.meta.url);';\n\nexport interface BundleOptions {\n\t/** Entry point file (e.g., .gkm/server/server.ts) */\n\tentryPoint: string;\n\t/** Output directory for bundled files */\n\toutputDir: string;\n\t/** The bundle's file name in `outputDir`. Defaults to `server.mjs`. */\n\toutfile?: string;\n\t/** Minify the output (default: true) */\n\tminify: boolean;\n\t/** Generate sourcemaps (default: false) */\n\tsourcemap: boolean;\n\t/** Packages to exclude from bundling */\n\texternal: string[];\n\t/** Stage for secrets injection (optional) */\n\tstage?: string;\n\t/** Constructs to validate environment variables for */\n\tconstructs?: Construct[];\n}\n\nexport interface BundleResult {\n\t/** Path to the bundled output */\n\toutputPath: string;\n\t/** Ephemeral master key for deployment (only if stage was provided) */\n\tmasterKey?: string;\n}\n\n/**\n * The esbuild binary, resolved from this package rather than from PATH.\n *\n * It used to be `npx esbuild`, which is two assumptions: that esbuild is\n * installed somewhere npx can find, and that the *app's* directory is where to\n * look. Neither holds — the CLI did not depend on esbuild at all, so a deploy\n * run from an app that had not installed it failed at the bundle step with\n * `sh: esbuild: command not found`, after provisioning had already happened.\n *\n * The same fix `bin/gkm.mjs` makes for tsx: resolve from this package's own\n * `node_modules`, so the tool the CLI shells out to is the one it depends on.\n */\nfunction esbuildBinary(): string {\n\tconst require = createRequire(import.meta.url);\n\n\ttry {\n\t\t// The package root, then its bin — `require.resolve('esbuild')` gives the\n\t\t// JS entry point, which is a library rather than the CLI.\n\t\tconst pkg = require.resolve('esbuild/package.json');\n\t\treturn join(dirname(pkg), 'bin', 'esbuild');\n\t} catch {\n\t\t// Better a PATH lookup than a hard failure: a project that installed\n\t\t// esbuild itself still works.\n\t\treturn 'esbuild';\n\t}\n}\n\n/**\n * Collect the environment variables a build cannot proceed without.\n *\n * Uses the SnifferEnvironmentParser to detect which env vars each service\n * reads, and keeps only the ones it cannot do without. `markOptional` is what\n * separates them: the sniffer already knows which reads went through\n * `.optional()` or `.default()`, and asking for that distinction is the\n * difference between a build that stops and one that proceeds correctly.\n *\n * Without it, a key that is *absent by design* failed the build. A surface\n * publishes `AUTH_COOKIE_DOMAIN` only when there is a domain to widen a cookie\n * to — one host has nothing to share it with, so the derivation correctly\n * yields nothing, and Better Auth reads it as optional for exactly that\n * reason. Treating every sniffed read as required made the honest answer\n * indistinguishable from a missing secret.\n *\n * @param constructs - Array of constructs to analyze\n * @returns Deduplicated, sorted names of the required variables\n */\nasync function collectRequiredEnvVars(\n\tconstructs: Construct[],\n): Promise<string[]> {\n\t// A key read optionally by one construct and required by another stays\n\t// required: the strictest read is the one that fails at runtime, and taking\n\t// the union of the required reads is what says so.\n\tconst required = new Set<string>();\n\n\tfor (const construct of constructs) {\n\t\tfor (const name of await construct.getEnvironment({ markOptional: true })) {\n\t\t\tif (!name.endsWith('?')) required.add(name);\n\t\t}\n\t}\n\n\treturn Array.from(required).sort();\n}\n\n/**\n * Bundle the server application using esbuild.\n * Creates a fully standalone bundle with all dependencies included.\n *\n * @param options - Bundle configuration options\n * @returns Bundle result with output path and optional master key\n */\n\nexport async function bundleServer(\n\toptions: BundleOptions,\n): Promise<BundleResult> {\n\tconst {\n\t\tentryPoint,\n\t\toutputDir,\n\t\tminify,\n\t\tsourcemap,\n\t\texternal,\n\t\tstage,\n\t\tconstructs,\n\t} = options;\n\n\t// Ensure output directory exists\n\tawait mkdir(outputDir, { recursive: true });\n\n\tconst mjsOutput = join(outputDir, options.outfile ?? 'server.mjs');\n\n\t// Build command-line arguments for esbuild\n\tconst args = [\n\t\tesbuildBinary(),\n\t\tentryPoint,\n\t\t'--bundle',\n\t\t'--platform=node',\n\t\t'--target=node22',\n\t\t'--format=esm',\n\t\t`--outfile=${mjsOutput}`,\n\t\t'--packages=bundle', // Bundle all dependencies for standalone output\n\t\t`--banner:js=${ESM_CJS_COMPAT_BANNER}`, // CJS compatibility for packages like pino\n\t];\n\n\tif (minify) {\n\t\t// Names kept: an error's class name is what a log line's `err.type` and\n\t\t// a response's `name` say, and minified they read `_6`.\n\t\targs.push('--minify', '--keep-names');\n\t}\n\n\tif (sourcemap) {\n\t\targs.push('--sourcemap');\n\t}\n\n\t// Add external packages (user-specified)\n\tfor (const ext of external) {\n\t\targs.push(`--external:${ext}`);\n\t}\n\n\t// Handle secrets injection if stage is provided\n\tlet masterKey: string | undefined;\n\n\tif (stage) {\n\t\tconst {\n\t\t\ttoEmbeddableSecrets,\n\t\t\tvalidateEnvironmentVariables,\n\t\t\tinitStageSecrets,\n\t\t} = await import('../secrets/storage');\n\t\tconst { FileSecretsStore, secretsStoreFor } = await import(\n\t\t\t'../secrets/store'\n\t\t);\n\t\tconst { ConfigNotFound, loadWorkspaceSettings } = await import('../config');\n\t\tconst { encryptSecrets, generateDefineOptions } = await import(\n\t\t\t'../secrets/encryption'\n\t\t);\n\n\t\t// The stage's own store — SSM or Secrets Manager for a deployed stage\n\t\t// kept there. Outside\n\t\t// any workspace nothing names one, so it is the file.\n\t\tconst store = await loadWorkspaceSettings().then(\n\t\t\t(workspace) => secretsStoreFor(workspace, stage),\n\t\t\t(error) => {\n\t\t\t\tif (error instanceof ConfigNotFound) {\n\t\t\t\t\treturn new FileSecretsStore(process.cwd());\n\t\t\t\t}\n\t\t\t\tthrow error;\n\t\t\t},\n\t\t);\n\t\tlet secrets = await store.read(stage);\n\n\t\tif (!secrets) {\n\t\t\t// Auto-initialize secrets for the stage\n\t\t\tconsole.log(` Initializing secrets for stage \"${stage}\"...`);\n\t\t\tsecrets = initStageSecrets(stage);\n\t\t\tawait store.write(stage, secrets);\n\t\t\tconsole.log(` ✓ Created the \"${stage}\" secrets (${store.name})`);\n\t\t}\n\n\t\t// Validate environment variables if constructs are provided\n\t\tif (constructs && constructs.length > 0) {\n\t\t\tconsole.log(' Analyzing environment variable requirements...');\n\t\t\tconst requiredVars = await collectRequiredEnvVars(constructs);\n\n\t\t\tif (requiredVars.length > 0) {\n\t\t\t\tconst validation = validateEnvironmentVariables(requiredVars, secrets);\n\n\t\t\t\tif (!validation.valid) {\n\t\t\t\t\tconst errorMessage = [\n\t\t\t\t\t\t`Missing environment variables for stage \"${stage}\":`,\n\t\t\t\t\t\t'',\n\t\t\t\t\t\t...validation.missing.map((v) => ` ❌ ${v}`),\n\t\t\t\t\t\t'',\n\t\t\t\t\t\t'To fix this, either:',\n\t\t\t\t\t\t` 1. Add the missing variables to the \"${stage}\" secrets using:`,\n\t\t\t\t\t\t` gkm secrets:set <KEY> <VALUE> --stage ${stage}`,\n\t\t\t\t\t\t'',\n\t\t\t\t\t\t` 2. Or import from a JSON file:`,\n\t\t\t\t\t\t` gkm secrets:import secrets.json --stage ${stage}`,\n\t\t\t\t\t\t'',\n\t\t\t\t\t\t'Required variables:',\n\t\t\t\t\t\t...validation.required.map((v) =>\n\t\t\t\t\t\t\tvalidation.missing.includes(v) ? ` ❌ ${v}` : ` ✓ ${v}`,\n\t\t\t\t\t\t),\n\t\t\t\t\t].join('\\n');\n\n\t\t\t\t\tthrow new Error(errorMessage);\n\t\t\t\t}\n\n\t\t\t\tconsole.log(\n\t\t\t\t\t` ✓ All ${requiredVars.length} required environment variables found`,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\t// Convert to embeddable format and encrypt\n\t\tconst embeddable = toEmbeddableSecrets(secrets);\n\t\tconst encrypted = encryptSecrets(embeddable);\n\t\tmasterKey = encrypted.masterKey;\n\n\t\t// Add define options for build-time injection using esbuild's --define:KEY=VALUE format\n\t\tconst defines = generateDefineOptions(encrypted);\n\t\tfor (const [key, value] of Object.entries(defines)) {\n\t\t\t// `value` is already a JS string literal; quoting it again would\n\t\t\t// embed the quotes, and the IV would not parse as hex.\n\t\t\targs.push(`--define:${key}=${value}`);\n\t\t}\n\n\t\tconsole.log(` Secrets encrypted for stage \"${stage}\"`);\n\t} else {\n\t\t// Credentials encrypted elsewhere — an image build hands them in as a\n\t\t// BuildKit secret and writes them beside the app's `.gkm/server` — are\n\t\t// embedded as they are; whoever encrypted them holds the key.\n\t\tconst gkmDir = join(outputDir, '..', '..');\n\t\tconst encryptedPath = join(gkmDir, 'credentials.enc');\n\t\tconst ivPath = join(gkmDir, 'credentials.iv');\n\t\tif (existsSync(encryptedPath) && existsSync(ivPath)) {\n\t\t\tconst { generateDefineOptions } = await import('../secrets/encryption');\n\t\t\tconst defines = generateDefineOptions({\n\t\t\t\tencrypted: readFileSync(encryptedPath, 'utf-8').trim(),\n\t\t\t\tiv: readFileSync(ivPath, 'utf-8').trim(),\n\t\t\t\tmasterKey: '',\n\t\t\t});\n\t\t\tfor (const [key, value] of Object.entries(defines)) {\n\t\t\t\targs.push(`--define:${key}=${value}`);\n\t\t\t}\n\t\t\tconsole.log(' Embedded the encrypted credentials the build was given');\n\t\t}\n\t}\n\n\ttry {\n\t\t// Run esbuild with command-line arguments\n\t\tconst [cmd, ...cmdArgs] = args as [string, ...string[]];\n\t\tconst result = spawnSync(cmd, cmdArgs, {\n\t\t\tcwd: process.cwd(),\n\t\t\tstdio: 'inherit',\n\t\t\tshell: process.platform === 'win32', // Only use shell on Windows for npx resolution\n\t\t});\n\n\t\tif (result.error) {\n\t\t\tthrow result.error;\n\t\t}\n\t\tif (result.status !== 0) {\n\t\t\tthrow new Error(`esbuild exited with code ${result.status}`);\n\t\t}\n\n\t\t// Add shebang to the bundled file\n\t\tconst { readFile } = await import('node:fs/promises');\n\t\tconst content = await readFile(mjsOutput, 'utf-8');\n\t\tif (!content.startsWith('#!')) {\n\t\t\tawait writeFile(mjsOutput, `#!/usr/bin/env node\\n${content}`);\n\t\t}\n\t} catch (error) {\n\t\tthrow new Error(\n\t\t\t`Failed to bundle server: ${error instanceof Error ? error.message : 'Unknown error'}`,\n\t\t);\n\t}\n\n\treturn {\n\t\toutputPath: mjsOutput,\n\t\tmasterKey,\n\t};\n}\n"],"mappings":";;;;;;;;;;;AAYA,MAAM,wBACL;;;;;;;;;;;;;AAwCD,SAAS,gBAAwB;CAChC,MAAMA,aAAAA,GAAUC,YAAAA,cAAAA,CAAAA,QAAAA,KAAAA,CAAAA,CAAAA,cAAAA,UAAAA,CAAAA,CAAAA,IAA6B;CAE7C,IAAI;EAGH,MAAM,MAAMD,UAAQ,QAAQ,sBAAsB;EAClD,QAAA,GAAOE,UAAAA,KAAAA,EAAAA,GAAKC,UAAAA,QAAAA,CAAQ,GAAG,GAAG,OAAO,SAAS;CAC3C,QAAQ;EAGP,OAAO;CACR;AACD;;;;;;;;;;;;;;;;;;;;AAqBA,eAAe,uBACd,YACoB;CAIpB,MAAM,2BAAW,IAAI,IAAY;CAEjC,KAAK,MAAM,aAAa,YACvB,KAAK,MAAM,QAAQ,MAAM,UAAU,eAAe,EAAE,cAAc,KAAK,CAAC,GACvE,IAAI,CAAC,KAAK,SAAS,GAAG,GAAG,SAAS,IAAI,IAAI;CAI5C,OAAO,MAAM,KAAK,QAAQ,CAAC,CAAC,KAAK;AAClC;;;;;;;;AAUA,eAAsB,aACrB,SACwB;CACxB,MAAM,EACL,YACA,WACA,QACA,WACA,UACA,OACA,eACG;CAGJ,OAAA,GAAMC,iBAAAA,MAAAA,CAAM,WAAW,EAAE,WAAW,KAAK,CAAC;CAE1C,MAAM,aAAA,GAAYF,UAAAA,KAAAA,CAAK,WAAW,QAAQ,WAAW,YAAY;CAGjE,MAAM,OAAO;EACZ,cAAc;EACd;EACA;EACA;EACA;EACA;EACA,aAAa;EACb;EACA,eAAe;CAChB;CAEA,IAAI,QAGH,KAAK,KAAK,YAAY,cAAc;CAGrC,IAAI,WACH,KAAK,KAAK,aAAa;CAIxB,KAAK,MAAM,OAAO,UACjB,KAAK,KAAK,cAAc,KAAK;CAI9B,IAAI;CAEJ,IAAI,OAAO;EACV,MAAM,EACL,qBACA,8BACA,qBACG,MAAA,QAAA,QAAA,CAAA,CAAA,WAAA,QAAM,sBAAA,CAAA,CAAA,CAAA,MAAA,MAAA,EAAA,eAAA;EACV,MAAM,EAAE,kBAAkB,oBAAoB,MAAA,QAAA,QAAA,CAAA,CAAA,WAAA,QAAM,sBAAA,CAAA,CAAA,CAAA,MAAA,MAAA,EAAA,aAAA;EAGpD,MAAM,EAAE,gBAAgB,0BAA0B,MAAA,QAAA,QAAA,CAAA,CAAA,WAAA,QAAM,cAAA,CAAA;EACxD,MAAM,EAAE,gBAAgB,0BAA0B,MAAA,QAAA,QAAA,CAAA,CAAA,WAAA,QAAM,wBAAA,CAAA,CAAA,CAAA,MAAA,MAAA,EAAA,kBAAA;EAOxD,MAAM,QAAQ,MAAM,sBAAsB,CAAC,CAAC,MAC1C,cAAc,gBAAgB,WAAW,KAAK,IAC9C,UAAU;GACV,IAAI,iBAAiB,gBACpB,OAAO,IAAI,iBAAiB,QAAQ,IAAI,CAAC;GAE1C,MAAM;EACP,CACD;EACA,IAAI,UAAU,MAAM,MAAM,KAAK,KAAK;EAEpC,IAAI,CAAC,SAAS;GAEb,QAAQ,IAAI,qCAAqC,MAAM,KAAK;GAC5D,UAAU,iBAAiB,KAAK;GAChC,MAAM,MAAM,MAAM,OAAO,OAAO;GAChC,QAAQ,IAAI,oBAAoB,MAAM,aAAa,MAAM,KAAK,EAAE;EACjE;EAGA,IAAI,cAAc,WAAW,SAAS,GAAG;GACxC,QAAQ,IAAI,kDAAkD;GAC9D,MAAM,eAAe,MAAM,uBAAuB,UAAU;GAE5D,IAAI,aAAa,SAAS,GAAG;IAC5B,MAAM,aAAa,6BAA6B,cAAc,OAAO;IAErE,IAAI,CAAC,WAAW,OAAO;KACtB,MAAM,eAAe;MACpB,4CAA4C,MAAM;MAClD;MACA,GAAG,WAAW,QAAQ,KAAK,MAAM,OAAO,GAAG;MAC3C;MACA;MACA,0CAA0C,MAAM;MAChD,8CAA8C;MAC9C;MACA;MACA,gDAAgD;MAChD;MACA;MACA,GAAG,WAAW,SAAS,KAAK,MAC3B,WAAW,QAAQ,SAAS,CAAC,IAAI,OAAO,MAAM,OAAO,GACtD;KACD,CAAC,CAAC,KAAK,IAAI;KAEX,MAAM,IAAI,MAAM,YAAY;IAC7B;IAEA,QAAQ,IACP,WAAW,aAAa,OAAO,sCAChC;GACD;EACD;EAIA,MAAM,YAAY,eADC,oBAAoB,OACG,CAAC;EAC3C,YAAY,UAAU;EAGtB,MAAM,UAAU,sBAAsB,SAAS;EAC/C,KAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,OAAO,GAGhD,KAAK,KAAK,YAAY,IAAI,GAAG,OAAO;EAGrC,QAAQ,IAAI,kCAAkC,MAAM,EAAE;CACvD,OAAO;EAIN,MAAM,UAAA,GAASA,UAAAA,KAAAA,CAAK,WAAW,MAAM,IAAI;EACzC,MAAM,iBAAA,GAAgBA,UAAAA,KAAAA,CAAK,QAAQ,iBAAiB;EACpD,MAAM,UAAA,GAASA,UAAAA,KAAAA,CAAK,QAAQ,gBAAgB;EAC5C,KAAA,GAAIG,QAAAA,WAAAA,CAAW,aAAa,MAAA,GAAKA,QAAAA,WAAAA,CAAW,MAAM,GAAG;GACpD,MAAM,EAAE,0BAA0B,MAAA,QAAA,QAAA,CAAA,CAAA,WAAA,QAAM,wBAAA,CAAA,CAAA,CAAA,MAAA,MAAA,EAAA,kBAAA;GACxC,MAAM,UAAU,sBAAsB;IACrC,YAAA,GAAWC,QAAAA,aAAAA,CAAa,eAAe,OAAO,CAAC,CAAC,KAAK;IACrD,KAAA,GAAIA,QAAAA,aAAAA,CAAa,QAAQ,OAAO,CAAC,CAAC,KAAK;IACvC,WAAW;GACZ,CAAC;GACD,KAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,OAAO,GAChD,KAAK,KAAK,YAAY,IAAI,GAAG,OAAO;GAErC,QAAQ,IAAI,0DAA0D;EACvE;CACD;CAEA,IAAI;EAEH,MAAM,CAAC,KAAK,GAAG,WAAW;EAC1B,MAAM,UAAA,GAASC,mBAAAA,UAAAA,CAAU,KAAK,SAAS;GACtC,KAAK,QAAQ,IAAI;GACjB,OAAO;GACP,OAAO,QAAQ,aAAa;EAC7B,CAAC;EAED,IAAI,OAAO,OACV,MAAM,OAAO;EAEd,IAAI,OAAO,WAAW,GACrB,MAAM,IAAI,MAAM,4BAA4B,OAAO,QAAQ;EAI5D,MAAM,EAAE,aAAa,MAAM,OAAO;EAClC,MAAM,UAAU,MAAM,SAAS,WAAW,OAAO;EACjD,IAAI,CAAC,QAAQ,WAAW,IAAI,GAC3B,OAAA,GAAMC,iBAAAA,UAAAA,CAAU,WAAW,wBAAwB,SAAS;CAE9D,SAAS,OAAO;EACf,MAAM,IAAI,MACT,4BAA4B,iBAAiB,QAAQ,MAAM,UAAU,iBACtE;CACD;CAEA,OAAO;EACN,YAAY;EACZ;CACD;AACD"}
1
+ {"version":3,"file":"bundler-CI3elfZS.cjs","names":["require","createRequire","join","dirname","mkdir","existsSync","readFileSync","spawnSync","writeFile"],"sources":["../src/build/bundler.ts"],"sourcesContent":["import { spawnSync } from 'node:child_process';\nimport { existsSync, readFileSync } from 'node:fs';\nimport { mkdir, writeFile } from 'node:fs/promises';\nimport { createRequire } from 'node:module';\nimport { dirname, join } from 'node:path';\nimport type { Construct } from '@geekmidas/constructs';\n\n/**\n * Banner to inject into ESM bundle for CJS compatibility.\n * Creates a `require` function using Node's createRequire for packages\n * that internally use CommonJS require() for Node builtins.\n */\nconst ESM_CJS_COMPAT_BANNER =\n\t'import { createRequire } from \"module\"; const require = createRequire(import.meta.url);';\n\nexport interface BundleOptions {\n\t/** Entry point file (e.g., .gkm/server/server.ts) */\n\tentryPoint: string;\n\t/** Output directory for bundled files */\n\toutputDir: string;\n\t/** The bundle's file name in `outputDir`. Defaults to `server.mjs`. */\n\toutfile?: string;\n\t/** Minify the output (default: true) */\n\tminify: boolean;\n\t/** Generate sourcemaps (default: false) */\n\tsourcemap: boolean;\n\t/** Packages to exclude from bundling */\n\texternal: string[];\n\t/** Stage for secrets injection (optional) */\n\tstage?: string;\n\t/** Constructs to validate environment variables for */\n\tconstructs?: Construct[];\n}\n\nexport interface BundleResult {\n\t/** Path to the bundled output */\n\toutputPath: string;\n\t/** Ephemeral master key for deployment (only if stage was provided) */\n\tmasterKey?: string;\n}\n\n/**\n * The esbuild binary, resolved from this package rather than from PATH.\n *\n * It used to be `npx esbuild`, which is two assumptions: that esbuild is\n * installed somewhere npx can find, and that the *app's* directory is where to\n * look. Neither holds — the CLI did not depend on esbuild at all, so a deploy\n * run from an app that had not installed it failed at the bundle step with\n * `sh: esbuild: command not found`, after provisioning had already happened.\n *\n * The same fix `bin/gkm.mjs` makes for tsx: resolve from this package's own\n * `node_modules`, so the tool the CLI shells out to is the one it depends on.\n */\nfunction esbuildBinary(): string {\n\tconst require = createRequire(import.meta.url);\n\n\ttry {\n\t\t// The package root, then its bin — `require.resolve('esbuild')` gives the\n\t\t// JS entry point, which is a library rather than the CLI.\n\t\tconst pkg = require.resolve('esbuild/package.json');\n\t\treturn join(dirname(pkg), 'bin', 'esbuild');\n\t} catch {\n\t\t// Better a PATH lookup than a hard failure: a project that installed\n\t\t// esbuild itself still works.\n\t\treturn 'esbuild';\n\t}\n}\n\n/**\n * Collect the environment variables a build cannot proceed without.\n *\n * Uses the SnifferEnvironmentParser to detect which env vars each service\n * reads, and keeps only the ones it cannot do without. `markOptional` is what\n * separates them: the sniffer already knows which reads went through\n * `.optional()` or `.default()`, and asking for that distinction is the\n * difference between a build that stops and one that proceeds correctly.\n *\n * Without it, a key that is *absent by design* failed the build. A surface\n * publishes `AUTH_COOKIE_DOMAIN` only when there is a domain to widen a cookie\n * to — one host has nothing to share it with, so the derivation correctly\n * yields nothing, and Better Auth reads it as optional for exactly that\n * reason. Treating every sniffed read as required made the honest answer\n * indistinguishable from a missing secret.\n *\n * @param constructs - Array of constructs to analyze\n * @returns Deduplicated, sorted names of the required variables\n */\nasync function collectRequiredEnvVars(\n\tconstructs: Construct[],\n): Promise<string[]> {\n\t// A key read optionally by one construct and required by another stays\n\t// required: the strictest read is the one that fails at runtime, and taking\n\t// the union of the required reads is what says so.\n\tconst required = new Set<string>();\n\n\tfor (const construct of constructs) {\n\t\tfor (const name of await construct.getEnvironment({ markOptional: true })) {\n\t\t\tif (!name.endsWith('?')) required.add(name);\n\t\t}\n\t}\n\n\treturn Array.from(required).sort();\n}\n\n/**\n * Bundle the server application using esbuild.\n * Creates a fully standalone bundle with all dependencies included.\n *\n * @param options - Bundle configuration options\n * @returns Bundle result with output path and optional master key\n */\n\nexport async function bundleServer(\n\toptions: BundleOptions,\n): Promise<BundleResult> {\n\tconst {\n\t\tentryPoint,\n\t\toutputDir,\n\t\tminify,\n\t\tsourcemap,\n\t\texternal,\n\t\tstage,\n\t\tconstructs,\n\t} = options;\n\n\t// Ensure output directory exists\n\tawait mkdir(outputDir, { recursive: true });\n\n\tconst mjsOutput = join(outputDir, options.outfile ?? 'server.mjs');\n\n\t// Build command-line arguments for esbuild\n\tconst args = [\n\t\tesbuildBinary(),\n\t\tentryPoint,\n\t\t'--bundle',\n\t\t'--platform=node',\n\t\t'--target=node22',\n\t\t'--format=esm',\n\t\t`--outfile=${mjsOutput}`,\n\t\t'--packages=bundle', // Bundle all dependencies for standalone output\n\t\t`--banner:js=${ESM_CJS_COMPAT_BANNER}`, // CJS compatibility for packages like pino\n\t];\n\n\tif (minify) {\n\t\t// Names kept: an error's class name is what a log line's `err.type` and\n\t\t// a response's `name` say, and minified they read `_6`.\n\t\targs.push('--minify', '--keep-names');\n\t}\n\n\tif (sourcemap) {\n\t\targs.push('--sourcemap');\n\t}\n\n\t// Add external packages (user-specified)\n\tfor (const ext of external) {\n\t\targs.push(`--external:${ext}`);\n\t}\n\n\t// Handle secrets injection if stage is provided\n\tlet masterKey: string | undefined;\n\n\tif (stage) {\n\t\tconst {\n\t\t\ttoEmbeddableSecrets,\n\t\t\tvalidateEnvironmentVariables,\n\t\t\tinitStageSecrets,\n\t\t} = await import('../secrets/storage');\n\t\tconst { FileSecretsStore, secretsStoreFor } = await import(\n\t\t\t'../secrets/store'\n\t\t);\n\t\tconst { ConfigNotFound, loadWorkspaceSettings } = await import('../config');\n\t\tconst { encryptSecrets, generateDefineOptions } = await import(\n\t\t\t'../secrets/encryption'\n\t\t);\n\n\t\t// The stage's own store — SSM or Secrets Manager for a deployed stage\n\t\t// kept there. Outside\n\t\t// any workspace nothing names one, so it is the file.\n\t\tconst store = await loadWorkspaceSettings().then(\n\t\t\t(workspace) => secretsStoreFor(workspace, stage),\n\t\t\t(error) => {\n\t\t\t\tif (error instanceof ConfigNotFound) {\n\t\t\t\t\treturn new FileSecretsStore(process.cwd());\n\t\t\t\t}\n\t\t\t\tthrow error;\n\t\t\t},\n\t\t);\n\t\tlet secrets = await store.read(stage);\n\n\t\tif (!secrets) {\n\t\t\t// Auto-initialize secrets for the stage\n\t\t\tconsole.log(` Initializing secrets for stage \"${stage}\"...`);\n\t\t\tsecrets = initStageSecrets(stage);\n\t\t\tawait store.write(stage, secrets);\n\t\t\tconsole.log(` ✓ Created the \"${stage}\" secrets (${store.name})`);\n\t\t}\n\n\t\t// Validate environment variables if constructs are provided\n\t\tif (constructs && constructs.length > 0) {\n\t\t\tconsole.log(' Analyzing environment variable requirements...');\n\t\t\tconst requiredVars = await collectRequiredEnvVars(constructs);\n\n\t\t\tif (requiredVars.length > 0) {\n\t\t\t\tconst validation = validateEnvironmentVariables(requiredVars, secrets);\n\n\t\t\t\tif (!validation.valid) {\n\t\t\t\t\tconst errorMessage = [\n\t\t\t\t\t\t`Missing environment variables for stage \"${stage}\":`,\n\t\t\t\t\t\t'',\n\t\t\t\t\t\t...validation.missing.map((v) => ` ❌ ${v}`),\n\t\t\t\t\t\t'',\n\t\t\t\t\t\t'To fix this, either:',\n\t\t\t\t\t\t` 1. Add the missing variables to the \"${stage}\" secrets using:`,\n\t\t\t\t\t\t` gkm secrets:set <KEY> <VALUE> --stage ${stage}`,\n\t\t\t\t\t\t'',\n\t\t\t\t\t\t` 2. Or import from a JSON file:`,\n\t\t\t\t\t\t` gkm secrets:import secrets.json --stage ${stage}`,\n\t\t\t\t\t\t'',\n\t\t\t\t\t\t'Required variables:',\n\t\t\t\t\t\t...validation.required.map((v) =>\n\t\t\t\t\t\t\tvalidation.missing.includes(v) ? ` ❌ ${v}` : ` ✓ ${v}`,\n\t\t\t\t\t\t),\n\t\t\t\t\t].join('\\n');\n\n\t\t\t\t\tthrow new Error(errorMessage);\n\t\t\t\t}\n\n\t\t\t\tconsole.log(\n\t\t\t\t\t` ✓ All ${requiredVars.length} required environment variables found`,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\t// Convert to embeddable format and encrypt\n\t\tconst embeddable = toEmbeddableSecrets(secrets);\n\t\tconst encrypted = encryptSecrets(embeddable);\n\t\tmasterKey = encrypted.masterKey;\n\n\t\t// Add define options for build-time injection using esbuild's --define:KEY=VALUE format\n\t\tconst defines = generateDefineOptions(encrypted);\n\t\tfor (const [key, value] of Object.entries(defines)) {\n\t\t\t// `value` is already a JS string literal; quoting it again would\n\t\t\t// embed the quotes, and the IV would not parse as hex.\n\t\t\targs.push(`--define:${key}=${value}`);\n\t\t}\n\n\t\tconsole.log(` Secrets encrypted for stage \"${stage}\"`);\n\t} else {\n\t\t// Credentials encrypted elsewhere — an image build hands them in as a\n\t\t// BuildKit secret and writes them beside the app's `.gkm/server` — are\n\t\t// embedded as they are; whoever encrypted them holds the key.\n\t\tconst gkmDir = join(outputDir, '..', '..');\n\t\tconst encryptedPath = join(gkmDir, 'credentials.enc');\n\t\tconst ivPath = join(gkmDir, 'credentials.iv');\n\t\tif (existsSync(encryptedPath) && existsSync(ivPath)) {\n\t\t\tconst { generateDefineOptions } = await import('../secrets/encryption');\n\t\t\tconst defines = generateDefineOptions({\n\t\t\t\tencrypted: readFileSync(encryptedPath, 'utf-8').trim(),\n\t\t\t\tiv: readFileSync(ivPath, 'utf-8').trim(),\n\t\t\t\tmasterKey: '',\n\t\t\t});\n\t\t\tfor (const [key, value] of Object.entries(defines)) {\n\t\t\t\targs.push(`--define:${key}=${value}`);\n\t\t\t}\n\t\t\tconsole.log(' Embedded the encrypted credentials the build was given');\n\t\t}\n\t}\n\n\ttry {\n\t\t// Run esbuild with command-line arguments\n\t\tconst [cmd, ...cmdArgs] = args as [string, ...string[]];\n\t\tconst result = spawnSync(cmd, cmdArgs, {\n\t\t\tcwd: process.cwd(),\n\t\t\tstdio: 'inherit',\n\t\t\tshell: process.platform === 'win32', // Only use shell on Windows for npx resolution\n\t\t});\n\n\t\tif (result.error) {\n\t\t\tthrow result.error;\n\t\t}\n\t\tif (result.status !== 0) {\n\t\t\tthrow new Error(`esbuild exited with code ${result.status}`);\n\t\t}\n\n\t\t// Add shebang to the bundled file\n\t\tconst { readFile } = await import('node:fs/promises');\n\t\tconst content = await readFile(mjsOutput, 'utf-8');\n\t\tif (!content.startsWith('#!')) {\n\t\t\tawait writeFile(mjsOutput, `#!/usr/bin/env node\\n${content}`);\n\t\t}\n\t} catch (error) {\n\t\tthrow new Error(\n\t\t\t`Failed to bundle server: ${error instanceof Error ? error.message : 'Unknown error'}`,\n\t\t);\n\t}\n\n\treturn {\n\t\toutputPath: mjsOutput,\n\t\tmasterKey,\n\t};\n}\n"],"mappings":"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"}
@@ -82,10 +82,10 @@ async function bundleServer(options) {
82
82
  for (const ext of external) args.push(`--external:${ext}`);
83
83
  let masterKey;
84
84
  if (stage) {
85
- const { toEmbeddableSecrets, validateEnvironmentVariables, initStageSecrets } = await import("./seeds-BSL55F6q.mjs").then((n) => n.dr);
86
- const { FileSecretsStore, secretsStoreFor } = await import("./seeds-BSL55F6q.mjs").then((n) => n.Yn);
85
+ const { toEmbeddableSecrets, validateEnvironmentVariables, initStageSecrets } = await import("./seeds-CoKkrSny.mjs").then((n) => n.Kn);
86
+ const { FileSecretsStore, secretsStoreFor } = await import("./seeds-CoKkrSny.mjs").then((n) => n.An);
87
87
  const { ConfigNotFound, loadWorkspaceSettings } = await import("./config.mjs");
88
- const { encryptSecrets, generateDefineOptions } = await import("./sniffer-BTtGAtm3.mjs").then((n) => n.d);
88
+ const { encryptSecrets, generateDefineOptions } = await import("./sniffer-CFRzIrby.mjs").then((n) => n.w);
89
89
  const store = await loadWorkspaceSettings().then((workspace) => secretsStoreFor(workspace, stage), (error) => {
90
90
  if (error instanceof ConfigNotFound) return new FileSecretsStore(process.cwd());
91
91
  throw error;
@@ -133,7 +133,7 @@ async function bundleServer(options) {
133
133
  const encryptedPath = join(gkmDir, "credentials.enc");
134
134
  const ivPath = join(gkmDir, "credentials.iv");
135
135
  if (existsSync(encryptedPath) && existsSync(ivPath)) {
136
- const { generateDefineOptions } = await import("./sniffer-BTtGAtm3.mjs").then((n) => n.d);
136
+ const { generateDefineOptions } = await import("./sniffer-CFRzIrby.mjs").then((n) => n.w);
137
137
  const defines = generateDefineOptions({
138
138
  encrypted: readFileSync(encryptedPath, "utf-8").trim(),
139
139
  iv: readFileSync(ivPath, "utf-8").trim(),
@@ -166,4 +166,4 @@ async function bundleServer(options) {
166
166
  //#endregion
167
167
  export { bundleServer };
168
168
 
169
- //# sourceMappingURL=bundler-BWrh-AJH.mjs.map
169
+ //# sourceMappingURL=bundler-ywR3C1B_.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"bundler-BWrh-AJH.mjs","names":[],"sources":["../src/build/bundler.ts"],"sourcesContent":["import { spawnSync } from 'node:child_process';\nimport { existsSync, readFileSync } from 'node:fs';\nimport { mkdir, writeFile } from 'node:fs/promises';\nimport { createRequire } from 'node:module';\nimport { dirname, join } from 'node:path';\nimport type { Construct } from '@geekmidas/constructs';\n\n/**\n * Banner to inject into ESM bundle for CJS compatibility.\n * Creates a `require` function using Node's createRequire for packages\n * that internally use CommonJS require() for Node builtins.\n */\nconst ESM_CJS_COMPAT_BANNER =\n\t'import { createRequire } from \"module\"; const require = createRequire(import.meta.url);';\n\nexport interface BundleOptions {\n\t/** Entry point file (e.g., .gkm/server/server.ts) */\n\tentryPoint: string;\n\t/** Output directory for bundled files */\n\toutputDir: string;\n\t/** The bundle's file name in `outputDir`. Defaults to `server.mjs`. */\n\toutfile?: string;\n\t/** Minify the output (default: true) */\n\tminify: boolean;\n\t/** Generate sourcemaps (default: false) */\n\tsourcemap: boolean;\n\t/** Packages to exclude from bundling */\n\texternal: string[];\n\t/** Stage for secrets injection (optional) */\n\tstage?: string;\n\t/** Constructs to validate environment variables for */\n\tconstructs?: Construct[];\n}\n\nexport interface BundleResult {\n\t/** Path to the bundled output */\n\toutputPath: string;\n\t/** Ephemeral master key for deployment (only if stage was provided) */\n\tmasterKey?: string;\n}\n\n/**\n * The esbuild binary, resolved from this package rather than from PATH.\n *\n * It used to be `npx esbuild`, which is two assumptions: that esbuild is\n * installed somewhere npx can find, and that the *app's* directory is where to\n * look. Neither holds — the CLI did not depend on esbuild at all, so a deploy\n * run from an app that had not installed it failed at the bundle step with\n * `sh: esbuild: command not found`, after provisioning had already happened.\n *\n * The same fix `bin/gkm.mjs` makes for tsx: resolve from this package's own\n * `node_modules`, so the tool the CLI shells out to is the one it depends on.\n */\nfunction esbuildBinary(): string {\n\tconst require = createRequire(import.meta.url);\n\n\ttry {\n\t\t// The package root, then its bin — `require.resolve('esbuild')` gives the\n\t\t// JS entry point, which is a library rather than the CLI.\n\t\tconst pkg = require.resolve('esbuild/package.json');\n\t\treturn join(dirname(pkg), 'bin', 'esbuild');\n\t} catch {\n\t\t// Better a PATH lookup than a hard failure: a project that installed\n\t\t// esbuild itself still works.\n\t\treturn 'esbuild';\n\t}\n}\n\n/**\n * Collect the environment variables a build cannot proceed without.\n *\n * Uses the SnifferEnvironmentParser to detect which env vars each service\n * reads, and keeps only the ones it cannot do without. `markOptional` is what\n * separates them: the sniffer already knows which reads went through\n * `.optional()` or `.default()`, and asking for that distinction is the\n * difference between a build that stops and one that proceeds correctly.\n *\n * Without it, a key that is *absent by design* failed the build. A surface\n * publishes `AUTH_COOKIE_DOMAIN` only when there is a domain to widen a cookie\n * to — one host has nothing to share it with, so the derivation correctly\n * yields nothing, and Better Auth reads it as optional for exactly that\n * reason. Treating every sniffed read as required made the honest answer\n * indistinguishable from a missing secret.\n *\n * @param constructs - Array of constructs to analyze\n * @returns Deduplicated, sorted names of the required variables\n */\nasync function collectRequiredEnvVars(\n\tconstructs: Construct[],\n): Promise<string[]> {\n\t// A key read optionally by one construct and required by another stays\n\t// required: the strictest read is the one that fails at runtime, and taking\n\t// the union of the required reads is what says so.\n\tconst required = new Set<string>();\n\n\tfor (const construct of constructs) {\n\t\tfor (const name of await construct.getEnvironment({ markOptional: true })) {\n\t\t\tif (!name.endsWith('?')) required.add(name);\n\t\t}\n\t}\n\n\treturn Array.from(required).sort();\n}\n\n/**\n * Bundle the server application using esbuild.\n * Creates a fully standalone bundle with all dependencies included.\n *\n * @param options - Bundle configuration options\n * @returns Bundle result with output path and optional master key\n */\n\nexport async function bundleServer(\n\toptions: BundleOptions,\n): Promise<BundleResult> {\n\tconst {\n\t\tentryPoint,\n\t\toutputDir,\n\t\tminify,\n\t\tsourcemap,\n\t\texternal,\n\t\tstage,\n\t\tconstructs,\n\t} = options;\n\n\t// Ensure output directory exists\n\tawait mkdir(outputDir, { recursive: true });\n\n\tconst mjsOutput = join(outputDir, options.outfile ?? 'server.mjs');\n\n\t// Build command-line arguments for esbuild\n\tconst args = [\n\t\tesbuildBinary(),\n\t\tentryPoint,\n\t\t'--bundle',\n\t\t'--platform=node',\n\t\t'--target=node22',\n\t\t'--format=esm',\n\t\t`--outfile=${mjsOutput}`,\n\t\t'--packages=bundle', // Bundle all dependencies for standalone output\n\t\t`--banner:js=${ESM_CJS_COMPAT_BANNER}`, // CJS compatibility for packages like pino\n\t];\n\n\tif (minify) {\n\t\t// Names kept: an error's class name is what a log line's `err.type` and\n\t\t// a response's `name` say, and minified they read `_6`.\n\t\targs.push('--minify', '--keep-names');\n\t}\n\n\tif (sourcemap) {\n\t\targs.push('--sourcemap');\n\t}\n\n\t// Add external packages (user-specified)\n\tfor (const ext of external) {\n\t\targs.push(`--external:${ext}`);\n\t}\n\n\t// Handle secrets injection if stage is provided\n\tlet masterKey: string | undefined;\n\n\tif (stage) {\n\t\tconst {\n\t\t\ttoEmbeddableSecrets,\n\t\t\tvalidateEnvironmentVariables,\n\t\t\tinitStageSecrets,\n\t\t} = await import('../secrets/storage');\n\t\tconst { FileSecretsStore, secretsStoreFor } = await import(\n\t\t\t'../secrets/store'\n\t\t);\n\t\tconst { ConfigNotFound, loadWorkspaceSettings } = await import('../config');\n\t\tconst { encryptSecrets, generateDefineOptions } = await import(\n\t\t\t'../secrets/encryption'\n\t\t);\n\n\t\t// The stage's own store — SSM or Secrets Manager for a deployed stage\n\t\t// kept there. Outside\n\t\t// any workspace nothing names one, so it is the file.\n\t\tconst store = await loadWorkspaceSettings().then(\n\t\t\t(workspace) => secretsStoreFor(workspace, stage),\n\t\t\t(error) => {\n\t\t\t\tif (error instanceof ConfigNotFound) {\n\t\t\t\t\treturn new FileSecretsStore(process.cwd());\n\t\t\t\t}\n\t\t\t\tthrow error;\n\t\t\t},\n\t\t);\n\t\tlet secrets = await store.read(stage);\n\n\t\tif (!secrets) {\n\t\t\t// Auto-initialize secrets for the stage\n\t\t\tconsole.log(` Initializing secrets for stage \"${stage}\"...`);\n\t\t\tsecrets = initStageSecrets(stage);\n\t\t\tawait store.write(stage, secrets);\n\t\t\tconsole.log(` ✓ Created the \"${stage}\" secrets (${store.name})`);\n\t\t}\n\n\t\t// Validate environment variables if constructs are provided\n\t\tif (constructs && constructs.length > 0) {\n\t\t\tconsole.log(' Analyzing environment variable requirements...');\n\t\t\tconst requiredVars = await collectRequiredEnvVars(constructs);\n\n\t\t\tif (requiredVars.length > 0) {\n\t\t\t\tconst validation = validateEnvironmentVariables(requiredVars, secrets);\n\n\t\t\t\tif (!validation.valid) {\n\t\t\t\t\tconst errorMessage = [\n\t\t\t\t\t\t`Missing environment variables for stage \"${stage}\":`,\n\t\t\t\t\t\t'',\n\t\t\t\t\t\t...validation.missing.map((v) => ` ❌ ${v}`),\n\t\t\t\t\t\t'',\n\t\t\t\t\t\t'To fix this, either:',\n\t\t\t\t\t\t` 1. Add the missing variables to the \"${stage}\" secrets using:`,\n\t\t\t\t\t\t` gkm secrets:set <KEY> <VALUE> --stage ${stage}`,\n\t\t\t\t\t\t'',\n\t\t\t\t\t\t` 2. Or import from a JSON file:`,\n\t\t\t\t\t\t` gkm secrets:import secrets.json --stage ${stage}`,\n\t\t\t\t\t\t'',\n\t\t\t\t\t\t'Required variables:',\n\t\t\t\t\t\t...validation.required.map((v) =>\n\t\t\t\t\t\t\tvalidation.missing.includes(v) ? ` ❌ ${v}` : ` ✓ ${v}`,\n\t\t\t\t\t\t),\n\t\t\t\t\t].join('\\n');\n\n\t\t\t\t\tthrow new Error(errorMessage);\n\t\t\t\t}\n\n\t\t\t\tconsole.log(\n\t\t\t\t\t` ✓ All ${requiredVars.length} required environment variables found`,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\t// Convert to embeddable format and encrypt\n\t\tconst embeddable = toEmbeddableSecrets(secrets);\n\t\tconst encrypted = encryptSecrets(embeddable);\n\t\tmasterKey = encrypted.masterKey;\n\n\t\t// Add define options for build-time injection using esbuild's --define:KEY=VALUE format\n\t\tconst defines = generateDefineOptions(encrypted);\n\t\tfor (const [key, value] of Object.entries(defines)) {\n\t\t\t// `value` is already a JS string literal; quoting it again would\n\t\t\t// embed the quotes, and the IV would not parse as hex.\n\t\t\targs.push(`--define:${key}=${value}`);\n\t\t}\n\n\t\tconsole.log(` Secrets encrypted for stage \"${stage}\"`);\n\t} else {\n\t\t// Credentials encrypted elsewhere — an image build hands them in as a\n\t\t// BuildKit secret and writes them beside the app's `.gkm/server` — are\n\t\t// embedded as they are; whoever encrypted them holds the key.\n\t\tconst gkmDir = join(outputDir, '..', '..');\n\t\tconst encryptedPath = join(gkmDir, 'credentials.enc');\n\t\tconst ivPath = join(gkmDir, 'credentials.iv');\n\t\tif (existsSync(encryptedPath) && existsSync(ivPath)) {\n\t\t\tconst { generateDefineOptions } = await import('../secrets/encryption');\n\t\t\tconst defines = generateDefineOptions({\n\t\t\t\tencrypted: readFileSync(encryptedPath, 'utf-8').trim(),\n\t\t\t\tiv: readFileSync(ivPath, 'utf-8').trim(),\n\t\t\t\tmasterKey: '',\n\t\t\t});\n\t\t\tfor (const [key, value] of Object.entries(defines)) {\n\t\t\t\targs.push(`--define:${key}=${value}`);\n\t\t\t}\n\t\t\tconsole.log(' Embedded the encrypted credentials the build was given');\n\t\t}\n\t}\n\n\ttry {\n\t\t// Run esbuild with command-line arguments\n\t\tconst [cmd, ...cmdArgs] = args as [string, ...string[]];\n\t\tconst result = spawnSync(cmd, cmdArgs, {\n\t\t\tcwd: process.cwd(),\n\t\t\tstdio: 'inherit',\n\t\t\tshell: process.platform === 'win32', // Only use shell on Windows for npx resolution\n\t\t});\n\n\t\tif (result.error) {\n\t\t\tthrow result.error;\n\t\t}\n\t\tif (result.status !== 0) {\n\t\t\tthrow new Error(`esbuild exited with code ${result.status}`);\n\t\t}\n\n\t\t// Add shebang to the bundled file\n\t\tconst { readFile } = await import('node:fs/promises');\n\t\tconst content = await readFile(mjsOutput, 'utf-8');\n\t\tif (!content.startsWith('#!')) {\n\t\t\tawait writeFile(mjsOutput, `#!/usr/bin/env node\\n${content}`);\n\t\t}\n\t} catch (error) {\n\t\tthrow new Error(\n\t\t\t`Failed to bundle server: ${error instanceof Error ? error.message : 'Unknown error'}`,\n\t\t);\n\t}\n\n\treturn {\n\t\toutputPath: mjsOutput,\n\t\tmasterKey,\n\t};\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"bundler-ywR3C1B_.mjs","names":[],"sources":["../src/build/bundler.ts"],"sourcesContent":["import { spawnSync } from 'node:child_process';\nimport { existsSync, readFileSync } from 'node:fs';\nimport { mkdir, writeFile } from 'node:fs/promises';\nimport { createRequire } from 'node:module';\nimport { dirname, join } from 'node:path';\nimport type { Construct } from '@geekmidas/constructs';\n\n/**\n * Banner to inject into ESM bundle for CJS compatibility.\n * Creates a `require` function using Node's createRequire for packages\n * that internally use CommonJS require() for Node builtins.\n */\nconst ESM_CJS_COMPAT_BANNER =\n\t'import { createRequire } from \"module\"; const require = createRequire(import.meta.url);';\n\nexport interface BundleOptions {\n\t/** Entry point file (e.g., .gkm/server/server.ts) */\n\tentryPoint: string;\n\t/** Output directory for bundled files */\n\toutputDir: string;\n\t/** The bundle's file name in `outputDir`. Defaults to `server.mjs`. */\n\toutfile?: string;\n\t/** Minify the output (default: true) */\n\tminify: boolean;\n\t/** Generate sourcemaps (default: false) */\n\tsourcemap: boolean;\n\t/** Packages to exclude from bundling */\n\texternal: string[];\n\t/** Stage for secrets injection (optional) */\n\tstage?: string;\n\t/** Constructs to validate environment variables for */\n\tconstructs?: Construct[];\n}\n\nexport interface BundleResult {\n\t/** Path to the bundled output */\n\toutputPath: string;\n\t/** Ephemeral master key for deployment (only if stage was provided) */\n\tmasterKey?: string;\n}\n\n/**\n * The esbuild binary, resolved from this package rather than from PATH.\n *\n * It used to be `npx esbuild`, which is two assumptions: that esbuild is\n * installed somewhere npx can find, and that the *app's* directory is where to\n * look. Neither holds — the CLI did not depend on esbuild at all, so a deploy\n * run from an app that had not installed it failed at the bundle step with\n * `sh: esbuild: command not found`, after provisioning had already happened.\n *\n * The same fix `bin/gkm.mjs` makes for tsx: resolve from this package's own\n * `node_modules`, so the tool the CLI shells out to is the one it depends on.\n */\nfunction esbuildBinary(): string {\n\tconst require = createRequire(import.meta.url);\n\n\ttry {\n\t\t// The package root, then its bin — `require.resolve('esbuild')` gives the\n\t\t// JS entry point, which is a library rather than the CLI.\n\t\tconst pkg = require.resolve('esbuild/package.json');\n\t\treturn join(dirname(pkg), 'bin', 'esbuild');\n\t} catch {\n\t\t// Better a PATH lookup than a hard failure: a project that installed\n\t\t// esbuild itself still works.\n\t\treturn 'esbuild';\n\t}\n}\n\n/**\n * Collect the environment variables a build cannot proceed without.\n *\n * Uses the SnifferEnvironmentParser to detect which env vars each service\n * reads, and keeps only the ones it cannot do without. `markOptional` is what\n * separates them: the sniffer already knows which reads went through\n * `.optional()` or `.default()`, and asking for that distinction is the\n * difference between a build that stops and one that proceeds correctly.\n *\n * Without it, a key that is *absent by design* failed the build. A surface\n * publishes `AUTH_COOKIE_DOMAIN` only when there is a domain to widen a cookie\n * to — one host has nothing to share it with, so the derivation correctly\n * yields nothing, and Better Auth reads it as optional for exactly that\n * reason. Treating every sniffed read as required made the honest answer\n * indistinguishable from a missing secret.\n *\n * @param constructs - Array of constructs to analyze\n * @returns Deduplicated, sorted names of the required variables\n */\nasync function collectRequiredEnvVars(\n\tconstructs: Construct[],\n): Promise<string[]> {\n\t// A key read optionally by one construct and required by another stays\n\t// required: the strictest read is the one that fails at runtime, and taking\n\t// the union of the required reads is what says so.\n\tconst required = new Set<string>();\n\n\tfor (const construct of constructs) {\n\t\tfor (const name of await construct.getEnvironment({ markOptional: true })) {\n\t\t\tif (!name.endsWith('?')) required.add(name);\n\t\t}\n\t}\n\n\treturn Array.from(required).sort();\n}\n\n/**\n * Bundle the server application using esbuild.\n * Creates a fully standalone bundle with all dependencies included.\n *\n * @param options - Bundle configuration options\n * @returns Bundle result with output path and optional master key\n */\n\nexport async function bundleServer(\n\toptions: BundleOptions,\n): Promise<BundleResult> {\n\tconst {\n\t\tentryPoint,\n\t\toutputDir,\n\t\tminify,\n\t\tsourcemap,\n\t\texternal,\n\t\tstage,\n\t\tconstructs,\n\t} = options;\n\n\t// Ensure output directory exists\n\tawait mkdir(outputDir, { recursive: true });\n\n\tconst mjsOutput = join(outputDir, options.outfile ?? 'server.mjs');\n\n\t// Build command-line arguments for esbuild\n\tconst args = [\n\t\tesbuildBinary(),\n\t\tentryPoint,\n\t\t'--bundle',\n\t\t'--platform=node',\n\t\t'--target=node22',\n\t\t'--format=esm',\n\t\t`--outfile=${mjsOutput}`,\n\t\t'--packages=bundle', // Bundle all dependencies for standalone output\n\t\t`--banner:js=${ESM_CJS_COMPAT_BANNER}`, // CJS compatibility for packages like pino\n\t];\n\n\tif (minify) {\n\t\t// Names kept: an error's class name is what a log line's `err.type` and\n\t\t// a response's `name` say, and minified they read `_6`.\n\t\targs.push('--minify', '--keep-names');\n\t}\n\n\tif (sourcemap) {\n\t\targs.push('--sourcemap');\n\t}\n\n\t// Add external packages (user-specified)\n\tfor (const ext of external) {\n\t\targs.push(`--external:${ext}`);\n\t}\n\n\t// Handle secrets injection if stage is provided\n\tlet masterKey: string | undefined;\n\n\tif (stage) {\n\t\tconst {\n\t\t\ttoEmbeddableSecrets,\n\t\t\tvalidateEnvironmentVariables,\n\t\t\tinitStageSecrets,\n\t\t} = await import('../secrets/storage');\n\t\tconst { FileSecretsStore, secretsStoreFor } = await import(\n\t\t\t'../secrets/store'\n\t\t);\n\t\tconst { ConfigNotFound, loadWorkspaceSettings } = await import('../config');\n\t\tconst { encryptSecrets, generateDefineOptions } = await import(\n\t\t\t'../secrets/encryption'\n\t\t);\n\n\t\t// The stage's own store — SSM or Secrets Manager for a deployed stage\n\t\t// kept there. Outside\n\t\t// any workspace nothing names one, so it is the file.\n\t\tconst store = await loadWorkspaceSettings().then(\n\t\t\t(workspace) => secretsStoreFor(workspace, stage),\n\t\t\t(error) => {\n\t\t\t\tif (error instanceof ConfigNotFound) {\n\t\t\t\t\treturn new FileSecretsStore(process.cwd());\n\t\t\t\t}\n\t\t\t\tthrow error;\n\t\t\t},\n\t\t);\n\t\tlet secrets = await store.read(stage);\n\n\t\tif (!secrets) {\n\t\t\t// Auto-initialize secrets for the stage\n\t\t\tconsole.log(` Initializing secrets for stage \"${stage}\"...`);\n\t\t\tsecrets = initStageSecrets(stage);\n\t\t\tawait store.write(stage, secrets);\n\t\t\tconsole.log(` ✓ Created the \"${stage}\" secrets (${store.name})`);\n\t\t}\n\n\t\t// Validate environment variables if constructs are provided\n\t\tif (constructs && constructs.length > 0) {\n\t\t\tconsole.log(' Analyzing environment variable requirements...');\n\t\t\tconst requiredVars = await collectRequiredEnvVars(constructs);\n\n\t\t\tif (requiredVars.length > 0) {\n\t\t\t\tconst validation = validateEnvironmentVariables(requiredVars, secrets);\n\n\t\t\t\tif (!validation.valid) {\n\t\t\t\t\tconst errorMessage = [\n\t\t\t\t\t\t`Missing environment variables for stage \"${stage}\":`,\n\t\t\t\t\t\t'',\n\t\t\t\t\t\t...validation.missing.map((v) => ` ❌ ${v}`),\n\t\t\t\t\t\t'',\n\t\t\t\t\t\t'To fix this, either:',\n\t\t\t\t\t\t` 1. Add the missing variables to the \"${stage}\" secrets using:`,\n\t\t\t\t\t\t` gkm secrets:set <KEY> <VALUE> --stage ${stage}`,\n\t\t\t\t\t\t'',\n\t\t\t\t\t\t` 2. Or import from a JSON file:`,\n\t\t\t\t\t\t` gkm secrets:import secrets.json --stage ${stage}`,\n\t\t\t\t\t\t'',\n\t\t\t\t\t\t'Required variables:',\n\t\t\t\t\t\t...validation.required.map((v) =>\n\t\t\t\t\t\t\tvalidation.missing.includes(v) ? ` ❌ ${v}` : ` ✓ ${v}`,\n\t\t\t\t\t\t),\n\t\t\t\t\t].join('\\n');\n\n\t\t\t\t\tthrow new Error(errorMessage);\n\t\t\t\t}\n\n\t\t\t\tconsole.log(\n\t\t\t\t\t` ✓ All ${requiredVars.length} required environment variables found`,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\t// Convert to embeddable format and encrypt\n\t\tconst embeddable = toEmbeddableSecrets(secrets);\n\t\tconst encrypted = encryptSecrets(embeddable);\n\t\tmasterKey = encrypted.masterKey;\n\n\t\t// Add define options for build-time injection using esbuild's --define:KEY=VALUE format\n\t\tconst defines = generateDefineOptions(encrypted);\n\t\tfor (const [key, value] of Object.entries(defines)) {\n\t\t\t// `value` is already a JS string literal; quoting it again would\n\t\t\t// embed the quotes, and the IV would not parse as hex.\n\t\t\targs.push(`--define:${key}=${value}`);\n\t\t}\n\n\t\tconsole.log(` Secrets encrypted for stage \"${stage}\"`);\n\t} else {\n\t\t// Credentials encrypted elsewhere — an image build hands them in as a\n\t\t// BuildKit secret and writes them beside the app's `.gkm/server` — are\n\t\t// embedded as they are; whoever encrypted them holds the key.\n\t\tconst gkmDir = join(outputDir, '..', '..');\n\t\tconst encryptedPath = join(gkmDir, 'credentials.enc');\n\t\tconst ivPath = join(gkmDir, 'credentials.iv');\n\t\tif (existsSync(encryptedPath) && existsSync(ivPath)) {\n\t\t\tconst { generateDefineOptions } = await import('../secrets/encryption');\n\t\t\tconst defines = generateDefineOptions({\n\t\t\t\tencrypted: readFileSync(encryptedPath, 'utf-8').trim(),\n\t\t\t\tiv: readFileSync(ivPath, 'utf-8').trim(),\n\t\t\t\tmasterKey: '',\n\t\t\t});\n\t\t\tfor (const [key, value] of Object.entries(defines)) {\n\t\t\t\targs.push(`--define:${key}=${value}`);\n\t\t\t}\n\t\t\tconsole.log(' Embedded the encrypted credentials the build was given');\n\t\t}\n\t}\n\n\ttry {\n\t\t// Run esbuild with command-line arguments\n\t\tconst [cmd, ...cmdArgs] = args as [string, ...string[]];\n\t\tconst result = spawnSync(cmd, cmdArgs, {\n\t\t\tcwd: process.cwd(),\n\t\t\tstdio: 'inherit',\n\t\t\tshell: process.platform === 'win32', // Only use shell on Windows for npx resolution\n\t\t});\n\n\t\tif (result.error) {\n\t\t\tthrow result.error;\n\t\t}\n\t\tif (result.status !== 0) {\n\t\t\tthrow new Error(`esbuild exited with code ${result.status}`);\n\t\t}\n\n\t\t// Add shebang to the bundled file\n\t\tconst { readFile } = await import('node:fs/promises');\n\t\tconst content = await readFile(mjsOutput, 'utf-8');\n\t\tif (!content.startsWith('#!')) {\n\t\t\tawait writeFile(mjsOutput, `#!/usr/bin/env node\\n${content}`);\n\t\t}\n\t} catch (error) {\n\t\tthrow new Error(\n\t\t\t`Failed to bundle server: ${error instanceof Error ? error.message : 'Unknown error'}`,\n\t\t);\n\t}\n\n\treturn {\n\t\toutputPath: mjsOutput,\n\t\tmasterKey,\n\t};\n}\n"],"mappings":"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"}
@@ -1,8 +1,8 @@
1
- import { r as storedCredentials } from "./credentials-C4KII3PD.mjs";
2
- import { t as deploy } from "./deploy-DYIyIUYd.mjs";
1
+ import { r as storedCredentials } from "./credentials-B5N5yKk6.mjs";
2
+ import { t as deploy } from "./deploy-B0drCD6s.mjs";
3
3
  import { i as formatError } from "./index.mjs";
4
4
  import { n as targetForProvider } from "./provider-CEOKk8NS.mjs";
5
- import { terminalCredentials } from "./terminal-C4XRdwnU.mjs";
5
+ import { terminalCredentials } from "./terminal-iNmAXXjs.mjs";
6
6
  //#region src/deploy/cli.ts
7
7
  /**
8
8
  * `gkm deploy`: the terminal around `deploy()`. CLI layer only.
@@ -32,7 +32,11 @@ async function deployCli(options, streams = { stdout: process.stdout }) {
32
32
  ...options.dryRun ? { dryRun: true } : {},
33
33
  ...options.atomic ? { atomic: true } : {},
34
34
  ...options.allowDevServices ? { allowDevServices: true } : {},
35
- ...options.skipDnsCheck ? { skipDnsCheck: true } : {}
35
+ ...options.skipDns ? { skipDns: true } : {},
36
+ ...options.resourcesOnly ? { resourcesOnly: true } : {},
37
+ ...options.skipResources ? { skipResources: true } : {},
38
+ ...options.rotateKeys ? { rotateKeys: true } : {},
39
+ ...options.retireOldKeys ? { retireOldKeys: true } : {}
36
40
  };
37
41
  if (options.json) {
38
42
  const run = deploy({
@@ -66,4 +70,4 @@ async function deployCli(options, streams = { stdout: process.stdout }) {
66
70
  //#endregion
67
71
  export { deployCli };
68
72
 
69
- //# sourceMappingURL=cli-B8otnZfX.mjs.map
73
+ //# sourceMappingURL=cli-BCSuCfQk.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli-BCSuCfQk.mjs","names":[],"sources":["../src/deploy/cli.ts"],"sourcesContent":["/**\n * `gkm deploy`: the terminal around `deploy()`. CLI layer only.\n *\n * Everything that belongs to a person at a terminal lives here and nowhere\n * below it: prompting for a missing login (and storing it), printing progress,\n * and turning the outcome into an exit code. The deploy itself is the same\n * `deploy()` a host calls.\n */\n\nimport { formatError } from '../debug';\nimport { targetForProvider } from '../target/provider';\nimport { storedCredentials } from './credentials';\nimport { deploy } from './deploy';\nimport { terminalCredentials } from './terminal';\n\nexport interface DeployCliOptions {\n\t/** The project directory: `--cwd`, else where the command was run. */\n\tcwd: string;\n\t/** `--target`: where to deploy. Defaults to `deploy.default`. */\n\ttarget?: string;\n\t/** `--provider`, deprecated: `dokploy` means `--target dokploy`. */\n\tprovider?: string;\n\tstage: string;\n\ttag?: string;\n\t/**\n\t * Print each event as one JSON object per line on stdout, instead of the\n\t * progress lines. Nothing prompts: a missing credential fails the run.\n\t */\n\tjson?: boolean;\n\t/** Plan only: create, change, build and push nothing. */\n\tdryRun?: boolean;\n\t/** On a failed release, roll back every app, not only the failed ones. */\n\tatomic?: boolean;\n\t/** `--allow-dev-services`. */\n\tallowDevServices?: boolean;\n\t/** `--skip-dns`. */\n\tskipDns?: boolean;\n\t/** `--resources-only`. */\n\tresourcesOnly?: boolean;\n\t/** `--skip-resources`. */\n\tskipResources?: boolean;\n\t/** `--rotate-keys`. */\n\trotateKeys?: boolean;\n\t/** `--retire-old-keys`. */\n\tretireOldKeys?: boolean;\n}\n\n/** Where the command writes. The process's own streams, outside tests. */\nexport interface DeployCliStreams {\n\tstdout: Pick<NodeJS.WriteStream, 'write'>;\n}\n\n/**\n * Run `gkm deploy` and resolve with its exit code: 0 when the run finished,\n * 1 when anything stopped it.\n */\nexport async function deployCli(\n\toptions: DeployCliOptions,\n\tstreams: DeployCliStreams = { stdout: process.stdout },\n): Promise<number> {\n\tlet target = options.target;\n\tif (options.provider !== undefined && target === undefined) {\n\t\ttry {\n\t\t\t// On stderr, so a `--json` run's stdout still carries only events.\n\t\t\ttarget = targetForProvider(options.provider, (message) =>\n\t\t\t\tconsole.warn(message),\n\t\t\t);\n\t\t} catch (error) {\n\t\t\tconsole.error(formatError(error));\n\t\t\treturn 1;\n\t\t}\n\t}\n\n\tconst input = {\n\t\tcwd: options.cwd,\n\t\tstage: options.stage,\n\t\t...(target ? { target } : {}),\n\t\t...(options.tag ? { tag: options.tag } : {}),\n\t\t...(options.dryRun ? { dryRun: true } : {}),\n\t\t...(options.atomic ? { atomic: true } : {}),\n\t\t...(options.allowDevServices ? { allowDevServices: true } : {}),\n\t\t...(options.skipDns ? { skipDns: true } : {}),\n\t\t...(options.resourcesOnly ? { resourcesOnly: true } : {}),\n\t\t...(options.skipResources ? { skipResources: true } : {}),\n\t\t...(options.rotateKeys ? { rotateKeys: true } : {}),\n\t\t...(options.retireOldKeys ? { retireOldKeys: true } : {}),\n\t};\n\n\tif (options.json) {\n\t\t// stdout carries the events and nothing else: docker's own output goes\n\t\t// to stderr, and nobody is asked anything — a prompt would be written\n\t\t// into the stream a program is parsing.\n\t\tconst run = deploy({\n\t\t\t...input,\n\t\t\tcredentials: storedCredentials(),\n\t\t\tchildOutput: 'stderr',\n\t\t});\n\t\tfor await (const event of run) {\n\t\t\tstreams.stdout.write(`${JSON.stringify(event)}\\n`);\n\t\t}\n\t\treturn run.result.then(\n\t\t\t() => 0,\n\t\t\t(error) => {\n\t\t\t\tconsole.error(formatError(error));\n\t\t\t\treturn 1;\n\t\t\t},\n\t\t);\n\t}\n\n\t// The lines arrive as they are written, rather than as events read back a\n\t// tick later, so they interleave with a prompt exactly as they always did.\n\tconst run = deploy({\n\t\t...input,\n\t\tcredentials: terminalCredentials(storedCredentials()),\n\t\tlogger: {\n\t\t\tinfo: (message) => console.log(message),\n\t\t\twarn: (message) => console.warn(message),\n\t\t\terror: (message) => console.error(message),\n\t\t},\n\t});\n\n\ttry {\n\t\tawait run.result;\n\t\treturn 0;\n\t} catch (error) {\n\t\tconsole.error(formatError(error));\n\t\treturn 1;\n\t}\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAwDA,eAAsB,UACrB,SACA,UAA4B,EAAE,QAAQ,QAAQ,OAAO,GACnC;CAClB,IAAI,SAAS,QAAQ;CACrB,IAAI,QAAQ,aAAa,KAAA,KAAa,WAAW,KAAA,GAChD,IAAI;EAEH,SAAS,kBAAkB,QAAQ,WAAW,YAC7C,QAAQ,KAAK,OAAO,CACrB;CACD,SAAS,OAAO;EACf,QAAQ,MAAM,YAAY,KAAK,CAAC;EAChC,OAAO;CACR;CAGD,MAAM,QAAQ;EACb,KAAK,QAAQ;EACb,OAAO,QAAQ;EACf,GAAI,SAAS,EAAE,OAAO,IAAI,CAAC;EAC3B,GAAI,QAAQ,MAAM,EAAE,KAAK,QAAQ,IAAI,IAAI,CAAC;EAC1C,GAAI,QAAQ,SAAS,EAAE,QAAQ,KAAK,IAAI,CAAC;EACzC,GAAI,QAAQ,SAAS,EAAE,QAAQ,KAAK,IAAI,CAAC;EACzC,GAAI,QAAQ,mBAAmB,EAAE,kBAAkB,KAAK,IAAI,CAAC;EAC7D,GAAI,QAAQ,UAAU,EAAE,SAAS,KAAK,IAAI,CAAC;EAC3C,GAAI,QAAQ,gBAAgB,EAAE,eAAe,KAAK,IAAI,CAAC;EACvD,GAAI,QAAQ,gBAAgB,EAAE,eAAe,KAAK,IAAI,CAAC;EACvD,GAAI,QAAQ,aAAa,EAAE,YAAY,KAAK,IAAI,CAAC;EACjD,GAAI,QAAQ,gBAAgB,EAAE,eAAe,KAAK,IAAI,CAAC;CACxD;CAEA,IAAI,QAAQ,MAAM;EAIjB,MAAM,MAAM,OAAO;GAClB,GAAG;GACH,aAAa,kBAAkB;GAC/B,aAAa;EACd,CAAC;EACD,WAAW,MAAM,SAAS,KACzB,QAAQ,OAAO,MAAM,GAAG,KAAK,UAAU,KAAK,EAAE,GAAG;EAElD,OAAO,IAAI,OAAO,WACX,IACL,UAAU;GACV,QAAQ,MAAM,YAAY,KAAK,CAAC;GAChC,OAAO;EACR,CACD;CACD;CAIA,MAAM,MAAM,OAAO;EAClB,GAAG;EACH,aAAa,oBAAoB,kBAAkB,CAAC;EACpD,QAAQ;GACP,OAAO,YAAY,QAAQ,IAAI,OAAO;GACtC,OAAO,YAAY,QAAQ,KAAK,OAAO;GACvC,QAAQ,YAAY,QAAQ,MAAM,OAAO;EAC1C;CACD,CAAC;CAED,IAAI;EACH,MAAM,IAAI;EACV,OAAO;CACR,SAAS,OAAO;EACf,QAAQ,MAAM,YAAY,KAAK,CAAC;EAChC,OAAO;CACR;AACD"}
@@ -1,8 +1,8 @@
1
- const require_credentials = require("./credentials-QBu7VgaQ.cjs");
2
- const require_deploy = require("./deploy-C3Mhnmus.cjs");
1
+ const require_credentials = require("./credentials-Zqr3QQYB.cjs");
2
+ const require_deploy = require("./deploy-Bw1FjX_x.cjs");
3
3
  const require_index = require("./index.cjs");
4
4
  const require_provider = require("./provider-BqpjG9QM.cjs");
5
- const require_terminal = require("./terminal-8XngdSTo.cjs");
5
+ const require_terminal = require("./terminal-CPHuH4S1.cjs");
6
6
  //#region src/deploy/cli.ts
7
7
  /**
8
8
  * `gkm deploy`: the terminal around `deploy()`. CLI layer only.
@@ -32,7 +32,11 @@ async function deployCli(options, streams = { stdout: process.stdout }) {
32
32
  ...options.dryRun ? { dryRun: true } : {},
33
33
  ...options.atomic ? { atomic: true } : {},
34
34
  ...options.allowDevServices ? { allowDevServices: true } : {},
35
- ...options.skipDnsCheck ? { skipDnsCheck: true } : {}
35
+ ...options.skipDns ? { skipDns: true } : {},
36
+ ...options.resourcesOnly ? { resourcesOnly: true } : {},
37
+ ...options.skipResources ? { skipResources: true } : {},
38
+ ...options.rotateKeys ? { rotateKeys: true } : {},
39
+ ...options.retireOldKeys ? { retireOldKeys: true } : {}
36
40
  };
37
41
  if (options.json) {
38
42
  const run = require_deploy.deploy({
@@ -66,4 +70,4 @@ async function deployCli(options, streams = { stdout: process.stdout }) {
66
70
  //#endregion
67
71
  exports.deployCli = deployCli;
68
72
 
69
- //# sourceMappingURL=cli-DL19w4OE.cjs.map
73
+ //# sourceMappingURL=cli-Dewt2T21.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli-Dewt2T21.cjs","names":["targetForProvider","formatError","deploy","storedCredentials","terminalCredentials"],"sources":["../src/deploy/cli.ts"],"sourcesContent":["/**\n * `gkm deploy`: the terminal around `deploy()`. CLI layer only.\n *\n * Everything that belongs to a person at a terminal lives here and nowhere\n * below it: prompting for a missing login (and storing it), printing progress,\n * and turning the outcome into an exit code. The deploy itself is the same\n * `deploy()` a host calls.\n */\n\nimport { formatError } from '../debug';\nimport { targetForProvider } from '../target/provider';\nimport { storedCredentials } from './credentials';\nimport { deploy } from './deploy';\nimport { terminalCredentials } from './terminal';\n\nexport interface DeployCliOptions {\n\t/** The project directory: `--cwd`, else where the command was run. */\n\tcwd: string;\n\t/** `--target`: where to deploy. Defaults to `deploy.default`. */\n\ttarget?: string;\n\t/** `--provider`, deprecated: `dokploy` means `--target dokploy`. */\n\tprovider?: string;\n\tstage: string;\n\ttag?: string;\n\t/**\n\t * Print each event as one JSON object per line on stdout, instead of the\n\t * progress lines. Nothing prompts: a missing credential fails the run.\n\t */\n\tjson?: boolean;\n\t/** Plan only: create, change, build and push nothing. */\n\tdryRun?: boolean;\n\t/** On a failed release, roll back every app, not only the failed ones. */\n\tatomic?: boolean;\n\t/** `--allow-dev-services`. */\n\tallowDevServices?: boolean;\n\t/** `--skip-dns`. */\n\tskipDns?: boolean;\n\t/** `--resources-only`. */\n\tresourcesOnly?: boolean;\n\t/** `--skip-resources`. */\n\tskipResources?: boolean;\n\t/** `--rotate-keys`. */\n\trotateKeys?: boolean;\n\t/** `--retire-old-keys`. */\n\tretireOldKeys?: boolean;\n}\n\n/** Where the command writes. The process's own streams, outside tests. */\nexport interface DeployCliStreams {\n\tstdout: Pick<NodeJS.WriteStream, 'write'>;\n}\n\n/**\n * Run `gkm deploy` and resolve with its exit code: 0 when the run finished,\n * 1 when anything stopped it.\n */\nexport async function deployCli(\n\toptions: DeployCliOptions,\n\tstreams: DeployCliStreams = { stdout: process.stdout },\n): Promise<number> {\n\tlet target = options.target;\n\tif (options.provider !== undefined && target === undefined) {\n\t\ttry {\n\t\t\t// On stderr, so a `--json` run's stdout still carries only events.\n\t\t\ttarget = targetForProvider(options.provider, (message) =>\n\t\t\t\tconsole.warn(message),\n\t\t\t);\n\t\t} catch (error) {\n\t\t\tconsole.error(formatError(error));\n\t\t\treturn 1;\n\t\t}\n\t}\n\n\tconst input = {\n\t\tcwd: options.cwd,\n\t\tstage: options.stage,\n\t\t...(target ? { target } : {}),\n\t\t...(options.tag ? { tag: options.tag } : {}),\n\t\t...(options.dryRun ? { dryRun: true } : {}),\n\t\t...(options.atomic ? { atomic: true } : {}),\n\t\t...(options.allowDevServices ? { allowDevServices: true } : {}),\n\t\t...(options.skipDns ? { skipDns: true } : {}),\n\t\t...(options.resourcesOnly ? { resourcesOnly: true } : {}),\n\t\t...(options.skipResources ? { skipResources: true } : {}),\n\t\t...(options.rotateKeys ? { rotateKeys: true } : {}),\n\t\t...(options.retireOldKeys ? { retireOldKeys: true } : {}),\n\t};\n\n\tif (options.json) {\n\t\t// stdout carries the events and nothing else: docker's own output goes\n\t\t// to stderr, and nobody is asked anything — a prompt would be written\n\t\t// into the stream a program is parsing.\n\t\tconst run = deploy({\n\t\t\t...input,\n\t\t\tcredentials: storedCredentials(),\n\t\t\tchildOutput: 'stderr',\n\t\t});\n\t\tfor await (const event of run) {\n\t\t\tstreams.stdout.write(`${JSON.stringify(event)}\\n`);\n\t\t}\n\t\treturn run.result.then(\n\t\t\t() => 0,\n\t\t\t(error) => {\n\t\t\t\tconsole.error(formatError(error));\n\t\t\t\treturn 1;\n\t\t\t},\n\t\t);\n\t}\n\n\t// The lines arrive as they are written, rather than as events read back a\n\t// tick later, so they interleave with a prompt exactly as they always did.\n\tconst run = deploy({\n\t\t...input,\n\t\tcredentials: terminalCredentials(storedCredentials()),\n\t\tlogger: {\n\t\t\tinfo: (message) => console.log(message),\n\t\t\twarn: (message) => console.warn(message),\n\t\t\terror: (message) => console.error(message),\n\t\t},\n\t});\n\n\ttry {\n\t\tawait run.result;\n\t\treturn 0;\n\t} catch (error) {\n\t\tconsole.error(formatError(error));\n\t\treturn 1;\n\t}\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAwDA,eAAsB,UACrB,SACA,UAA4B,EAAE,QAAQ,QAAQ,OAAO,GACnC;CAClB,IAAI,SAAS,QAAQ;CACrB,IAAI,QAAQ,aAAa,KAAA,KAAa,WAAW,KAAA,GAChD,IAAI;EAEH,SAASA,iBAAAA,kBAAkB,QAAQ,WAAW,YAC7C,QAAQ,KAAK,OAAO,CACrB;CACD,SAAS,OAAO;EACf,QAAQ,MAAMC,cAAAA,YAAY,KAAK,CAAC;EAChC,OAAO;CACR;CAGD,MAAM,QAAQ;EACb,KAAK,QAAQ;EACb,OAAO,QAAQ;EACf,GAAI,SAAS,EAAE,OAAO,IAAI,CAAC;EAC3B,GAAI,QAAQ,MAAM,EAAE,KAAK,QAAQ,IAAI,IAAI,CAAC;EAC1C,GAAI,QAAQ,SAAS,EAAE,QAAQ,KAAK,IAAI,CAAC;EACzC,GAAI,QAAQ,SAAS,EAAE,QAAQ,KAAK,IAAI,CAAC;EACzC,GAAI,QAAQ,mBAAmB,EAAE,kBAAkB,KAAK,IAAI,CAAC;EAC7D,GAAI,QAAQ,UAAU,EAAE,SAAS,KAAK,IAAI,CAAC;EAC3C,GAAI,QAAQ,gBAAgB,EAAE,eAAe,KAAK,IAAI,CAAC;EACvD,GAAI,QAAQ,gBAAgB,EAAE,eAAe,KAAK,IAAI,CAAC;EACvD,GAAI,QAAQ,aAAa,EAAE,YAAY,KAAK,IAAI,CAAC;EACjD,GAAI,QAAQ,gBAAgB,EAAE,eAAe,KAAK,IAAI,CAAC;CACxD;CAEA,IAAI,QAAQ,MAAM;EAIjB,MAAM,MAAMC,eAAAA,OAAO;GAClB,GAAG;GACH,aAAaC,oBAAAA,kBAAkB;GAC/B,aAAa;EACd,CAAC;EACD,WAAW,MAAM,SAAS,KACzB,QAAQ,OAAO,MAAM,GAAG,KAAK,UAAU,KAAK,EAAE,GAAG;EAElD,OAAO,IAAI,OAAO,WACX,IACL,UAAU;GACV,QAAQ,MAAMF,cAAAA,YAAY,KAAK,CAAC;GAChC,OAAO;EACR,CACD;CACD;CAIA,MAAM,MAAMC,eAAAA,OAAO;EAClB,GAAG;EACH,aAAaE,iBAAAA,oBAAoBD,oBAAAA,kBAAkB,CAAC;EACpD,QAAQ;GACP,OAAO,YAAY,QAAQ,IAAI,OAAO;GACtC,OAAO,YAAY,QAAQ,KAAK,OAAO;GACvC,QAAQ,YAAY,QAAQ,MAAM,OAAO;EAC1C;CACD,CAAC;CAED,IAAI;EACH,MAAM,IAAI;EACV,OAAO;CACR,SAAS,OAAO;EACf,QAAQ,MAAMF,cAAAA,YAAY,KAAK,CAAC;EAChC,OAAO;CACR;AACD"}
@@ -1,15 +1,15 @@
1
1
  import { t as __exportAll } from "./rolldown-runtime-BhDjJH2R.mjs";
2
2
  import { t as GkmError } from "./errors-D8Gwp5kU.mjs";
3
- import { c as runOutput, s as run, x as gkmHome } from "./credentials-C4KII3PD.mjs";
3
+ import { a as runOutput, i as run, s as gkmHome } from "./run-BJLIerMM.mjs";
4
4
  import { r as discover } from "./discover-qjFapetL.mjs";
5
- import { it as SERVER_IPV4_KEY, tt as ComposeTlsFileMissing } from "./workspace-Bzw7Zs82.mjs";
5
+ import { it as SERVER_IPV4_KEY, tt as ComposeTlsFileMissing } from "./workspace-DWK1PTXP.mjs";
6
6
  import { t as defineTarget } from "./define-6poNqm5O.mjs";
7
- import { $t as bucketClient, C as HostNotPointingAtServer, D as serverAddressHint, Dt as constructGlobs, E as requiredServerAddress, Gt as applyPolicies, It as REDIS_SERVICE, Kt as applyPostgres, L as recordRelease, Ln as primaryPortKey, Mt as loadLocalCredentials, N as createComposeState, O as stackHosts, Qt as ensurePostgresLogin, T as isLocalHost, Wt as applyBuckets, Yt as postgresStatements, Zt as LEGACY_LOCAL_LOGIN, an as envFor, cn as imageLayout, en as pgClient, fn as findBuildRoot, gr as logsAccess, gt as reportDevServices, hr as LOGS_SERVICE, i as assertNoStaleSecrets, ir as imageRef, it as currentActor, k as systemLookup, n as reportDatabaseRuns, o as verifyStageProviders, r as reportPlannedSeeds, t as DeploySeedsFailed, u as DeployJournal, w as checkStackDns, y as ensureDockerignore } from "./seeds-BSL55F6q.mjs";
7
+ import { At as postgresStatements, Bt as envFor, Dt as applyPostgres, Et as applyPolicies, F as DeployJournal, Ft as pgClient, H as createComposeState, K as recordRelease, Mt as LEGACY_LOCAL_LOGIN, Nt as ensurePostgresLogin, Pt as bucketClient, Tt as applyBuckets, Ut as imageLayout, Xn as LOGS_SERVICE, Zn as logsAccess, _t as REDIS_SERVICE, c as ensureDockerignore, ct as constructGlobs, h as currentActor, m as recordDnsChanges, n as reportDatabaseRuns, pt as loadLocalCredentials, qt as findBuildRoot, r as reportPlannedSeeds, t as DeploySeedsFailed, vn as primaryPortKey, zn as imageRef } from "./seeds-CoKkrSny.mjs";
8
8
  import { i as installedFrom } from "./drivers-CTaWrA_L.mjs";
9
- import { _ as edgeComposeFile, a as composeStack, f as pinImages, g as EDGE_SERVICE, h as EDGE_PROJECT, i as composeProject, l as RegistryRequired, m as EDGE_NETWORK, n as LOGS_PORT_ENV, o as envFile, r as LOG_ROTATION, s as stackDir, t as EDGE_PORT_ENV, u as assertImagesExist, v as traefikStaticFile } from "./stack-Co4uZkAo.mjs";
10
- import { t as deployedStackSecrets } from "./secrets-DbPmAS4k.mjs";
9
+ import { a as serverAddressHint, i as requiredServerAddress, l as systemLookup, o as stackHosts, r as isLocalHost, s as stageDns, t as HostNotPointingAtServer } from "./dns-idXfyCay.mjs";
10
+ import { _ as edgeComposeFile, a as composeStack, f as pinImages, g as EDGE_SERVICE, h as EDGE_PROJECT, i as composeProject, l as RegistryRequired, m as EDGE_NETWORK, n as LOGS_PORT_ENV, o as envFile, r as LOG_ROTATION, s as stackDir, t as EDGE_PORT_ENV, u as assertImagesExist, v as traefikStaticFile } from "./stack-B7O975TR.mjs";
11
+ import { t as deployedStackSecrets } from "./secrets-oI9ClAPR.mjs";
11
12
  import { f as plannedSeeds, o as SeedFailed, p as seedDatabases, u as migrateDatabases } from "./databases-BeGP5eDh.mjs";
12
- import { n as assertStageCredentials } from "./credentialSchemas-BJFvfkaz.mjs";
13
13
  import { dirname, join } from "node:path";
14
14
  import { existsSync } from "node:fs";
15
15
  import { chmod, copyFile, mkdir, readFile, readdir, rename, rm, writeFile } from "node:fs/promises";
@@ -665,21 +665,6 @@ async function validateCompose(ctx, deps, options = {}) {
665
665
  background
666
666
  });
667
667
  const { secrets, generated } = await stageSecrets(ctx, manifest);
668
- const server = push || stage === workspace.stages.local ? void 0 : requiredServerAddress(stage, workspace.domains?.[stage], secrets?.custom);
669
- if (!push) {
670
- assertNoStaleSecrets({
671
- manifest,
672
- stage,
673
- supplied: secrets?.custom ?? {}
674
- });
675
- await assertStageCredentials({
676
- root,
677
- patterns: constructGlobs(workspace),
678
- manifest,
679
- stage,
680
- supplied: secrets?.custom ?? {}
681
- });
682
- }
683
668
  const layout = mode === "build" ? imageLayout(workspace) : void 0;
684
669
  const composed = composeStack({
685
670
  workspace,
@@ -700,23 +685,9 @@ async function validateCompose(ctx, deps, options = {}) {
700
685
  ...layout ? { layout } : {},
701
686
  ...push ? { buildOnly: true } : {}
702
687
  });
703
- reportDevServices(ctx, composed.devServices);
704
- if (!push && stage !== workspace.stages.local) {
705
- const verified = await verifyStageProviders({
706
- workspace,
707
- manifest,
708
- stage,
709
- secrets: secrets?.custom ?? {}
710
- });
711
- for (const line of verified) ctx.logger.info(`✓ ${line} verified`);
712
- }
713
688
  if (mode === "build") assertRedisClient(workspace, composed);
714
689
  const stack = options.pin ? withPinnedImages(composed, options.pin.file, options.pin.digests) : composed;
715
690
  if (mode === "pull" && !ctx.dryRun) await assertImagesExist(deps.docker, tag, [...stack.apps, ...stack.workers]);
716
- if (stack.tls && !push) {
717
- for (const file of [stack.tls.certFile, stack.tls.keyFile]) if (!existsSync(file)) throw new ComposeTlsFileMissing(stage, file);
718
- }
719
- if (!push && !stack.local) await checkDns(ctx, deps, stackHosts(stack).filter((host) => !isLocalHost(host)), server);
720
691
  if (stack.redis && !stack.local) ctx.secrets.mask(stack.redis.password);
721
692
  if (stack.logs && (!stack.local || stack.logs.passwordFromSecrets)) {
722
693
  ctx.secrets.mask(stack.logs.password);
@@ -756,6 +727,21 @@ async function validateCompose(ctx, deps, options = {}) {
756
727
  changes: []
757
728
  };
758
729
  }
730
+ /**
731
+ * What only a compose deploy checks before it changes anything, once the
732
+ * stage's own keys are: the stage's own certificate is there, and every
733
+ * public host points at the stage's server — its records written where a
734
+ * provider holds them, then confirmed — before Caddy or Traefik ask Let's
735
+ * Encrypt for a certificate it could not issue. A build-only run never asks.
736
+ */
737
+ async function readyCompose(ctx, run, deps) {
738
+ const { stack } = run;
739
+ if (stack.tls) {
740
+ for (const file of [stack.tls.certFile, stack.tls.keyFile]) if (!existsSync(file)) throw new ComposeTlsFileMissing(ctx.stage, file);
741
+ }
742
+ if (stack.local) return;
743
+ await stageHostsDns(ctx, deps, stackHosts(stack).filter((host) => !isLocalHost(host)), run.secrets?.custom);
744
+ }
759
745
  /** A stack whose caches are in Redis, built for an app that has no client. */
760
746
  var RedisClientMissing = class extends GkmError {
761
747
  apps;
@@ -785,30 +771,54 @@ function assertRedisClient(workspace, stack) {
785
771
  * leaves the stage's secrets as it found them.
786
772
  */
787
773
  /**
788
- * The deploy-time DNS check: each public host resolved with the system
789
- * resolver and compared with the server's address from the stage's secrets.
790
- * A dry run warns rather than stops.
774
+ * The deploy's DNS step, for a deployed stage: its server's address — required
775
+ * where it serves a real domain — then its own hosts written through each
776
+ * domain's provider in `dns` where they differ, read back from it, and
777
+ * recorded in the stage's state; hosts no provider writes resolved with the
778
+ * system resolver. A dry run prints the plan and writes nothing, and warns
779
+ * rather than stops. What a deploy (`ready`) and `--resources-only` both run.
780
+ *
781
+ * @throws {ServerAddressMissing} when the stage has a domain and no address
782
+ * @throws {ServerAddressInvalid} for a value that is not an address
783
+ * @throws {HostNotPointingAtServer} when a host is not the server
791
784
  */
792
- async function checkDns(ctx, deps, hosts, server) {
785
+ async function stageHostsDns(ctx, deps, hosts, custom) {
793
786
  const { workspace, stage } = ctx;
787
+ const server = requiredServerAddress(stage, workspace.domains?.[stage], custom);
794
788
  if (hosts.length === 0) return;
795
- if (ctx.skipDnsCheck) {
796
- ctx.logger.info("🌐 DNS check skipped (--skip-dns-check)");
789
+ if (ctx.skipDns) {
790
+ ctx.logger.info("🌐 DNS skipped (--skip-dns): no record is written or checked");
791
+ return;
792
+ }
793
+ if (ctx.skipResources) {
794
+ ctx.logger.info("🌐 DNS skipped (--skip-resources): the --resources-only run wrote and confirmed the records");
797
795
  return;
798
796
  }
799
797
  if (!server) {
800
- ctx.logger.info(`🌐 DNS check skipped: no ${SERVER_IPV4_KEY} in '${stage}''s secrets — ${serverAddressHint(stage)}`);
798
+ ctx.logger.info(`🌐 DNS skipped: no ${SERVER_IPV4_KEY} in '${stage}''s secrets — ${serverAddressHint(stage)}`);
801
799
  return;
802
800
  }
801
+ const log = (line) => ctx.logger.info(line);
802
+ if (workspace.dns) log(`🌐 DNS for '${stage}' → ${server.ipv4}${server.ipv6 ? ` / ${server.ipv6}` : ""}${ctx.dryRun ? " (dry run — nothing is written)" : ""}`);
803
803
  try {
804
- const ok = await checkStackDns({
804
+ const result = await stageDns({
805
805
  stage,
806
806
  hosts,
807
807
  server,
808
808
  dns: workspace.dns,
809
- lookup: deps.lookup ?? systemLookup
809
+ credentials: ctx.credentials,
810
+ log,
811
+ lookup: deps.lookup ?? systemLookup,
812
+ ...ctx.dryRun ? { dryRun: true } : {},
813
+ ...deps.dnsProviderFor ? { providerFor: deps.dnsProviderFor } : {}
810
814
  });
811
- ctx.logger.info(`🌐 ${ok.length} host${ok.length === 1 ? "" : "s"} resolve${ok.length === 1 ? "s" : ""} to ${server.ipv4}`);
815
+ if (!ctx.dryRun) {
816
+ const journal = await DeployJournal.open(ctx.state, stage, () => createComposeState(stage));
817
+ const providers = new Map(result.plan.domains.map((d) => [d.domain, d.provider]));
818
+ await recordDnsChanges(journal, result.changes, (domain) => providers.get(domain));
819
+ }
820
+ const parts = [result.confirmed.length > 0 ? `${result.confirmed.length} host${result.confirmed.length === 1 ? "" : "s"} confirmed by the DNS provider` : "", result.resolved.length > 0 ? `${result.resolved.length} host${result.resolved.length === 1 ? "" : "s"} resolve${result.resolved.length === 1 ? "s" : ""} to ${server.ipv4}` : ""].filter(Boolean);
821
+ if (parts.length > 0) log(`🌐 ${parts.join(", ")}`);
812
822
  } catch (error) {
813
823
  if (ctx.dryRun && error instanceof HostNotPointingAtServer) {
814
824
  ctx.logger.warn(`⚠ ${error.message}`);
@@ -817,6 +827,25 @@ async function checkDns(ctx, deps, hosts, server) {
817
827
  throw error;
818
828
  }
819
829
  }
830
+ /**
831
+ * `--resources-only`: the stage's DNS records, from the hosts its stack would
832
+ * serve — composed in memory, nothing written, no image asked for. What a CI
833
+ * runner runs with the DNS provider's token, so the server never holds it.
834
+ */
835
+ async function resourcesCompose(ctx, deps) {
836
+ const { workspace, stage } = ctx;
837
+ if (stage === workspace.stages.local) return;
838
+ const stored = await ctx.secrets.read();
839
+ const { composeStageHosts } = await import("./dns-X3oqEV4C.mjs").then((n) => n.n);
840
+ await stageHostsDns(ctx, deps, (await composeStageHosts({
841
+ workspace,
842
+ stage,
843
+ stored,
844
+ manifest: ctx.manifest,
845
+ runnables: ctx.runnables ?? {},
846
+ background: ctx.background ?? {}
847
+ })).filter((host) => !isLocalHost(host)), stored?.custom);
848
+ }
820
849
  async function stageSecrets(ctx, manifest) {
821
850
  const stored = await ctx.secrets.read();
822
851
  if (ctx.stage === ctx.workspace.stages.local) return {
@@ -1419,6 +1448,8 @@ function printPlan(ctx, run) {
1419
1448
  *
1420
1449
  * - `validate`: the stack (`composeStack`, pure) and, for a tag, every image
1421
1450
  * looked up in the registry — `ImageTagNotFound` before anything changes
1451
+ * - `ready`: a deploy's own checks, after the stage's keys are — the stage's
1452
+ * certificate, its server's address, and every public host's DNS
1422
1453
  * - `plan`: the stack's files and what a run would create or reuse
1423
1454
  * - `provision`: generated secrets kept, files written, infrastructure up,
1424
1455
  * databases, roles, grants and migrations
@@ -1429,7 +1460,9 @@ function printPlan(ctx, run) {
1429
1460
  * - `verify`: each app asked through Caddy over HTTPS
1430
1461
  *
1431
1462
  * With `push` (`gkm compose --build --push`), run with `buildOnly`, it builds
1432
- * every image and pushes it to `deploy.registry`, and does nothing else.
1463
+ * every image and pushes it to `deploy.registry`, and does nothing else: no
1464
+ * readiness check runs, so a stage whose keys the deploy has yet to write
1465
+ * still builds.
1433
1466
  *
1434
1467
  * `gkm compose` is this target with a few more switches (`--build`, `--pull`,
1435
1468
  * `--down`), run through the same `deploy()`.
@@ -1459,7 +1492,9 @@ function composeTarget(options = {}) {
1459
1492
  ...push ? { push } : {},
1460
1493
  ...pin ? { pin } : {}
1461
1494
  }),
1495
+ ready: (ctx, run) => readyCompose(ctx, run, deps),
1462
1496
  plan: (ctx, run) => planCompose(ctx, run),
1497
+ resources: (ctx) => resourcesCompose(ctx, deps),
1463
1498
  provision: (ctx, run) => provisionCompose(ctx, run, deps),
1464
1499
  build: (ctx, run) => buildCompose(ctx, run, deps),
1465
1500
  release: (ctx, run) => releaseCompose(ctx, run, deps),
@@ -1473,4 +1508,4 @@ function composeTarget(options = {}) {
1473
1508
  //#endregion
1474
1509
  export { stackOverrideFile as a, dockerCompose as c, ComposePushNeedsBuild as i, compose_exports as n, edgeDir as o, ComposePinNeedsPull as r, removeEdgeRoutes as s, composeTarget as t };
1475
1510
 
1476
- //# sourceMappingURL=compose-DrEB_4F-.mjs.map
1511
+ //# sourceMappingURL=compose-C4js1JDv.mjs.map