@geekmidas/cli 10.0.0-alpha.1 → 10.0.0-alpha.100

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 (491) hide show
  1. package/README.md +326 -421
  2. package/bin/adjacent-tsconfig.mjs +97 -0
  3. package/bin/gkm.mjs +16 -2
  4. package/bin/owning-tsconfig-jsx-register.mjs +18 -0
  5. package/bin/owning-tsconfig-jsx.mjs +108 -0
  6. package/dist/EndpointGenerator-Br97xgs_.mjs +1031 -0
  7. package/dist/EndpointGenerator-Br97xgs_.mjs.map +1 -0
  8. package/dist/EndpointGenerator-By5_tYE9.cjs +1090 -0
  9. package/dist/EndpointGenerator-By5_tYE9.cjs.map +1 -0
  10. package/dist/GoDaddyProvider-CVnzcWX5.mjs +388 -0
  11. package/dist/GoDaddyProvider-CVnzcWX5.mjs.map +1 -0
  12. package/dist/GoDaddyProvider-DS4Wgu0c.cjs +388 -0
  13. package/dist/GoDaddyProvider-DS4Wgu0c.cjs.map +1 -0
  14. package/dist/{HostingerProvider-Cft7lEYr.mjs → HostingerProvider-BNpS9aRJ.mjs} +29 -25
  15. package/dist/HostingerProvider-BNpS9aRJ.mjs.map +1 -0
  16. package/dist/{HostingerProvider-h3EbEp-Z.cjs → HostingerProvider-DR1iws1P.cjs} +29 -25
  17. package/dist/HostingerProvider-DR1iws1P.cjs.map +1 -0
  18. package/dist/LegacyStateStore-C2Xlqy4v.mjs +124 -0
  19. package/dist/LegacyStateStore-C2Xlqy4v.mjs.map +1 -0
  20. package/dist/LegacyStateStore-CoHPQMLO.cjs +124 -0
  21. package/dist/LegacyStateStore-CoHPQMLO.cjs.map +1 -0
  22. package/dist/LocalStateStore-BGDzf2f8.cjs +178 -0
  23. package/dist/LocalStateStore-BGDzf2f8.cjs.map +1 -0
  24. package/dist/LocalStateStore-By59pUve.mjs +167 -0
  25. package/dist/LocalStateStore-By59pUve.mjs.map +1 -0
  26. package/dist/OpenApiTsGenerator-BgSX_Z-e.cjs +541 -0
  27. package/dist/OpenApiTsGenerator-BgSX_Z-e.cjs.map +1 -0
  28. package/dist/OpenApiTsGenerator-C8aTX--y.mjs +536 -0
  29. package/dist/OpenApiTsGenerator-C8aTX--y.mjs.map +1 -0
  30. package/dist/{Route53Provider-di2fMM5N.cjs → Route53Provider-Bllus2NR.cjs} +21 -22
  31. package/dist/Route53Provider-Bllus2NR.cjs.map +1 -0
  32. package/dist/{Route53Provider-RdpUDJQk.mjs → Route53Provider-QXxjkZO1.mjs} +13 -13
  33. package/dist/Route53Provider-QXxjkZO1.mjs.map +1 -0
  34. package/dist/S3StateStore-CU485pYn.mjs +223 -0
  35. package/dist/S3StateStore-CU485pYn.mjs.map +1 -0
  36. package/dist/S3StateStore-Re4LfDTl.cjs +222 -0
  37. package/dist/S3StateStore-Re4LfDTl.cjs.map +1 -0
  38. package/dist/SSMStateStore-BquRBbUG.mjs +205 -0
  39. package/dist/SSMStateStore-BquRBbUG.mjs.map +1 -0
  40. package/dist/SSMStateStore-CLX4Dm5d.cjs +204 -0
  41. package/dist/SSMStateStore-CLX4Dm5d.cjs.map +1 -0
  42. package/dist/SubscriberGenerator-1-IsjIwF.mjs +449 -0
  43. package/dist/SubscriberGenerator-1-IsjIwF.mjs.map +1 -0
  44. package/dist/SubscriberGenerator-BlIOdbi-.cjs +490 -0
  45. package/dist/SubscriberGenerator-BlIOdbi-.cjs.map +1 -0
  46. package/dist/add-Blv6Q_YA.mjs +718 -0
  47. package/dist/add-Blv6Q_YA.mjs.map +1 -0
  48. package/dist/add-C6RhiCBX.cjs +720 -0
  49. package/dist/add-C6RhiCBX.cjs.map +1 -0
  50. package/dist/appPorts-C9z9Pzn9.mjs +223 -0
  51. package/dist/appPorts-C9z9Pzn9.mjs.map +1 -0
  52. package/dist/appPorts-Cu79hJF6.cjs +264 -0
  53. package/dist/appPorts-Cu79hJF6.cjs.map +1 -0
  54. package/dist/aws-8QQ8n-t6.mjs +89 -0
  55. package/dist/aws-8QQ8n-t6.mjs.map +1 -0
  56. package/dist/aws-DY9NqQIT.cjs +100 -0
  57. package/dist/aws-DY9NqQIT.cjs.map +1 -0
  58. package/dist/awsStore-Bx5nCFnS.mjs +121 -0
  59. package/dist/awsStore-Bx5nCFnS.mjs.map +1 -0
  60. package/dist/awsStore-u3ehhMoY.cjs +138 -0
  61. package/dist/awsStore-u3ehhMoY.cjs.map +1 -0
  62. package/dist/{backup-provisioner-Bgj5Vi_L.mjs → backup-provisioner-C8DnCmxK.mjs} +11 -8
  63. package/dist/backup-provisioner-C8DnCmxK.mjs.map +1 -0
  64. package/dist/{backup-provisioner-BrsHwYG0.cjs → backup-provisioner-oDEsPj02.cjs} +22 -20
  65. package/dist/backup-provisioner-oDEsPj02.cjs.map +1 -0
  66. package/dist/backups/runner.cjs +519 -0
  67. package/dist/backups/runner.cjs.map +1 -0
  68. package/dist/backups/runner.d.cts +102 -0
  69. package/dist/backups/runner.d.cts.map +1 -0
  70. package/dist/backups/runner.d.mts +102 -0
  71. package/dist/backups/runner.d.mts.map +1 -0
  72. package/dist/backups/runner.mjs +506 -0
  73. package/dist/backups/runner.mjs.map +1 -0
  74. package/dist/{bundler-Be8Zg4Wd.mjs → bundler-Cquc0e8N.mjs} +36 -32
  75. package/dist/bundler-Cquc0e8N.mjs.map +1 -0
  76. package/dist/{bundler-BY1OmV1e.cjs → bundler-DAeBIOlG.cjs} +38 -35
  77. package/dist/bundler-DAeBIOlG.cjs.map +1 -0
  78. package/dist/cli-DbeqYBTs.cjs +71 -0
  79. package/dist/cli-DbeqYBTs.cjs.map +1 -0
  80. package/dist/cli-tWfeiYmO.mjs +71 -0
  81. package/dist/cli-tWfeiYmO.mjs.map +1 -0
  82. package/dist/compose-BftbEv0b.mjs +3154 -0
  83. package/dist/compose-BftbEv0b.mjs.map +1 -0
  84. package/dist/compose-C_mfrSVH.cjs +3267 -0
  85. package/dist/compose-C_mfrSVH.cjs.map +1 -0
  86. package/dist/config-D48erO2j.d.mts +269 -0
  87. package/dist/config-D48erO2j.d.mts.map +1 -0
  88. package/dist/config-DHDtsQrB.d.cts +269 -0
  89. package/dist/config-DHDtsQrB.d.cts.map +1 -0
  90. package/dist/config.cjs +421 -11
  91. package/dist/config.cjs.map +1 -0
  92. package/dist/config.d.cts +4 -120
  93. package/dist/config.d.mts +4 -120
  94. package/dist/config.mjs +405 -4
  95. package/dist/config.mjs.map +1 -0
  96. package/dist/credentialSchemas-DDda4Mmm.cjs +272 -0
  97. package/dist/credentialSchemas-DDda4Mmm.cjs.map +1 -0
  98. package/dist/credentialSchemas-DvitraL-.mjs +237 -0
  99. package/dist/credentialSchemas-DvitraL-.mjs.map +1 -0
  100. package/dist/credentials-B5N5yKk6.mjs +267 -0
  101. package/dist/credentials-B5N5yKk6.mjs.map +1 -0
  102. package/dist/credentials-Zqr3QQYB.cjs +350 -0
  103. package/dist/credentials-Zqr3QQYB.cjs.map +1 -0
  104. package/dist/databases-BeGP5eDh.mjs +495 -0
  105. package/dist/databases-BeGP5eDh.mjs.map +1 -0
  106. package/dist/databases-DGALFDG3.cjs +598 -0
  107. package/dist/databases-DGALFDG3.cjs.map +1 -0
  108. package/dist/define-6poNqm5O.mjs +106 -0
  109. package/dist/define-6poNqm5O.mjs.map +1 -0
  110. package/dist/define-crmMcXFS.cjs +153 -0
  111. package/dist/define-crmMcXFS.cjs.map +1 -0
  112. package/dist/deploy/public.cjs +212 -0
  113. package/dist/deploy/public.cjs.map +1 -0
  114. package/dist/deploy/public.d.cts +653 -0
  115. package/dist/deploy/public.d.cts.map +1 -0
  116. package/dist/deploy/public.d.mts +653 -0
  117. package/dist/deploy/public.d.mts.map +1 -0
  118. package/dist/deploy/public.mjs +145 -0
  119. package/dist/deploy/public.mjs.map +1 -0
  120. package/dist/deploy/sniffer-envkit-patch.cjs +18 -10
  121. package/dist/deploy/sniffer-envkit-patch.cjs.map +1 -1
  122. package/dist/deploy/sniffer-envkit-patch.d.cts +0 -2
  123. package/dist/deploy/sniffer-envkit-patch.d.cts.map +1 -1
  124. package/dist/deploy/sniffer-envkit-patch.d.mts +0 -2
  125. package/dist/deploy/sniffer-envkit-patch.d.mts.map +1 -1
  126. package/dist/deploy/sniffer-envkit-patch.mjs +10 -2
  127. package/dist/deploy/sniffer-envkit-patch.mjs.map +1 -1
  128. package/dist/deploy/sniffer-envparser-worker.cjs +54 -0
  129. package/dist/deploy/sniffer-envparser-worker.cjs.map +1 -0
  130. package/dist/deploy/sniffer-envparser-worker.d.cts +1 -0
  131. package/dist/deploy/sniffer-envparser-worker.d.mts +1 -0
  132. package/dist/deploy/sniffer-envparser-worker.mjs +55 -0
  133. package/dist/deploy/sniffer-envparser-worker.mjs.map +1 -0
  134. package/dist/deploy/sniffer-hooks.cjs +13 -7
  135. package/dist/deploy/sniffer-hooks.cjs.map +1 -1
  136. package/dist/deploy/sniffer-hooks.d.cts +1 -2
  137. package/dist/deploy/sniffer-hooks.d.cts.map +1 -1
  138. package/dist/deploy/sniffer-hooks.d.mts +1 -2
  139. package/dist/deploy/sniffer-hooks.d.mts.map +1 -1
  140. package/dist/deploy/sniffer-hooks.mjs +10 -3
  141. package/dist/deploy/sniffer-hooks.mjs.map +1 -1
  142. package/dist/deploy/sniffer-loader.cjs +16 -7
  143. package/dist/deploy/sniffer-loader.cjs.map +1 -1
  144. package/dist/deploy/sniffer-loader.d.cts +1 -1
  145. package/dist/deploy/sniffer-loader.d.mts +1 -1
  146. package/dist/deploy/sniffer-loader.mjs +14 -3
  147. package/dist/deploy/sniffer-loader.mjs.map +1 -1
  148. package/dist/deploy/sniffer-routes-worker.cjs +11 -11
  149. package/dist/deploy/sniffer-routes-worker.cjs.map +1 -1
  150. package/dist/deploy/sniffer-routes-worker.d.cts +1 -1
  151. package/dist/deploy/sniffer-routes-worker.d.mts +1 -1
  152. package/dist/deploy/sniffer-routes-worker.mjs +4 -4
  153. package/dist/deploy/sniffer-routes-worker.mjs.map +1 -1
  154. package/dist/deploy/sniffer-worker.cjs +15 -6
  155. package/dist/deploy/sniffer-worker.cjs.map +1 -1
  156. package/dist/deploy/sniffer-worker.d.cts +1 -3
  157. package/dist/deploy/sniffer-worker.d.cts.map +1 -1
  158. package/dist/deploy/sniffer-worker.d.mts +1 -3
  159. package/dist/deploy/sniffer-worker.d.mts.map +1 -1
  160. package/dist/deploy/sniffer-worker.mjs +15 -4
  161. package/dist/deploy/sniffer-worker.mjs.map +1 -1
  162. package/dist/deploy-BSilGXuR.mjs +2317 -0
  163. package/dist/deploy-BSilGXuR.mjs.map +1 -0
  164. package/dist/deploy-CktQpmpU.cjs +2390 -0
  165. package/dist/deploy-CktQpmpU.cjs.map +1 -0
  166. package/dist/derive-B4vDpzgP.mjs +150 -0
  167. package/dist/derive-B4vDpzgP.mjs.map +1 -0
  168. package/dist/derive-DAbo49sm.cjs +161 -0
  169. package/dist/derive-DAbo49sm.cjs.map +1 -0
  170. package/dist/discover-BfhVW_kT.cjs +600 -0
  171. package/dist/discover-BfhVW_kT.cjs.map +1 -0
  172. package/dist/discover-CvTtV5ZD.d.cts +108 -0
  173. package/dist/discover-CvTtV5ZD.d.cts.map +1 -0
  174. package/dist/discover-W2kab9Lc.d.mts +108 -0
  175. package/dist/discover-W2kab9Lc.d.mts.map +1 -0
  176. package/dist/discover-kziEht4W.mjs +527 -0
  177. package/dist/discover-kziEht4W.mjs.map +1 -0
  178. package/dist/dns-CQZQL3gj.mjs +926 -0
  179. package/dist/dns-CQZQL3gj.mjs.map +1 -0
  180. package/dist/dns-KPxvcCdL.cjs +1057 -0
  181. package/dist/dns-KPxvcCdL.cjs.map +1 -0
  182. package/dist/dokploy-B7eMa6Pa.cjs +38 -0
  183. package/dist/dokploy-B7eMa6Pa.cjs.map +1 -0
  184. package/dist/dokploy-Dguhz3Uo.mjs +38 -0
  185. package/dist/dokploy-Dguhz3Uo.mjs.map +1 -0
  186. package/dist/drivers-BLU1fNs_.cjs +200 -0
  187. package/dist/drivers-BLU1fNs_.cjs.map +1 -0
  188. package/dist/drivers-C08LL4E8.mjs +177 -0
  189. package/dist/drivers-C08LL4E8.mjs.map +1 -0
  190. package/dist/{emit-CiZS_5Ub.mjs → emit-C1e8qD08.mjs} +13 -26
  191. package/dist/emit-C1e8qD08.mjs.map +1 -0
  192. package/dist/{emit-CbcRolsa.cjs → emit-Dmc1nvdS.cjs} +31 -57
  193. package/dist/emit-Dmc1nvdS.cjs.map +1 -0
  194. package/dist/encryption-CixpDF6e.mjs +89 -0
  195. package/dist/encryption-CixpDF6e.mjs.map +1 -0
  196. package/dist/encryption-DrhCX7G6.cjs +90 -0
  197. package/dist/encryption-DrhCX7G6.cjs.map +1 -0
  198. package/dist/engine-32gL2ju3.mjs +3082 -0
  199. package/dist/engine-32gL2ju3.mjs.map +1 -0
  200. package/dist/engine-CQgycl7o.cjs +3195 -0
  201. package/dist/engine-CQgycl7o.cjs.map +1 -0
  202. package/dist/errors-D8Gwp5kU.mjs +23 -0
  203. package/dist/errors-D8Gwp5kU.mjs.map +1 -0
  204. package/dist/errors-DMC4Umsb.cjs +34 -0
  205. package/dist/errors-DMC4Umsb.cjs.map +1 -0
  206. package/dist/github-DYQ5wvod.mjs +829 -0
  207. package/dist/github-DYQ5wvod.mjs.map +1 -0
  208. package/dist/github-DkSCUoWS.cjs +829 -0
  209. package/dist/github-DkSCUoWS.cjs.map +1 -0
  210. package/dist/identity-CBXr4wNi.mjs +129 -0
  211. package/dist/identity-CBXr4wNi.mjs.map +1 -0
  212. package/dist/identity-CbLfgQNT.cjs +182 -0
  213. package/dist/identity-CbLfgQNT.cjs.map +1 -0
  214. package/dist/{index-BThUzEIp.d.mts → index-8OfpOtSI.d.cts} +39 -24
  215. package/dist/index-8OfpOtSI.d.cts.map +1 -0
  216. package/dist/{index-CHB4tSzX.d.cts → index-Dpji6Bxq.d.mts} +39 -24
  217. package/dist/index-Dpji6Bxq.d.mts.map +1 -0
  218. package/dist/index.cjs +10483 -11859
  219. package/dist/index.cjs.map +1 -1
  220. package/dist/index.d.cts +1 -1
  221. package/dist/index.d.mts +1 -1
  222. package/dist/index.mjs +10527 -11915
  223. package/dist/index.mjs.map +1 -1
  224. package/dist/local-BwC2v2Y8.mjs +224 -0
  225. package/dist/local-BwC2v2Y8.mjs.map +1 -0
  226. package/dist/local-DNhnkugT.cjs +241 -0
  227. package/dist/local-DNhnkugT.cjs.map +1 -0
  228. package/dist/migrate-BoJxKbfR.mjs +181 -0
  229. package/dist/migrate-BoJxKbfR.mjs.map +1 -0
  230. package/dist/migrate-CJTyeBul.cjs +271 -0
  231. package/dist/migrate-CJTyeBul.cjs.map +1 -0
  232. package/dist/migrate-CxmkvMbw.mjs +266 -0
  233. package/dist/migrate-CxmkvMbw.mjs.map +1 -0
  234. package/dist/migrate-ISBZNDKU.cjs +181 -0
  235. package/dist/migrate-ISBZNDKU.cjs.map +1 -0
  236. package/dist/openapi.cjs +214 -8
  237. package/dist/openapi.cjs.map +1 -0
  238. package/dist/openapi.d.cts +72 -15
  239. package/dist/openapi.d.cts.map +1 -1
  240. package/dist/openapi.d.mts +72 -15
  241. package/dist/openapi.d.mts.map +1 -1
  242. package/dist/openapi.mjs +208 -5
  243. package/dist/openapi.mjs.map +1 -0
  244. package/dist/projectBucket-BBbQ1lHF.cjs +263 -0
  245. package/dist/projectBucket-BBbQ1lHF.cjs.map +1 -0
  246. package/dist/projectBucket-C_DN4WzF.mjs +222 -0
  247. package/dist/projectBucket-C_DN4WzF.mjs.map +1 -0
  248. package/dist/provider-BqpjG9QM.cjs +57 -0
  249. package/dist/provider-BqpjG9QM.cjs.map +1 -0
  250. package/dist/provider-CEOKk8NS.mjs +46 -0
  251. package/dist/provider-CEOKk8NS.mjs.map +1 -0
  252. package/dist/ready-BtxiI7Qb.cjs +403 -0
  253. package/dist/ready-BtxiI7Qb.cjs.map +1 -0
  254. package/dist/ready-CzHNHhI6.mjs +374 -0
  255. package/dist/ready-CzHNHhI6.mjs.map +1 -0
  256. package/dist/reconcile/public.cjs +3 -5
  257. package/dist/reconcile/public.d.cts +11 -87
  258. package/dist/reconcile/public.d.cts.map +1 -1
  259. package/dist/reconcile/public.d.mts +11 -87
  260. package/dist/reconcile/public.d.mts.map +1 -1
  261. package/dist/reconcile/public.mjs +3 -4
  262. package/dist/{reconcile-CFs8C_1a.mjs → reconcile--I7V4Klj.mjs} +4 -7
  263. package/dist/reconcile--I7V4Klj.mjs.map +1 -0
  264. package/dist/{reconcile-D0pimNiy.cjs → reconcile-CuCQBa5-.cjs} +5 -8
  265. package/dist/reconcile-CuCQBa5-.cjs.map +1 -0
  266. package/dist/resolve-Bei6BMbw.mjs +263 -0
  267. package/dist/resolve-Bei6BMbw.mjs.map +1 -0
  268. package/dist/resolve-qm7FrBj_.cjs +316 -0
  269. package/dist/resolve-qm7FrBj_.cjs.map +1 -0
  270. package/dist/rollback-BJ3H4kQ8.mjs +136 -0
  271. package/dist/rollback-BJ3H4kQ8.mjs.map +1 -0
  272. package/dist/rollback-Bt4xRXtq.cjs +165 -0
  273. package/dist/rollback-Bt4xRXtq.cjs.map +1 -0
  274. package/dist/rolldown-runtime-BhDjJH2R.mjs +15 -0
  275. package/dist/{chunk-CUT6urMc.cjs → rolldown-runtime-C0BPl7ul.cjs} +23 -10
  276. package/dist/run-BJLIerMM.mjs +133 -0
  277. package/dist/run-BJLIerMM.mjs.map +1 -0
  278. package/dist/run-fVZ-rLnc.cjs +174 -0
  279. package/dist/run-fVZ-rLnc.cjs.map +1 -0
  280. package/dist/runtime-ACdfK59n.d.cts +82 -0
  281. package/dist/runtime-ACdfK59n.d.cts.map +1 -0
  282. package/dist/runtime-YyQuekxi.d.mts +82 -0
  283. package/dist/runtime-YyQuekxi.d.mts.map +1 -0
  284. package/dist/s3-CrPoA89T.cjs +215 -0
  285. package/dist/s3-CrPoA89T.cjs.map +1 -0
  286. package/dist/s3-DQXZdmCM.mjs +215 -0
  287. package/dist/s3-DQXZdmCM.mjs.map +1 -0
  288. package/dist/sandbox/config-worker.cjs +43 -0
  289. package/dist/sandbox/config-worker.cjs.map +1 -0
  290. package/dist/sandbox/config-worker.d.cts +1 -0
  291. package/dist/sandbox/config-worker.d.mts +1 -0
  292. package/dist/sandbox/config-worker.mjs +44 -0
  293. package/dist/sandbox/config-worker.mjs.map +1 -0
  294. package/dist/sandbox/credentials-worker.cjs +54 -0
  295. package/dist/sandbox/credentials-worker.cjs.map +1 -0
  296. package/dist/sandbox/credentials-worker.d.cts +1 -0
  297. package/dist/sandbox/credentials-worker.d.mts +1 -0
  298. package/dist/sandbox/credentials-worker.mjs +55 -0
  299. package/dist/sandbox/credentials-worker.mjs.map +1 -0
  300. package/dist/sandbox/discover-worker.cjs +47 -0
  301. package/dist/sandbox/discover-worker.cjs.map +1 -0
  302. package/dist/sandbox/discover-worker.d.cts +1 -0
  303. package/dist/sandbox/discover-worker.d.mts +1 -0
  304. package/dist/sandbox/discover-worker.mjs +48 -0
  305. package/dist/sandbox/discover-worker.mjs.map +1 -0
  306. package/dist/sandbox/migrate-worker.cjs +75 -0
  307. package/dist/sandbox/migrate-worker.cjs.map +1 -0
  308. package/dist/sandbox/migrate-worker.d.cts +1 -0
  309. package/dist/sandbox/migrate-worker.d.mts +1 -0
  310. package/dist/sandbox/migrate-worker.mjs +76 -0
  311. package/dist/sandbox/migrate-worker.mjs.map +1 -0
  312. package/dist/sandbox-C4g1eG31.d.mts +104 -0
  313. package/dist/sandbox-C4g1eG31.d.mts.map +1 -0
  314. package/dist/sandbox-CHv3OYXg.cjs +165 -0
  315. package/dist/sandbox-CHv3OYXg.cjs.map +1 -0
  316. package/dist/sandbox-CbVB7uOD.mjs +118 -0
  317. package/dist/sandbox-CbVB7uOD.mjs.map +1 -0
  318. package/dist/sandbox-CdKgQ3XU.d.cts +104 -0
  319. package/dist/sandbox-CdKgQ3XU.d.cts.map +1 -0
  320. package/dist/schemas-BCwKKA42.mjs +5961 -0
  321. package/dist/schemas-BCwKKA42.mjs.map +1 -0
  322. package/dist/schemas-BQ_v0lEX.cjs +6068 -0
  323. package/dist/schemas-BQ_v0lEX.cjs.map +1 -0
  324. package/dist/secretsManager-CQORubp9.mjs +97 -0
  325. package/dist/secretsManager-CQORubp9.mjs.map +1 -0
  326. package/dist/secretsManager-RAGcEDX1.cjs +108 -0
  327. package/dist/secretsManager-RAGcEDX1.cjs.map +1 -0
  328. package/dist/seeds-CHIPcMrY.cjs +9115 -0
  329. package/dist/seeds-CHIPcMrY.cjs.map +1 -0
  330. package/dist/seeds-E4nUeXTl.mjs +8148 -0
  331. package/dist/seeds-E4nUeXTl.mjs.map +1 -0
  332. package/dist/sniffer-bUiSXLMj.mjs +1825 -0
  333. package/dist/sniffer-bUiSXLMj.mjs.map +1 -0
  334. package/dist/sniffer-n3TkX6JD.cjs +1998 -0
  335. package/dist/sniffer-n3TkX6JD.cjs.map +1 -0
  336. package/dist/sst-B-Uz4cvm.cjs +464 -0
  337. package/dist/sst-B-Uz4cvm.cjs.map +1 -0
  338. package/dist/sst-C1pxbFEd.mjs +441 -0
  339. package/dist/sst-C1pxbFEd.mjs.map +1 -0
  340. package/dist/stages-DJrOYLZ-.mjs +176 -0
  341. package/dist/stages-DJrOYLZ-.mjs.map +1 -0
  342. package/dist/stages-_3RVNG83.cjs +176 -0
  343. package/dist/stages-_3RVNG83.cjs.map +1 -0
  344. package/dist/target/public.cjs +15 -0
  345. package/dist/target/public.d.cts +28 -0
  346. package/dist/target/public.d.cts.map +1 -0
  347. package/dist/target/public.d.mts +28 -0
  348. package/dist/target/public.d.mts.map +1 -0
  349. package/dist/target/public.mjs +4 -0
  350. package/dist/terminal-Bs_lNQhL.mjs +85 -0
  351. package/dist/terminal-Bs_lNQhL.mjs.map +1 -0
  352. package/dist/terminal-CsQz4oT0.cjs +85 -0
  353. package/dist/terminal-CsQz4oT0.cjs.map +1 -0
  354. package/dist/types-B6UXlEkf.d.cts +7650 -0
  355. package/dist/types-B6UXlEkf.d.cts.map +1 -0
  356. package/dist/types-HqVPddRK.d.mts +7649 -0
  357. package/dist/types-HqVPddRK.d.mts.map +1 -0
  358. package/dist/utils-D2Nk1Nv2.cjs +205 -0
  359. package/dist/utils-D2Nk1Nv2.cjs.map +1 -0
  360. package/dist/utils-D_fxUqvU.mjs +156 -0
  361. package/dist/utils-D_fxUqvU.mjs.map +1 -0
  362. package/dist/vitest.cjs +65 -0
  363. package/dist/vitest.cjs.map +1 -0
  364. package/dist/vitest.d.cts +29 -0
  365. package/dist/vitest.d.cts.map +1 -0
  366. package/dist/vitest.d.mts +29 -0
  367. package/dist/vitest.d.mts.map +1 -0
  368. package/dist/vitest.mjs +65 -0
  369. package/dist/vitest.mjs.map +1 -0
  370. package/dist/workerRuntime-BXfhbe13.cjs +108 -0
  371. package/dist/workerRuntime-BXfhbe13.cjs.map +1 -0
  372. package/dist/workerRuntime-CsOyBRx2.mjs +79 -0
  373. package/dist/workerRuntime-CsOyBRx2.mjs.map +1 -0
  374. package/dist/workspace/index.cjs +8 -4
  375. package/dist/workspace/index.d.cts +3 -3
  376. package/dist/workspace/index.d.mts +3 -3
  377. package/dist/workspace/index.mjs +2 -3
  378. package/dist/workspace-BwqQnool.cjs +2806 -0
  379. package/dist/workspace-BwqQnool.cjs.map +1 -0
  380. package/dist/workspace-D1QbNd55.mjs +2394 -0
  381. package/dist/workspace-D1QbNd55.mjs.map +1 -0
  382. package/package.json +73 -40
  383. package/dist/CachedStateProvider-BLo7zv7S.cjs +0 -3
  384. package/dist/CachedStateProvider-BxoAm-B2.mjs +0 -3
  385. package/dist/CachedStateProvider-CqPdW7CB.cjs +0 -60
  386. package/dist/CachedStateProvider-CqPdW7CB.cjs.map +0 -1
  387. package/dist/CachedStateProvider-DTniehMP.mjs +0 -54
  388. package/dist/CachedStateProvider-DTniehMP.mjs.map +0 -1
  389. package/dist/HostingerProvider-Cft7lEYr.mjs.map +0 -1
  390. package/dist/HostingerProvider-h3EbEp-Z.cjs.map +0 -1
  391. package/dist/LocalStateProvider-Bn6tS-oL.mjs +0 -42
  392. package/dist/LocalStateProvider-Bn6tS-oL.mjs.map +0 -1
  393. package/dist/LocalStateProvider-Db9SEjyH.cjs +0 -43
  394. package/dist/LocalStateProvider-Db9SEjyH.cjs.map +0 -1
  395. package/dist/Route53Provider-RdpUDJQk.mjs.map +0 -1
  396. package/dist/Route53Provider-di2fMM5N.cjs.map +0 -1
  397. package/dist/SSMStateProvider-BRt2py-A.mjs +0 -66
  398. package/dist/SSMStateProvider-BRt2py-A.mjs.map +0 -1
  399. package/dist/SSMStateProvider-DyX8s9HI.cjs +0 -66
  400. package/dist/SSMStateProvider-DyX8s9HI.cjs.map +0 -1
  401. package/dist/backup-provisioner-Bgj5Vi_L.mjs.map +0 -1
  402. package/dist/backup-provisioner-BrsHwYG0.cjs.map +0 -1
  403. package/dist/bundler-BY1OmV1e.cjs.map +0 -1
  404. package/dist/bundler-Be8Zg4Wd.mjs.map +0 -1
  405. package/dist/chunk-Duj1WY3L.mjs +0 -7
  406. package/dist/config-D8o6I_7Z.mjs +0 -469
  407. package/dist/config-D8o6I_7Z.mjs.map +0 -1
  408. package/dist/config-DbPE1KXF.cjs +0 -535
  409. package/dist/config-DbPE1KXF.cjs.map +0 -1
  410. package/dist/config.d.cts.map +0 -1
  411. package/dist/config.d.mts.map +0 -1
  412. package/dist/credentials-B5zRHdAl.mjs +0 -141
  413. package/dist/credentials-B5zRHdAl.mjs.map +0 -1
  414. package/dist/credentials-BapzjyV5.cjs +0 -195
  415. package/dist/credentials-BapzjyV5.cjs.map +0 -1
  416. package/dist/credentials-Dh0Q6HzY.mjs +0 -2548
  417. package/dist/credentials-Dh0Q6HzY.mjs.map +0 -1
  418. package/dist/credentials-K961ThG3.cjs +0 -2680
  419. package/dist/credentials-K961ThG3.cjs.map +0 -1
  420. package/dist/discover-CAlFgYec.mjs +0 -229
  421. package/dist/discover-CAlFgYec.mjs.map +0 -1
  422. package/dist/discover-DTmFeloL.cjs +0 -271
  423. package/dist/discover-DTmFeloL.cjs.map +0 -1
  424. package/dist/dokploy-api-BS2xnJLZ.mjs +0 -3
  425. package/dist/dokploy-api-BsVH0y_s.cjs +0 -718
  426. package/dist/dokploy-api-BsVH0y_s.cjs.map +0 -1
  427. package/dist/dokploy-api-BuxDRo3l.cjs +0 -3
  428. package/dist/dokploy-api-aTFPz7_4.mjs +0 -706
  429. package/dist/dokploy-api-aTFPz7_4.mjs.map +0 -1
  430. package/dist/emit-CbcRolsa.cjs.map +0 -1
  431. package/dist/emit-CiZS_5Ub.mjs.map +0 -1
  432. package/dist/encryption-C6jaU0hE.cjs +0 -54
  433. package/dist/encryption-C6jaU0hE.cjs.map +0 -1
  434. package/dist/encryption-CHzzeR8a.cjs +0 -4
  435. package/dist/encryption-CQUncu7v.mjs +0 -3
  436. package/dist/encryption-D-abyhZx.mjs +0 -42
  437. package/dist/encryption-D-abyhZx.mjs.map +0 -1
  438. package/dist/fullstack-secrets-C-GGohke.cjs +0 -111
  439. package/dist/fullstack-secrets-C-GGohke.cjs.map +0 -1
  440. package/dist/fullstack-secrets-D1o9-G5l.mjs +0 -87
  441. package/dist/fullstack-secrets-D1o9-G5l.mjs.map +0 -1
  442. package/dist/generator-CNzBw7g5.cjs +0 -289
  443. package/dist/generator-CNzBw7g5.cjs.map +0 -1
  444. package/dist/generator-VE2JrFlY.mjs +0 -253
  445. package/dist/generator-VE2JrFlY.mjs.map +0 -1
  446. package/dist/index-BThUzEIp.d.mts.map +0 -1
  447. package/dist/index-CHB4tSzX.d.cts.map +0 -1
  448. package/dist/openapi-CgpMWMmM.mjs +0 -1962
  449. package/dist/openapi-CgpMWMmM.mjs.map +0 -1
  450. package/dist/openapi-CljONd_M.cjs +0 -1998
  451. package/dist/openapi-CljONd_M.cjs.map +0 -1
  452. package/dist/openapi-react-query-Byltvm_7.mjs +0 -167
  453. package/dist/openapi-react-query-Byltvm_7.mjs.map +0 -1
  454. package/dist/openapi-react-query-CmJ1xDbn.cjs +0 -173
  455. package/dist/openapi-react-query-CmJ1xDbn.cjs.map +0 -1
  456. package/dist/openapi-react-query.cjs +0 -4
  457. package/dist/openapi-react-query.d.cts +0 -11
  458. package/dist/openapi-react-query.d.cts.map +0 -1
  459. package/dist/openapi-react-query.d.mts +0 -11
  460. package/dist/openapi-react-query.d.mts.map +0 -1
  461. package/dist/openapi-react-query.mjs +0 -4
  462. package/dist/reconcile-CFs8C_1a.mjs.map +0 -1
  463. package/dist/reconcile-D0pimNiy.cjs.map +0 -1
  464. package/dist/setup-CJiQM2pX.cjs +0 -473
  465. package/dist/setup-CJiQM2pX.cjs.map +0 -1
  466. package/dist/setup-DMtU3p41.cjs +0 -11
  467. package/dist/setup-DOsYueeQ.mjs +0 -443
  468. package/dist/setup-DOsYueeQ.mjs.map +0 -1
  469. package/dist/setup-DSutDAlt.mjs +0 -11
  470. package/dist/storage-BJmzYxt8.cjs +0 -363
  471. package/dist/storage-BJmzYxt8.cjs.map +0 -1
  472. package/dist/storage-BM9hGpgv.cjs +0 -7
  473. package/dist/storage-Bi24WfoW.mjs +0 -297
  474. package/dist/storage-Bi24WfoW.mjs.map +0 -1
  475. package/dist/storage-CYlGwWTj.mjs +0 -3
  476. package/dist/sync-CmEuNZsB.mjs +0 -76
  477. package/dist/sync-CmEuNZsB.mjs.map +0 -1
  478. package/dist/sync-D306yOWu.cjs +0 -4
  479. package/dist/sync-SizaChmC.cjs +0 -93
  480. package/dist/sync-SizaChmC.cjs.map +0 -1
  481. package/dist/sync-hOqAWHR6.mjs +0 -3
  482. package/dist/types-C-arnQ1r.d.mts +0 -2184
  483. package/dist/types-C-arnQ1r.d.mts.map +0 -1
  484. package/dist/types-abJQuk7m.d.cts +0 -2184
  485. package/dist/types-abJQuk7m.d.cts.map +0 -1
  486. package/dist/workspace-7FqprxuJ.mjs +0 -4323
  487. package/dist/workspace-7FqprxuJ.mjs.map +0 -1
  488. package/dist/workspace-8acupeaI.cjs +0 -9
  489. package/dist/workspace-XvqO9jIv.cjs +0 -4472
  490. package/dist/workspace-XvqO9jIv.cjs.map +0 -1
  491. package/dist/workspace-yP5AHnrn.mjs +0 -8
package/README.md CHANGED
@@ -7,7 +7,7 @@ A powerful CLI tool for building and managing TypeScript-based backend APIs with
7
7
  - **Project Scaffolding**: Interactive `init` command to bootstrap new projects with templates
8
8
  - **Multi-Provider Support**: Generate handlers for AWS Lambda (API Gateway v1/v2) and server applications
9
9
  - **Development Server**: Hot-reload development server with file watching
10
- - **Telescope Integration**: Laravel-style debugging dashboard for inspecting requests, logs, and exceptions
10
+ - **Telescope Integration**: Laravel-style recording of requests, logs and exceptions, served as JSON
11
11
  - **OpenAPI Generation**: Auto-generate OpenAPI 3.0 specifications from your endpoints
12
12
  - **Docker Support**: Generate optimized Dockerfiles with multi-stage builds, turbo prune for monorepos
13
13
  - **Secrets Management**: Secure credential generation, encryption, and stage-based secrets storage
@@ -54,6 +54,7 @@ Create a `gkm.config.ts` file in your project root:
54
54
  import { defineConfig } from '@geekmidas/cli/config';
55
55
 
56
56
  export default defineConfig({
57
+ stages: { local: 'dev', deployed: ['prod'] },
57
58
  // Glob pattern to find endpoint files
58
59
  routes: 'src/routes/**/*.ts',
59
60
 
@@ -72,7 +73,7 @@ export default defineConfig({
72
73
  // Logger configuration
73
74
  logger: './src/logger.ts#logger',
74
75
 
75
- // Optional: Telescope debugging dashboard (enabled by default in dev)
76
+ // Optional: Telescope request recording (enabled by default in dev)
76
77
  telescope: {
77
78
  enabled: true,
78
79
  path: '/__telescope',
@@ -142,36 +143,32 @@ export const createUser = api
142
143
 
143
144
  ### 5. Create Subscribers (Optional)
144
145
 
145
- Create event subscribers in `src/subscribers/`:
146
+ Declare the topic once, and a worker to run what has no port; a subscriber is
147
+ built from the worker and binds to the topic:
146
148
 
147
149
  ```typescript
150
+ // src/constructs/topics.ts
151
+ import { Topic } from '@geekmidas/constructs/topic';
152
+ import { z } from 'zod';
153
+
154
+ export const users = new Topic('Users', {
155
+ events: {
156
+ 'user.created': z.object({ userId: z.string(), email: z.email() }),
157
+ 'user.updated': z.object({ userId: z.string() }),
158
+ },
159
+ });
160
+
161
+ // src/constructs/worker.ts
162
+ import { Worker } from '@geekmidas/constructs/worker';
163
+
164
+ export const worker = new Worker('Jobs', { logger });
165
+
148
166
  // src/subscribers/userSubscriber.ts
149
- import { SubscriberBuilder } from '@geekmidas/constructs/subscribers';
150
- import type { Service } from '@geekmidas/services';
151
- import type { EventPublisher, PublishableMessage } from '@geekmidas/events';
152
- import type { EnvironmentParser } from '@geekmidas/envkit';
153
-
154
- // Define event types
155
- type UserEvents =
156
- | PublishableMessage<'user.created', { userId: string; email: string }>
157
- | PublishableMessage<'user.updated', { userId: string }>;
158
-
159
- // Create event publisher service
160
- const userEventPublisher = {
161
- serviceName: 'userEventPublisher' as const,
162
- async register(envParser: EnvironmentParser<{}>) {
163
- const config = envParser.create((get) => ({
164
- publisherUrl: get('EVENT_PUBLISHER_URL').string()
165
- })).parse();
166
-
167
- const { Publisher } = await import('@geekmidas/events');
168
- return Publisher.fromConnectionString<UserEvents>(config.publisherUrl);
169
- }
170
- } satisfies Service<'userEventPublisher', EventPublisher<UserEvents>>;
167
+ import { users } from '../constructs/topics';
168
+ import { worker } from '../constructs/worker';
171
169
 
172
- // Create subscriber
173
- export const userCreatedSubscriber = new SubscriberBuilder()
174
- .publisher(userEventPublisher)
170
+ export const userCreatedSubscriber = worker
171
+ .topic(users)
175
172
  .subscribe(['user.created'])
176
173
  .handle(async ({ events, logger }) => {
177
174
  for (const event of events) {
@@ -181,11 +178,16 @@ export const userCreatedSubscriber = new SubscriberBuilder()
181
178
  });
182
179
  ```
183
180
 
181
+ An endpoint publishes to the topic with `.event(users, { type: 'user.created',
182
+ payload: (user) => ({ userId: user.id, email: user.email }) })`. Declaring the
183
+ topic is what puts a broker in the local plan and resolves
184
+ `USERS_PUBLISHER_CONNECTION_STRING` for whatever publishes to it.
185
+
184
186
  ### 6. Build Handlers
185
187
 
186
188
  ```bash
187
- # Generate AWS Lambda handlers
188
- npx gkm build --provider aws-apigatewayv1
189
+ # Build for where gkm.config.ts deploys (AWS for `deploy: { default: 'sst' }`)
190
+ npx gkm build
189
191
 
190
192
  # Generate server application
191
193
  npx gkm build --provider server
@@ -224,7 +226,7 @@ When run without `--yes`, the command will ask:
224
226
  - `api` - Full API with auth, database, services
225
227
  - `serverless` - AWS Lambda handlers
226
228
  - `worker` - Background job processing
227
- 3. **Telescope** - Include debugging dashboard (default: yes)
229
+ 3. **Telescope** - Include request, exception and log recording (default: yes)
228
230
  4. **Database** - Include Kysely database support (default: yes)
229
231
  5. **Logger** - Choose logger implementation:
230
232
  - `pino` - Fast JSON logger for production (recommended)
@@ -309,17 +311,20 @@ Generate handlers from your endpoints.
309
311
  gkm build [options]
310
312
  ```
311
313
 
314
+ By default it builds for where the project deploys: `deploy: { default: 'sst' }`
315
+ builds for AWS, one Lambda per construct; `dokploy` (the default when nothing
316
+ is declared) builds a server.
317
+
312
318
  **Options:**
313
- - `--provider <provider>`: Target provider (default: `aws-apigatewayv1`)
314
- - `aws-apigatewayv1`: AWS API Gateway v1 Lambda handlers
315
- - `aws-apigatewayv2`: AWS API Gateway v2 Lambda handlers
319
+ - `--provider <provider>`: Override the deploy target
320
+ - `aws`: One Lambda handler per construct (API Gateway v2 for endpoints)
316
321
  - `server`: Server application with Hono
317
322
  - `--production`: Generate production-optimized bundle (server provider only)
318
323
 
319
324
  **Example:**
320
325
  ```bash
321
- # Generate AWS Lambda handlers
322
- gkm build --provider aws-apigatewayv1
326
+ # Build for where gkm.config.ts deploys
327
+ gkm build
323
328
 
324
329
  # Generate server application
325
330
  gkm build --provider server
@@ -333,7 +338,7 @@ gkm build --provider server --production
333
338
  When using `--production` with the server provider, the CLI generates an optimized bundle at `.gkm/server/dist/server.mjs`. This bundle:
334
339
  - Is minified and tree-shaken for smaller size
335
340
  - Includes all dependencies (single-file deployment)
336
- - Can be used with `gkm docker --slim` for minimal Docker images
341
+ - Is what `gkm docker`'s images run — built inside the image, never copied in from the host
337
342
 
338
343
  ### `gkm openapi`
339
344
 
@@ -433,54 +438,44 @@ gkm docker [options]
433
438
  ```
434
439
 
435
440
  **Options:**
436
- - `--build`: Build Docker image after generating files
437
- - `--push`: Push image to registry after building
441
+ - `--build`: Build each app's image after generating files
442
+ - `--push`: Push the images to the registry after building
438
443
  - `--tag <tag>`: Image tag (default: `latest`)
439
444
  - `--registry <url>`: Container registry URL
440
- - `--slim`: Use slim Dockerfile (requires pre-built bundle from `gkm build --production`)
441
- - `--turbo`: Enable turbo prune for monorepo optimization
442
- - `--turbo-package <name>`: Package name for turbo prune (defaults to package.json name)
443
445
 
444
446
  **Generated Files:**
445
- - `.gkm/docker/Dockerfile` - Multi-stage or slim Dockerfile
446
- - `.gkm/docker/docker-compose.yml` - Docker Compose configuration
447
- - `.gkm/docker/docker-entrypoint.sh` - Entrypoint script
448
- - `.dockerignore` - Docker ignore file (project root)
447
+ - `.gkm/docker/Dockerfile.<app>` - one per app (`Dockerfile` for an app at the root)
448
+ - `docker-compose.constructs.yml` - the containers the constructs imply, and the apps (project root)
449
+ - `.dockerignore` - at the build root, created or completed
449
450
 
450
- **Dockerfile Types:**
451
+ **How an image is built:**
451
452
 
452
- | Type | Flag | Description |
453
- |------|------|-------------|
454
- | Multi-stage | (default) | Builds from source inside Docker, most reproducible |
455
- | Turbo | `--turbo` | Optimized for monorepos with turbo prune |
456
- | Slim | `--slim` | Uses pre-built bundle, requires prior `gkm build --production` |
453
+ Every image is built inside Docker — `docker build` on a clean checkout is all
454
+ it takes. The context is the build root (the directory holding the lockfile or
455
+ `pnpm-workspace.yaml`, at or above the workspace); `turbo prune` cuts the app's
456
+ slice of it; the image installs it, builds the workspace packages the app
457
+ depends on, and builds the app (`gkm build --provider server --production` for
458
+ a backend, the framework's build for a site). The runner holds `server.mjs`, a
459
+ Next.js standalone server, or a Vite site's files served by Caddy.
457
460
 
458
461
  **Example:**
459
462
  ```bash
460
- # Generate multi-stage Dockerfile (default, recommended)
463
+ # Generate the Dockerfiles
461
464
  gkm docker
462
465
 
463
- # Generate and build image
466
+ # Generate and build the images
464
467
  gkm docker --build --tag v1.0.0
465
468
 
466
469
  # Build and push to registry
467
470
  gkm docker --build --push --registry ghcr.io/myorg --tag v1.0.0
468
-
469
- # Use turbo prune for monorepo
470
- gkm docker --turbo --turbo-package my-api
471
-
472
- # Use slim Dockerfile (after running gkm build --production)
473
- gkm build --provider server --production
474
- gkm docker --slim
475
471
  ```
476
472
 
477
473
  **Package Manager Support:**
478
474
 
479
- The CLI auto-detects your package manager from lockfiles and generates optimized Dockerfiles:
480
- - **pnpm**: Uses `pnpm fetch` for better layer caching
481
- - **npm**: Uses `npm ci` with cache mounts
482
- - **yarn**: Uses `yarn install --frozen-lockfile`
483
- - **bun**: Uses `bun install --frozen-lockfile`
475
+ The package manager is detected from the lockfile and pinned to the build
476
+ root's `packageManager` field; turbo is pinned to the version the build root
477
+ resolves. Dependencies install with a BuildKit cache mount for the package
478
+ manager's store.
484
479
 
485
480
  **Configuration:**
486
481
 
@@ -490,6 +485,7 @@ Configure Docker settings in `gkm.config.ts`:
490
485
  import { defineConfig } from '@geekmidas/cli/config';
491
486
 
492
487
  export default defineConfig({
488
+ stages: { local: 'dev', deployed: ['prod'] },
493
489
  routes: 'src/routes/**/*.ts',
494
490
  envParser: './src/env.ts',
495
491
  logger: './src/logger.ts',
@@ -503,38 +499,20 @@ export default defineConfig({
503
499
  baseImage: 'node:22-alpine',
504
500
  // Port to expose (default: 3000)
505
501
  port: 3000,
506
- // Docker Compose services
507
- compose: {
508
- services: {
509
- postgres: { image: 'postgis/postgis:16-3.4-alpine' }, // Custom image
510
- redis: true, // Default version
511
- rabbitmq: { version: '3.12-management-alpine' }, // Custom version
512
- },
513
- },
514
502
  },
515
503
  });
516
504
  ```
517
505
 
518
- **Docker Compose Services:**
506
+ **Compose:** there is no `compose` option. `gkm docker` writes
507
+ `docker-compose.constructs.yml` at the project root from the declared
508
+ constructs; an image pin or an extra service goes in your own
509
+ `docker-compose.yml`, which is merged over it:
519
510
 
520
- Services can be configured with custom versions, custom images, or use defaults:
521
-
522
- ```typescript
523
- // Object format (recommended)
524
- services: {
525
- postgres: { version: '15-alpine' }, // Custom version
526
- redis: true, // Default: redis:7-alpine
527
- rabbitmq: { version: '3.12-management-alpine' },
528
- }
529
-
530
- // Custom images (e.g., PostGIS, Redis Stack)
531
- services: {
532
- postgres: { image: 'postgis/postgis:16-3.4-alpine' }, // Full image reference
533
- redis: { image: 'redis/redis-stack:latest' },
534
- }
535
-
536
- // Legacy array format - uses default versions
537
- services: ['postgres', 'redis', 'rabbitmq']
511
+ ```yaml
512
+ # docker-compose.yml
513
+ services:
514
+ postgres:
515
+ image: postgis/postgis:16-3.4-alpine
538
516
  ```
539
517
 
540
518
  **Service Configuration Options:**
@@ -557,7 +535,7 @@ services: ['postgres', 'redis', 'rabbitmq']
557
535
 
558
536
  ### `gkm dev`
559
537
 
560
- Start a development server with hot-reload and optional Telescope debugging dashboard.
538
+ Start a development server with hot-reload and optional Telescope recording.
561
539
 
562
540
  ```bash
563
541
  gkm dev [options]
@@ -569,7 +547,8 @@ gkm dev [options]
569
547
  **Features:**
570
548
  - Hot-reload on file changes (endpoints, functions, crons, subscribers)
571
549
  - Automatic port switching if requested port is in use
572
- - Telescope debugging dashboard (enabled by default)
550
+ - Telescope JSON API at `/__telescope/api` (enabled by default)
551
+ - The declared database, read-only, as JSON at `/__gkm/db`
573
552
  - Real-time WebSocket updates in Telescope
574
553
 
575
554
  **Example:**
@@ -682,8 +661,8 @@ gkm secrets:init --stage production --force
682
661
  ```
683
662
 
684
663
  **Generated:**
685
- - Secure passwords for postgres, redis, rabbitmq (based on `docker.compose.services` config)
686
- - Connection URLs (`DATABASE_URL`, `REDIS_URL`, `RABBITMQ_URL`)
664
+ - Custom secrets for the stage; the containers' credentials are provisioned by
665
+ reconcile from the declared constructs, not stored here
687
666
  - Stored in `.gkm/secrets/<stage>.json` (gitignored)
688
667
 
689
668
  ### `gkm secrets:set`
@@ -797,7 +776,7 @@ Store credentials locally to avoid setting environment variables for every comma
797
776
 
798
777
  ### `gkm login`
799
778
 
800
- Authenticate with a deployment service. Credentials are stored in `~/.gkm/credentials.json`.
779
+ Authenticate with a deployment service. Credentials are stored in `~/.gkm/credentials.json` (`$GKM_HOME/credentials.json` when `GKM_HOME` is set).
801
780
 
802
781
  ```bash
803
782
  gkm login [options]
@@ -825,7 +804,7 @@ gkm login --endpoint https://dokploy.example.com
825
804
  # These commands no longer need DOKPLOY_API_TOKEN
826
805
  gkm deploy:list
827
806
  gkm deploy:init --project my-project --app api
828
- gkm deploy --provider dokploy --stage production
807
+ gkm deploy --stage production
829
808
  ```
830
809
 
831
810
  ### `gkm logout`
@@ -871,91 +850,99 @@ gkm whoami
871
850
 
872
851
  ### `gkm deploy`
873
852
 
874
- Deploy application to a provider. Builds for production, injects encrypted secrets, and deploys.
853
+ Deploy a stage through its **target**: `deploy.default` in `gkm.config.ts`
854
+ (`dokploy` when unset), or `--target` for one run. `dokploy`, `compose` and
855
+ `sst` ship with the CLI; any other target is a package the project installs and
856
+ names in `deploy.targets`.
875
857
 
876
858
  ```bash
877
- gkm deploy --provider <provider> --stage <stage> [options]
859
+ gkm deploy --stage <stage> [options]
878
860
  ```
879
861
 
880
862
  **Options:**
881
- - `--provider <provider>`: Deploy provider (`docker`, `dokploy`, `aws-lambda`)
882
- - `--stage <stage>`: Deployment stage
883
- - `--tag <tag>`: Image tag (default: `stage-timestamp`)
884
- - `--skip-push`: Skip pushing image to registry
885
- - `--skip-build`: Skip build step (use existing build)
863
+ - `--stage <stage>`: Deployment stage (required): one of `stages.deployed`, or the local stage through `compose`
864
+ - `--target <name>`: `dokploy`, `compose`, `sst`, or a name in `deploy.targets` (default: `deploy.default`)
865
+ - `--tag <tag>`: Image tag (default: `<stage>-<timestamp>`; compose: the commit). Through compose, a given tag is pulled
866
+ - `--json`: Write the deploy's events as JSON lines on stdout instead of progress; never prompts
867
+ - `--dry-run`: Show what would be created or reused, and change, build and push nothing
868
+ - `--atomic`: If the release fails, roll back every app it released, not only the ones that failed
869
+ - `--provider <provider>`: Deprecated. `dokploy` means `--target dokploy`; `docker` and `aws-lambda` fail with `ProviderRemoved`
870
+ - `--skip-push`, `--skip-build`: Deprecated and ignored
886
871
 
887
872
  **Examples:**
888
873
  ```bash
889
- # Docker: build and push image
890
- gkm deploy --provider docker --stage production
874
+ # deploy.default (dokploy unless configured otherwise)
875
+ DOKPLOY_API_TOKEN=xxx gkm deploy --stage production
891
876
 
892
- # Dokploy: build, push, and trigger deployment
893
- DOKPLOY_API_TOKEN=xxx gkm deploy --provider dokploy --stage production
877
+ # Plan only
878
+ gkm deploy --stage production --dry-run
894
879
 
895
- # Custom tag
896
- gkm deploy --provider docker --stage production --tag v1.0.0
897
- ```
880
+ # One Docker Compose stack behind Caddy, on this machine, from images CI pushed
881
+ gkm deploy --target compose --stage production --tag v1.4.0
898
882
 
899
- **Workflow:**
900
- 1. **Sniffs environment variables** - Automatically detects which env vars each app needs
901
- 2. Builds production bundle with `gkm build --provider server --production --stage <stage>`
902
- 3. Encrypts secrets from `.gkm/secrets/<stage>.json` into the bundle
903
- 4. Generates Docker files with `gkm docker`
904
- 5. Builds and pushes Docker image
905
- 6. (Dokploy) Triggers deployment via API with `GKM_MASTER_KEY`
883
+ # AWS, with deploy: { default: 'sst' }: gkm build --provider aws, then sst deploy
884
+ AWS_PROFILE=acme-prod gkm deploy --stage production
906
885
 
907
- **Environment Variable Detection:**
908
-
909
- The deploy command automatically detects required environment variables for each app using different strategies based on app configuration:
886
+ # Events for another program
887
+ gkm deploy --stage production --json | jq -c 'select(.type == "app.deployed")'
888
+ ```
910
889
 
911
- | App Type | Detection Strategy |
912
- |----------|-------------------|
913
- | Frontend apps | Returns empty (no server secrets) |
914
- | Apps with `requiredEnv` | Uses explicit list from config |
915
- | Entry-based apps | Imports entry file in subprocess to capture `config.parse()` calls |
916
- | Route-based apps | Loads routes and calls `getEnvironment()` on each construct |
917
- | Apps with `envParser` only | Runs SnifferEnvironmentParser to detect usage |
890
+ **What every deploy does:** loads the config and discovers the constructs in a
891
+ sandbox, takes the stage's lock (a second run gets `StateLocked`; a crashed
892
+ run's lock is released with `gkm state:unlock`), checks every credential and
893
+ secret before anything changes, then runs the target's phases
894
+ (`provision`, `build`, `release`, `verify`) and reports each as events.
918
895
 
919
- For route-based apps, the sniffer loads each endpoint/function/cron/subscriber and collects environment variables from:
920
- - All services attached to the construct (via `service.register()`)
921
- - Publisher service (if any)
922
- - Auditor storage service (if any)
923
- - Database service (if any)
896
+ **Verified, or rolled back (Dokploy).** An app counts as released once Dokploy's deployment has finished and the app has answered its health route 2xx three times in a row (`/health` for a backend, `/` for a site; an app without a domain gets the deployment check only). Backends are released and checked before any site is released, and a failed backend stops the run. Whatever fails is pointed back at the image it ran before. Pending migrations are applied before any app is switched, in the deploy's sandbox, with each database URL handed over as a secret file. Tune the checks with `deploy.dokploy.verify: { deploymentTimeoutMs, healthCheckPath, healthyAfter, intervalMs, healthTimeoutMs }`.
924
897
 
925
- This allows the CLI to validate that all required secrets are configured before deployment, preventing runtime errors from missing environment variables.
898
+ At a terminal a missing Dokploy or registry login is asked for (and the Dokploy one stored). With `--json` or without a terminal nothing is asked: the deploy stops with `MissingCredential` and exits 1.
926
899
 
927
- **Configuration:**
900
+ **From a program:** the same deploy is `deploy()` from `@geekmidas/cli/deploy` — explicit `cwd`, an injected `CredentialProvider`, a logger and an `AbortSignal`; it returns a run you iterate for JSON events, plus a `result` promise. It never prompts, prints or exits.
928
901
 
929
902
  ```typescript
930
- // gkm.config.ts
931
- export default defineConfig({
932
- routes: 'src/endpoints/**/*.ts',
933
- envParser: './src/env.ts',
934
- logger: './src/logger.ts',
903
+ import { deploy } from '@geekmidas/cli/deploy';
935
904
 
936
- docker: {
937
- registry: 'ghcr.io/myorg',
938
- imageName: 'my-api',
939
- },
940
-
941
- // For Dokploy deployments
942
- providers: {
943
- dokploy: {
944
- endpoint: 'https://dokploy.example.com',
945
- projectId: 'proj_xxx',
946
- applicationId: 'app_xxx',
947
- },
948
- },
949
- });
905
+ const run = deploy({ cwd: '/srv/shop', stage: 'production', signal });
906
+ for await (const event of run) console.log(event.type);
907
+ const result = await run.result;
950
908
  ```
951
909
 
910
+ The project's own code — loading `gkm.config.ts`, discovering constructs, sniffing each app's environment, running migrations — runs in a `Sandbox`, never in the host process and never with the deploy's credentials. The default `LocalSandbox` is a child process with an allowlisted environment and a timeout per step; a host building repositories it does not trust passes its own isolating one (`sandbox`), and a config holding live objects then fails with `ConfigObjectNotSerializable`.
911
+
912
+ **Writing a target:** `defineTarget` from `@geekmidas/cli/target`, with the package's runtime declared in its `package.json` (`"gkm": { "runtime": "server" }`).
913
+
952
914
  **Environment Variables:**
953
915
  - `DOKPLOY_API_TOKEN`: API token for Dokploy (not needed if logged in via `gkm login`)
954
- - `GKM_MASTER_KEY`: Automatically set by Dokploy, or manually for Docker deployments
916
+ - `DOKPLOY_ENDPOINT`: Dokploy URL, if neither the stored login nor `deploy.dokploy.endpoint` gives one
917
+ - `DOCKER_REGISTRY_USERNAME` / `DOCKER_REGISTRY_PASSWORD`: a registry login, used only when Dokploy has no registry for `deploy.registry` and one has to be created
918
+ - `AWS_PROFILE`, or `AWS_ACCESS_KEY_ID` / `AWS_SECRET_ACCESS_KEY` / `AWS_SESSION_TOKEN`: the `sst` target's AWS credentials, handed to `sst deploy` only (the profile wins when both are set)
919
+ - `GKM_HOME`: where stage keys and stored logins live (default `~/.gkm`)
920
+ - `GKM_MASTER_KEY`: set in each container's runtime environment by the deploy; for an image you run yourself, from `.gkm/server/master.key`, which `gkm build --stage` writes (the key is never printed; output shows its fingerprint)
921
+
922
+ **Guides:**
923
+ [Deploy targets](https://geekmidas.github.io/toolbox/next/guide/deploy-targets) ·
924
+ [Writing a target](https://geekmidas.github.io/toolbox/next/guide/writing-a-target) ·
925
+ [Deploying from a program](https://geekmidas.github.io/toolbox/next/guide/deploy-api) ·
926
+ [The sandbox](https://geekmidas.github.io/toolbox/next/guide/sandbox) ·
927
+ [Deploy state](https://geekmidas.github.io/toolbox/next/guide/state) ·
928
+ [Running in production](https://geekmidas.github.io/toolbox/next/guide/production) ·
929
+ [Upgrading to 10.0.0-alpha](https://geekmidas.github.io/toolbox/next/guide/upgrading) ·
930
+ [Deprecated deploy APIs](https://geekmidas.github.io/toolbox/next/guide/deploy-deprecations)
931
+
932
+ ### `gkm deploy:rollback`
933
+
934
+ Put a stage's app back on the release before the one it runs (Dokploy). One app by default; `--atomic` rolls back every app that has an earlier release, for apps that only work together. It restores images only: migrations are forward-only.
935
+
936
+ ```bash
937
+ gkm deploy:rollback --stage production --app api
938
+ gkm deploy:rollback --stage production --atomic
939
+ ```
940
+
941
+ From a program: `rollbackStage({ cwd, stage, app })` from `@geekmidas/cli/deploy`.
955
942
 
956
943
  ### `gkm deploy:init`
957
944
 
958
- Initialize a new Dokploy deployment by creating a project and application via the Dokploy API. Automatically updates `gkm.config.ts` with the configuration.
945
+ Initialize a new Dokploy deployment by creating a project and application via the Dokploy API. Nothing is written to `gkm.config.ts`: the ids are rediscovered by name on each run and kept in the deploy state file.
959
946
 
960
947
  ```bash
961
948
  gkm deploy:init --project <name> --app <name> [options]
@@ -990,8 +977,7 @@ gkm deploy:init \
990
977
  1. Searches for existing project by name, or creates a new one
991
978
  2. Creates a new application in the project
992
979
  3. Configures registry if `--registry-id` is provided
993
- 4. Updates `gkm.config.ts` with the Dokploy configuration
994
- 5. Shows next steps for secrets and deployment
980
+ 4. Shows next steps for secrets and deployment
995
981
 
996
982
  ### `gkm deploy:list`
997
983
 
@@ -1017,6 +1003,24 @@ gkm deploy:list --registries
1017
1003
  gkm deploy:list --endpoint https://dokploy.example.com
1018
1004
  ```
1019
1005
 
1006
+ ### `gkm state:*`
1007
+
1008
+ Deploy state records what a stage's deploys created, so the next deploy finds
1009
+ it again. It lives where `state` in `gkm.config.ts` says: `.gkm/deploy-<stage>.json`
1010
+ by default, or SSM (`{ provider: 'ssm', region }`) or S3
1011
+ (`{ provider: 's3', bucket, region }`) for teams and CI. Every deploy holds the
1012
+ stage's lock and writes conditionally.
1013
+
1014
+ ```bash
1015
+ gkm state:show --stage production [--json] # ids, releases, pending resources; secrets masked
1016
+ gkm state:pull --stage production # remote → .gkm/
1017
+ gkm state:push --stage production # .gkm/ → remote, under the remote lock
1018
+ gkm state:diff --stage production
1019
+ gkm state:unlock --stage production # release a crashed deploy's lock
1020
+ ```
1021
+
1022
+ See [Deploy state](https://geekmidas.github.io/toolbox/next/guide/state).
1023
+
1020
1024
  ### Using Encrypted Credentials
1021
1025
 
1022
1026
  After deploying with secrets, your application decrypts credentials at runtime:
@@ -1040,7 +1044,7 @@ export const envParser = new EnvironmentParser({...process.env, ...Credentials})
1040
1044
 
1041
1045
  **How it works:**
1042
1046
  - At build time, secrets are encrypted with AES-256-GCM and embedded in the bundle
1043
- - An ephemeral master key is generated per build
1047
+ - An ephemeral master key is generated per build and written to `.gkm/server/master.key` (mode `0600`); the build prints its path and fingerprint, never the key
1044
1048
  - At runtime, `Credentials` decrypts using `GKM_MASTER_KEY` environment variable
1045
1049
  - In development (no embedded secrets), `Credentials` returns `{}`
1046
1050
 
@@ -1059,28 +1063,23 @@ The following commands are planned for future releases:
1059
1063
  The `gkm.config.ts` file defines how the CLI discovers and processes your endpoints:
1060
1064
 
1061
1065
  ```typescript
1062
- // Construct types accept a string, string[], or partitioned config
1063
- type Routes = string | string[] | PartitionedRoutes;
1064
-
1065
- interface PartitionedRoutes {
1066
- paths: string | string[];
1067
- partition: (filepath: string) => string;
1068
- }
1066
+ // Construct types accept a glob string or an array of them
1067
+ type Routes = string | string[];
1069
1068
 
1070
1069
  interface GkmConfig {
1071
- routes: Routes; // Glob patterns or partitioned config
1070
+ routes: Routes; // Glob patterns
1072
1071
  envParser: string; // Path to environment parser
1073
1072
  logger: string; // Path to logger configuration
1074
- functions?: Routes; // Glob patterns or partitioned config
1075
- crons?: Routes; // Glob patterns or partitioned config
1076
- subscribers?: Routes; // Glob patterns or partitioned config
1073
+ functions?: Routes; // Glob patterns
1074
+ crons?: Routes; // Glob patterns
1075
+ subscribers?: Routes; // Glob patterns
1077
1076
  runtime?: 'node' | 'bun'; // Runtime environment (default: 'node')
1078
1077
  telescope?: boolean | TelescopeConfig; // Telescope debugging config
1079
1078
  }
1080
1079
 
1081
1080
  interface TelescopeConfig {
1082
1081
  enabled?: boolean; // Enable/disable (default: true in dev)
1083
- path?: string; // Dashboard path (default: '/__telescope')
1082
+ path?: string; // Where the JSON API is mounted (default: '/__telescope')
1084
1083
  ignore?: string[]; // URL patterns to ignore
1085
1084
  recordBody?: boolean; // Record request/response bodies (default: true)
1086
1085
  maxEntries?: number; // Max entries to keep (default: 1000)
@@ -1092,7 +1091,7 @@ interface TelescopeConfig {
1092
1091
 
1093
1092
  #### `routes`
1094
1093
 
1095
- Glob pattern(s) to discover endpoint files. Can be a single pattern, array of patterns, or a partitioned config:
1094
+ Glob pattern(s) to discover endpoint files. Can be a single pattern or an array of patterns:
1096
1095
 
1097
1096
  ```typescript
1098
1097
  // Single pattern
@@ -1104,19 +1103,8 @@ routes: [
1104
1103
  'src/api/**/*.ts',
1105
1104
  'src/handlers/**/*.ts'
1106
1105
  ]
1107
-
1108
- // Partitioned — groups constructs in the generated manifest
1109
- routes: {
1110
- paths: './src/endpoints/**/*.ts',
1111
- partition: (filepath) => {
1112
- const match = filepath.match(/endpoints\/([^/]+)\//);
1113
- return match?.[1] ?? 'default';
1114
- },
1115
- }
1116
1106
  ```
1117
1107
 
1118
- The same partitioned format works for `functions`, `crons`, and `subscribers`. When a `partition` callback is provided, the generated manifest groups constructs by partition name (e.g., `manifest.routes.admin`). Without it, manifest fields remain flat arrays.
1119
-
1120
1108
  #### `envParser`
1121
1109
 
1122
1110
  Path to your environment parser configuration. Supports both default and named exports.
@@ -1149,7 +1137,7 @@ logger: './src/utils.ts#appLogger'
1149
1137
 
1150
1138
  #### `telescope`
1151
1139
 
1152
- Configuration for the Telescope debugging dashboard. Telescope is enabled by default when using `gkm dev`.
1140
+ Configuration for Telescope, which records requests, logs and exceptions and serves them as JSON. Telescope is enabled by default when using `gkm dev`.
1153
1141
 
1154
1142
  ```typescript
1155
1143
  // Disable telescope
@@ -1174,7 +1162,7 @@ telescope: {
1174
1162
  | Option | Type | Default | Description |
1175
1163
  |--------|------|---------|-------------|
1176
1164
  | `enabled` | `boolean` | `true` | Enable/disable Telescope |
1177
- | `path` | `string` | `/__telescope` | Dashboard URL path |
1165
+ | `path` | `string` | `/__telescope` | Where the JSON API is mounted |
1178
1166
  | `ignore` | `string[]` | `[]` | URL patterns to exclude from recording |
1179
1167
  | `recordBody` | `boolean` | `true` | Record request/response bodies |
1180
1168
  | `maxEntries` | `number` | `1000` | Maximum entries per type to keep |
@@ -1216,6 +1204,7 @@ import { defineWorkspace } from '@geekmidas/cli/config';
1216
1204
 
1217
1205
  export default defineWorkspace({
1218
1206
  name: 'my-project',
1207
+ stages: { local: 'dev', deployed: ['prod'] },
1219
1208
  constructs: './constructs/**/*.ts',
1220
1209
  shared: {
1221
1210
  packages: ['packages/*'],
@@ -1239,7 +1228,7 @@ them out of the manifest; none of them is listed in config.
1239
1228
 
1240
1229
  ```typescript
1241
1230
  // constructs/api.ts
1242
- export const api = new RestApi('Api', { defaultAuthorizer: 'none', logger });
1231
+ export const api = new RestApi('Api', { path: 'apps/api', defaultAuthorizer: 'none', logger });
1243
1232
  ```
1244
1233
 
1245
1234
  `gkm build --provider server` generates a Hono server from the endpoints built
@@ -1253,6 +1242,7 @@ An auth server mounts a wildcard, so there is nothing for a glob to find:
1253
1242
  ```typescript
1254
1243
  // constructs/auth.ts
1255
1244
  export const auth = new BetterAuth('Auth', {
1245
+ path: 'apps/auth',
1256
1246
  database: authDb,
1257
1247
  basePath: '/api/auth',
1258
1248
  });
@@ -1271,8 +1261,8 @@ from being read by it.
1271
1261
 
1272
1262
  ```typescript
1273
1263
  // constructs/site.ts
1274
- export const web = new StaticSite('Web').dependsOn([api, auth]);
1275
- export const admin = new StaticSite('Admin', { variant: 'next' }).dependsOn([api]);
1264
+ export const web = new StaticSite('Web', { path: 'apps/web' }).dependsOn([api, auth]);
1265
+ export const admin = new StaticSite('Admin', { path: 'apps/admin', variant: 'next' }).dependsOn([api]);
1276
1266
  ```
1277
1267
 
1278
1268
  `.dependsOn()` is the single fact behind four things that are hand-maintained
@@ -1291,7 +1281,7 @@ gkm docker
1291
1281
  - `.gkm/docker/Dockerfile.api` - Routes-based backend (uses `gkm build`)
1292
1282
  - `.gkm/docker/Dockerfile.auth` - Entry-based backend (uses esbuild bundling)
1293
1283
  - `.gkm/docker/Dockerfile.web` - Next.js standalone output
1294
- - `.gkm/docker/docker-compose.yml` - Full stack with all apps and services
1284
+ - `docker-compose.constructs.yml` - every container the constructs imply, and each app behind the `apps` profile (project root)
1295
1285
  - `.dockerignore` - Optimized ignore patterns
1296
1286
 
1297
1287
  **Dockerfile types by app:**
@@ -1358,12 +1348,10 @@ interface WorkspaceConfig {
1358
1348
  What an app is comes from the declaration, not from here:
1359
1349
 
1360
1350
  ```typescript
1361
- /** Overrides, all optional. A surface normally has none. */
1351
+ /** How a site is built and run. A surface declares only its `path`. */
1362
1352
  interface AppSpec {
1363
- /** Default: `apps/<kebab-id>` if present, else the project root. */
1364
- path?: string;
1365
- /** Default: the conventional directories under `path`. */
1366
- code?: string;
1353
+ /** Required: where the app lives, relative to the workspace root. */
1354
+ path: string;
1367
1355
  /** Default: assigned in a stable order, so adding an app renumbers nothing. */
1368
1356
  port?: number;
1369
1357
  entry?: string;
@@ -1371,42 +1359,24 @@ interface AppSpec {
1371
1359
  }
1372
1360
  ```
1373
1361
 
1374
- ## Providers
1375
-
1376
- ### AWS API Gateway v1
1377
-
1378
- Generates Lambda handlers compatible with AWS API Gateway v1 (REST API).
1379
-
1380
- ```bash
1381
- gkm build --provider aws-apigatewayv1
1382
- ```
1383
-
1384
- **Generated Handler:**
1385
- ```typescript
1386
- import { AmazonApiGatewayV1Endpoint } from '@geekmidas/constructs/aws';
1387
- import { myEndpoint } from '../src/routes/example.js';
1388
- import { envParser } from '../src/env.js';
1362
+ ## Build Targets
1389
1363
 
1390
- const adapter = new AmazonApiGatewayV1Endpoint(envParser, myEndpoint);
1364
+ ### AWS
1391
1365
 
1392
- export const handler = adapter.handler;
1393
- ```
1394
-
1395
- ### AWS API Gateway v2
1396
-
1397
- Generates Lambda handlers compatible with AWS API Gateway v2 (HTTP API).
1366
+ Generates one Lambda handler per construct. Endpoints get an API Gateway v2
1367
+ (HTTP API) adapter.
1398
1368
 
1399
1369
  ```bash
1400
- gkm build --provider aws-apigatewayv2
1370
+ gkm build # with deploy: { default: 'sst' }
1371
+ gkm build --provider aws # whatever the deploy target
1401
1372
  ```
1402
1373
 
1403
1374
  **Generated Handler:**
1404
1375
  ```typescript
1405
1376
  import { AmazonApiGatewayV2Endpoint } from '@geekmidas/constructs/aws';
1406
- import { myEndpoint } from '../src/routes/example.js';
1407
- import { envParser } from '../src/env.js';
1377
+ import { myEndpoint } from '../../../src/routes/example.js';
1408
1378
 
1409
- const adapter = new AmazonApiGatewayV2Endpoint(envParser, myEndpoint);
1379
+ const adapter = new AmazonApiGatewayV2Endpoint(myEndpoint);
1410
1380
 
1411
1381
  export const handler = adapter.handler;
1412
1382
  ```
@@ -1448,139 +1418,141 @@ export default createApp;
1448
1418
 
1449
1419
  ## Output Structure
1450
1420
 
1451
- The CLI generates files in the `.gkm/<provider>` directory:
1421
+ Handlers are generated beside the app, in `<app>/.gkm/<target>`; the manifest
1422
+ at the workspace root, where `sst.config.ts` runs:
1452
1423
 
1453
1424
  ```
1454
- .gkm/
1455
- ├── aws-apigatewayv1/
1456
- │ ├── getUsers.ts # Individual Lambda handler
1457
- │ ├── createUser.ts # Individual Lambda handler
1458
- ├── server/
1459
- │ ├── app.ts # Server application
1460
- │ ├── endpoints.ts # Endpoint exports
1461
- ├── manifest/
1462
- │ ├── aws.ts # AWS manifest with types
1463
- │ └── server.ts # Server manifest with types
1464
- └── openapi.json # OpenAPI specification
1425
+ <root>/
1426
+ ├── .gkm/manifest/
1427
+ │ ├── aws.ts # AWS manifest with types
1428
+ │ └── server.ts # Server manifest with types
1429
+ └── apps/api/.gkm/
1430
+ ├── aws/
1431
+ │ ├── routes/getUsers.ts # One Lambda handler per endpoint
1432
+ │ ├── functions/
1433
+ │ ├── crons/
1434
+ │ ├── queues/
1435
+ │ └── subscribers/
1436
+ └── server/
1437
+ ├── app.ts # Server application
1438
+ └── endpoints.ts # Endpoint exports
1465
1439
  ```
1466
1440
 
1467
1441
  ### Build Manifest
1468
1442
 
1469
- The CLI generates TypeScript manifests with full type information in the `.gkm/manifest/` directory. These manifests export both the data and derived types for type-safe usage.
1443
+ The manifest is the application's, not an app's: the root `gkm build` builds
1444
+ every backend and writes it once, to `.gkm/manifest/aws.ts` or
1445
+ `.gkm/manifest/server.ts` at the workspace root. An app's own build writes no
1446
+ manifest. Every handler path in it is relative to the workspace root. `gkm init`
1447
+ adds a root tsconfig alias for the manifest, `@<project>/manifest`.
1470
1448
 
1471
- #### AWS Manifest (`.gkm/manifest/aws.ts`)
1449
+ It exports two values — every declared construct keyed by id, and the backends
1450
+ the build resolved — and the types derived from them:
1472
1451
 
1473
1452
  ```typescript
1474
- export const manifest = {
1475
- routes: [
1476
- {
1477
- path: '/users',
1478
- method: 'GET',
1479
- handler: '.gkm/aws-apigatewayv1/getUsers.handler',
1480
- authorizer: 'jwt',
1481
- },
1482
- {
1483
- path: '/users',
1484
- method: 'POST',
1485
- handler: '.gkm/aws-apigatewayv1/createUser.handler',
1486
- authorizer: 'jwt',
1487
- },
1488
- ],
1489
- functions: [
1490
- {
1491
- name: 'processData',
1492
- handler: '.gkm/aws-lambda/functions/processData.handler',
1493
- timeout: 60,
1494
- memorySize: 256,
1495
- },
1496
- ],
1497
- crons: [
1498
- {
1499
- name: 'dailyCleanup',
1500
- handler: '.gkm/aws-lambda/crons/dailyCleanup.handler',
1501
- schedule: 'rate(1 day)',
1502
- timeout: 300,
1503
- memorySize: 512,
1453
+ export const constructs = {
1454
+ Database: { id: 'Database', kind: 'database' },
1455
+ Api: {
1456
+ id: 'Api',
1457
+ kind: 'rest-api',
1458
+ path: 'apps/api',
1459
+ endpoints: [
1460
+ {
1461
+ id: 'ApiGET/users',
1462
+ method: 'GET',
1463
+ path: '/users',
1464
+ handler: 'apps/api/.gkm/aws/routes/getUsers.handler',
1465
+ dependencies: [{ target: 'Database', kind: 'database' }],
1466
+ authorizer: 'iam',
1467
+ },
1468
+ ],
1469
+ },
1470
+ ProcessData: {
1471
+ id: 'ProcessData',
1472
+ kind: 'function',
1473
+ handler: 'apps/api/.gkm/aws/functions/processData.handler',
1474
+ dependencies: [],
1475
+ },
1476
+ DailyCleanup: {
1477
+ id: 'DailyCleanup',
1478
+ kind: 'cron',
1479
+ handler: 'apps/api/.gkm/aws/crons/dailyCleanup.handler',
1480
+ schedule: 'rate(1 day)',
1481
+ dependencies: [{ target: 'Database', kind: 'database' }],
1482
+ },
1483
+ Emails: {
1484
+ id: 'Emails',
1485
+ kind: 'queue',
1486
+ // The queue's consumer is nested in it
1487
+ worker: {
1488
+ id: 'emails',
1489
+ handler: 'apps/api/.gkm/aws/queues/emails.handler',
1490
+ dependencies: [],
1504
1491
  },
1505
- ],
1506
- subscribers: [],
1507
- } as const;
1492
+ },
1493
+ Users: {
1494
+ id: 'Users',
1495
+ kind: 'topic',
1496
+ events: ['user.created'],
1497
+ // As are a topic's subscribers
1498
+ subscribers: [
1499
+ {
1500
+ id: 'onUser',
1501
+ handler: 'apps/api/.gkm/aws/subscribers/onUser.handler',
1502
+ events: ['user.created'],
1503
+ dependencies: [],
1504
+ },
1505
+ ],
1506
+ },
1507
+ } as const satisfies ConstructManifest;
1508
+
1509
+ export const backends = { cache: 'upstash', email: 'ses' } as const;
1508
1510
 
1509
1511
  // Derived types
1510
- export type Route = (typeof manifest.routes)[number];
1511
- export type Function = (typeof manifest.functions)[number];
1512
- export type Cron = (typeof manifest.crons)[number];
1513
- export type Subscriber = (typeof manifest.subscribers)[number];
1512
+ export type Ids = IdsOf<typeof constructs>;
1513
+ export type Construct<Id extends Ids> = DeclarationOf<typeof constructs, Id>;
1514
+ export type Kind = Construct<Ids>['kind'];
1514
1515
 
1515
1516
  // Useful union types
1516
- export type Authorizer = Route['authorizer'];
1517
- export type HttpMethod = Route['method'];
1518
- export type RoutePath = Route['path'];
1517
+ export type ProvidedKeys = AllProvidedKeys<typeof constructs>;
1518
+ export type Surfaces = IdsOfKind<typeof constructs, 'rest-api'>;
1519
+ export type CacheBackend = (typeof backends)['cache'];
1520
+ export type EmailBackend = (typeof backends)['email'];
1519
1521
  ```
1520
1522
 
1521
- When routes are partitioned, the manifest groups them by partition name and generates partition-aware types:
1522
-
1523
- ```typescript
1524
- export const manifest = {
1525
- routes: {
1526
- "admin": [{ path: '/admin/users', method: 'GET', handler: '...', authorizer: 'jwt' }],
1527
- "default": [{ path: '/users', method: 'GET', handler: '...', authorizer: 'jwt' }],
1528
- },
1529
- functions: [...], // flat if not partitioned
1530
- } as const;
1523
+ A `RestApi` carries its endpoints, each with its method, path, handler, the
1524
+ dependencies it declared and its authorizer. On AWS the handler is the
1525
+ endpoint's own Lambda (`apps/api/.gkm/aws/routes/<export>.handler`); in the
1526
+ server manifest every endpoint's handler is the app entry
1527
+ (`apps/api/.gkm/server/app.ts`). Functions and crons are top-level
1528
+ declarations; a queue's worker and a topic's subscribers are nested in the
1529
+ queue or topic.
1531
1530
 
1532
- // Partition-aware derived types
1533
- export type RoutePartition = keyof typeof manifest.routes;
1534
- export type Route<P extends RoutePartition = RoutePartition> =
1535
- (typeof manifest.routes)[P][number];
1536
- ```
1531
+ #### Using the Manifest
1537
1532
 
1538
- #### Server Manifest (`.gkm/manifest/server.ts`)
1533
+ On AWS, `fromManifest` from `@geekmidas/cloud/sst` provisions all of it —
1534
+ resources, each API's endpoints, queue consumers, functions and crons:
1539
1535
 
1540
1536
  ```typescript
1541
- export const manifest = {
1542
- app: {
1543
- handler: '.gkm/server/app.ts',
1544
- endpoints: '.gkm/server/endpoints.ts',
1545
- },
1546
- routes: [
1547
- { path: '/users', method: 'GET', authorizer: 'jwt' },
1548
- { path: '/users', method: 'POST', authorizer: 'jwt' },
1549
- ],
1550
- subscribers: [
1551
- { name: 'orderHandler', subscribedEvents: ['order.created'] },
1552
- ],
1553
- } as const;
1537
+ // sst.config.ts
1538
+ const { App, fromManifest, Stack } = await import('@geekmidas/cloud/sst');
1539
+ const { backends, constructs } = await import('./.gkm/manifest/aws.js');
1554
1540
 
1555
- // Derived types
1556
- export type Route = (typeof manifest.routes)[number];
1557
- export type Subscriber = (typeof manifest.subscribers)[number];
1558
-
1559
- // Useful union types
1560
- export type Authorizer = Route['authorizer'];
1561
- export type HttpMethod = Route['method'];
1562
- export type RoutePath = Route['path'];
1541
+ fromManifest(new Stack(app, 'Shop'), constructs, { Database: { vpc } }, backends);
1563
1542
  ```
1564
1543
 
1565
- #### Using Manifest Types
1566
-
1567
- Import the manifest types for type-safe infrastructure configuration:
1544
+ The types narrow to what was declared:
1568
1545
 
1569
1546
  ```typescript
1570
- import { manifest, type Route, type Authorizer } from './.gkm/manifest/aws';
1547
+ import { constructs, type Construct, type Surfaces } from './.gkm/manifest/aws';
1571
1548
 
1572
- // Type-safe route iteration
1573
- for (const route of manifest.routes) {
1574
- console.log(`${route.method} ${route.path} -> ${route.handler}`);
1575
- }
1549
+ const api: Construct<'Api'> = constructs.Api;
1576
1550
 
1577
- // Use union types for validation
1578
- function isValidMethod(method: string): method is HttpMethod {
1579
- return manifest.routes.some((r) => r.method === method);
1551
+ for (const endpoint of api.endpoints) {
1552
+ console.log(`${endpoint.method} ${endpoint.path} -> ${endpoint.handler}`);
1580
1553
  }
1581
1554
 
1582
- // Access authorizer names
1583
- const authorizers = new Set(manifest.routes.map((r) => r.authorizer));
1555
+ const surface: Surfaces = 'Api'; // any other id is a type error
1584
1556
  ```
1585
1557
 
1586
1558
  ## OpenAPI Generation
@@ -1663,62 +1635,25 @@ gkm openapi --output api-docs.json --json
1663
1635
 
1664
1636
  ## Deployment Examples
1665
1637
 
1666
- ### AWS Lambda with Serverless Framework
1638
+ Deploying goes through `gkm deploy` and a target, rather than through a
1639
+ hand-written server file or framework config:
1667
1640
 
1668
- ```yaml
1669
- # serverless.yml
1670
- service: my-api
1671
-
1672
- provider:
1673
- name: aws
1674
- runtime: nodejs18.x
1675
-
1676
- functions:
1677
- getUsers:
1678
- handler: .gkm/aws-apigatewayv1/getUsers.handler
1679
- events:
1680
- - http:
1681
- path: users
1682
- method: get
1683
-
1684
- createUser:
1685
- handler: .gkm/aws-apigatewayv1/createUser.handler
1686
- events:
1687
- - http:
1688
- path: users
1689
- method: post
1690
- ```
1691
-
1692
- ### Server Deployment
1641
+ ```bash
1642
+ # Dokploy (the default target)
1643
+ gkm deploy --stage production
1693
1644
 
1694
- ```typescript
1695
- // server.ts
1696
- import { createApp } from './.gkm/server/app.js';
1645
+ # One Docker Compose stack behind Caddy, on this machine
1646
+ gkm compose --stage production --tag v1.4.0
1697
1647
 
1698
- const app = createApp();
1648
+ # AWS through SST, with deploy: { default: 'sst' }
1649
+ gkm deploy --stage production
1699
1650
 
1700
- const port = process.env.PORT || 3000;
1701
- app.listen(port, () => {
1702
- console.log(`Server running on port ${port}`);
1703
- });
1651
+ # Only the Docker files, to build and run images yourself
1652
+ gkm docker --build --tag v1.4.0
1704
1653
  ```
1705
1654
 
1706
- ### Docker Deployment
1707
-
1708
- ```dockerfile
1709
- FROM node:18-alpine
1710
-
1711
- WORKDIR /app
1712
- COPY package*.json ./
1713
- RUN npm ci --only=production
1714
-
1715
- COPY . .
1716
- RUN npm run build
1717
-
1718
- EXPOSE 3000
1719
-
1720
- CMD ["node", "server.js"]
1721
- ```
1655
+ See [Deploy targets](https://geekmidas.github.io/toolbox/next/guide/deploy-targets) and the
1656
+ [deployment guide](https://geekmidas.github.io/toolbox/next/guide/deployment).
1722
1657
 
1723
1658
  ## Advanced Usage
1724
1659
 
@@ -1883,6 +1818,7 @@ Configure multiple patterns for complex project structures:
1883
1818
  import { defineConfig } from '@geekmidas/cli/config';
1884
1819
 
1885
1820
  export default defineConfig({
1821
+ stages: { local: 'dev', deployed: ['prod'] },
1886
1822
  routes: [
1887
1823
  'src/routes/**/*.ts',
1888
1824
  'src/api/v1/**/*.ts',
@@ -1914,8 +1850,8 @@ Error: Failed to load gkm.config.ts: Invalid configuration
1914
1850
  # No endpoints found
1915
1851
  No endpoints found to process
1916
1852
 
1917
- # Invalid provider
1918
- Error: Unsupported provider: invalid-provider
1853
+ # Unknown deploy target
1854
+ Unknown deploy target "fly". Use one of dokploy, compose, sst, or name the package that provides it in gkm.config.ts: deploy: { targets: { "fly": '<package>' } }.
1919
1855
  ```
1920
1856
 
1921
1857
  ### OpenAPI Errors
@@ -1935,44 +1871,22 @@ Error: OpenAPI generation failed: Invalid endpoint schema
1935
1871
  "dev": "gkm dev",
1936
1872
  "dev:port": "gkm dev --port 8080",
1937
1873
  "build": "gkm build",
1938
- "build:lambda": "gkm build --provider aws-apigatewayv1",
1874
+ "build:lambda": "gkm build --provider aws",
1939
1875
  "build:server": "gkm build --provider server",
1940
- "docs": "gkm openapi --output src/api.ts"
1876
+ "client": "gkm openapi"
1941
1877
  }
1942
1878
  }
1943
1879
  ```
1944
1880
 
1945
1881
  ### CI/CD Pipeline
1946
1882
 
1947
- ```yaml
1948
- # .github/workflows/deploy.yml
1949
- name: Deploy API
1950
-
1951
- on:
1952
- push:
1953
- branches: [main]
1954
-
1955
- jobs:
1956
- deploy:
1957
- runs-on: ubuntu-latest
1958
-
1959
- steps:
1960
- - uses: actions/checkout@v3
1961
-
1962
- - name: Setup Node.js
1963
- uses: actions/setup-node@v3
1964
- with:
1965
- node-version: '18'
1966
-
1967
- - name: Install dependencies
1968
- run: npm ci
1969
-
1970
- - name: Build handlers
1971
- run: npm run build:lambda
1972
-
1973
- - name: Deploy to AWS
1974
- run: npx serverless deploy
1975
- ```
1883
+ `gkm init` writes a GitHub Actions deploy workflow that runs
1884
+ `gkm deploy --stage "$STAGE"` for each stage. Its credentials come from the
1885
+ stage's GitHub environment: `AWS_ROLE_ARN` for SST (set by
1886
+ `gkm deploy:github --stage <stage>`), or `DOKPLOY_API_TOKEN` and
1887
+ `DOKPLOY_ENDPOINT` for Dokploy. In any CI job, `gkm deploy --json` writes the
1888
+ deploy's events as JSON lines and never prompts. See
1889
+ [Deploying from GitHub Actions](https://geekmidas.github.io/toolbox/next/guide/deployment#deploying-from-github-actions).
1976
1890
 
1977
1891
  ## Troubleshooting
1978
1892
 
@@ -2029,8 +1943,8 @@ DEBUG=gkm:* npx gkm build
2029
1943
  ### Types
2030
1944
 
2031
1945
  ```typescript
2032
- // Provider options
2033
- type Provider = 'server' | 'aws-apigatewayv1' | 'aws-apigatewayv2';
1946
+ // Build targets
1947
+ type Provider = 'aws' | 'server';
2034
1948
 
2035
1949
  // Runtime options
2036
1950
  type Runtime = 'node' | 'bun';
@@ -2054,17 +1968,8 @@ interface DockerConfig {
2054
1968
  imageName?: string; // Image name (defaults to package.json name)
2055
1969
  baseImage?: string; // Base image (default: node:22-alpine)
2056
1970
  port?: number; // Port to expose (default: 3000)
2057
- compose?: {
2058
- services?: ComposeServicesConfig | ComposeServiceName[];
2059
- };
2060
1971
  }
2061
1972
 
2062
- // Service configuration for docker-compose
2063
- type ComposeServiceName = 'postgres' | 'redis' | 'rabbitmq';
2064
- type ComposeServicesConfig = {
2065
- [K in ComposeServiceName]?: boolean | { version?: string };
2066
- };
2067
-
2068
1973
  // Telescope configuration
2069
1974
  interface TelescopeConfig {
2070
1975
  enabled?: boolean;
@@ -2077,7 +1982,7 @@ interface TelescopeConfig {
2077
1982
 
2078
1983
  // Build options
2079
1984
  interface BuildOptions {
2080
- provider: Provider;
1985
+ provider?: Provider; // default: where gkm.config.ts deploys
2081
1986
  }
2082
1987
 
2083
1988
  // Dev options