@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
@@ -0,0 +1,81 @@
1
+ import type {
2
+ GeneratedFile,
3
+ TemplateConfig,
4
+ TemplateOptions,
5
+ } from '../templates/index.js';
6
+
7
+ /**
8
+ * Generate package.json with dependencies based on template and options
9
+ */
10
+ export function generatePackageJson(
11
+ options: TemplateOptions,
12
+ template: TemplateConfig,
13
+ ): GeneratedFile[] {
14
+ const { name, telescope, database, monorepo } = options;
15
+
16
+ // Start with template dependencies
17
+ const dependencies = { ...template.dependencies };
18
+ const devDependencies = { ...template.devDependencies };
19
+ const scripts = { ...template.scripts };
20
+
21
+ // Add optional dependencies based on user choices
22
+ if (telescope) {
23
+ dependencies['@geekmidas/telescope'] = 'workspace:*';
24
+ }
25
+
26
+ if (database) {
27
+ dependencies['@geekmidas/db'] = 'workspace:*';
28
+ dependencies['kysely'] = '~0.28.2';
29
+ dependencies['pg'] = '~8.16.0';
30
+ devDependencies['@types/pg'] = '~8.15.0';
31
+ }
32
+
33
+ // Add zod for schema validation (commonly used)
34
+ dependencies['zod'] = '~4.1.0';
35
+
36
+ // For monorepo apps, remove biome/turbo (they're at root) and lint/fmt scripts
37
+ if (monorepo) {
38
+ delete devDependencies['@biomejs/biome'];
39
+ delete devDependencies['turbo'];
40
+ delete scripts['lint'];
41
+ delete scripts['fmt'];
42
+ delete scripts['fmt:check'];
43
+
44
+ // Add models package as dependency
45
+ dependencies[`@${name}/models`] = 'workspace:*';
46
+
47
+ // Remove zod from api package (it's in models)
48
+ delete dependencies['zod'];
49
+ }
50
+
51
+ // Sort dependencies alphabetically
52
+ const sortObject = (obj: Record<string, string>) =>
53
+ Object.fromEntries(
54
+ Object.entries(obj).sort(([a], [b]) => a.localeCompare(b)),
55
+ );
56
+
57
+ // For monorepo, derive package name from apiPath (e.g., apps/api -> @name/api)
58
+ let packageName = name;
59
+ if (monorepo && options.apiPath) {
60
+ const pathParts = options.apiPath.split('/');
61
+ const appName = pathParts[pathParts.length - 1] || 'api';
62
+ packageName = `@${name}/${appName}`;
63
+ }
64
+
65
+ const packageJson = {
66
+ name: packageName,
67
+ version: '0.0.1',
68
+ private: true,
69
+ type: 'module',
70
+ scripts,
71
+ dependencies: sortObject(dependencies),
72
+ devDependencies: sortObject(devDependencies),
73
+ };
74
+
75
+ return [
76
+ {
77
+ path: 'package.json',
78
+ content: JSON.stringify(packageJson, null, 2) + '\n',
79
+ },
80
+ ];
81
+ }
@@ -0,0 +1,15 @@
1
+ import type {
2
+ GeneratedFile,
3
+ TemplateConfig,
4
+ TemplateOptions,
5
+ } from '../templates/index.js';
6
+
7
+ /**
8
+ * Generate source files from template
9
+ */
10
+ export function generateSourceFiles(
11
+ options: TemplateOptions,
12
+ template: TemplateConfig,
13
+ ): GeneratedFile[] {
14
+ return template.files(options);
15
+ }
@@ -0,0 +1,206 @@
1
+ import { execSync } from 'node:child_process';
2
+ import { mkdir, writeFile } from 'node:fs/promises';
3
+ import { dirname, join } from 'node:path';
4
+ import prompts from 'prompts';
5
+ import { generateConfigFiles } from './generators/config.js';
6
+ import { generateDockerFiles } from './generators/docker.js';
7
+ import { generateEnvFiles } from './generators/env.js';
8
+ import { generateModelsPackage } from './generators/models.js';
9
+ import { generateMonorepoFiles } from './generators/monorepo.js';
10
+ import { generatePackageJson } from './generators/package.js';
11
+ import { generateSourceFiles } from './generators/source.js';
12
+ import {
13
+ type TemplateName,
14
+ type TemplateOptions,
15
+ getTemplate,
16
+ routeStyleChoices,
17
+ templateChoices,
18
+ } from './templates/index.js';
19
+ import {
20
+ checkDirectoryExists,
21
+ detectPackageManager,
22
+ getInstallCommand,
23
+ getRunCommand,
24
+ validateProjectName,
25
+ } from './utils.js';
26
+
27
+ export interface InitOptions {
28
+ template?: TemplateName;
29
+ skipInstall?: boolean;
30
+ yes?: boolean;
31
+ monorepo?: boolean;
32
+ apiPath?: string;
33
+ }
34
+
35
+ /**
36
+ * Main init command - scaffolds a new project
37
+ */
38
+ export async function initCommand(
39
+ projectName?: string,
40
+ options: InitOptions = {},
41
+ ): Promise<void> {
42
+ const cwd = process.cwd();
43
+ const pkgManager = detectPackageManager(cwd);
44
+
45
+ // Handle Ctrl+C gracefully
46
+ prompts.override({});
47
+ const onCancel = () => {
48
+ process.exit(0);
49
+ };
50
+
51
+ // Gather answers via prompts
52
+ const answers = await prompts(
53
+ [
54
+ {
55
+ type: projectName ? null : 'text',
56
+ name: 'name',
57
+ message: 'Project name:',
58
+ initial: 'my-api',
59
+ validate: (value: string) => {
60
+ const nameValid = validateProjectName(value);
61
+ if (nameValid !== true) return nameValid;
62
+ const dirValid = checkDirectoryExists(value, cwd);
63
+ if (dirValid !== true) return dirValid;
64
+ return true;
65
+ },
66
+ },
67
+ {
68
+ type: options.template || options.yes ? null : 'select',
69
+ name: 'template',
70
+ message: 'Template:',
71
+ choices: templateChoices,
72
+ initial: 0,
73
+ },
74
+ {
75
+ type: options.yes ? null : 'confirm',
76
+ name: 'telescope',
77
+ message: 'Include Telescope (debugging dashboard)?',
78
+ initial: true,
79
+ },
80
+ {
81
+ type: options.yes ? null : 'confirm',
82
+ name: 'database',
83
+ message: 'Include database support (Kysely)?',
84
+ initial: true,
85
+ },
86
+ {
87
+ type: options.yes ? null : 'select',
88
+ name: 'routeStyle',
89
+ message: 'Route organization:',
90
+ choices: routeStyleChoices,
91
+ initial: 0,
92
+ },
93
+ {
94
+ type: options.yes || options.monorepo !== undefined ? null : 'confirm',
95
+ name: 'monorepo',
96
+ message: 'Setup as monorepo?',
97
+ initial: false,
98
+ },
99
+ {
100
+ type: (prev) =>
101
+ (prev === true || options.monorepo) && !options.apiPath
102
+ ? 'text'
103
+ : null,
104
+ name: 'apiPath',
105
+ message: 'API app path:',
106
+ initial: 'apps/api',
107
+ },
108
+ ],
109
+ { onCancel },
110
+ );
111
+
112
+ // Build final options
113
+ const name = projectName || answers.name;
114
+ if (!name) {
115
+ console.error(' Error: Project name is required\n');
116
+ process.exit(1);
117
+ }
118
+
119
+ // Validate name if provided via argument
120
+ if (projectName) {
121
+ const nameValid = validateProjectName(projectName);
122
+ if (nameValid !== true) {
123
+ console.error(` Error: ${nameValid}\n`);
124
+ process.exit(1);
125
+ }
126
+ const dirValid = checkDirectoryExists(projectName, cwd);
127
+ if (dirValid !== true) {
128
+ console.error(` Error: ${dirValid}\n`);
129
+ process.exit(1);
130
+ }
131
+ }
132
+
133
+ const monorepo =
134
+ options.monorepo ?? (options.yes ? false : (answers.monorepo ?? false));
135
+ const templateOptions: TemplateOptions = {
136
+ name,
137
+ template: options.template || answers.template || 'minimal',
138
+ telescope: options.yes ? true : (answers.telescope ?? true),
139
+ database: options.yes ? true : (answers.database ?? true),
140
+ routeStyle: options.yes
141
+ ? 'file-based'
142
+ : (answers.routeStyle ?? 'file-based'),
143
+ monorepo,
144
+ apiPath: monorepo ? (options.apiPath ?? answers.apiPath ?? 'apps/api') : '',
145
+ };
146
+
147
+ const targetDir = join(cwd, name);
148
+ const template = getTemplate(templateOptions.template);
149
+
150
+ const isMonorepo = templateOptions.monorepo;
151
+ const apiPath = templateOptions.apiPath;
152
+
153
+ // Create project directory
154
+ await mkdir(targetDir, { recursive: true });
155
+
156
+ // For monorepo, app files go in the specified apiPath (e.g., apps/api)
157
+ const appDir = isMonorepo ? join(targetDir, apiPath) : targetDir;
158
+ if (isMonorepo) {
159
+ await mkdir(appDir, { recursive: true });
160
+ }
161
+
162
+ // Collect app files
163
+ const appFiles = [
164
+ ...generatePackageJson(templateOptions, template),
165
+ ...generateConfigFiles(templateOptions, template),
166
+ ...generateEnvFiles(templateOptions, template),
167
+ ...generateSourceFiles(templateOptions, template),
168
+ ...generateDockerFiles(templateOptions, template),
169
+ ];
170
+
171
+ // Collect root monorepo files (includes packages/models)
172
+ const rootFiles = [
173
+ ...generateMonorepoFiles(templateOptions, template),
174
+ ...generateModelsPackage(templateOptions),
175
+ ];
176
+
177
+ // Write root files (for monorepo)
178
+ for (const { path, content } of rootFiles) {
179
+ const fullPath = join(targetDir, path);
180
+ await mkdir(dirname(fullPath), { recursive: true });
181
+ await writeFile(fullPath, content);
182
+ }
183
+
184
+ // Write app files
185
+ for (const { path, content } of appFiles) {
186
+ const fullPath = join(appDir, path);
187
+ const displayPath = isMonorepo ? `${apiPath}/${path}` : path;
188
+ await mkdir(dirname(fullPath), { recursive: true });
189
+ await writeFile(fullPath, content);
190
+ }
191
+
192
+ // Install dependencies
193
+ if (!options.skipInstall) {
194
+ try {
195
+ execSync(getInstallCommand(pkgManager), {
196
+ cwd: targetDir,
197
+ stdio: 'inherit',
198
+ });
199
+ } catch {
200
+ console.error('\n Warning: Failed to install dependencies.');
201
+ }
202
+ }
203
+
204
+ // Print next steps
205
+ const devCommand = getRunCommand(pkgManager, 'dev');
206
+ }
@@ -0,0 +1,218 @@
1
+ import type {
2
+ GeneratedFile,
3
+ TemplateConfig,
4
+ TemplateOptions,
5
+ } from './index.js';
6
+
7
+ export const apiTemplate: TemplateConfig = {
8
+ name: 'api',
9
+ description: 'Full API with auth, database, services',
10
+
11
+ dependencies: {
12
+ '@geekmidas/constructs': 'workspace:*',
13
+ '@geekmidas/envkit': 'workspace:*',
14
+ '@geekmidas/logger': 'workspace:*',
15
+ '@geekmidas/services': 'workspace:*',
16
+ '@geekmidas/errors': 'workspace:*',
17
+ '@geekmidas/auth': 'workspace:*',
18
+ hono: '~4.8.2',
19
+ pino: '~9.6.0',
20
+ },
21
+
22
+ devDependencies: {
23
+ '@biomejs/biome': '~1.9.4',
24
+ '@geekmidas/cli': 'workspace:*',
25
+ '@types/node': '~22.0.0',
26
+ tsx: '~4.20.0',
27
+ turbo: '~2.3.0',
28
+ typescript: '~5.8.2',
29
+ vitest: '~4.0.0',
30
+ },
31
+
32
+ scripts: {
33
+ dev: 'gkm dev',
34
+ build: 'gkm build',
35
+ test: 'vitest',
36
+ 'test:once': 'vitest run',
37
+ typecheck: 'tsc --noEmit',
38
+ lint: 'biome lint .',
39
+ fmt: 'biome format . --write',
40
+ 'fmt:check': 'biome format .',
41
+ },
42
+
43
+ files: (options: TemplateOptions): GeneratedFile[] => {
44
+ const files: GeneratedFile[] = [
45
+ // src/config/env.ts
46
+ {
47
+ path: 'src/config/env.ts',
48
+ content: `import { EnvironmentParser } from '@geekmidas/envkit';
49
+
50
+ export const envParser = new EnvironmentParser(process.env);
51
+
52
+ export const config = envParser
53
+ .create((get) => ({
54
+ port: get('PORT').string().transform(Number).default(3000),
55
+ nodeEnv: get('NODE_ENV').string().default('development'),
56
+ jwtSecret: get('JWT_SECRET').string().default('change-me-in-production'),${
57
+ options.database
58
+ ? `
59
+ database: {
60
+ url: get('DATABASE_URL').string().default('postgresql://localhost:5432/mydb'),
61
+ },`
62
+ : ''
63
+ }
64
+ }))
65
+ .parse();
66
+ `,
67
+ },
68
+
69
+ // src/config/logger.ts - using pino
70
+ {
71
+ path: 'src/config/logger.ts',
72
+ content: `import { PinoLogger } from '@geekmidas/logger/pino';
73
+
74
+ export const logger = new PinoLogger({
75
+ app: '${options.name}',
76
+ level: process.env.LOG_LEVEL || 'info',
77
+ });
78
+ `,
79
+ },
80
+
81
+ // src/endpoints/health.ts
82
+ {
83
+ path: 'src/endpoints/health.ts',
84
+ content: `import { e } from '@geekmidas/constructs/endpoints';
85
+
86
+ export default e
87
+ .get('/health')
88
+ .handle(async () => ({
89
+ status: 'ok',
90
+ timestamp: new Date().toISOString(),
91
+ }));
92
+ `,
93
+ },
94
+ ];
95
+
96
+ // Add user endpoints based on route style
97
+ if (options.routeStyle === 'flat') {
98
+ files.push(
99
+ {
100
+ path: 'src/endpoints/users-list.ts',
101
+ content: `import { e } from '@geekmidas/constructs/endpoints';
102
+
103
+ export default e
104
+ .get('/users')
105
+ .handle(async () => ({
106
+ users: [
107
+ { id: '1', name: 'Alice' },
108
+ { id: '2', name: 'Bob' },
109
+ ],
110
+ }));
111
+ `,
112
+ },
113
+ {
114
+ path: 'src/endpoints/users-get.ts',
115
+ content: `import { e } from '@geekmidas/constructs/endpoints';
116
+ import { z } from 'zod';
117
+
118
+ export default e
119
+ .get('/users/:id')
120
+ .params(z.object({ id: z.string() }))
121
+ .handle(async ({ params }) => ({
122
+ id: params.id,
123
+ name: 'Alice',
124
+ email: 'alice@example.com',
125
+ }));
126
+ `,
127
+ },
128
+ );
129
+ } else {
130
+ files.push(
131
+ {
132
+ path: 'src/endpoints/users/list.ts',
133
+ content: `import { e } from '@geekmidas/constructs/endpoints';
134
+
135
+ export default e
136
+ .get('/users')
137
+ .handle(async () => ({
138
+ users: [
139
+ { id: '1', name: 'Alice' },
140
+ { id: '2', name: 'Bob' },
141
+ ],
142
+ }));
143
+ `,
144
+ },
145
+ {
146
+ path: 'src/endpoints/users/get.ts',
147
+ content: `import { e } from '@geekmidas/constructs/endpoints';
148
+ import { z } from 'zod';
149
+
150
+ export default e
151
+ .get('/users/:id')
152
+ .params(z.object({ id: z.string() }))
153
+ .handle(async ({ params }) => ({
154
+ id: params.id,
155
+ name: 'Alice',
156
+ email: 'alice@example.com',
157
+ }));
158
+ `,
159
+ },
160
+ );
161
+ }
162
+
163
+ // Add database service if enabled
164
+ if (options.database) {
165
+ files.push({
166
+ path: 'src/services/database.ts',
167
+ content: `import type { Service } from '@geekmidas/services';
168
+ import { Kysely, PostgresDialect } from 'kysely';
169
+ import pg from 'pg';
170
+
171
+ // Define your database schema
172
+ export interface Database {
173
+ users: {
174
+ id: string;
175
+ name: string;
176
+ email: string;
177
+ created_at: Date;
178
+ };
179
+ }
180
+
181
+ export const databaseService = {
182
+ serviceName: 'database' as const,
183
+ async register(envParser) {
184
+ const config = envParser
185
+ .create((get) => ({
186
+ url: get('DATABASE_URL').string(),
187
+ }))
188
+ .parse();
189
+
190
+ return new Kysely<Database>({
191
+ dialect: new PostgresDialect({
192
+ pool: new pg.Pool({ connectionString: config.url }),
193
+ }),
194
+ });
195
+ },
196
+ } satisfies Service<'database', Kysely<Database>>;
197
+ `,
198
+ });
199
+ }
200
+
201
+ // Add Telescope config if enabled
202
+ if (options.telescope) {
203
+ files.push({
204
+ path: 'src/config/telescope.ts',
205
+ content: `import { Telescope } from '@geekmidas/telescope';
206
+ import { InMemoryStorage } from '@geekmidas/telescope/storage/memory';
207
+
208
+ export const telescope = new Telescope({
209
+ storage: new InMemoryStorage({ maxEntries: 100 }),
210
+ enabled: process.env.NODE_ENV === 'development',
211
+ });
212
+ `,
213
+ });
214
+ }
215
+
216
+ return files;
217
+ },
218
+ };
@@ -0,0 +1,108 @@
1
+ import { apiTemplate } from './api.js';
2
+ import { minimalTemplate } from './minimal.js';
3
+ import { serverlessTemplate } from './serverless.js';
4
+ import { workerTemplate } from './worker.js';
5
+
6
+ /**
7
+ * Route organization style
8
+ */
9
+ export type RouteStyle = 'file-based' | 'flat';
10
+
11
+ /**
12
+ * Options collected from user prompts
13
+ */
14
+ export interface TemplateOptions {
15
+ name: string;
16
+ template: TemplateName;
17
+ telescope: boolean;
18
+ database: boolean;
19
+ routeStyle: RouteStyle;
20
+ monorepo: boolean;
21
+ /** Path for the API app in monorepo (e.g., 'apps/api') */
22
+ apiPath: string;
23
+ }
24
+
25
+ /**
26
+ * A file to be generated
27
+ */
28
+ export interface GeneratedFile {
29
+ path: string;
30
+ content: string;
31
+ }
32
+
33
+ /**
34
+ * Template configuration
35
+ */
36
+ export interface TemplateConfig {
37
+ name: TemplateName;
38
+ description: string;
39
+ dependencies: Record<string, string>;
40
+ devDependencies: Record<string, string>;
41
+ scripts: Record<string, string>;
42
+ files: (options: TemplateOptions) => GeneratedFile[];
43
+ }
44
+
45
+ export type TemplateName = 'minimal' | 'api' | 'serverless' | 'worker';
46
+
47
+ /**
48
+ * All available templates
49
+ */
50
+ export const templates: Record<TemplateName, TemplateConfig> = {
51
+ minimal: minimalTemplate,
52
+ api: apiTemplate,
53
+ serverless: serverlessTemplate,
54
+ worker: workerTemplate,
55
+ };
56
+
57
+ /**
58
+ * Template choices for prompts
59
+ */
60
+ export const templateChoices = [
61
+ {
62
+ title: 'Minimal',
63
+ value: 'minimal' as TemplateName,
64
+ description: 'Basic health endpoint',
65
+ },
66
+ {
67
+ title: 'API',
68
+ value: 'api' as TemplateName,
69
+ description: 'Full API with auth, database, services',
70
+ },
71
+ {
72
+ title: 'Serverless',
73
+ value: 'serverless' as TemplateName,
74
+ description: 'AWS Lambda handlers',
75
+ },
76
+ {
77
+ title: 'Worker',
78
+ value: 'worker' as TemplateName,
79
+ description: 'Background job processing',
80
+ },
81
+ ];
82
+
83
+ /**
84
+ * Route style choices for prompts
85
+ */
86
+ export const routeStyleChoices = [
87
+ {
88
+ title: 'File-based',
89
+ value: 'file-based' as RouteStyle,
90
+ description: 'Folder structure matches URL paths (users/list.ts → /users)',
91
+ },
92
+ {
93
+ title: 'Flat',
94
+ value: 'flat' as RouteStyle,
95
+ description: 'All endpoints in one folder (users-list.ts → /users)',
96
+ },
97
+ ];
98
+
99
+ /**
100
+ * Get a template by name
101
+ */
102
+ export function getTemplate(name: TemplateName): TemplateConfig {
103
+ const template = templates[name];
104
+ if (!template) {
105
+ throw new Error(`Unknown template: ${name}`);
106
+ }
107
+ return template;
108
+ }