@geekmidas/cli 10.0.0-alpha.9 → 10.0.0-alpha.90

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 (457) hide show
  1. package/README.md +315 -414
  2. package/bin/adjacent-tsconfig.mjs +46 -8
  3. package/bin/gkm.mjs +11 -3
  4. package/bin/owning-tsconfig-jsx-register.mjs +18 -0
  5. package/bin/owning-tsconfig-jsx.mjs +108 -0
  6. package/dist/EndpointGenerator-CVc6Oi1Y.mjs +1021 -0
  7. package/dist/EndpointGenerator-CVc6Oi1Y.mjs.map +1 -0
  8. package/dist/EndpointGenerator-CwLjBCFE.cjs +1080 -0
  9. package/dist/EndpointGenerator-CwLjBCFE.cjs.map +1 -0
  10. package/dist/GoDaddyProvider-DSStJVAv.mjs +387 -0
  11. package/dist/GoDaddyProvider-DSStJVAv.mjs.map +1 -0
  12. package/dist/GoDaddyProvider-DqZ1qD_F.cjs +387 -0
  13. package/dist/GoDaddyProvider-DqZ1qD_F.cjs.map +1 -0
  14. package/dist/{HostingerProvider-Cft7lEYr.mjs → HostingerProvider-BI6J7oJr.mjs} +22 -23
  15. package/dist/HostingerProvider-BI6J7oJr.mjs.map +1 -0
  16. package/dist/{HostingerProvider-h3EbEp-Z.cjs → HostingerProvider-CyTpG_jy.cjs} +22 -23
  17. package/dist/HostingerProvider-CyTpG_jy.cjs.map +1 -0
  18. package/dist/LegacyStateStore-DXmNA7hy.cjs +89 -0
  19. package/dist/LegacyStateStore-DXmNA7hy.cjs.map +1 -0
  20. package/dist/LegacyStateStore-ZkdmiUFZ.mjs +89 -0
  21. package/dist/LegacyStateStore-ZkdmiUFZ.mjs.map +1 -0
  22. package/dist/LocalStateStore-BBeTlRTH.cjs +178 -0
  23. package/dist/LocalStateStore-BBeTlRTH.cjs.map +1 -0
  24. package/dist/LocalStateStore-CU-O0SBp.mjs +167 -0
  25. package/dist/LocalStateStore-CU-O0SBp.mjs.map +1 -0
  26. package/dist/OpenApiTsGenerator-B--HV-sW.cjs +541 -0
  27. package/dist/OpenApiTsGenerator-B--HV-sW.cjs.map +1 -0
  28. package/dist/OpenApiTsGenerator-CkvsPdgg.mjs +536 -0
  29. package/dist/OpenApiTsGenerator-CkvsPdgg.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-Br8VMY22.cjs +160 -0
  35. package/dist/S3StateStore-Br8VMY22.cjs.map +1 -0
  36. package/dist/S3StateStore-bwxcI_wQ.mjs +161 -0
  37. package/dist/S3StateStore-bwxcI_wQ.mjs.map +1 -0
  38. package/dist/SSMStateStore-CsOS0W1y.mjs +154 -0
  39. package/dist/SSMStateStore-CsOS0W1y.mjs.map +1 -0
  40. package/dist/SSMStateStore-DoZE1Wi1.cjs +153 -0
  41. package/dist/SSMStateStore-DoZE1Wi1.cjs.map +1 -0
  42. package/dist/SubscriberGenerator-BPqQf8fB.mjs +448 -0
  43. package/dist/SubscriberGenerator-BPqQf8fB.mjs.map +1 -0
  44. package/dist/SubscriberGenerator-BVn7cQ-2.cjs +489 -0
  45. package/dist/SubscriberGenerator-BVn7cQ-2.cjs.map +1 -0
  46. package/dist/add-CNMF0Q3m.cjs +594 -0
  47. package/dist/add-CNMF0Q3m.cjs.map +1 -0
  48. package/dist/add-DHk1roh_.mjs +592 -0
  49. package/dist/add-DHk1roh_.mjs.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-B-6uEhgP.mjs +71 -0
  55. package/dist/aws-B-6uEhgP.mjs.map +1 -0
  56. package/dist/aws-BTawF0F-.cjs +82 -0
  57. package/dist/aws-BTawF0F-.cjs.map +1 -0
  58. package/dist/awsStore-7VmS_cZR.cjs +54 -0
  59. package/dist/awsStore-7VmS_cZR.cjs.map +1 -0
  60. package/dist/awsStore-B529csle.mjs +43 -0
  61. package/dist/awsStore-B529csle.mjs.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/{bundler-BY1OmV1e.cjs → bundler-BQJiB7Ub.cjs} +38 -35
  67. package/dist/bundler-BQJiB7Ub.cjs.map +1 -0
  68. package/dist/{bundler-Be8Zg4Wd.mjs → bundler-D6eBfVkl.mjs} +36 -32
  69. package/dist/bundler-D6eBfVkl.mjs.map +1 -0
  70. package/dist/cli-BE9mqeX8.cjs +69 -0
  71. package/dist/cli-BE9mqeX8.cjs.map +1 -0
  72. package/dist/cli-DD-Yk-I5.mjs +69 -0
  73. package/dist/cli-DD-Yk-I5.mjs.map +1 -0
  74. package/dist/compose-Bhmf0n4o.mjs +3140 -0
  75. package/dist/compose-Bhmf0n4o.mjs.map +1 -0
  76. package/dist/compose-CvpU6ooi.cjs +3265 -0
  77. package/dist/compose-CvpU6ooi.cjs.map +1 -0
  78. package/dist/config-CdEcTrjG.d.mts +269 -0
  79. package/dist/config-CdEcTrjG.d.mts.map +1 -0
  80. package/dist/config-pST7E0CS.d.cts +269 -0
  81. package/dist/config-pST7E0CS.d.cts.map +1 -0
  82. package/dist/config.cjs +420 -11
  83. package/dist/config.cjs.map +1 -0
  84. package/dist/config.d.cts +4 -120
  85. package/dist/config.d.mts +4 -120
  86. package/dist/config.mjs +404 -4
  87. package/dist/config.mjs.map +1 -0
  88. package/dist/credentialSchemas-BJqRJNK4.mjs +236 -0
  89. package/dist/credentialSchemas-BJqRJNK4.mjs.map +1 -0
  90. package/dist/credentialSchemas-DCR4Wd1W.cjs +271 -0
  91. package/dist/credentialSchemas-DCR4Wd1W.cjs.map +1 -0
  92. package/dist/credentials-BKfIugu2.cjs +513 -0
  93. package/dist/credentials-BKfIugu2.cjs.map +1 -0
  94. package/dist/credentials-CnVqoXMb.mjs +388 -0
  95. package/dist/credentials-CnVqoXMb.mjs.map +1 -0
  96. package/dist/databases-BY-pEImp.cjs +597 -0
  97. package/dist/databases-BY-pEImp.cjs.map +1 -0
  98. package/dist/databases-CzszQV0N.mjs +494 -0
  99. package/dist/databases-CzszQV0N.mjs.map +1 -0
  100. package/dist/define-DR8xGYfL.mjs +97 -0
  101. package/dist/define-DR8xGYfL.mjs.map +1 -0
  102. package/dist/define-DzRz8FgH.cjs +144 -0
  103. package/dist/define-DzRz8FgH.cjs.map +1 -0
  104. package/dist/deploy/public.cjs +208 -0
  105. package/dist/deploy/public.cjs.map +1 -0
  106. package/dist/deploy/public.d.cts +649 -0
  107. package/dist/deploy/public.d.cts.map +1 -0
  108. package/dist/deploy/public.d.mts +649 -0
  109. package/dist/deploy/public.d.mts.map +1 -0
  110. package/dist/deploy/public.mjs +142 -0
  111. package/dist/deploy/public.mjs.map +1 -0
  112. package/dist/deploy/sniffer-envkit-patch.cjs +18 -10
  113. package/dist/deploy/sniffer-envkit-patch.cjs.map +1 -1
  114. package/dist/deploy/sniffer-envkit-patch.d.cts +0 -2
  115. package/dist/deploy/sniffer-envkit-patch.d.cts.map +1 -1
  116. package/dist/deploy/sniffer-envkit-patch.d.mts +0 -2
  117. package/dist/deploy/sniffer-envkit-patch.d.mts.map +1 -1
  118. package/dist/deploy/sniffer-envkit-patch.mjs +10 -2
  119. package/dist/deploy/sniffer-envkit-patch.mjs.map +1 -1
  120. package/dist/deploy/sniffer-envparser-worker.cjs +54 -0
  121. package/dist/deploy/sniffer-envparser-worker.cjs.map +1 -0
  122. package/dist/deploy/sniffer-envparser-worker.d.cts +1 -0
  123. package/dist/deploy/sniffer-envparser-worker.d.mts +1 -0
  124. package/dist/deploy/sniffer-envparser-worker.mjs +55 -0
  125. package/dist/deploy/sniffer-envparser-worker.mjs.map +1 -0
  126. package/dist/deploy/sniffer-hooks.cjs +13 -7
  127. package/dist/deploy/sniffer-hooks.cjs.map +1 -1
  128. package/dist/deploy/sniffer-hooks.d.cts +1 -2
  129. package/dist/deploy/sniffer-hooks.d.cts.map +1 -1
  130. package/dist/deploy/sniffer-hooks.d.mts +1 -2
  131. package/dist/deploy/sniffer-hooks.d.mts.map +1 -1
  132. package/dist/deploy/sniffer-hooks.mjs +10 -3
  133. package/dist/deploy/sniffer-hooks.mjs.map +1 -1
  134. package/dist/deploy/sniffer-loader.cjs +16 -7
  135. package/dist/deploy/sniffer-loader.cjs.map +1 -1
  136. package/dist/deploy/sniffer-loader.d.cts +1 -1
  137. package/dist/deploy/sniffer-loader.d.mts +1 -1
  138. package/dist/deploy/sniffer-loader.mjs +14 -3
  139. package/dist/deploy/sniffer-loader.mjs.map +1 -1
  140. package/dist/deploy/sniffer-routes-worker.cjs +11 -11
  141. package/dist/deploy/sniffer-routes-worker.cjs.map +1 -1
  142. package/dist/deploy/sniffer-routes-worker.d.cts +1 -1
  143. package/dist/deploy/sniffer-routes-worker.d.mts +1 -1
  144. package/dist/deploy/sniffer-routes-worker.mjs +4 -4
  145. package/dist/deploy/sniffer-routes-worker.mjs.map +1 -1
  146. package/dist/deploy/sniffer-worker.cjs +15 -6
  147. package/dist/deploy/sniffer-worker.cjs.map +1 -1
  148. package/dist/deploy/sniffer-worker.d.cts +1 -3
  149. package/dist/deploy/sniffer-worker.d.cts.map +1 -1
  150. package/dist/deploy/sniffer-worker.d.mts +1 -3
  151. package/dist/deploy/sniffer-worker.d.mts.map +1 -1
  152. package/dist/deploy/sniffer-worker.mjs +15 -4
  153. package/dist/deploy/sniffer-worker.mjs.map +1 -1
  154. package/dist/deploy-CuHasEA4.cjs +554 -0
  155. package/dist/deploy-CuHasEA4.cjs.map +1 -0
  156. package/dist/deploy-QNtx_eWR.mjs +525 -0
  157. package/dist/deploy-QNtx_eWR.mjs.map +1 -0
  158. package/dist/derive-B4vDpzgP.mjs +150 -0
  159. package/dist/derive-B4vDpzgP.mjs.map +1 -0
  160. package/dist/derive-DAbo49sm.cjs +161 -0
  161. package/dist/derive-DAbo49sm.cjs.map +1 -0
  162. package/dist/discover-BPelzeGW.mjs +526 -0
  163. package/dist/discover-BPelzeGW.mjs.map +1 -0
  164. package/dist/discover-CU0paUyH.d.cts +108 -0
  165. package/dist/discover-CU0paUyH.d.cts.map +1 -0
  166. package/dist/discover-D1It5r_h.cjs +599 -0
  167. package/dist/discover-D1It5r_h.cjs.map +1 -0
  168. package/dist/discover-DFiJxwfv.d.mts +108 -0
  169. package/dist/discover-DFiJxwfv.d.mts.map +1 -0
  170. package/dist/dokploy-CYcMLh9-.mjs +38 -0
  171. package/dist/dokploy-CYcMLh9-.mjs.map +1 -0
  172. package/dist/dokploy-DIowwyIB.cjs +38 -0
  173. package/dist/dokploy-DIowwyIB.cjs.map +1 -0
  174. package/dist/drivers-DTZzxeIl.mjs +177 -0
  175. package/dist/drivers-DTZzxeIl.mjs.map +1 -0
  176. package/dist/drivers-LYSdQDmd.cjs +200 -0
  177. package/dist/drivers-LYSdQDmd.cjs.map +1 -0
  178. package/dist/{emit-CiZS_5Ub.mjs → emit-C1e8qD08.mjs} +13 -26
  179. package/dist/emit-C1e8qD08.mjs.map +1 -0
  180. package/dist/{emit-CbcRolsa.cjs → emit-Dmc1nvdS.cjs} +31 -57
  181. package/dist/emit-Dmc1nvdS.cjs.map +1 -0
  182. package/dist/encryption-BrEef7Jk.mjs +88 -0
  183. package/dist/encryption-BrEef7Jk.mjs.map +1 -0
  184. package/dist/encryption-CjYdUb2s.cjs +89 -0
  185. package/dist/encryption-CjYdUb2s.cjs.map +1 -0
  186. package/dist/engine-2h4k5ICq.mjs +3085 -0
  187. package/dist/engine-2h4k5ICq.mjs.map +1 -0
  188. package/dist/engine-BhJ7ZP9K.cjs +3198 -0
  189. package/dist/engine-BhJ7ZP9K.cjs.map +1 -0
  190. package/dist/github-B5Bw4HIu.cjs +669 -0
  191. package/dist/github-B5Bw4HIu.cjs.map +1 -0
  192. package/dist/github-BCDF6xVH.mjs +669 -0
  193. package/dist/github-BCDF6xVH.mjs.map +1 -0
  194. package/dist/{index-C6e-ULLx.d.mts → index-D-F_hTDz.d.cts} +39 -24
  195. package/dist/index-D-F_hTDz.d.cts.map +1 -0
  196. package/dist/{index-CR5urhWX.d.cts → index-YFNxR5Ns.d.mts} +39 -24
  197. package/dist/index-YFNxR5Ns.d.mts.map +1 -0
  198. package/dist/index.cjs +9487 -12080
  199. package/dist/index.cjs.map +1 -1
  200. package/dist/index.d.cts +1 -1
  201. package/dist/index.d.mts +1 -1
  202. package/dist/index.mjs +9420 -12026
  203. package/dist/index.mjs.map +1 -1
  204. package/dist/local-BjxDfPvy.cjs +241 -0
  205. package/dist/local-BjxDfPvy.cjs.map +1 -0
  206. package/dist/local-IuoIF3CT.mjs +224 -0
  207. package/dist/local-IuoIF3CT.mjs.map +1 -0
  208. package/dist/migrate-CGaancHY.cjs +93 -0
  209. package/dist/migrate-CGaancHY.cjs.map +1 -0
  210. package/dist/migrate-DWZz9kah.mjs +93 -0
  211. package/dist/migrate-DWZz9kah.mjs.map +1 -0
  212. package/dist/migrate-DbtcuOr_.mjs +265 -0
  213. package/dist/migrate-DbtcuOr_.mjs.map +1 -0
  214. package/dist/migrate-q2YYLJLE.cjs +270 -0
  215. package/dist/migrate-q2YYLJLE.cjs.map +1 -0
  216. package/dist/openapi.cjs +214 -10
  217. package/dist/openapi.cjs.map +1 -0
  218. package/dist/openapi.d.cts +47 -17
  219. package/dist/openapi.d.cts.map +1 -1
  220. package/dist/openapi.d.mts +47 -17
  221. package/dist/openapi.d.mts.map +1 -1
  222. package/dist/openapi.mjs +208 -5
  223. package/dist/openapi.mjs.map +1 -0
  224. package/dist/provider-C9_-45d5.cjs +56 -0
  225. package/dist/provider-C9_-45d5.cjs.map +1 -0
  226. package/dist/provider-q4lsYzYG.mjs +45 -0
  227. package/dist/provider-q4lsYzYG.mjs.map +1 -0
  228. package/dist/ready-BpNbORRB.cjs +402 -0
  229. package/dist/ready-BpNbORRB.cjs.map +1 -0
  230. package/dist/ready-b6vm0-W-.mjs +373 -0
  231. package/dist/ready-b6vm0-W-.mjs.map +1 -0
  232. package/dist/reconcile/public.cjs +3 -5
  233. package/dist/reconcile/public.d.cts +11 -87
  234. package/dist/reconcile/public.d.cts.map +1 -1
  235. package/dist/reconcile/public.d.mts +11 -87
  236. package/dist/reconcile/public.d.mts.map +1 -1
  237. package/dist/reconcile/public.mjs +3 -4
  238. package/dist/{reconcile-D0pimNiy.cjs → reconcile-CuCQBa5-.cjs} +5 -8
  239. package/dist/reconcile-CuCQBa5-.cjs.map +1 -0
  240. package/dist/{reconcile-CFs8C_1a.mjs → reconcile-Dh1Jk7WE.mjs} +4 -7
  241. package/dist/reconcile-Dh1Jk7WE.mjs.map +1 -0
  242. package/dist/resolve-Cns0v6dN.cjs +315 -0
  243. package/dist/resolve-Cns0v6dN.cjs.map +1 -0
  244. package/dist/resolve-DNg0icnh.mjs +262 -0
  245. package/dist/resolve-DNg0icnh.mjs.map +1 -0
  246. package/dist/rollback-CFrNLmxs.mjs +132 -0
  247. package/dist/rollback-CFrNLmxs.mjs.map +1 -0
  248. package/dist/rollback-UIjS25F1.cjs +161 -0
  249. package/dist/rollback-UIjS25F1.cjs.map +1 -0
  250. package/dist/rolldown-runtime-BhDjJH2R.mjs +15 -0
  251. package/dist/{chunk-CUT6urMc.cjs → rolldown-runtime-C0BPl7ul.cjs} +23 -10
  252. package/dist/runtime-CN_kmqxo.d.cts +90 -0
  253. package/dist/runtime-CN_kmqxo.d.cts.map +1 -0
  254. package/dist/runtime-Cjvon3oj.d.mts +90 -0
  255. package/dist/runtime-Cjvon3oj.d.mts.map +1 -0
  256. package/dist/sandbox/config-worker.cjs +43 -0
  257. package/dist/sandbox/config-worker.cjs.map +1 -0
  258. package/dist/sandbox/config-worker.d.cts +1 -0
  259. package/dist/sandbox/config-worker.d.mts +1 -0
  260. package/dist/sandbox/config-worker.mjs +44 -0
  261. package/dist/sandbox/config-worker.mjs.map +1 -0
  262. package/dist/sandbox/credentials-worker.cjs +54 -0
  263. package/dist/sandbox/credentials-worker.cjs.map +1 -0
  264. package/dist/sandbox/credentials-worker.d.cts +1 -0
  265. package/dist/sandbox/credentials-worker.d.mts +1 -0
  266. package/dist/sandbox/credentials-worker.mjs +55 -0
  267. package/dist/sandbox/credentials-worker.mjs.map +1 -0
  268. package/dist/sandbox/discover-worker.cjs +47 -0
  269. package/dist/sandbox/discover-worker.cjs.map +1 -0
  270. package/dist/sandbox/discover-worker.d.cts +1 -0
  271. package/dist/sandbox/discover-worker.d.mts +1 -0
  272. package/dist/sandbox/discover-worker.mjs +48 -0
  273. package/dist/sandbox/discover-worker.mjs.map +1 -0
  274. package/dist/sandbox/migrate-worker.cjs +75 -0
  275. package/dist/sandbox/migrate-worker.cjs.map +1 -0
  276. package/dist/sandbox/migrate-worker.d.cts +1 -0
  277. package/dist/sandbox/migrate-worker.d.mts +1 -0
  278. package/dist/sandbox/migrate-worker.mjs +76 -0
  279. package/dist/sandbox/migrate-worker.mjs.map +1 -0
  280. package/dist/sandbox-CL--ZDui.cjs +164 -0
  281. package/dist/sandbox-CL--ZDui.cjs.map +1 -0
  282. package/dist/sandbox-Dm247NGx.mjs +117 -0
  283. package/dist/sandbox-Dm247NGx.mjs.map +1 -0
  284. package/dist/sandbox-M8UnLhXE.d.cts +126 -0
  285. package/dist/sandbox-M8UnLhXE.d.cts.map +1 -0
  286. package/dist/sandbox-M8UnLhXE.d.mts +126 -0
  287. package/dist/sandbox-M8UnLhXE.d.mts.map +1 -0
  288. package/dist/{workspace-zoqRbihZ.mjs → schemas-BObwxB_t.cjs} +998 -1659
  289. package/dist/schemas-BObwxB_t.cjs.map +1 -0
  290. package/dist/{workspace-C6VJQVtG.cjs → schemas-D-xeKJDD.mjs} +913 -1842
  291. package/dist/schemas-D-xeKJDD.mjs.map +1 -0
  292. package/dist/secretsManager-Chs9VV2r.mjs +76 -0
  293. package/dist/secretsManager-Chs9VV2r.mjs.map +1 -0
  294. package/dist/secretsManager-DcMlHnRC.cjs +87 -0
  295. package/dist/secretsManager-DcMlHnRC.cjs.map +1 -0
  296. package/dist/seeds-CkIPFGNO.cjs +10560 -0
  297. package/dist/seeds-CkIPFGNO.cjs.map +1 -0
  298. package/dist/seeds-odfgSCmu.mjs +9538 -0
  299. package/dist/seeds-odfgSCmu.mjs.map +1 -0
  300. package/dist/sniffer-BTtX3NUM.mjs +1262 -0
  301. package/dist/sniffer-BTtX3NUM.mjs.map +1 -0
  302. package/dist/sniffer-IAQEpsQb.cjs +1333 -0
  303. package/dist/sniffer-IAQEpsQb.cjs.map +1 -0
  304. package/dist/sst-BgcOsaBi.cjs +453 -0
  305. package/dist/sst-BgcOsaBi.cjs.map +1 -0
  306. package/dist/sst-CJzvyrEz.mjs +430 -0
  307. package/dist/sst-CJzvyrEz.mjs.map +1 -0
  308. package/dist/stages-CUn6gvXL.cjs +174 -0
  309. package/dist/stages-CUn6gvXL.cjs.map +1 -0
  310. package/dist/stages-CnZRYmkI.mjs +174 -0
  311. package/dist/stages-CnZRYmkI.mjs.map +1 -0
  312. package/dist/target/public.cjs +15 -0
  313. package/dist/target/public.d.cts +28 -0
  314. package/dist/target/public.d.cts.map +1 -0
  315. package/dist/target/public.d.mts +28 -0
  316. package/dist/target/public.d.mts.map +1 -0
  317. package/dist/target/public.mjs +4 -0
  318. package/dist/terminal-D8TPK7o9.mjs +84 -0
  319. package/dist/terminal-D8TPK7o9.mjs.map +1 -0
  320. package/dist/terminal-DuapRxh6.cjs +84 -0
  321. package/dist/terminal-DuapRxh6.cjs.map +1 -0
  322. package/dist/types-NqX1Hz4P.d.cts +7454 -0
  323. package/dist/types-NqX1Hz4P.d.cts.map +1 -0
  324. package/dist/types-ZHuZ89hv.d.mts +7453 -0
  325. package/dist/types-ZHuZ89hv.d.mts.map +1 -0
  326. package/dist/utils-D2Nk1Nv2.cjs +205 -0
  327. package/dist/utils-D2Nk1Nv2.cjs.map +1 -0
  328. package/dist/utils-D_fxUqvU.mjs +156 -0
  329. package/dist/utils-D_fxUqvU.mjs.map +1 -0
  330. package/dist/vitest.cjs +65 -0
  331. package/dist/vitest.cjs.map +1 -0
  332. package/dist/vitest.d.cts +29 -0
  333. package/dist/vitest.d.cts.map +1 -0
  334. package/dist/vitest.d.mts +29 -0
  335. package/dist/vitest.d.mts.map +1 -0
  336. package/dist/vitest.mjs +65 -0
  337. package/dist/vitest.mjs.map +1 -0
  338. package/dist/workerRuntime-BXfhbe13.cjs +108 -0
  339. package/dist/workerRuntime-BXfhbe13.cjs.map +1 -0
  340. package/dist/workerRuntime-CsOyBRx2.mjs +79 -0
  341. package/dist/workerRuntime-CsOyBRx2.mjs.map +1 -0
  342. package/dist/workspace/index.cjs +8 -4
  343. package/dist/workspace/index.d.cts +3 -3
  344. package/dist/workspace/index.d.mts +3 -3
  345. package/dist/workspace/index.mjs +2 -3
  346. package/dist/workspace-CJ0lKFq-.mjs +1979 -0
  347. package/dist/workspace-CJ0lKFq-.mjs.map +1 -0
  348. package/dist/workspace-CwW3Gkru.cjs +2355 -0
  349. package/dist/workspace-CwW3Gkru.cjs.map +1 -0
  350. package/package.json +53 -22
  351. package/dist/CachedStateProvider-BLo7zv7S.cjs +0 -3
  352. package/dist/CachedStateProvider-BxoAm-B2.mjs +0 -3
  353. package/dist/CachedStateProvider-CqPdW7CB.cjs +0 -60
  354. package/dist/CachedStateProvider-CqPdW7CB.cjs.map +0 -1
  355. package/dist/CachedStateProvider-DTniehMP.mjs +0 -54
  356. package/dist/CachedStateProvider-DTniehMP.mjs.map +0 -1
  357. package/dist/HostingerProvider-Cft7lEYr.mjs.map +0 -1
  358. package/dist/HostingerProvider-h3EbEp-Z.cjs.map +0 -1
  359. package/dist/LocalStateProvider-Bn6tS-oL.mjs +0 -42
  360. package/dist/LocalStateProvider-Bn6tS-oL.mjs.map +0 -1
  361. package/dist/LocalStateProvider-Db9SEjyH.cjs +0 -43
  362. package/dist/LocalStateProvider-Db9SEjyH.cjs.map +0 -1
  363. package/dist/Route53Provider-RdpUDJQk.mjs.map +0 -1
  364. package/dist/Route53Provider-di2fMM5N.cjs.map +0 -1
  365. package/dist/SSMStateProvider-BRt2py-A.mjs +0 -66
  366. package/dist/SSMStateProvider-BRt2py-A.mjs.map +0 -1
  367. package/dist/SSMStateProvider-DyX8s9HI.cjs +0 -66
  368. package/dist/SSMStateProvider-DyX8s9HI.cjs.map +0 -1
  369. package/dist/backup-provisioner-Bgj5Vi_L.mjs.map +0 -1
  370. package/dist/backup-provisioner-BrsHwYG0.cjs.map +0 -1
  371. package/dist/bundler-BY1OmV1e.cjs.map +0 -1
  372. package/dist/bundler-Be8Zg4Wd.mjs.map +0 -1
  373. package/dist/chunk-Duj1WY3L.mjs +0 -7
  374. package/dist/config-BZ1F0WuA.cjs +0 -462
  375. package/dist/config-BZ1F0WuA.cjs.map +0 -1
  376. package/dist/config-DVVph9yz.mjs +0 -402
  377. package/dist/config-DVVph9yz.mjs.map +0 -1
  378. package/dist/config.d.cts.map +0 -1
  379. package/dist/config.d.mts.map +0 -1
  380. package/dist/credentials-B5zRHdAl.mjs +0 -141
  381. package/dist/credentials-B5zRHdAl.mjs.map +0 -1
  382. package/dist/credentials-BapzjyV5.cjs +0 -195
  383. package/dist/credentials-BapzjyV5.cjs.map +0 -1
  384. package/dist/credentials-Xamqe_NJ.cjs +0 -2681
  385. package/dist/credentials-Xamqe_NJ.cjs.map +0 -1
  386. package/dist/credentials-dP8vRVRv.mjs +0 -2549
  387. package/dist/credentials-dP8vRVRv.mjs.map +0 -1
  388. package/dist/discover-CAlFgYec.mjs +0 -229
  389. package/dist/discover-CAlFgYec.mjs.map +0 -1
  390. package/dist/discover-DTmFeloL.cjs +0 -271
  391. package/dist/discover-DTmFeloL.cjs.map +0 -1
  392. package/dist/dokploy-api-BS2xnJLZ.mjs +0 -3
  393. package/dist/dokploy-api-BsVH0y_s.cjs +0 -718
  394. package/dist/dokploy-api-BsVH0y_s.cjs.map +0 -1
  395. package/dist/dokploy-api-BuxDRo3l.cjs +0 -3
  396. package/dist/dokploy-api-aTFPz7_4.mjs +0 -706
  397. package/dist/dokploy-api-aTFPz7_4.mjs.map +0 -1
  398. package/dist/emit-CbcRolsa.cjs.map +0 -1
  399. package/dist/emit-CiZS_5Ub.mjs.map +0 -1
  400. package/dist/encryption-C6jaU0hE.cjs +0 -54
  401. package/dist/encryption-C6jaU0hE.cjs.map +0 -1
  402. package/dist/encryption-CHzzeR8a.cjs +0 -4
  403. package/dist/encryption-CQUncu7v.mjs +0 -3
  404. package/dist/encryption-D-abyhZx.mjs +0 -42
  405. package/dist/encryption-D-abyhZx.mjs.map +0 -1
  406. package/dist/fullstack-secrets-C-GGohke.cjs +0 -111
  407. package/dist/fullstack-secrets-C-GGohke.cjs.map +0 -1
  408. package/dist/fullstack-secrets-D1o9-G5l.mjs +0 -87
  409. package/dist/fullstack-secrets-D1o9-G5l.mjs.map +0 -1
  410. package/dist/generator-CNzBw7g5.cjs +0 -289
  411. package/dist/generator-CNzBw7g5.cjs.map +0 -1
  412. package/dist/generator-VE2JrFlY.mjs +0 -253
  413. package/dist/generator-VE2JrFlY.mjs.map +0 -1
  414. package/dist/index-C6e-ULLx.d.mts.map +0 -1
  415. package/dist/index-CR5urhWX.d.cts.map +0 -1
  416. package/dist/openapi-SjsgARie.cjs +0 -2075
  417. package/dist/openapi-SjsgARie.cjs.map +0 -1
  418. package/dist/openapi-Xx0A7Wg0.mjs +0 -2021
  419. package/dist/openapi-Xx0A7Wg0.mjs.map +0 -1
  420. package/dist/openapi-react-query-Byltvm_7.mjs +0 -167
  421. package/dist/openapi-react-query-Byltvm_7.mjs.map +0 -1
  422. package/dist/openapi-react-query-CmJ1xDbn.cjs +0 -173
  423. package/dist/openapi-react-query-CmJ1xDbn.cjs.map +0 -1
  424. package/dist/openapi-react-query.cjs +0 -4
  425. package/dist/openapi-react-query.d.cts +0 -11
  426. package/dist/openapi-react-query.d.cts.map +0 -1
  427. package/dist/openapi-react-query.d.mts +0 -11
  428. package/dist/openapi-react-query.d.mts.map +0 -1
  429. package/dist/openapi-react-query.mjs +0 -4
  430. package/dist/reconcile-CFs8C_1a.mjs.map +0 -1
  431. package/dist/reconcile-D0pimNiy.cjs.map +0 -1
  432. package/dist/setup-BA8ciTPU.mjs +0 -11
  433. package/dist/setup-BsZvZP6f.cjs +0 -11
  434. package/dist/setup-C8KOx8_8.mjs +0 -443
  435. package/dist/setup-C8KOx8_8.mjs.map +0 -1
  436. package/dist/setup-hC6hI86f.cjs +0 -473
  437. package/dist/setup-hC6hI86f.cjs.map +0 -1
  438. package/dist/storage-BJmzYxt8.cjs +0 -363
  439. package/dist/storage-BJmzYxt8.cjs.map +0 -1
  440. package/dist/storage-BM9hGpgv.cjs +0 -7
  441. package/dist/storage-Bi24WfoW.mjs +0 -297
  442. package/dist/storage-Bi24WfoW.mjs.map +0 -1
  443. package/dist/storage-CYlGwWTj.mjs +0 -3
  444. package/dist/sync-CmEuNZsB.mjs +0 -76
  445. package/dist/sync-CmEuNZsB.mjs.map +0 -1
  446. package/dist/sync-D306yOWu.cjs +0 -4
  447. package/dist/sync-SizaChmC.cjs +0 -93
  448. package/dist/sync-SizaChmC.cjs.map +0 -1
  449. package/dist/sync-hOqAWHR6.mjs +0 -3
  450. package/dist/types-6pkp2RRj.d.mts +0 -2220
  451. package/dist/types-6pkp2RRj.d.mts.map +0 -1
  452. package/dist/types-Y3fKQSAK.d.cts +0 -2220
  453. package/dist/types-Y3fKQSAK.d.cts.map +0 -1
  454. package/dist/workspace-BzrG_2SI.mjs +0 -8
  455. package/dist/workspace-C6VJQVtG.cjs.map +0 -1
  456. package/dist/workspace-XXtNhqJl.cjs +0 -9
  457. package/dist/workspace-zoqRbihZ.mjs.map +0 -1
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
@@ -73,7 +73,7 @@ export default defineConfig({
73
73
  // Logger configuration
74
74
  logger: './src/logger.ts#logger',
75
75
 
76
- // Optional: Telescope debugging dashboard (enabled by default in dev)
76
+ // Optional: Telescope request recording (enabled by default in dev)
77
77
  telescope: {
78
78
  enabled: true,
79
79
  path: '/__telescope',
@@ -143,36 +143,32 @@ export const createUser = api
143
143
 
144
144
  ### 5. Create Subscribers (Optional)
145
145
 
146
- 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:
147
148
 
148
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
+
149
166
  // src/subscribers/userSubscriber.ts
150
- import { SubscriberBuilder } from '@geekmidas/constructs/subscribers';
151
- import type { Service } from '@geekmidas/services';
152
- import type { EventPublisher, PublishableMessage } from '@geekmidas/events';
153
- import type { EnvironmentParser } from '@geekmidas/envkit';
154
-
155
- // Define event types
156
- type UserEvents =
157
- | PublishableMessage<'user.created', { userId: string; email: string }>
158
- | PublishableMessage<'user.updated', { userId: string }>;
159
-
160
- // Create event publisher service
161
- const userEventPublisher = {
162
- serviceName: 'userEventPublisher' as const,
163
- async register(envParser: EnvironmentParser<{}>) {
164
- const config = envParser.create((get) => ({
165
- publisherUrl: get('EVENT_PUBLISHER_URL').string()
166
- })).parse();
167
-
168
- const { Publisher } = await import('@geekmidas/events');
169
- return Publisher.fromConnectionString<UserEvents>(config.publisherUrl);
170
- }
171
- } satisfies Service<'userEventPublisher', EventPublisher<UserEvents>>;
167
+ import { users } from '../constructs/topics';
168
+ import { worker } from '../constructs/worker';
172
169
 
173
- // Create subscriber
174
- export const userCreatedSubscriber = new SubscriberBuilder()
175
- .publisher(userEventPublisher)
170
+ export const userCreatedSubscriber = worker
171
+ .topic(users)
176
172
  .subscribe(['user.created'])
177
173
  .handle(async ({ events, logger }) => {
178
174
  for (const event of events) {
@@ -182,11 +178,16 @@ export const userCreatedSubscriber = new SubscriberBuilder()
182
178
  });
183
179
  ```
184
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
+
185
186
  ### 6. Build Handlers
186
187
 
187
188
  ```bash
188
- # Generate AWS Lambda handlers
189
- npx gkm build --provider aws-apigatewayv1
189
+ # Build for where gkm.config.ts deploys (AWS for `deploy: { default: 'sst' }`)
190
+ npx gkm build
190
191
 
191
192
  # Generate server application
192
193
  npx gkm build --provider server
@@ -225,7 +226,7 @@ When run without `--yes`, the command will ask:
225
226
  - `api` - Full API with auth, database, services
226
227
  - `serverless` - AWS Lambda handlers
227
228
  - `worker` - Background job processing
228
- 3. **Telescope** - Include debugging dashboard (default: yes)
229
+ 3. **Telescope** - Include request, exception and log recording (default: yes)
229
230
  4. **Database** - Include Kysely database support (default: yes)
230
231
  5. **Logger** - Choose logger implementation:
231
232
  - `pino` - Fast JSON logger for production (recommended)
@@ -310,17 +311,20 @@ Generate handlers from your endpoints.
310
311
  gkm build [options]
311
312
  ```
312
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
+
313
318
  **Options:**
314
- - `--provider <provider>`: Target provider (default: `aws-apigatewayv1`)
315
- - `aws-apigatewayv1`: AWS API Gateway v1 Lambda handlers
316
- - `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)
317
321
  - `server`: Server application with Hono
318
322
  - `--production`: Generate production-optimized bundle (server provider only)
319
323
 
320
324
  **Example:**
321
325
  ```bash
322
- # Generate AWS Lambda handlers
323
- gkm build --provider aws-apigatewayv1
326
+ # Build for where gkm.config.ts deploys
327
+ gkm build
324
328
 
325
329
  # Generate server application
326
330
  gkm build --provider server
@@ -334,7 +338,7 @@ gkm build --provider server --production
334
338
  When using `--production` with the server provider, the CLI generates an optimized bundle at `.gkm/server/dist/server.mjs`. This bundle:
335
339
  - Is minified and tree-shaken for smaller size
336
340
  - Includes all dependencies (single-file deployment)
337
- - 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
338
342
 
339
343
  ### `gkm openapi`
340
344
 
@@ -434,54 +438,44 @@ gkm docker [options]
434
438
  ```
435
439
 
436
440
  **Options:**
437
- - `--build`: Build Docker image after generating files
438
- - `--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
439
443
  - `--tag <tag>`: Image tag (default: `latest`)
440
444
  - `--registry <url>`: Container registry URL
441
- - `--slim`: Use slim Dockerfile (requires pre-built bundle from `gkm build --production`)
442
- - `--turbo`: Enable turbo prune for monorepo optimization
443
- - `--turbo-package <name>`: Package name for turbo prune (defaults to package.json name)
444
445
 
445
446
  **Generated Files:**
446
- - `.gkm/docker/Dockerfile` - Multi-stage or slim Dockerfile
447
- - `.gkm/docker/docker-compose.yml` - Docker Compose configuration
448
- - `.gkm/docker/docker-entrypoint.sh` - Entrypoint script
449
- - `.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
450
450
 
451
- **Dockerfile Types:**
451
+ **How an image is built:**
452
452
 
453
- | Type | Flag | Description |
454
- |------|------|-------------|
455
- | Multi-stage | (default) | Builds from source inside Docker, most reproducible |
456
- | Turbo | `--turbo` | Optimized for monorepos with turbo prune |
457
- | 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.
458
460
 
459
461
  **Example:**
460
462
  ```bash
461
- # Generate multi-stage Dockerfile (default, recommended)
463
+ # Generate the Dockerfiles
462
464
  gkm docker
463
465
 
464
- # Generate and build image
466
+ # Generate and build the images
465
467
  gkm docker --build --tag v1.0.0
466
468
 
467
469
  # Build and push to registry
468
470
  gkm docker --build --push --registry ghcr.io/myorg --tag v1.0.0
469
-
470
- # Use turbo prune for monorepo
471
- gkm docker --turbo --turbo-package my-api
472
-
473
- # Use slim Dockerfile (after running gkm build --production)
474
- gkm build --provider server --production
475
- gkm docker --slim
476
471
  ```
477
472
 
478
473
  **Package Manager Support:**
479
474
 
480
- The CLI auto-detects your package manager from lockfiles and generates optimized Dockerfiles:
481
- - **pnpm**: Uses `pnpm fetch` for better layer caching
482
- - **npm**: Uses `npm ci` with cache mounts
483
- - **yarn**: Uses `yarn install --frozen-lockfile`
484
- - **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.
485
479
 
486
480
  **Configuration:**
487
481
 
@@ -505,38 +499,20 @@ export default defineConfig({
505
499
  baseImage: 'node:22-alpine',
506
500
  // Port to expose (default: 3000)
507
501
  port: 3000,
508
- // Docker Compose services
509
- compose: {
510
- services: {
511
- postgres: { image: 'postgis/postgis:16-3.4-alpine' }, // Custom image
512
- redis: true, // Default version
513
- rabbitmq: { version: '3.12-management-alpine' }, // Custom version
514
- },
515
- },
516
502
  },
517
503
  });
518
504
  ```
519
505
 
520
- **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:
521
510
 
522
- Services can be configured with custom versions, custom images, or use defaults:
523
-
524
- ```typescript
525
- // Object format (recommended)
526
- services: {
527
- postgres: { version: '15-alpine' }, // Custom version
528
- redis: true, // Default: redis:7-alpine
529
- rabbitmq: { version: '3.12-management-alpine' },
530
- }
531
-
532
- // Custom images (e.g., PostGIS, Redis Stack)
533
- services: {
534
- postgres: { image: 'postgis/postgis:16-3.4-alpine' }, // Full image reference
535
- redis: { image: 'redis/redis-stack:latest' },
536
- }
537
-
538
- // Legacy array format - uses default versions
539
- services: ['postgres', 'redis', 'rabbitmq']
511
+ ```yaml
512
+ # docker-compose.yml
513
+ services:
514
+ postgres:
515
+ image: postgis/postgis:16-3.4-alpine
540
516
  ```
541
517
 
542
518
  **Service Configuration Options:**
@@ -559,7 +535,7 @@ services: ['postgres', 'redis', 'rabbitmq']
559
535
 
560
536
  ### `gkm dev`
561
537
 
562
- Start a development server with hot-reload and optional Telescope debugging dashboard.
538
+ Start a development server with hot-reload and optional Telescope recording.
563
539
 
564
540
  ```bash
565
541
  gkm dev [options]
@@ -571,7 +547,8 @@ gkm dev [options]
571
547
  **Features:**
572
548
  - Hot-reload on file changes (endpoints, functions, crons, subscribers)
573
549
  - Automatic port switching if requested port is in use
574
- - 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`
575
552
  - Real-time WebSocket updates in Telescope
576
553
 
577
554
  **Example:**
@@ -684,8 +661,8 @@ gkm secrets:init --stage production --force
684
661
  ```
685
662
 
686
663
  **Generated:**
687
- - Secure passwords for postgres, redis, rabbitmq (based on `docker.compose.services` config)
688
- - 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
689
666
  - Stored in `.gkm/secrets/<stage>.json` (gitignored)
690
667
 
691
668
  ### `gkm secrets:set`
@@ -799,7 +776,7 @@ Store credentials locally to avoid setting environment variables for every comma
799
776
 
800
777
  ### `gkm login`
801
778
 
802
- 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).
803
780
 
804
781
  ```bash
805
782
  gkm login [options]
@@ -827,7 +804,7 @@ gkm login --endpoint https://dokploy.example.com
827
804
  # These commands no longer need DOKPLOY_API_TOKEN
828
805
  gkm deploy:list
829
806
  gkm deploy:init --project my-project --app api
830
- gkm deploy --provider dokploy --stage production
807
+ gkm deploy --stage production
831
808
  ```
832
809
 
833
810
  ### `gkm logout`
@@ -873,92 +850,99 @@ gkm whoami
873
850
 
874
851
  ### `gkm deploy`
875
852
 
876
- 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`.
877
857
 
878
858
  ```bash
879
- gkm deploy --provider <provider> --stage <stage> [options]
859
+ gkm deploy --stage <stage> [options]
880
860
  ```
881
861
 
882
862
  **Options:**
883
- - `--provider <provider>`: Deploy provider (`docker`, `dokploy`, `aws-lambda`)
884
- - `--stage <stage>`: Deployment stage
885
- - `--tag <tag>`: Image tag (default: `stage-timestamp`)
886
- - `--skip-push`: Skip pushing image to registry
887
- - `--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
888
871
 
889
872
  **Examples:**
890
873
  ```bash
891
- # Docker: build and push image
892
- gkm deploy --provider docker --stage production
874
+ # deploy.default (dokploy unless configured otherwise)
875
+ DOKPLOY_API_TOKEN=xxx gkm deploy --stage production
893
876
 
894
- # Dokploy: build, push, and trigger deployment
895
- DOKPLOY_API_TOKEN=xxx gkm deploy --provider dokploy --stage production
877
+ # Plan only
878
+ gkm deploy --stage production --dry-run
896
879
 
897
- # Custom tag
898
- gkm deploy --provider docker --stage production --tag v1.0.0
899
- ```
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
900
882
 
901
- **Workflow:**
902
- 1. **Sniffs environment variables** - Automatically detects which env vars each app needs
903
- 2. Builds production bundle with `gkm build --provider server --production --stage <stage>`
904
- 3. Encrypts secrets from `.gkm/secrets/<stage>.json` into the bundle
905
- 4. Generates Docker files with `gkm docker`
906
- 5. Builds and pushes Docker image
907
- 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
908
885
 
909
- **Environment Variable Detection:**
910
-
911
- 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
+ ```
912
889
 
913
- | App Type | Detection Strategy |
914
- |----------|-------------------|
915
- | Frontend apps | Returns empty (no server secrets) |
916
- | Apps with `requiredEnv` | Uses explicit list from config |
917
- | Entry-based apps | Imports entry file in subprocess to capture `config.parse()` calls |
918
- | Route-based apps | Loads routes and calls `getEnvironment()` on each construct |
919
- | 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.
920
895
 
921
- For route-based apps, the sniffer loads each endpoint/function/cron/subscriber and collects environment variables from:
922
- - All services attached to the construct (via `service.register()`)
923
- - Publisher service (if any)
924
- - Auditor storage service (if any)
925
- - 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 }`.
926
897
 
927
- 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.
928
899
 
929
- **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.
930
901
 
931
902
  ```typescript
932
- // gkm.config.ts
933
- export default defineConfig({
934
- stages: { local: 'dev', deployed: ['prod'] },
935
- routes: 'src/endpoints/**/*.ts',
936
- envParser: './src/env.ts',
937
- logger: './src/logger.ts',
938
-
939
- docker: {
940
- registry: 'ghcr.io/myorg',
941
- imageName: 'my-api',
942
- },
903
+ import { deploy } from '@geekmidas/cli/deploy';
943
904
 
944
- // For Dokploy deployments
945
- providers: {
946
- dokploy: {
947
- endpoint: 'https://dokploy.example.com',
948
- projectId: 'proj_xxx',
949
- applicationId: 'app_xxx',
950
- },
951
- },
952
- });
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;
953
908
  ```
954
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
+
955
914
  **Environment Variables:**
956
915
  - `DOKPLOY_API_TOKEN`: API token for Dokploy (not needed if logged in via `gkm login`)
957
- - `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`.
958
942
 
959
943
  ### `gkm deploy:init`
960
944
 
961
- 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.
962
946
 
963
947
  ```bash
964
948
  gkm deploy:init --project <name> --app <name> [options]
@@ -993,8 +977,7 @@ gkm deploy:init \
993
977
  1. Searches for existing project by name, or creates a new one
994
978
  2. Creates a new application in the project
995
979
  3. Configures registry if `--registry-id` is provided
996
- 4. Updates `gkm.config.ts` with the Dokploy configuration
997
- 5. Shows next steps for secrets and deployment
980
+ 4. Shows next steps for secrets and deployment
998
981
 
999
982
  ### `gkm deploy:list`
1000
983
 
@@ -1020,6 +1003,24 @@ gkm deploy:list --registries
1020
1003
  gkm deploy:list --endpoint https://dokploy.example.com
1021
1004
  ```
1022
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
+
1023
1024
  ### Using Encrypted Credentials
1024
1025
 
1025
1026
  After deploying with secrets, your application decrypts credentials at runtime:
@@ -1043,7 +1044,7 @@ export const envParser = new EnvironmentParser({...process.env, ...Credentials})
1043
1044
 
1044
1045
  **How it works:**
1045
1046
  - At build time, secrets are encrypted with AES-256-GCM and embedded in the bundle
1046
- - 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
1047
1048
  - At runtime, `Credentials` decrypts using `GKM_MASTER_KEY` environment variable
1048
1049
  - In development (no embedded secrets), `Credentials` returns `{}`
1049
1050
 
@@ -1062,28 +1063,23 @@ The following commands are planned for future releases:
1062
1063
  The `gkm.config.ts` file defines how the CLI discovers and processes your endpoints:
1063
1064
 
1064
1065
  ```typescript
1065
- // Construct types accept a string, string[], or partitioned config
1066
- type Routes = string | string[] | PartitionedRoutes;
1067
-
1068
- interface PartitionedRoutes {
1069
- paths: string | string[];
1070
- partition: (filepath: string) => string;
1071
- }
1066
+ // Construct types accept a glob string or an array of them
1067
+ type Routes = string | string[];
1072
1068
 
1073
1069
  interface GkmConfig {
1074
- routes: Routes; // Glob patterns or partitioned config
1070
+ routes: Routes; // Glob patterns
1075
1071
  envParser: string; // Path to environment parser
1076
1072
  logger: string; // Path to logger configuration
1077
- functions?: Routes; // Glob patterns or partitioned config
1078
- crons?: Routes; // Glob patterns or partitioned config
1079
- subscribers?: Routes; // Glob patterns or partitioned config
1073
+ functions?: Routes; // Glob patterns
1074
+ crons?: Routes; // Glob patterns
1075
+ subscribers?: Routes; // Glob patterns
1080
1076
  runtime?: 'node' | 'bun'; // Runtime environment (default: 'node')
1081
1077
  telescope?: boolean | TelescopeConfig; // Telescope debugging config
1082
1078
  }
1083
1079
 
1084
1080
  interface TelescopeConfig {
1085
1081
  enabled?: boolean; // Enable/disable (default: true in dev)
1086
- path?: string; // Dashboard path (default: '/__telescope')
1082
+ path?: string; // Where the JSON API is mounted (default: '/__telescope')
1087
1083
  ignore?: string[]; // URL patterns to ignore
1088
1084
  recordBody?: boolean; // Record request/response bodies (default: true)
1089
1085
  maxEntries?: number; // Max entries to keep (default: 1000)
@@ -1095,7 +1091,7 @@ interface TelescopeConfig {
1095
1091
 
1096
1092
  #### `routes`
1097
1093
 
1098
- 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:
1099
1095
 
1100
1096
  ```typescript
1101
1097
  // Single pattern
@@ -1107,19 +1103,8 @@ routes: [
1107
1103
  'src/api/**/*.ts',
1108
1104
  'src/handlers/**/*.ts'
1109
1105
  ]
1110
-
1111
- // Partitioned — groups constructs in the generated manifest
1112
- routes: {
1113
- paths: './src/endpoints/**/*.ts',
1114
- partition: (filepath) => {
1115
- const match = filepath.match(/endpoints\/([^/]+)\//);
1116
- return match?.[1] ?? 'default';
1117
- },
1118
- }
1119
1106
  ```
1120
1107
 
1121
- 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.
1122
-
1123
1108
  #### `envParser`
1124
1109
 
1125
1110
  Path to your environment parser configuration. Supports both default and named exports.
@@ -1152,7 +1137,7 @@ logger: './src/utils.ts#appLogger'
1152
1137
 
1153
1138
  #### `telescope`
1154
1139
 
1155
- 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`.
1156
1141
 
1157
1142
  ```typescript
1158
1143
  // Disable telescope
@@ -1177,7 +1162,7 @@ telescope: {
1177
1162
  | Option | Type | Default | Description |
1178
1163
  |--------|------|---------|-------------|
1179
1164
  | `enabled` | `boolean` | `true` | Enable/disable Telescope |
1180
- | `path` | `string` | `/__telescope` | Dashboard URL path |
1165
+ | `path` | `string` | `/__telescope` | Where the JSON API is mounted |
1181
1166
  | `ignore` | `string[]` | `[]` | URL patterns to exclude from recording |
1182
1167
  | `recordBody` | `boolean` | `true` | Record request/response bodies |
1183
1168
  | `maxEntries` | `number` | `1000` | Maximum entries per type to keep |
@@ -1296,7 +1281,7 @@ gkm docker
1296
1281
  - `.gkm/docker/Dockerfile.api` - Routes-based backend (uses `gkm build`)
1297
1282
  - `.gkm/docker/Dockerfile.auth` - Entry-based backend (uses esbuild bundling)
1298
1283
  - `.gkm/docker/Dockerfile.web` - Next.js standalone output
1299
- - `.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)
1300
1285
  - `.dockerignore` - Optimized ignore patterns
1301
1286
 
1302
1287
  **Dockerfile types by app:**
@@ -1374,42 +1359,24 @@ interface AppSpec {
1374
1359
  }
1375
1360
  ```
1376
1361
 
1377
- ## Providers
1362
+ ## Build Targets
1378
1363
 
1379
- ### AWS API Gateway v1
1364
+ ### AWS
1380
1365
 
1381
- Generates Lambda handlers compatible with AWS API Gateway v1 (REST API).
1366
+ Generates one Lambda handler per construct. Endpoints get an API Gateway v2
1367
+ (HTTP API) adapter.
1382
1368
 
1383
1369
  ```bash
1384
- gkm build --provider aws-apigatewayv1
1385
- ```
1386
-
1387
- **Generated Handler:**
1388
- ```typescript
1389
- import { AmazonApiGatewayV1Endpoint } from '@geekmidas/constructs/aws';
1390
- import { myEndpoint } from '../src/routes/example.js';
1391
- import { envParser } from '../src/env.js';
1392
-
1393
- const adapter = new AmazonApiGatewayV1Endpoint(envParser, myEndpoint);
1394
-
1395
- export const handler = adapter.handler;
1396
- ```
1397
-
1398
- ### AWS API Gateway v2
1399
-
1400
- Generates Lambda handlers compatible with AWS API Gateway v2 (HTTP API).
1401
-
1402
- ```bash
1403
- gkm build --provider aws-apigatewayv2
1370
+ gkm build # with deploy: { default: 'sst' }
1371
+ gkm build --provider aws # whatever the deploy target
1404
1372
  ```
1405
1373
 
1406
1374
  **Generated Handler:**
1407
1375
  ```typescript
1408
1376
  import { AmazonApiGatewayV2Endpoint } from '@geekmidas/constructs/aws';
1409
- import { myEndpoint } from '../src/routes/example.js';
1410
- import { envParser } from '../src/env.js';
1377
+ import { myEndpoint } from '../../../src/routes/example.js';
1411
1378
 
1412
- const adapter = new AmazonApiGatewayV2Endpoint(envParser, myEndpoint);
1379
+ const adapter = new AmazonApiGatewayV2Endpoint(myEndpoint);
1413
1380
 
1414
1381
  export const handler = adapter.handler;
1415
1382
  ```
@@ -1451,139 +1418,141 @@ export default createApp;
1451
1418
 
1452
1419
  ## Output Structure
1453
1420
 
1454
- 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:
1455
1423
 
1456
1424
  ```
1457
- .gkm/
1458
- ├── aws-apigatewayv1/
1459
- │ ├── getUsers.ts # Individual Lambda handler
1460
- │ ├── createUser.ts # Individual Lambda handler
1461
- ├── server/
1462
- │ ├── app.ts # Server application
1463
- │ ├── endpoints.ts # Endpoint exports
1464
- ├── manifest/
1465
- │ ├── aws.ts # AWS manifest with types
1466
- │ └── server.ts # Server manifest with types
1467
- └── 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
1468
1439
  ```
1469
1440
 
1470
1441
  ### Build Manifest
1471
1442
 
1472
- 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`.
1473
1448
 
1474
- #### 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:
1475
1451
 
1476
1452
  ```typescript
1477
- export const manifest = {
1478
- routes: [
1479
- {
1480
- path: '/users',
1481
- method: 'GET',
1482
- handler: '.gkm/aws-apigatewayv1/getUsers.handler',
1483
- authorizer: 'jwt',
1484
- },
1485
- {
1486
- path: '/users',
1487
- method: 'POST',
1488
- handler: '.gkm/aws-apigatewayv1/createUser.handler',
1489
- authorizer: 'jwt',
1490
- },
1491
- ],
1492
- functions: [
1493
- {
1494
- name: 'processData',
1495
- handler: '.gkm/aws-lambda/functions/processData.handler',
1496
- timeout: 60,
1497
- memorySize: 256,
1498
- },
1499
- ],
1500
- crons: [
1501
- {
1502
- name: 'dailyCleanup',
1503
- handler: '.gkm/aws-lambda/crons/dailyCleanup.handler',
1504
- schedule: 'rate(1 day)',
1505
- timeout: 300,
1506
- 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: [],
1507
1491
  },
1508
- ],
1509
- subscribers: [],
1510
- } 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;
1511
1510
 
1512
1511
  // Derived types
1513
- export type Route = (typeof manifest.routes)[number];
1514
- export type Function = (typeof manifest.functions)[number];
1515
- export type Cron = (typeof manifest.crons)[number];
1516
- 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'];
1517
1515
 
1518
1516
  // Useful union types
1519
- export type Authorizer = Route['authorizer'];
1520
- export type HttpMethod = Route['method'];
1521
- 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'];
1522
1521
  ```
1523
1522
 
1524
- When routes are partitioned, the manifest groups them by partition name and generates partition-aware types:
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.
1525
1530
 
1526
- ```typescript
1527
- export const manifest = {
1528
- routes: {
1529
- "admin": [{ path: '/admin/users', method: 'GET', handler: '...', authorizer: 'jwt' }],
1530
- "default": [{ path: '/users', method: 'GET', handler: '...', authorizer: 'jwt' }],
1531
- },
1532
- functions: [...], // flat if not partitioned
1533
- } as const;
1531
+ #### Using the Manifest
1534
1532
 
1535
- // Partition-aware derived types
1536
- export type RoutePartition = keyof typeof manifest.routes;
1537
- export type Route<P extends RoutePartition = RoutePartition> =
1538
- (typeof manifest.routes)[P][number];
1539
- ```
1540
-
1541
- #### 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:
1542
1535
 
1543
1536
  ```typescript
1544
- export const manifest = {
1545
- app: {
1546
- handler: '.gkm/server/app.ts',
1547
- endpoints: '.gkm/server/endpoints.ts',
1548
- },
1549
- routes: [
1550
- { path: '/users', method: 'GET', authorizer: 'jwt' },
1551
- { path: '/users', method: 'POST', authorizer: 'jwt' },
1552
- ],
1553
- subscribers: [
1554
- { name: 'orderHandler', subscribedEvents: ['order.created'] },
1555
- ],
1556
- } 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');
1557
1540
 
1558
- // Derived types
1559
- export type Route = (typeof manifest.routes)[number];
1560
- export type Subscriber = (typeof manifest.subscribers)[number];
1561
-
1562
- // Useful union types
1563
- export type Authorizer = Route['authorizer'];
1564
- export type HttpMethod = Route['method'];
1565
- export type RoutePath = Route['path'];
1541
+ fromManifest(new Stack(app, 'Shop'), constructs, { Database: { vpc } }, backends);
1566
1542
  ```
1567
1543
 
1568
- #### Using Manifest Types
1569
-
1570
- Import the manifest types for type-safe infrastructure configuration:
1544
+ The types narrow to what was declared:
1571
1545
 
1572
1546
  ```typescript
1573
- import { manifest, type Route, type Authorizer } from './.gkm/manifest/aws';
1547
+ import { constructs, type Construct, type Surfaces } from './.gkm/manifest/aws';
1574
1548
 
1575
- // Type-safe route iteration
1576
- for (const route of manifest.routes) {
1577
- console.log(`${route.method} ${route.path} -> ${route.handler}`);
1578
- }
1549
+ const api: Construct<'Api'> = constructs.Api;
1579
1550
 
1580
- // Use union types for validation
1581
- function isValidMethod(method: string): method is HttpMethod {
1582
- return manifest.routes.some((r) => r.method === method);
1551
+ for (const endpoint of api.endpoints) {
1552
+ console.log(`${endpoint.method} ${endpoint.path} -> ${endpoint.handler}`);
1583
1553
  }
1584
1554
 
1585
- // Access authorizer names
1586
- const authorizers = new Set(manifest.routes.map((r) => r.authorizer));
1555
+ const surface: Surfaces = 'Api'; // any other id is a type error
1587
1556
  ```
1588
1557
 
1589
1558
  ## OpenAPI Generation
@@ -1666,62 +1635,25 @@ gkm openapi --output api-docs.json --json
1666
1635
 
1667
1636
  ## Deployment Examples
1668
1637
 
1669
- ### 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:
1670
1640
 
1671
- ```yaml
1672
- # serverless.yml
1673
- service: my-api
1674
-
1675
- provider:
1676
- name: aws
1677
- runtime: nodejs18.x
1678
-
1679
- functions:
1680
- getUsers:
1681
- handler: .gkm/aws-apigatewayv1/getUsers.handler
1682
- events:
1683
- - http:
1684
- path: users
1685
- method: get
1686
-
1687
- createUser:
1688
- handler: .gkm/aws-apigatewayv1/createUser.handler
1689
- events:
1690
- - http:
1691
- path: users
1692
- method: post
1693
- ```
1694
-
1695
- ### Server Deployment
1641
+ ```bash
1642
+ # Dokploy (the default target)
1643
+ gkm deploy --stage production
1696
1644
 
1697
- ```typescript
1698
- // server.ts
1699
- 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
1700
1647
 
1701
- const app = createApp();
1648
+ # AWS through SST, with deploy: { default: 'sst' }
1649
+ gkm deploy --stage production
1702
1650
 
1703
- const port = process.env.PORT || 3000;
1704
- app.listen(port, () => {
1705
- console.log(`Server running on port ${port}`);
1706
- });
1651
+ # Only the Docker files, to build and run images yourself
1652
+ gkm docker --build --tag v1.4.0
1707
1653
  ```
1708
1654
 
1709
- ### Docker Deployment
1710
-
1711
- ```dockerfile
1712
- FROM node:18-alpine
1713
-
1714
- WORKDIR /app
1715
- COPY package*.json ./
1716
- RUN npm ci --only=production
1717
-
1718
- COPY . .
1719
- RUN npm run build
1720
-
1721
- EXPOSE 3000
1722
-
1723
- CMD ["node", "server.js"]
1724
- ```
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).
1725
1657
 
1726
1658
  ## Advanced Usage
1727
1659
 
@@ -1918,8 +1850,8 @@ Error: Failed to load gkm.config.ts: Invalid configuration
1918
1850
  # No endpoints found
1919
1851
  No endpoints found to process
1920
1852
 
1921
- # Invalid provider
1922
- 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>' } }.
1923
1855
  ```
1924
1856
 
1925
1857
  ### OpenAPI Errors
@@ -1939,44 +1871,22 @@ Error: OpenAPI generation failed: Invalid endpoint schema
1939
1871
  "dev": "gkm dev",
1940
1872
  "dev:port": "gkm dev --port 8080",
1941
1873
  "build": "gkm build",
1942
- "build:lambda": "gkm build --provider aws-apigatewayv1",
1874
+ "build:lambda": "gkm build --provider aws",
1943
1875
  "build:server": "gkm build --provider server",
1944
- "docs": "gkm openapi --output src/api.ts"
1876
+ "client": "gkm openapi"
1945
1877
  }
1946
1878
  }
1947
1879
  ```
1948
1880
 
1949
1881
  ### CI/CD Pipeline
1950
1882
 
1951
- ```yaml
1952
- # .github/workflows/deploy.yml
1953
- name: Deploy API
1954
-
1955
- on:
1956
- push:
1957
- branches: [main]
1958
-
1959
- jobs:
1960
- deploy:
1961
- runs-on: ubuntu-latest
1962
-
1963
- steps:
1964
- - uses: actions/checkout@v3
1965
-
1966
- - name: Setup Node.js
1967
- uses: actions/setup-node@v3
1968
- with:
1969
- node-version: '18'
1970
-
1971
- - name: Install dependencies
1972
- run: npm ci
1973
-
1974
- - name: Build handlers
1975
- run: npm run build:lambda
1976
-
1977
- - name: Deploy to AWS
1978
- run: npx serverless deploy
1979
- ```
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).
1980
1890
 
1981
1891
  ## Troubleshooting
1982
1892
 
@@ -2033,8 +1943,8 @@ DEBUG=gkm:* npx gkm build
2033
1943
  ### Types
2034
1944
 
2035
1945
  ```typescript
2036
- // Provider options
2037
- type Provider = 'server' | 'aws-apigatewayv1' | 'aws-apigatewayv2';
1946
+ // Build targets
1947
+ type Provider = 'aws' | 'server';
2038
1948
 
2039
1949
  // Runtime options
2040
1950
  type Runtime = 'node' | 'bun';
@@ -2058,17 +1968,8 @@ interface DockerConfig {
2058
1968
  imageName?: string; // Image name (defaults to package.json name)
2059
1969
  baseImage?: string; // Base image (default: node:22-alpine)
2060
1970
  port?: number; // Port to expose (default: 3000)
2061
- compose?: {
2062
- services?: ComposeServicesConfig | ComposeServiceName[];
2063
- };
2064
1971
  }
2065
1972
 
2066
- // Service configuration for docker-compose
2067
- type ComposeServiceName = 'postgres' | 'redis' | 'rabbitmq';
2068
- type ComposeServicesConfig = {
2069
- [K in ComposeServiceName]?: boolean | { version?: string };
2070
- };
2071
-
2072
1973
  // Telescope configuration
2073
1974
  interface TelescopeConfig {
2074
1975
  enabled?: boolean;
@@ -2081,7 +1982,7 @@ interface TelescopeConfig {
2081
1982
 
2082
1983
  // Build options
2083
1984
  interface BuildOptions {
2084
- provider: Provider;
1985
+ provider?: Provider; // default: where gkm.config.ts deploys
2085
1986
  }
2086
1987
 
2087
1988
  // Dev options