@geekmidas/cli 0.3.0 → 0.5.0

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 (309) hide show
  1. package/README.md +488 -71
  2. package/dist/CronGenerator-BPTqNYOR.d.cts +14 -0
  3. package/dist/{CronGenerator-Bh26MaNA.mjs → CronGenerator-CCRYptuT.mjs} +2 -2
  4. package/dist/{CronGenerator-Bh26MaNA.mjs.map → CronGenerator-CCRYptuT.mjs.map} +1 -1
  5. package/dist/{CronGenerator-C6MF8rlG.cjs → CronGenerator-D4TWXQbh.cjs} +2 -2
  6. package/dist/{CronGenerator-C6MF8rlG.cjs.map → CronGenerator-D4TWXQbh.cjs.map} +1 -1
  7. package/dist/CronGenerator-YAj59JUd.d.mts +14 -0
  8. package/dist/EndpointGenerator-ChAD1INz.d.cts +19 -0
  9. package/dist/EndpointGenerator-Cj3O1U8-.d.mts +19 -0
  10. package/dist/{EndpointGenerator-CWh18d92.mjs → EndpointGenerator-DGivkPLT.mjs} +77 -7
  11. package/dist/EndpointGenerator-DGivkPLT.mjs.map +1 -0
  12. package/dist/{EndpointGenerator-C73wNoih.cjs → EndpointGenerator-npWEDoK2.cjs} +77 -7
  13. package/dist/EndpointGenerator-npWEDoK2.cjs.map +1 -0
  14. package/dist/FunctionGenerator-429-9NER.d.cts +14 -0
  15. package/dist/FunctionGenerator-BQ4ehoID.d.mts +14 -0
  16. package/dist/{FunctionGenerator-BNE_GC7N.mjs → FunctionGenerator-CVk0h8tO.mjs} +2 -2
  17. package/dist/{FunctionGenerator-BNE_GC7N.mjs.map → FunctionGenerator-CVk0h8tO.mjs.map} +1 -1
  18. package/dist/{FunctionGenerator-FgZUTd8L.cjs → FunctionGenerator-DYTnyr4c.cjs} +2 -2
  19. package/dist/{FunctionGenerator-FgZUTd8L.cjs.map → FunctionGenerator-DYTnyr4c.cjs.map} +1 -1
  20. package/dist/Generator-BjHK_qce.d.mts +27 -0
  21. package/dist/{Generator-UanJW0_V.mjs → Generator-CDt4pB3W.mjs} +1 -1
  22. package/dist/{Generator-UanJW0_V.mjs.map → Generator-CDt4pB3W.mjs.map} +1 -1
  23. package/dist/{Generator-CDoEXCDg.cjs → Generator-CLVplqm2.cjs} +1 -1
  24. package/dist/{Generator-CDoEXCDg.cjs.map → Generator-CLVplqm2.cjs.map} +1 -1
  25. package/dist/Generator-DxQMCQp7.d.cts +27 -0
  26. package/dist/OpenApiTsGenerator-Be-sKGTT.cjs +501 -0
  27. package/dist/OpenApiTsGenerator-Be-sKGTT.cjs.map +1 -0
  28. package/dist/OpenApiTsGenerator-C4mHHaku.mjs +495 -0
  29. package/dist/OpenApiTsGenerator-C4mHHaku.mjs.map +1 -0
  30. package/dist/SubscriberGenerator-7uX42xyG.d.mts +15 -0
  31. package/dist/{SubscriberGenerator-Dnlj_1FK.mjs → SubscriberGenerator-DABaJXML.mjs} +2 -2
  32. package/dist/{SubscriberGenerator-Dnlj_1FK.mjs.map → SubscriberGenerator-DABaJXML.mjs.map} +1 -1
  33. package/dist/{SubscriberGenerator-Bd-a7aiw.cjs → SubscriberGenerator-D_zpNGFr.cjs} +2 -2
  34. package/dist/{SubscriberGenerator-Bd-a7aiw.cjs.map → SubscriberGenerator-D_zpNGFr.cjs.map} +1 -1
  35. package/dist/SubscriberGenerator-Dtb3HS4i.d.cts +15 -0
  36. package/dist/api-B3SCEHPf.cjs +190 -0
  37. package/dist/api-B3SCEHPf.cjs.map +1 -0
  38. package/dist/api-BKIN0s0S.mjs +184 -0
  39. package/dist/api-BKIN0s0S.mjs.map +1 -0
  40. package/dist/build/index.cjs +11 -10
  41. package/dist/build/index.d.cts +7 -0
  42. package/dist/build/index.d.mts +7 -0
  43. package/dist/build/index.mjs +11 -10
  44. package/dist/build/manifests.cjs +1 -1
  45. package/dist/build/manifests.d.cts +13 -0
  46. package/dist/build/manifests.d.mts +13 -0
  47. package/dist/build/manifests.mjs +1 -1
  48. package/dist/build/providerResolver.cjs +1 -1
  49. package/dist/build/providerResolver.d.cts +23 -0
  50. package/dist/build/providerResolver.d.mts +23 -0
  51. package/dist/build/providerResolver.mjs +1 -1
  52. package/dist/build/types.d.cts +3 -0
  53. package/dist/build/types.d.mts +3 -0
  54. package/dist/{build-C6uEGRj8.mjs → build-B8C_qHir.mjs} +15 -13
  55. package/dist/build-B8C_qHir.mjs.map +1 -0
  56. package/dist/{build-CBYBPZpC.cjs → build-D0Wr49bf.cjs} +15 -13
  57. package/dist/build-D0Wr49bf.cjs.map +1 -0
  58. package/dist/config-Ba-Gbpbc.d.cts +11 -0
  59. package/dist/config-Bq72aj8e.mjs +75 -0
  60. package/dist/config-Bq72aj8e.mjs.map +1 -0
  61. package/dist/config-CFls09Ey.cjs +93 -0
  62. package/dist/config-CFls09Ey.cjs.map +1 -0
  63. package/dist/config-CLEDqKO3.cjs +157 -0
  64. package/dist/config-CLEDqKO3.cjs.map +1 -0
  65. package/dist/config-DBsmMDhf.d.mts +11 -0
  66. package/dist/config-Dp8RonV_.mjs +151 -0
  67. package/dist/config-Dp8RonV_.mjs.map +1 -0
  68. package/dist/config.cjs +4 -2
  69. package/dist/config.d.cts +48 -0
  70. package/dist/config.d.mts +48 -0
  71. package/dist/config.mjs +2 -2
  72. package/dist/dev/index.cjs +12 -10
  73. package/dist/dev/index.d.cts +36 -0
  74. package/dist/dev/index.d.mts +36 -0
  75. package/dist/dev/index.mjs +10 -10
  76. package/dist/dev-B734w3L1.mjs +343 -0
  77. package/dist/dev-B734w3L1.mjs.map +1 -0
  78. package/dist/{dev-DbtyToc7.cjs → dev-DHqYn8k4.cjs} +161 -47
  79. package/dist/dev-DHqYn8k4.cjs.map +1 -0
  80. package/dist/docker-5d8Yh5_X.cjs +119 -0
  81. package/dist/docker-5d8Yh5_X.cjs.map +1 -0
  82. package/dist/docker-DlUqdFle.mjs +113 -0
  83. package/dist/docker-DlUqdFle.mjs.map +1 -0
  84. package/dist/env-B-OKjgI4.cjs +144 -0
  85. package/dist/env-B-OKjgI4.cjs.map +1 -0
  86. package/dist/env-HfuJRlg5.d.cts +11 -0
  87. package/dist/env-nd-iQPYM.d.mts +11 -0
  88. package/dist/env-tv1HlZlw.mjs +138 -0
  89. package/dist/env-tv1HlZlw.mjs.map +1 -0
  90. package/dist/generators/CronGenerator.cjs +2 -2
  91. package/dist/generators/CronGenerator.d.cts +5 -0
  92. package/dist/generators/CronGenerator.d.mts +5 -0
  93. package/dist/generators/CronGenerator.mjs +2 -2
  94. package/dist/generators/EndpointGenerator.cjs +2 -2
  95. package/dist/generators/EndpointGenerator.d.cts +5 -0
  96. package/dist/generators/EndpointGenerator.d.mts +5 -0
  97. package/dist/generators/EndpointGenerator.mjs +2 -2
  98. package/dist/generators/FunctionGenerator.cjs +2 -2
  99. package/dist/generators/FunctionGenerator.d.cts +5 -0
  100. package/dist/generators/FunctionGenerator.d.mts +5 -0
  101. package/dist/generators/FunctionGenerator.mjs +2 -2
  102. package/dist/generators/Generator.cjs +1 -1
  103. package/dist/generators/Generator.d.cts +4 -0
  104. package/dist/generators/Generator.d.mts +4 -0
  105. package/dist/generators/Generator.mjs +1 -1
  106. package/dist/generators/OpenApiTsGenerator.cjs +3 -0
  107. package/dist/generators/OpenApiTsGenerator.d.cts +44 -0
  108. package/dist/generators/OpenApiTsGenerator.d.mts +44 -0
  109. package/dist/generators/OpenApiTsGenerator.mjs +3 -0
  110. package/dist/generators/SubscriberGenerator.cjs +2 -2
  111. package/dist/generators/SubscriberGenerator.d.cts +5 -0
  112. package/dist/generators/SubscriberGenerator.d.mts +5 -0
  113. package/dist/generators/SubscriberGenerator.mjs +2 -2
  114. package/dist/generators/index.cjs +6 -6
  115. package/dist/generators/index.d.cts +8 -0
  116. package/dist/generators/index.d.mts +8 -0
  117. package/dist/generators/index.mjs +6 -6
  118. package/dist/index-C523No_B.d.mts +64 -0
  119. package/dist/index-DrzN4xkQ.d.cts +64 -0
  120. package/dist/index.cjs +56 -18
  121. package/dist/index.cjs.map +1 -1
  122. package/dist/index.d.cts +1 -0
  123. package/dist/index.d.mts +1 -0
  124. package/dist/index.mjs +56 -18
  125. package/dist/index.mjs.map +1 -1
  126. package/dist/init/generators/config.cjs +3 -0
  127. package/dist/init/generators/config.d.cts +3 -0
  128. package/dist/init/generators/config.d.mts +3 -0
  129. package/dist/init/generators/config.mjs +3 -0
  130. package/dist/init/generators/docker.cjs +3 -0
  131. package/dist/init/generators/docker.d.cts +11 -0
  132. package/dist/init/generators/docker.d.mts +11 -0
  133. package/dist/init/generators/docker.mjs +3 -0
  134. package/dist/init/generators/env.cjs +3 -0
  135. package/dist/init/generators/env.d.cts +3 -0
  136. package/dist/init/generators/env.d.mts +3 -0
  137. package/dist/init/generators/env.mjs +3 -0
  138. package/dist/init/generators/index.cjs +9 -0
  139. package/dist/init/generators/index.d.cts +6 -0
  140. package/dist/init/generators/index.d.mts +6 -0
  141. package/dist/init/generators/index.mjs +6 -0
  142. package/dist/init/generators/models.cjs +3 -0
  143. package/dist/init/generators/models.d.cts +11 -0
  144. package/dist/init/generators/models.d.mts +11 -0
  145. package/dist/init/generators/models.mjs +3 -0
  146. package/dist/init/generators/monorepo.cjs +3 -0
  147. package/dist/init/generators/monorepo.d.cts +11 -0
  148. package/dist/init/generators/monorepo.d.mts +11 -0
  149. package/dist/init/generators/monorepo.mjs +3 -0
  150. package/dist/init/generators/package.cjs +3 -0
  151. package/dist/init/generators/package.d.cts +3 -0
  152. package/dist/init/generators/package.d.mts +3 -0
  153. package/dist/init/generators/package.mjs +3 -0
  154. package/dist/init/generators/source.cjs +3 -0
  155. package/dist/init/generators/source.d.cts +3 -0
  156. package/dist/init/generators/source.d.mts +3 -0
  157. package/dist/init/generators/source.mjs +3 -0
  158. package/dist/init/index.cjs +16 -0
  159. package/dist/init/index.d.cts +17 -0
  160. package/dist/init/index.d.mts +17 -0
  161. package/dist/init/index.mjs +16 -0
  162. package/dist/init/templates/api.cjs +3 -0
  163. package/dist/init/templates/api.d.cts +7 -0
  164. package/dist/init/templates/api.d.mts +7 -0
  165. package/dist/init/templates/api.mjs +3 -0
  166. package/dist/init/templates/index.cjs +10 -0
  167. package/dist/init/templates/index.d.cts +2 -0
  168. package/dist/init/templates/index.d.mts +2 -0
  169. package/dist/init/templates/index.mjs +7 -0
  170. package/dist/init/templates/minimal.cjs +3 -0
  171. package/dist/init/templates/minimal.d.cts +7 -0
  172. package/dist/init/templates/minimal.d.mts +7 -0
  173. package/dist/init/templates/minimal.mjs +3 -0
  174. package/dist/init/templates/serverless.cjs +3 -0
  175. package/dist/init/templates/serverless.d.cts +7 -0
  176. package/dist/init/templates/serverless.d.mts +7 -0
  177. package/dist/init/templates/serverless.mjs +3 -0
  178. package/dist/init/templates/worker.cjs +3 -0
  179. package/dist/init/templates/worker.d.cts +7 -0
  180. package/dist/init/templates/worker.d.mts +7 -0
  181. package/dist/init/templates/worker.mjs +3 -0
  182. package/dist/init/utils.cjs +7 -0
  183. package/dist/init/utils.d.cts +25 -0
  184. package/dist/init/utils.d.mts +25 -0
  185. package/dist/init/utils.mjs +3 -0
  186. package/dist/init-CtOnZn3G.mjs +145 -0
  187. package/dist/init-CtOnZn3G.mjs.map +1 -0
  188. package/dist/init-qLFsWR-R.cjs +151 -0
  189. package/dist/init-qLFsWR-R.cjs.map +1 -0
  190. package/dist/{manifests-C2eMoMUm.mjs → manifests-DIA_2QYd.mjs} +1 -1
  191. package/dist/{manifests-C2eMoMUm.mjs.map → manifests-DIA_2QYd.mjs.map} +1 -1
  192. package/dist/{manifests-CK1VV_pM.cjs → manifests-VJ9-2JpW.cjs} +1 -1
  193. package/dist/{manifests-CK1VV_pM.cjs.map → manifests-VJ9-2JpW.cjs.map} +1 -1
  194. package/dist/minimal-Bdhhpp7v.cjs +93 -0
  195. package/dist/minimal-Bdhhpp7v.cjs.map +1 -0
  196. package/dist/minimal-C4GsE45s.mjs +87 -0
  197. package/dist/minimal-C4GsE45s.mjs.map +1 -0
  198. package/dist/models-DyNwdOcz.cjs +121 -0
  199. package/dist/models-DyNwdOcz.cjs.map +1 -0
  200. package/dist/models-cvNg6Oea.mjs +115 -0
  201. package/dist/models-cvNg6Oea.mjs.map +1 -0
  202. package/dist/monorepo-Cknwzj5C.mjs +184 -0
  203. package/dist/monorepo-Cknwzj5C.mjs.map +1 -0
  204. package/dist/monorepo-sEK8gW59.cjs +190 -0
  205. package/dist/monorepo-sEK8gW59.cjs.map +1 -0
  206. package/dist/openapi-BQWPWyNB.cjs +56 -0
  207. package/dist/openapi-BQWPWyNB.cjs.map +1 -0
  208. package/dist/openapi-DBX8cJJ8.mjs +50 -0
  209. package/dist/openapi-DBX8cJJ8.mjs.map +1 -0
  210. package/dist/{openapi-react-query-D9Z7lh0p.cjs → openapi-react-query-DxHjXQvg.cjs} +1 -1
  211. package/dist/{openapi-react-query-D9Z7lh0p.cjs.map → openapi-react-query-DxHjXQvg.cjs.map} +1 -1
  212. package/dist/{openapi-react-query-MEBlYIM1.mjs → openapi-react-query-o7Mp1Jd5.mjs} +1 -1
  213. package/dist/{openapi-react-query-MEBlYIM1.mjs.map → openapi-react-query-o7Mp1Jd5.mjs.map} +1 -1
  214. package/dist/openapi-react-query.cjs +1 -1
  215. package/dist/openapi-react-query.d.cts +11 -0
  216. package/dist/openapi-react-query.d.mts +11 -0
  217. package/dist/openapi-react-query.mjs +1 -1
  218. package/dist/openapi.cjs +5 -4
  219. package/dist/openapi.d.cts +11 -0
  220. package/dist/openapi.d.mts +11 -0
  221. package/dist/openapi.mjs +5 -4
  222. package/dist/package-C7WhWU8m.d.mts +11 -0
  223. package/dist/package-CIfmeuSW.mjs +51 -0
  224. package/dist/package-CIfmeuSW.mjs.map +1 -0
  225. package/dist/package-DvWEMz6z.d.cts +11 -0
  226. package/dist/package-PP-o1nvq.cjs +57 -0
  227. package/dist/package-PP-o1nvq.cjs.map +1 -0
  228. package/dist/{providerResolver-B_TjNF0_.mjs → providerResolver-DEVKngbC.mjs} +1 -1
  229. package/dist/{providerResolver-B_TjNF0_.mjs.map → providerResolver-DEVKngbC.mjs.map} +1 -1
  230. package/dist/{providerResolver-DgvzNfP4.cjs → providerResolver-DOTbN9jo.cjs} +1 -1
  231. package/dist/{providerResolver-DgvzNfP4.cjs.map → providerResolver-DOTbN9jo.cjs.map} +1 -1
  232. package/dist/serverless-DkHBF2vC.mjs +108 -0
  233. package/dist/serverless-DkHBF2vC.mjs.map +1 -0
  234. package/dist/serverless-Yav3GRVz.cjs +114 -0
  235. package/dist/serverless-Yav3GRVz.cjs.map +1 -0
  236. package/dist/source-D6v2BnKT.d.mts +11 -0
  237. package/dist/source-D8fK9qRo.d.cts +11 -0
  238. package/dist/source-DT5Xhiob.cjs +17 -0
  239. package/dist/source-DT5Xhiob.cjs.map +1 -0
  240. package/dist/source-DnaH_MLA.mjs +11 -0
  241. package/dist/source-DnaH_MLA.mjs.map +1 -0
  242. package/dist/templates-CBFUwpBy.mjs +64 -0
  243. package/dist/templates-CBFUwpBy.mjs.map +1 -0
  244. package/dist/templates-DM_rtYYW.cjs +87 -0
  245. package/dist/templates-DM_rtYYW.cjs.map +1 -0
  246. package/dist/types-C4KITv-y.d.mts +51 -0
  247. package/dist/types-Cxl8-uwV.d.mts +129 -0
  248. package/dist/types-DB99_qIy.d.cts +129 -0
  249. package/dist/types-DLFN49M3.d.cts +51 -0
  250. package/dist/types.d.cts +2 -0
  251. package/dist/types.d.mts +2 -0
  252. package/dist/utils-BX3F4fT8.cjs +99 -0
  253. package/dist/utils-BX3F4fT8.cjs.map +1 -0
  254. package/dist/utils-C31-SWHP.mjs +69 -0
  255. package/dist/utils-C31-SWHP.mjs.map +1 -0
  256. package/dist/worker--8O5a3Hv.cjs +150 -0
  257. package/dist/worker--8O5a3Hv.cjs.map +1 -0
  258. package/dist/worker-Jme7uOOJ.mjs +144 -0
  259. package/dist/worker-Jme7uOOJ.mjs.map +1 -0
  260. package/docs/OPENAPI_TYPESCRIPT_DESIGN.md +408 -0
  261. package/package.json +19 -4
  262. package/src/__tests__/loadEnvFiles.spec.ts +131 -0
  263. package/src/__tests__/openapi.spec.ts +78 -63
  264. package/src/build/index.ts +14 -16
  265. package/src/build/types.ts +18 -2
  266. package/src/config.ts +61 -2
  267. package/src/dev/__tests__/index.spec.ts +98 -1
  268. package/src/dev/index.ts +229 -42
  269. package/src/generators/EndpointGenerator.ts +98 -5
  270. package/src/generators/OpenApiTsGenerator.ts +798 -0
  271. package/src/index.ts +32 -3
  272. package/src/init/__tests__/generators.spec.ts +366 -0
  273. package/src/init/__tests__/init.spec.ts +341 -0
  274. package/src/init/__tests__/utils.spec.ts +104 -0
  275. package/src/init/generators/config.ts +192 -0
  276. package/src/init/generators/docker.ts +134 -0
  277. package/src/init/generators/env.ts +182 -0
  278. package/src/init/generators/index.ts +4 -0
  279. package/src/init/generators/models.ts +129 -0
  280. package/src/init/generators/monorepo.ts +211 -0
  281. package/src/init/generators/package.ts +81 -0
  282. package/src/init/generators/source.ts +15 -0
  283. package/src/init/index.ts +206 -0
  284. package/src/init/templates/api.ts +218 -0
  285. package/src/init/templates/index.ts +108 -0
  286. package/src/init/templates/minimal.ts +102 -0
  287. package/src/init/templates/serverless.ts +129 -0
  288. package/src/init/templates/worker.ts +169 -0
  289. package/src/init/utils.ts +98 -0
  290. package/src/openapi.ts +36 -15
  291. package/src/types.ts +43 -0
  292. package/tsdown.config.ts +1 -1
  293. package/dist/EndpointGenerator-C73wNoih.cjs.map +0 -1
  294. package/dist/EndpointGenerator-CWh18d92.mjs.map +0 -1
  295. package/dist/build-C6uEGRj8.mjs.map +0 -1
  296. package/dist/build-CBYBPZpC.cjs.map +0 -1
  297. package/dist/config-D1EpSGk6.cjs +0 -36
  298. package/dist/config-D1EpSGk6.cjs.map +0 -1
  299. package/dist/config-U-mdW-7Y.mjs +0 -30
  300. package/dist/config-U-mdW-7Y.mjs.map +0 -1
  301. package/dist/dev-DbtyToc7.cjs.map +0 -1
  302. package/dist/dev-DnGYXuMn.mjs +0 -241
  303. package/dist/dev-DnGYXuMn.mjs.map +0 -1
  304. package/dist/openapi-BTHbPrxS.mjs +0 -36
  305. package/dist/openapi-BTHbPrxS.mjs.map +0 -1
  306. package/dist/openapi-CewcfoRH.cjs +0 -42
  307. package/dist/openapi-CewcfoRH.cjs.map +0 -1
  308. /package/dist/{generators-CEKtVh81.cjs → generators-3IemvCLk.cjs} +0 -0
  309. /package/dist/{generators-CsLujGXs.mjs → generators-FNpdfN6J.mjs} +0 -0
@@ -1,32 +1,59 @@
1
1
  const require_chunk = require('./chunk-CUT6urMc.cjs');
2
- const require_config = require('./config-D1EpSGk6.cjs');
3
- const require_CronGenerator = require('./CronGenerator-C6MF8rlG.cjs');
4
- const require_EndpointGenerator = require('./EndpointGenerator-C73wNoih.cjs');
5
- const require_FunctionGenerator = require('./FunctionGenerator-FgZUTd8L.cjs');
6
- const require_SubscriberGenerator = require('./SubscriberGenerator-Bd-a7aiw.cjs');
7
- const require_providerResolver = require('./providerResolver-DgvzNfP4.cjs');
2
+ const require_config = require('./config-CFls09Ey.cjs');
3
+ const require_providerResolver = require('./providerResolver-DOTbN9jo.cjs');
4
+ const require_CronGenerator = require('./CronGenerator-D4TWXQbh.cjs');
5
+ const require_EndpointGenerator = require('./EndpointGenerator-npWEDoK2.cjs');
6
+ const require_FunctionGenerator = require('./FunctionGenerator-DYTnyr4c.cjs');
7
+ const require_SubscriberGenerator = require('./SubscriberGenerator-D_zpNGFr.cjs');
8
8
  const node_fs_promises = require_chunk.__toESM(require("node:fs/promises"));
9
9
  const node_path = require_chunk.__toESM(require("node:path"));
10
10
  const node_child_process = require_chunk.__toESM(require("node:child_process"));
11
+ const node_fs = require_chunk.__toESM(require("node:fs"));
11
12
  const node_net = require_chunk.__toESM(require("node:net"));
12
13
  const chokidar = require_chunk.__toESM(require("chokidar"));
14
+ const dotenv = require_chunk.__toESM(require("dotenv"));
15
+ const fast_glob = require_chunk.__toESM(require("fast-glob"));
13
16
 
14
17
  //#region src/dev/index.ts
15
18
  const logger = console;
16
19
  /**
20
+ * Load environment files
21
+ * @internal Exported for testing
22
+ */
23
+ function loadEnvFiles(envConfig, cwd = process.cwd()) {
24
+ const loaded = [];
25
+ const missing = [];
26
+ const envFiles = envConfig ? Array.isArray(envConfig) ? envConfig : [envConfig] : [".env"];
27
+ for (const envFile of envFiles) {
28
+ const envPath = (0, node_path.resolve)(cwd, envFile);
29
+ if ((0, node_fs.existsSync)(envPath)) {
30
+ (0, dotenv.config)({
31
+ path: envPath,
32
+ override: true,
33
+ quiet: true
34
+ });
35
+ loaded.push(envFile);
36
+ } else if (envConfig) missing.push(envFile);
37
+ }
38
+ return {
39
+ loaded,
40
+ missing
41
+ };
42
+ }
43
+ /**
17
44
  * Check if a port is available
18
45
  * @internal Exported for testing
19
46
  */
20
47
  async function isPortAvailable(port) {
21
- return new Promise((resolve) => {
48
+ return new Promise((resolve$1) => {
22
49
  const server = (0, node_net.createServer)();
23
50
  server.once("error", (err) => {
24
- if (err.code === "EADDRINUSE") resolve(false);
25
- else resolve(false);
51
+ if (err.code === "EADDRINUSE") resolve$1(false);
52
+ else resolve$1(false);
26
53
  });
27
54
  server.once("listening", () => {
28
55
  server.close();
29
- resolve(true);
56
+ resolve$1(true);
30
57
  });
31
58
  server.listen(port);
32
59
  });
@@ -43,8 +70,46 @@ async function findAvailablePort(preferredPort, maxAttempts = 10) {
43
70
  }
44
71
  throw new Error(`Could not find an available port after trying ${maxAttempts} ports starting from ${preferredPort}`);
45
72
  }
73
+ /**
74
+ * Normalize telescope configuration
75
+ * @internal Exported for testing
76
+ */
77
+ function normalizeTelescopeConfig(config) {
78
+ if (config === false) return void 0;
79
+ if (typeof config === "string") {
80
+ const { path: telescopePath, importPattern: telescopeImportPattern } = require_config.parseModuleConfig(config, "telescope");
81
+ return {
82
+ enabled: true,
83
+ telescopePath,
84
+ telescopeImportPattern,
85
+ path: "/__telescope",
86
+ ignore: [],
87
+ recordBody: true,
88
+ maxEntries: 1e3,
89
+ websocket: true
90
+ };
91
+ }
92
+ const isEnabled = config === true || config === void 0 || config.enabled !== false;
93
+ if (!isEnabled) return void 0;
94
+ const telescopeConfig = typeof config === "object" ? config : {};
95
+ return {
96
+ enabled: true,
97
+ path: telescopeConfig.path ?? "/__telescope",
98
+ ignore: telescopeConfig.ignore ?? [],
99
+ recordBody: telescopeConfig.recordBody ?? true,
100
+ maxEntries: telescopeConfig.maxEntries ?? 1e3,
101
+ websocket: telescopeConfig.websocket ?? true
102
+ };
103
+ }
46
104
  async function devCommand(options) {
105
+ const defaultEnv = loadEnvFiles(".env");
106
+ if (defaultEnv.loaded.length > 0) logger.log(`📦 Loaded env: ${defaultEnv.loaded.join(", ")}`);
47
107
  const config = await require_config.loadConfig();
108
+ if (config.env) {
109
+ const { loaded, missing } = loadEnvFiles(config.env);
110
+ if (loaded.length > 0) logger.log(`📦 Loaded env: ${loaded.join(", ")}`);
111
+ if (missing.length > 0) logger.warn(`⚠️ Missing env files: ${missing.join(", ")}`);
112
+ }
48
113
  const resolved = require_providerResolver.resolveProviders(config, { provider: "server" });
49
114
  logger.log("🚀 Starting development server...");
50
115
  logger.log(`Loading routes from: ${config.routes}`);
@@ -52,32 +117,51 @@ async function devCommand(options) {
52
117
  if (config.crons) logger.log(`Loading crons from: ${config.crons}`);
53
118
  if (config.subscribers) logger.log(`Loading subscribers from: ${config.subscribers}`);
54
119
  logger.log(`Using envParser: ${config.envParser}`);
55
- const [envParserPath, envParserName] = config.envParser.split("#");
56
- const envParserImportPattern = !envParserName ? "envParser" : envParserName === "envParser" ? "{ envParser }" : `{ ${envParserName} as envParser }`;
57
- const [loggerPath, loggerName] = config.logger.split("#");
58
- const loggerImportPattern = !loggerName ? "logger" : loggerName === "logger" ? "{ logger }" : `{ ${loggerName} as logger }`;
120
+ const { path: envParserPath, importPattern: envParserImportPattern } = require_config.parseModuleConfig(config.envParser, "envParser");
121
+ const { path: loggerPath, importPattern: loggerImportPattern } = require_config.parseModuleConfig(config.logger, "logger");
122
+ const telescope = normalizeTelescopeConfig(config.telescope);
123
+ if (telescope) logger.log(`🔭 Telescope enabled at ${telescope.path}`);
59
124
  const buildContext = {
60
125
  envParserPath,
61
126
  envParserImportPattern,
62
127
  loggerPath,
63
- loggerImportPattern
128
+ loggerImportPattern,
129
+ telescope
64
130
  };
65
131
  await buildServer(config, buildContext, resolved.providers[0], resolved.enableOpenApi);
66
- const devServer = new DevServer(resolved.providers[0], options.port || 3e3, resolved.enableOpenApi);
132
+ const runtime = config.runtime ?? "node";
133
+ const devServer = new DevServer(resolved.providers[0], options.port || 3e3, resolved.enableOpenApi, telescope, runtime);
67
134
  await devServer.start();
135
+ const envParserFile = config.envParser.split("#")[0];
136
+ const loggerFile = config.logger.split("#")[0];
68
137
  const watchPatterns = [
69
138
  config.routes,
70
139
  ...config.functions ? [config.functions] : [],
71
140
  ...config.crons ? [config.crons] : [],
72
141
  ...config.subscribers ? [config.subscribers] : [],
73
- config.envParser.split("#")[0],
74
- config.logger.split("#")[0]
142
+ envParserFile.endsWith(".ts") ? envParserFile : `${envParserFile}.ts`,
143
+ loggerFile.endsWith(".ts") ? loggerFile : `${loggerFile}.ts`
75
144
  ].flat();
76
- logger.log(`👀 Watching for changes in: ${watchPatterns.join(", ")}`);
77
- const watcher = chokidar.default.watch(watchPatterns, {
145
+ const normalizedPatterns = watchPatterns.map((p) => p.startsWith("./") ? p.slice(2) : p);
146
+ logger.log(`👀 Watching for changes in: ${normalizedPatterns.join(", ")}`);
147
+ const resolvedFiles = await (0, fast_glob.default)(normalizedPatterns, {
148
+ cwd: process.cwd(),
149
+ absolute: false,
150
+ onlyFiles: true
151
+ });
152
+ const dirsToWatch = [...new Set(resolvedFiles.map((f) => f.split("/").slice(0, -1).join("/")))];
153
+ logger.log(`📁 Found ${resolvedFiles.length} files in ${dirsToWatch.length} directories`);
154
+ const watcher = chokidar.default.watch([...resolvedFiles, ...dirsToWatch], {
78
155
  ignored: /(^|[\/\\])\../,
79
156
  persistent: true,
80
- ignoreInitial: true
157
+ ignoreInitial: true,
158
+ cwd: process.cwd()
159
+ });
160
+ watcher.on("ready", () => {
161
+ logger.log("🔍 File watcher ready");
162
+ });
163
+ watcher.on("error", (error) => {
164
+ logger.error("❌ Watcher error:", error);
81
165
  });
82
166
  let rebuildTimeout = null;
83
167
  watcher.on("change", async (path) => {
@@ -130,10 +214,12 @@ var DevServer = class {
130
214
  serverProcess = null;
131
215
  isRunning = false;
132
216
  actualPort;
133
- constructor(provider, requestedPort, enableOpenApi) {
217
+ constructor(provider, requestedPort, enableOpenApi, telescope, runtime = "node") {
134
218
  this.provider = provider;
135
219
  this.requestedPort = requestedPort;
136
220
  this.enableOpenApi = enableOpenApi;
221
+ this.telescope = telescope;
222
+ this.runtime = runtime;
137
223
  this.actualPort = requestedPort;
138
224
  }
139
225
  async start() {
@@ -153,7 +239,8 @@ var DevServer = class {
153
239
  env: {
154
240
  ...process.env,
155
241
  NODE_ENV: "development"
156
- }
242
+ },
243
+ detached: true
157
244
  });
158
245
  this.isRunning = true;
159
246
  this.serverProcess.on("error", (error) => {
@@ -163,23 +250,29 @@ var DevServer = class {
163
250
  if (code !== null && code !== 0 && signal !== "SIGTERM") logger.error(`❌ Server exited with code ${code}`);
164
251
  this.isRunning = false;
165
252
  });
166
- await new Promise((resolve) => setTimeout(resolve, 1e3));
253
+ await new Promise((resolve$1) => setTimeout(resolve$1, 1e3));
167
254
  if (this.isRunning) {
168
255
  logger.log(`\n🎉 Server running at http://localhost:${this.actualPort}`);
169
256
  if (this.enableOpenApi) logger.log(`📚 API Docs available at http://localhost:${this.actualPort}/docs`);
257
+ if (this.telescope) logger.log(`🔭 Telescope available at http://localhost:${this.actualPort}${this.telescope.path}`);
170
258
  }
171
259
  }
172
260
  async stop() {
173
261
  if (this.serverProcess && this.isRunning) {
174
- this.serverProcess.kill("SIGTERM");
175
- await new Promise((resolve) => {
262
+ const pid = this.serverProcess.pid;
263
+ if (pid) try {
264
+ process.kill(-pid, "SIGTERM");
265
+ } catch {}
266
+ await new Promise((resolve$1) => {
176
267
  const timeout = setTimeout(() => {
177
- this.serverProcess?.kill("SIGKILL");
178
- resolve();
179
- }, 5e3);
268
+ if (pid) try {
269
+ process.kill(-pid, "SIGKILL");
270
+ } catch {}
271
+ resolve$1();
272
+ }, 3e3);
180
273
  this.serverProcess?.on("exit", () => {
181
274
  clearTimeout(timeout);
182
- resolve();
275
+ resolve$1();
183
276
  });
184
277
  });
185
278
  this.serverProcess = null;
@@ -187,7 +280,15 @@ var DevServer = class {
187
280
  }
188
281
  }
189
282
  async restart() {
283
+ const portToReuse = this.actualPort;
190
284
  await this.stop();
285
+ let attempts = 0;
286
+ while (attempts < 30) {
287
+ if (await isPortAvailable(portToReuse)) break;
288
+ await new Promise((resolve$1) => setTimeout(resolve$1, 100));
289
+ attempts++;
290
+ }
291
+ this.requestedPort = portToReuse;
191
292
  await this.start();
192
293
  }
193
294
  async createServerEntry() {
@@ -195,6 +296,20 @@ var DevServer = class {
195
296
  const { relative, dirname } = await import("node:path");
196
297
  const serverPath = (0, node_path.join)(process.cwd(), ".gkm", this.provider, "server.ts");
197
298
  const relativeAppPath = relative(dirname(serverPath), (0, node_path.join)(dirname(serverPath), "app.js"));
299
+ const serveCode = this.runtime === "bun" ? `Bun.serve({
300
+ port,
301
+ fetch: app.fetch,
302
+ });` : `const { serve } = await import('@hono/node-server');
303
+ const server = serve({
304
+ fetch: app.fetch,
305
+ port,
306
+ });
307
+ // Inject WebSocket support if available
308
+ const injectWs = (app as any).__injectWebSocket;
309
+ if (injectWs) {
310
+ injectWs(server);
311
+ console.log('🔌 Telescope real-time updates enabled');
312
+ }`;
198
313
  const content = `#!/usr/bin/env node
199
314
  /**
200
315
  * Development server entry point
@@ -206,27 +321,14 @@ const port = process.argv.includes('--port')
206
321
  ? Number.parseInt(process.argv[process.argv.indexOf('--port') + 1])
207
322
  : 3000;
208
323
 
209
- const { app, start } = createApp(undefined, ${this.enableOpenApi});
324
+ // createApp is async to support optional WebSocket setup
325
+ const { app, start } = await createApp(undefined, ${this.enableOpenApi});
210
326
 
211
327
  // Start the server
212
328
  start({
213
329
  port,
214
330
  serve: async (app, port) => {
215
- // Detect runtime and use appropriate server
216
- if (typeof Bun !== 'undefined') {
217
- // Bun runtime
218
- Bun.serve({
219
- port,
220
- fetch: app.fetch,
221
- });
222
- } else {
223
- // Node.js runtime with @hono/node-server
224
- const { serve } = await import('@hono/node-server');
225
- serve({
226
- fetch: app.fetch,
227
- port,
228
- });
229
- }
331
+ ${serveCode}
230
332
  },
231
333
  }).catch((error) => {
232
334
  console.error('Failed to start server:', error);
@@ -256,4 +358,16 @@ Object.defineProperty(exports, 'isPortAvailable', {
256
358
  return isPortAvailable;
257
359
  }
258
360
  });
259
- //# sourceMappingURL=dev-DbtyToc7.cjs.map
361
+ Object.defineProperty(exports, 'loadEnvFiles', {
362
+ enumerable: true,
363
+ get: function () {
364
+ return loadEnvFiles;
365
+ }
366
+ });
367
+ Object.defineProperty(exports, 'normalizeTelescopeConfig', {
368
+ enumerable: true,
369
+ get: function () {
370
+ return normalizeTelescopeConfig;
371
+ }
372
+ });
373
+ //# sourceMappingURL=dev-DHqYn8k4.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dev-DHqYn8k4.cjs","names":["envConfig: string | string[] | undefined","cwd: string","loaded: string[]","missing: string[]","port: number","resolve","err: NodeJS.ErrnoException","preferredPort: number","config: GkmConfig['telescope']","telescopeConfig: TelescopeConfig","options: DevOptions","buildContext: BuildContext","runtime: Runtime","rebuildTimeout: NodeJS.Timeout | null","config: any","context: BuildContext","provider: LegacyProvider","enableOpenApi: boolean","EndpointGenerator","FunctionGenerator","CronGenerator","SubscriberGenerator","requestedPort: number","telescope?: NormalizedTelescopeConfig"],"sources":["../src/dev/index.ts"],"sourcesContent":["import { type ChildProcess, spawn } from 'node:child_process';\nimport { existsSync } from 'node:fs';\nimport { mkdir } from 'node:fs/promises';\nimport { createServer } from 'node:net';\nimport { join, resolve } from 'node:path';\nimport chokidar from 'chokidar';\nimport { config as dotenvConfig } from 'dotenv';\nimport fg from 'fast-glob';\nimport { resolveProviders } from '../build/providerResolver';\nimport type { BuildContext, NormalizedTelescopeConfig } from '../build/types';\nimport { loadConfig, parseModuleConfig } from '../config';\nimport {\n CronGenerator,\n EndpointGenerator,\n FunctionGenerator,\n SubscriberGenerator,\n} from '../generators';\nimport type {\n GkmConfig,\n LegacyProvider,\n Runtime,\n TelescopeConfig,\n} from '../types';\n\nconst logger = console;\n\n/**\n * Load environment files\n * @internal Exported for testing\n */\nexport function loadEnvFiles(\n envConfig: string | string[] | undefined,\n cwd: string = process.cwd(),\n): { loaded: string[]; missing: string[] } {\n const loaded: string[] = [];\n const missing: string[] = [];\n\n // Normalize to array\n const envFiles = envConfig\n ? Array.isArray(envConfig)\n ? envConfig\n : [envConfig]\n : ['.env'];\n\n // Load each env file in order (later files override earlier)\n for (const envFile of envFiles) {\n const envPath = resolve(cwd, envFile);\n if (existsSync(envPath)) {\n dotenvConfig({ path: envPath, override: true, quiet: true });\n loaded.push(envFile);\n } else if (envConfig) {\n // Only report as missing if explicitly configured\n missing.push(envFile);\n }\n }\n\n return { loaded, missing };\n}\n\n/**\n * Check if a port is available\n * @internal Exported for testing\n */\nexport async function isPortAvailable(port: number): Promise<boolean> {\n return new Promise((resolve) => {\n const server = createServer();\n\n server.once('error', (err: NodeJS.ErrnoException) => {\n if (err.code === 'EADDRINUSE') {\n resolve(false);\n } else {\n resolve(false);\n }\n });\n\n server.once('listening', () => {\n server.close();\n resolve(true);\n });\n\n server.listen(port);\n });\n}\n\n/**\n * Find an available port starting from the preferred port\n * @internal Exported for testing\n */\nexport async function findAvailablePort(\n preferredPort: number,\n maxAttempts = 10,\n): Promise<number> {\n for (let i = 0; i < maxAttempts; i++) {\n const port = preferredPort + i;\n if (await isPortAvailable(port)) {\n return port;\n }\n logger.log(`⚠️ Port ${port} is in use, trying ${port + 1}...`);\n }\n\n throw new Error(\n `Could not find an available port after trying ${maxAttempts} ports starting from ${preferredPort}`,\n );\n}\n\n/**\n * Normalize telescope configuration\n * @internal Exported for testing\n */\nexport function normalizeTelescopeConfig(\n config: GkmConfig['telescope'],\n): NormalizedTelescopeConfig | undefined {\n if (config === false) {\n return undefined;\n }\n\n // Handle string path (e.g., './src/config/telescope')\n if (typeof config === 'string') {\n const { path: telescopePath, importPattern: telescopeImportPattern } =\n parseModuleConfig(config, 'telescope');\n\n return {\n enabled: true,\n telescopePath,\n telescopeImportPattern,\n path: '/__telescope',\n ignore: [],\n recordBody: true,\n maxEntries: 1000,\n websocket: true,\n };\n }\n\n // Default to enabled in development mode\n const isEnabled =\n config === true || config === undefined || config.enabled !== false;\n\n if (!isEnabled) {\n return undefined;\n }\n\n const telescopeConfig: TelescopeConfig =\n typeof config === 'object' ? config : {};\n\n return {\n enabled: true,\n path: telescopeConfig.path ?? '/__telescope',\n ignore: telescopeConfig.ignore ?? [],\n recordBody: telescopeConfig.recordBody ?? true,\n maxEntries: telescopeConfig.maxEntries ?? 1000,\n websocket: telescopeConfig.websocket ?? true,\n };\n}\n\nexport interface DevOptions {\n port?: number;\n enableOpenApi?: boolean;\n}\n\nexport async function devCommand(options: DevOptions): Promise<void> {\n // Load default .env file BEFORE loading config\n // This ensures env vars are available when config and its dependencies are loaded\n const defaultEnv = loadEnvFiles('.env');\n if (defaultEnv.loaded.length > 0) {\n logger.log(`📦 Loaded env: ${defaultEnv.loaded.join(', ')}`);\n }\n\n const config = await loadConfig();\n\n // Load any additional env files specified in config\n if (config.env) {\n const { loaded, missing } = loadEnvFiles(config.env);\n if (loaded.length > 0) {\n logger.log(`📦 Loaded env: ${loaded.join(', ')}`);\n }\n if (missing.length > 0) {\n logger.warn(`⚠️ Missing env files: ${missing.join(', ')}`);\n }\n }\n\n // Force server provider for dev mode\n const resolved = resolveProviders(config, { provider: 'server' });\n\n logger.log('🚀 Starting development server...');\n logger.log(`Loading routes from: ${config.routes}`);\n if (config.functions) {\n logger.log(`Loading functions from: ${config.functions}`);\n }\n if (config.crons) {\n logger.log(`Loading crons from: ${config.crons}`);\n }\n if (config.subscribers) {\n logger.log(`Loading subscribers from: ${config.subscribers}`);\n }\n logger.log(`Using envParser: ${config.envParser}`);\n\n // Parse envParser and logger configuration\n const { path: envParserPath, importPattern: envParserImportPattern } =\n parseModuleConfig(config.envParser, 'envParser');\n const { path: loggerPath, importPattern: loggerImportPattern } =\n parseModuleConfig(config.logger, 'logger');\n\n // Normalize telescope configuration\n const telescope = normalizeTelescopeConfig(config.telescope);\n if (telescope) {\n logger.log(`🔭 Telescope enabled at ${telescope.path}`);\n }\n\n const buildContext: BuildContext = {\n envParserPath,\n envParserImportPattern,\n loggerPath,\n loggerImportPattern,\n telescope,\n };\n\n // Build initial version\n await buildServer(\n config,\n buildContext,\n resolved.providers[0] as LegacyProvider,\n resolved.enableOpenApi,\n );\n\n // Determine runtime (default to node)\n const runtime: Runtime = config.runtime ?? 'node';\n\n // Start the dev server\n const devServer = new DevServer(\n resolved.providers[0] as LegacyProvider,\n options.port || 3000,\n resolved.enableOpenApi,\n telescope,\n runtime,\n );\n\n await devServer.start();\n\n // Watch for file changes\n const envParserFile = config.envParser.split('#')[0];\n const loggerFile = config.logger.split('#')[0];\n\n const watchPatterns = [\n config.routes,\n ...(config.functions ? [config.functions] : []),\n ...(config.crons ? [config.crons] : []),\n ...(config.subscribers ? [config.subscribers] : []),\n // Add .ts extension if not present for config files\n envParserFile.endsWith('.ts') ? envParserFile : `${envParserFile}.ts`,\n loggerFile.endsWith('.ts') ? loggerFile : `${loggerFile}.ts`,\n ].flat();\n\n // Normalize patterns - remove leading ./ when using cwd option\n const normalizedPatterns = watchPatterns.map((p) =>\n p.startsWith('./') ? p.slice(2) : p,\n );\n\n logger.log(`👀 Watching for changes in: ${normalizedPatterns.join(', ')}`);\n\n // Resolve glob patterns to actual files (chokidar 4.x doesn't support globs)\n const resolvedFiles = await fg(normalizedPatterns, {\n cwd: process.cwd(),\n absolute: false,\n onlyFiles: true,\n });\n\n // Also watch the directories for new files\n const dirsToWatch = [\n ...new Set(resolvedFiles.map((f) => f.split('/').slice(0, -1).join('/'))),\n ];\n\n logger.log(\n `📁 Found ${resolvedFiles.length} files in ${dirsToWatch.length} directories`,\n );\n\n const watcher = chokidar.watch([...resolvedFiles, ...dirsToWatch], {\n ignored: /(^|[\\/\\\\])\\../, // ignore dotfiles\n persistent: true,\n ignoreInitial: true,\n cwd: process.cwd(),\n });\n\n watcher.on('ready', () => {\n logger.log('🔍 File watcher ready');\n });\n\n watcher.on('error', (error) => {\n logger.error('❌ Watcher error:', error);\n });\n\n let rebuildTimeout: NodeJS.Timeout | null = null;\n\n watcher.on('change', async (path) => {\n logger.log(`📝 File changed: ${path}`);\n\n // Debounce rebuilds\n if (rebuildTimeout) {\n clearTimeout(rebuildTimeout);\n }\n\n rebuildTimeout = setTimeout(async () => {\n try {\n logger.log('🔄 Rebuilding...');\n await buildServer(\n config,\n buildContext,\n resolved.providers[0] as LegacyProvider,\n resolved.enableOpenApi,\n );\n logger.log('✅ Rebuild complete, restarting server...');\n await devServer.restart();\n } catch (error) {\n logger.error('❌ Rebuild failed:', (error as Error).message);\n }\n }, 300);\n });\n\n // Handle graceful shutdown\n const shutdown = async () => {\n logger.log('\\n🛑 Shutting down...');\n await watcher.close();\n await devServer.stop();\n process.exit(0);\n };\n\n process.on('SIGINT', shutdown);\n process.on('SIGTERM', shutdown);\n}\n\nasync function buildServer(\n config: any,\n context: BuildContext,\n provider: LegacyProvider,\n enableOpenApi: boolean,\n): Promise<void> {\n // Initialize generators\n const endpointGenerator = new EndpointGenerator();\n const functionGenerator = new FunctionGenerator();\n const cronGenerator = new CronGenerator();\n const subscriberGenerator = new SubscriberGenerator();\n\n // Load all constructs\n const [allEndpoints, allFunctions, allCrons, allSubscribers] =\n await Promise.all([\n endpointGenerator.load(config.routes),\n config.functions ? functionGenerator.load(config.functions) : [],\n config.crons ? cronGenerator.load(config.crons) : [],\n config.subscribers ? subscriberGenerator.load(config.subscribers) : [],\n ]);\n\n // Ensure .gkm directory exists\n const outputDir = join(process.cwd(), '.gkm', provider);\n await mkdir(outputDir, { recursive: true });\n\n // Build for server provider\n await Promise.all([\n endpointGenerator.build(context, allEndpoints, outputDir, {\n provider,\n enableOpenApi,\n }),\n functionGenerator.build(context, allFunctions, outputDir, { provider }),\n cronGenerator.build(context, allCrons, outputDir, { provider }),\n subscriberGenerator.build(context, allSubscribers, outputDir, { provider }),\n ]);\n}\n\nclass DevServer {\n private serverProcess: ChildProcess | null = null;\n private isRunning = false;\n private actualPort: number;\n\n constructor(\n private provider: LegacyProvider,\n private requestedPort: number,\n private enableOpenApi: boolean,\n private telescope?: NormalizedTelescopeConfig,\n private runtime: Runtime = 'node',\n ) {\n this.actualPort = requestedPort;\n }\n\n async start(): Promise<void> {\n if (this.isRunning) {\n await this.stop();\n }\n\n // Find an available port\n this.actualPort = await findAvailablePort(this.requestedPort);\n\n if (this.actualPort !== this.requestedPort) {\n logger.log(\n `ℹ️ Port ${this.requestedPort} was in use, using port ${this.actualPort} instead`,\n );\n }\n\n const serverEntryPath = join(\n process.cwd(),\n '.gkm',\n this.provider,\n 'server.ts',\n );\n\n // Create server entry file\n await this.createServerEntry();\n\n logger.log(`\\n✨ Starting server on port ${this.actualPort}...`);\n\n // Start the server using tsx (TypeScript execution)\n // Use detached: true so we can kill the entire process tree\n this.serverProcess = spawn(\n 'npx',\n ['tsx', serverEntryPath, '--port', this.actualPort.toString()],\n {\n stdio: 'inherit',\n env: { ...process.env, NODE_ENV: 'development' },\n detached: true,\n },\n );\n\n this.isRunning = true;\n\n this.serverProcess.on('error', (error) => {\n logger.error('❌ Server error:', error);\n });\n\n this.serverProcess.on('exit', (code, signal) => {\n if (code !== null && code !== 0 && signal !== 'SIGTERM') {\n logger.error(`❌ Server exited with code ${code}`);\n }\n this.isRunning = false;\n });\n\n // Give the server a moment to start\n await new Promise((resolve) => setTimeout(resolve, 1000));\n\n if (this.isRunning) {\n logger.log(`\\n🎉 Server running at http://localhost:${this.actualPort}`);\n if (this.enableOpenApi) {\n logger.log(\n `📚 API Docs available at http://localhost:${this.actualPort}/docs`,\n );\n }\n if (this.telescope) {\n logger.log(\n `🔭 Telescope available at http://localhost:${this.actualPort}${this.telescope.path}`,\n );\n }\n }\n }\n\n async stop(): Promise<void> {\n if (this.serverProcess && this.isRunning) {\n const pid = this.serverProcess.pid;\n\n // Kill the entire process group (negative PID kills the group)\n if (pid) {\n try {\n process.kill(-pid, 'SIGTERM');\n } catch {\n // Process might already be dead\n }\n }\n\n // Wait for process to exit\n await new Promise<void>((resolve) => {\n const timeout = setTimeout(() => {\n if (pid) {\n try {\n process.kill(-pid, 'SIGKILL');\n } catch {\n // Process might already be dead\n }\n }\n resolve();\n }, 3000);\n\n this.serverProcess?.on('exit', () => {\n clearTimeout(timeout);\n resolve();\n });\n });\n\n this.serverProcess = null;\n this.isRunning = false;\n }\n }\n\n async restart(): Promise<void> {\n const portToReuse = this.actualPort;\n await this.stop();\n\n // Wait for port to be released (up to 3 seconds)\n let attempts = 0;\n while (attempts < 30) {\n if (await isPortAvailable(portToReuse)) {\n break;\n }\n await new Promise((resolve) => setTimeout(resolve, 100));\n attempts++;\n }\n\n // Force reuse the same port\n this.requestedPort = portToReuse;\n await this.start();\n }\n\n private async createServerEntry(): Promise<void> {\n const { writeFile } = await import('node:fs/promises');\n const { relative, dirname } = await import('node:path');\n\n const serverPath = join(process.cwd(), '.gkm', this.provider, 'server.ts');\n\n const relativeAppPath = relative(\n dirname(serverPath),\n join(dirname(serverPath), 'app.js'),\n );\n\n const serveCode =\n this.runtime === 'bun'\n ? `Bun.serve({\n port,\n fetch: app.fetch,\n });`\n : `const { serve } = await import('@hono/node-server');\n const server = serve({\n fetch: app.fetch,\n port,\n });\n // Inject WebSocket support if available\n const injectWs = (app as any).__injectWebSocket;\n if (injectWs) {\n injectWs(server);\n console.log('🔌 Telescope real-time updates enabled');\n }`;\n\n const content = `#!/usr/bin/env node\n/**\n * Development server entry point\n * This file is auto-generated by 'gkm dev'\n */\nimport { createApp } from './${relativeAppPath.startsWith('.') ? relativeAppPath : './' + relativeAppPath}';\n\nconst port = process.argv.includes('--port')\n ? Number.parseInt(process.argv[process.argv.indexOf('--port') + 1])\n : 3000;\n\n// createApp is async to support optional WebSocket setup\nconst { app, start } = await createApp(undefined, ${this.enableOpenApi});\n\n// Start the server\nstart({\n port,\n serve: async (app, port) => {\n ${serveCode}\n },\n}).catch((error) => {\n console.error('Failed to start server:', error);\n process.exit(1);\n});\n`;\n\n await writeFile(serverPath, content);\n }\n}\n"],"mappings":"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"}
@@ -0,0 +1,119 @@
1
+
2
+ //#region src/init/generators/docker.ts
3
+ /**
4
+ * Generate docker-compose.yml based on template and options
5
+ */
6
+ function generateDockerFiles(options, template) {
7
+ const { database } = options;
8
+ const isServerless = template.name === "serverless";
9
+ const hasWorker = template.name === "worker";
10
+ const services = [];
11
+ const volumes = [];
12
+ if (database) {
13
+ services.push(` postgres:
14
+ image: postgres:16-alpine
15
+ container_name: ${options.name}-postgres
16
+ restart: unless-stopped
17
+ environment:
18
+ POSTGRES_USER: postgres
19
+ POSTGRES_PASSWORD: postgres
20
+ POSTGRES_DB: ${options.name.replace(/-/g, "_")}_dev
21
+ ports:
22
+ - '5432:5432'
23
+ volumes:
24
+ - postgres_data:/var/lib/postgresql/data
25
+ healthcheck:
26
+ test: ['CMD-SHELL', 'pg_isready -U postgres']
27
+ interval: 5s
28
+ timeout: 5s
29
+ retries: 5`);
30
+ volumes.push(" postgres_data:");
31
+ }
32
+ if (isServerless) {
33
+ services.push(` redis:
34
+ image: redis:7-alpine
35
+ container_name: ${options.name}-redis
36
+ restart: unless-stopped
37
+ ports:
38
+ - '6379:6379'
39
+ volumes:
40
+ - redis_data:/data
41
+ healthcheck:
42
+ test: ['CMD', 'redis-cli', 'ping']
43
+ interval: 5s
44
+ timeout: 5s
45
+ retries: 5
46
+
47
+ serverless-redis:
48
+ image: hiett/serverless-redis-http:latest
49
+ container_name: ${options.name}-serverless-redis
50
+ restart: unless-stopped
51
+ ports:
52
+ - '8079:80'
53
+ environment:
54
+ SRH_MODE: env
55
+ SRH_TOKEN: local_dev_token
56
+ SRH_CONNECTION_STRING: redis://redis:6379
57
+ depends_on:
58
+ redis:
59
+ condition: service_healthy`);
60
+ volumes.push(" redis_data:");
61
+ } else {
62
+ services.push(` redis:
63
+ image: redis:7-alpine
64
+ container_name: ${options.name}-redis
65
+ restart: unless-stopped
66
+ ports:
67
+ - '6379:6379'
68
+ volumes:
69
+ - redis_data:/data
70
+ healthcheck:
71
+ test: ['CMD', 'redis-cli', 'ping']
72
+ interval: 5s
73
+ timeout: 5s
74
+ retries: 5`);
75
+ volumes.push(" redis_data:");
76
+ }
77
+ if (hasWorker) {
78
+ services.push(` rabbitmq:
79
+ image: rabbitmq:3-management-alpine
80
+ container_name: ${options.name}-rabbitmq
81
+ restart: unless-stopped
82
+ ports:
83
+ - '5672:5672'
84
+ - '15672:15672'
85
+ environment:
86
+ RABBITMQ_DEFAULT_USER: guest
87
+ RABBITMQ_DEFAULT_PASS: guest
88
+ volumes:
89
+ - rabbitmq_data:/var/lib/rabbitmq
90
+ healthcheck:
91
+ test: ['CMD', 'rabbitmq-diagnostics', 'check_running']
92
+ interval: 10s
93
+ timeout: 5s
94
+ retries: 5`);
95
+ volumes.push(" rabbitmq_data:");
96
+ }
97
+ let dockerCompose = `version: '3.8'
98
+
99
+ services:
100
+ ${services.join("\n\n")}
101
+ `;
102
+ if (volumes.length > 0) dockerCompose += `
103
+ volumes:
104
+ ${volumes.join("\n")}
105
+ `;
106
+ return [{
107
+ path: "docker-compose.yml",
108
+ content: dockerCompose
109
+ }];
110
+ }
111
+
112
+ //#endregion
113
+ Object.defineProperty(exports, 'generateDockerFiles', {
114
+ enumerable: true,
115
+ get: function () {
116
+ return generateDockerFiles;
117
+ }
118
+ });
119
+ //# sourceMappingURL=docker-5d8Yh5_X.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"docker-5d8Yh5_X.cjs","names":["options: TemplateOptions","template: TemplateConfig","services: string[]","volumes: string[]"],"sources":["../src/init/generators/docker.ts"],"sourcesContent":["import type {\n GeneratedFile,\n TemplateConfig,\n TemplateOptions,\n} from '../templates/index.js';\n\n/**\n * Generate docker-compose.yml based on template and options\n */\nexport function generateDockerFiles(\n options: TemplateOptions,\n template: TemplateConfig,\n): GeneratedFile[] {\n const { database } = options;\n const isServerless = template.name === 'serverless';\n const hasWorker = template.name === 'worker';\n\n const services: string[] = [];\n const volumes: string[] = [];\n\n // PostgreSQL database\n if (database) {\n services.push(` postgres:\n image: postgres:16-alpine\n container_name: ${options.name}-postgres\n restart: unless-stopped\n environment:\n POSTGRES_USER: postgres\n POSTGRES_PASSWORD: postgres\n POSTGRES_DB: ${options.name.replace(/-/g, '_')}_dev\n ports:\n - '5432:5432'\n volumes:\n - postgres_data:/var/lib/postgresql/data\n healthcheck:\n test: ['CMD-SHELL', 'pg_isready -U postgres']\n interval: 5s\n timeout: 5s\n retries: 5`);\n volumes.push(' postgres_data:');\n }\n\n // Redis - different setup for serverless vs standard\n if (isServerless) {\n // Use serverless-redis-http for Lambda compatibility\n services.push(` redis:\n image: redis:7-alpine\n container_name: ${options.name}-redis\n restart: unless-stopped\n ports:\n - '6379:6379'\n volumes:\n - redis_data:/data\n healthcheck:\n test: ['CMD', 'redis-cli', 'ping']\n interval: 5s\n timeout: 5s\n retries: 5\n\n serverless-redis:\n image: hiett/serverless-redis-http:latest\n container_name: ${options.name}-serverless-redis\n restart: unless-stopped\n ports:\n - '8079:80'\n environment:\n SRH_MODE: env\n SRH_TOKEN: local_dev_token\n SRH_CONNECTION_STRING: redis://redis:6379\n depends_on:\n redis:\n condition: service_healthy`);\n volumes.push(' redis_data:');\n } else {\n // Standard Redis for non-serverless templates\n services.push(` redis:\n image: redis:7-alpine\n container_name: ${options.name}-redis\n restart: unless-stopped\n ports:\n - '6379:6379'\n volumes:\n - redis_data:/data\n healthcheck:\n test: ['CMD', 'redis-cli', 'ping']\n interval: 5s\n timeout: 5s\n retries: 5`);\n volumes.push(' redis_data:');\n }\n\n // RabbitMQ for worker template\n if (hasWorker) {\n services.push(` rabbitmq:\n image: rabbitmq:3-management-alpine\n container_name: ${options.name}-rabbitmq\n restart: unless-stopped\n ports:\n - '5672:5672'\n - '15672:15672'\n environment:\n RABBITMQ_DEFAULT_USER: guest\n RABBITMQ_DEFAULT_PASS: guest\n volumes:\n - rabbitmq_data:/var/lib/rabbitmq\n healthcheck:\n test: ['CMD', 'rabbitmq-diagnostics', 'check_running']\n interval: 10s\n timeout: 5s\n retries: 5`);\n volumes.push(' rabbitmq_data:');\n }\n\n // Build docker-compose.yml\n let dockerCompose = `version: '3.8'\n\nservices:\n${services.join('\\n\\n')}\n`;\n\n if (volumes.length > 0) {\n dockerCompose += `\nvolumes:\n${volumes.join('\\n')}\n`;\n }\n\n return [\n {\n path: 'docker-compose.yml',\n content: dockerCompose,\n },\n ];\n}\n"],"mappings":";;;;;AASA,SAAgB,oBACdA,SACAC,UACiB;CACjB,MAAM,EAAE,UAAU,GAAG;CACrB,MAAM,eAAe,SAAS,SAAS;CACvC,MAAM,YAAY,SAAS,SAAS;CAEpC,MAAMC,WAAqB,CAAE;CAC7B,MAAMC,UAAoB,CAAE;AAG5B,KAAI,UAAU;AACZ,WAAS,MAAM;;sBAEG,QAAQ,KAAK;;;;;qBAKd,QAAQ,KAAK,QAAQ,MAAM,IAAI,CAAC;;;;;;;;;kBASnC;AACd,UAAQ,KAAK,mBAAmB;CACjC;AAGD,KAAI,cAAc;AAEhB,WAAS,MAAM;;sBAEG,QAAQ,KAAK;;;;;;;;;;;;;;sBAcb,QAAQ,KAAK;;;;;;;;;;oCAUC;AAChC,UAAQ,KAAK,gBAAgB;CAC9B,OAAM;AAEL,WAAS,MAAM;;sBAEG,QAAQ,KAAK;;;;;;;;;;kBAUjB;AACd,UAAQ,KAAK,gBAAgB;CAC9B;AAGD,KAAI,WAAW;AACb,WAAS,MAAM;;sBAEG,QAAQ,KAAK;;;;;;;;;;;;;;kBAcjB;AACd,UAAQ,KAAK,mBAAmB;CACjC;CAGD,IAAI,iBAAiB;;;EAGrB,SAAS,KAAK,OAAO,CAAC;;AAGtB,KAAI,QAAQ,SAAS,EACnB,mBAAkB;;EAEpB,QAAQ,KAAK,KAAK,CAAC;;AAInB,QAAO,CACL;EACE,MAAM;EACN,SAAS;CACV,CACF;AACF"}
@@ -0,0 +1,113 @@
1
+ //#region src/init/generators/docker.ts
2
+ /**
3
+ * Generate docker-compose.yml based on template and options
4
+ */
5
+ function generateDockerFiles(options, template) {
6
+ const { database } = options;
7
+ const isServerless = template.name === "serverless";
8
+ const hasWorker = template.name === "worker";
9
+ const services = [];
10
+ const volumes = [];
11
+ if (database) {
12
+ services.push(` postgres:
13
+ image: postgres:16-alpine
14
+ container_name: ${options.name}-postgres
15
+ restart: unless-stopped
16
+ environment:
17
+ POSTGRES_USER: postgres
18
+ POSTGRES_PASSWORD: postgres
19
+ POSTGRES_DB: ${options.name.replace(/-/g, "_")}_dev
20
+ ports:
21
+ - '5432:5432'
22
+ volumes:
23
+ - postgres_data:/var/lib/postgresql/data
24
+ healthcheck:
25
+ test: ['CMD-SHELL', 'pg_isready -U postgres']
26
+ interval: 5s
27
+ timeout: 5s
28
+ retries: 5`);
29
+ volumes.push(" postgres_data:");
30
+ }
31
+ if (isServerless) {
32
+ services.push(` redis:
33
+ image: redis:7-alpine
34
+ container_name: ${options.name}-redis
35
+ restart: unless-stopped
36
+ ports:
37
+ - '6379:6379'
38
+ volumes:
39
+ - redis_data:/data
40
+ healthcheck:
41
+ test: ['CMD', 'redis-cli', 'ping']
42
+ interval: 5s
43
+ timeout: 5s
44
+ retries: 5
45
+
46
+ serverless-redis:
47
+ image: hiett/serverless-redis-http:latest
48
+ container_name: ${options.name}-serverless-redis
49
+ restart: unless-stopped
50
+ ports:
51
+ - '8079:80'
52
+ environment:
53
+ SRH_MODE: env
54
+ SRH_TOKEN: local_dev_token
55
+ SRH_CONNECTION_STRING: redis://redis:6379
56
+ depends_on:
57
+ redis:
58
+ condition: service_healthy`);
59
+ volumes.push(" redis_data:");
60
+ } else {
61
+ services.push(` redis:
62
+ image: redis:7-alpine
63
+ container_name: ${options.name}-redis
64
+ restart: unless-stopped
65
+ ports:
66
+ - '6379:6379'
67
+ volumes:
68
+ - redis_data:/data
69
+ healthcheck:
70
+ test: ['CMD', 'redis-cli', 'ping']
71
+ interval: 5s
72
+ timeout: 5s
73
+ retries: 5`);
74
+ volumes.push(" redis_data:");
75
+ }
76
+ if (hasWorker) {
77
+ services.push(` rabbitmq:
78
+ image: rabbitmq:3-management-alpine
79
+ container_name: ${options.name}-rabbitmq
80
+ restart: unless-stopped
81
+ ports:
82
+ - '5672:5672'
83
+ - '15672:15672'
84
+ environment:
85
+ RABBITMQ_DEFAULT_USER: guest
86
+ RABBITMQ_DEFAULT_PASS: guest
87
+ volumes:
88
+ - rabbitmq_data:/var/lib/rabbitmq
89
+ healthcheck:
90
+ test: ['CMD', 'rabbitmq-diagnostics', 'check_running']
91
+ interval: 10s
92
+ timeout: 5s
93
+ retries: 5`);
94
+ volumes.push(" rabbitmq_data:");
95
+ }
96
+ let dockerCompose = `version: '3.8'
97
+
98
+ services:
99
+ ${services.join("\n\n")}
100
+ `;
101
+ if (volumes.length > 0) dockerCompose += `
102
+ volumes:
103
+ ${volumes.join("\n")}
104
+ `;
105
+ return [{
106
+ path: "docker-compose.yml",
107
+ content: dockerCompose
108
+ }];
109
+ }
110
+
111
+ //#endregion
112
+ export { generateDockerFiles };
113
+ //# sourceMappingURL=docker-DlUqdFle.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"docker-DlUqdFle.mjs","names":["options: TemplateOptions","template: TemplateConfig","services: string[]","volumes: string[]"],"sources":["../src/init/generators/docker.ts"],"sourcesContent":["import type {\n GeneratedFile,\n TemplateConfig,\n TemplateOptions,\n} from '../templates/index.js';\n\n/**\n * Generate docker-compose.yml based on template and options\n */\nexport function generateDockerFiles(\n options: TemplateOptions,\n template: TemplateConfig,\n): GeneratedFile[] {\n const { database } = options;\n const isServerless = template.name === 'serverless';\n const hasWorker = template.name === 'worker';\n\n const services: string[] = [];\n const volumes: string[] = [];\n\n // PostgreSQL database\n if (database) {\n services.push(` postgres:\n image: postgres:16-alpine\n container_name: ${options.name}-postgres\n restart: unless-stopped\n environment:\n POSTGRES_USER: postgres\n POSTGRES_PASSWORD: postgres\n POSTGRES_DB: ${options.name.replace(/-/g, '_')}_dev\n ports:\n - '5432:5432'\n volumes:\n - postgres_data:/var/lib/postgresql/data\n healthcheck:\n test: ['CMD-SHELL', 'pg_isready -U postgres']\n interval: 5s\n timeout: 5s\n retries: 5`);\n volumes.push(' postgres_data:');\n }\n\n // Redis - different setup for serverless vs standard\n if (isServerless) {\n // Use serverless-redis-http for Lambda compatibility\n services.push(` redis:\n image: redis:7-alpine\n container_name: ${options.name}-redis\n restart: unless-stopped\n ports:\n - '6379:6379'\n volumes:\n - redis_data:/data\n healthcheck:\n test: ['CMD', 'redis-cli', 'ping']\n interval: 5s\n timeout: 5s\n retries: 5\n\n serverless-redis:\n image: hiett/serverless-redis-http:latest\n container_name: ${options.name}-serverless-redis\n restart: unless-stopped\n ports:\n - '8079:80'\n environment:\n SRH_MODE: env\n SRH_TOKEN: local_dev_token\n SRH_CONNECTION_STRING: redis://redis:6379\n depends_on:\n redis:\n condition: service_healthy`);\n volumes.push(' redis_data:');\n } else {\n // Standard Redis for non-serverless templates\n services.push(` redis:\n image: redis:7-alpine\n container_name: ${options.name}-redis\n restart: unless-stopped\n ports:\n - '6379:6379'\n volumes:\n - redis_data:/data\n healthcheck:\n test: ['CMD', 'redis-cli', 'ping']\n interval: 5s\n timeout: 5s\n retries: 5`);\n volumes.push(' redis_data:');\n }\n\n // RabbitMQ for worker template\n if (hasWorker) {\n services.push(` rabbitmq:\n image: rabbitmq:3-management-alpine\n container_name: ${options.name}-rabbitmq\n restart: unless-stopped\n ports:\n - '5672:5672'\n - '15672:15672'\n environment:\n RABBITMQ_DEFAULT_USER: guest\n RABBITMQ_DEFAULT_PASS: guest\n volumes:\n - rabbitmq_data:/var/lib/rabbitmq\n healthcheck:\n test: ['CMD', 'rabbitmq-diagnostics', 'check_running']\n interval: 10s\n timeout: 5s\n retries: 5`);\n volumes.push(' rabbitmq_data:');\n }\n\n // Build docker-compose.yml\n let dockerCompose = `version: '3.8'\n\nservices:\n${services.join('\\n\\n')}\n`;\n\n if (volumes.length > 0) {\n dockerCompose += `\nvolumes:\n${volumes.join('\\n')}\n`;\n }\n\n return [\n {\n path: 'docker-compose.yml',\n content: dockerCompose,\n },\n ];\n}\n"],"mappings":";;;;AASA,SAAgB,oBACdA,SACAC,UACiB;CACjB,MAAM,EAAE,UAAU,GAAG;CACrB,MAAM,eAAe,SAAS,SAAS;CACvC,MAAM,YAAY,SAAS,SAAS;CAEpC,MAAMC,WAAqB,CAAE;CAC7B,MAAMC,UAAoB,CAAE;AAG5B,KAAI,UAAU;AACZ,WAAS,MAAM;;sBAEG,QAAQ,KAAK;;;;;qBAKd,QAAQ,KAAK,QAAQ,MAAM,IAAI,CAAC;;;;;;;;;kBASnC;AACd,UAAQ,KAAK,mBAAmB;CACjC;AAGD,KAAI,cAAc;AAEhB,WAAS,MAAM;;sBAEG,QAAQ,KAAK;;;;;;;;;;;;;;sBAcb,QAAQ,KAAK;;;;;;;;;;oCAUC;AAChC,UAAQ,KAAK,gBAAgB;CAC9B,OAAM;AAEL,WAAS,MAAM;;sBAEG,QAAQ,KAAK;;;;;;;;;;kBAUjB;AACd,UAAQ,KAAK,gBAAgB;CAC9B;AAGD,KAAI,WAAW;AACb,WAAS,MAAM;;sBAEG,QAAQ,KAAK;;;;;;;;;;;;;;kBAcjB;AACd,UAAQ,KAAK,mBAAmB;CACjC;CAGD,IAAI,iBAAiB;;;EAGrB,SAAS,KAAK,OAAO,CAAC;;AAGtB,KAAI,QAAQ,SAAS,EACnB,mBAAkB;;EAEpB,QAAQ,KAAK,KAAK,CAAC;;AAInB,QAAO,CACL;EACE,MAAM;EACN,SAAS;CACV,CACF;AACF"}