alepha 0.13.6 → 0.13.8

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 (487) hide show
  1. package/README.md +5 -2
  2. package/assets/swagger-ui/swagger-ui-bundle.js +1 -1
  3. package/assets/swagger-ui/swagger-ui-standalone-preset.js +1 -1
  4. package/assets/swagger-ui/swagger-ui.css +1 -1
  5. package/dist/api/audits/index.browser.js +116 -0
  6. package/dist/api/audits/index.browser.js.map +1 -0
  7. package/dist/api/audits/index.d.ts +1194 -0
  8. package/dist/api/audits/index.js +674 -0
  9. package/dist/api/audits/index.js.map +1 -0
  10. package/dist/{api-files → api/files}/index.browser.js +5 -5
  11. package/dist/api/files/index.browser.js.map +1 -0
  12. package/dist/{api-files → api/files}/index.d.ts +16 -9
  13. package/dist/{api-files → api/files}/index.js +10 -10
  14. package/dist/api/files/index.js.map +1 -0
  15. package/dist/{api-jobs → api/jobs}/index.browser.js +5 -5
  16. package/dist/api/jobs/index.browser.js.map +1 -0
  17. package/dist/{api-jobs → api/jobs}/index.d.ts +35 -35
  18. package/dist/{api-jobs → api/jobs}/index.js +9 -9
  19. package/dist/api/jobs/index.js.map +1 -0
  20. package/dist/{api-notifications → api/notifications}/index.browser.js +11 -11
  21. package/dist/api/notifications/index.browser.js.map +1 -0
  22. package/dist/api/notifications/index.d.ts +327 -0
  23. package/dist/{api-notifications → api/notifications}/index.js +11 -11
  24. package/dist/api/notifications/index.js.map +1 -0
  25. package/dist/api/parameters/index.browser.js +60 -0
  26. package/dist/api/parameters/index.browser.js.map +1 -0
  27. package/dist/api/parameters/index.d.ts +761 -0
  28. package/dist/api/parameters/index.js +877 -0
  29. package/dist/api/parameters/index.js.map +1 -0
  30. package/dist/{api-users → api/users}/index.browser.js +6 -6
  31. package/dist/api/users/index.browser.js.map +1 -0
  32. package/dist/{api-users → api/users}/index.d.ts +259 -247
  33. package/dist/{api-users → api/users}/index.js +125 -112
  34. package/dist/api/users/index.js.map +1 -0
  35. package/dist/{api-verifications → api/verifications}/index.browser.js +5 -5
  36. package/dist/api/verifications/index.browser.js.map +1 -0
  37. package/dist/api/verifications/index.d.ts +248 -0
  38. package/dist/{api-verifications → api/verifications}/index.js +13 -12
  39. package/dist/api/verifications/index.js.map +1 -0
  40. package/dist/bin/index.js +1 -0
  41. package/dist/bin/index.js.map +1 -1
  42. package/dist/cache/{index.d.ts → core/index.d.ts} +4 -4
  43. package/dist/cache/{index.js → core/index.js} +5 -5
  44. package/dist/cache/core/index.js.map +1 -0
  45. package/dist/{cache-redis → cache/redis}/index.d.ts +2 -2
  46. package/dist/{cache-redis → cache/redis}/index.js +2 -2
  47. package/dist/cache/redis/index.js.map +1 -0
  48. package/dist/cli/index.d.ts +71 -9
  49. package/dist/cli/index.js +280 -79
  50. package/dist/cli/index.js.map +1 -1
  51. package/dist/command/index.d.ts +63 -2
  52. package/dist/command/index.js +30 -3
  53. package/dist/command/index.js.map +1 -1
  54. package/dist/core/index.browser.js +241 -61
  55. package/dist/core/index.browser.js.map +1 -1
  56. package/dist/core/index.d.ts +170 -90
  57. package/dist/core/index.js +264 -67
  58. package/dist/core/index.js.map +1 -1
  59. package/dist/core/index.native.js +248 -65
  60. package/dist/core/index.native.js.map +1 -1
  61. package/dist/email/index.js +15 -10554
  62. package/dist/email/index.js.map +1 -1
  63. package/dist/lock/{index.d.ts → core/index.d.ts} +5 -5
  64. package/dist/lock/{index.js → core/index.js} +5 -5
  65. package/dist/lock/core/index.js.map +1 -0
  66. package/dist/{lock-redis → lock/redis}/index.d.ts +2 -2
  67. package/dist/{lock-redis → lock/redis}/index.js +2 -2
  68. package/dist/lock/redis/index.js.map +1 -0
  69. package/dist/logger/index.d.ts +4 -4
  70. package/dist/logger/index.js +77 -72
  71. package/dist/logger/index.js.map +1 -1
  72. package/dist/orm/index.d.ts +5 -1
  73. package/dist/orm/index.js +24 -7
  74. package/dist/orm/index.js.map +1 -1
  75. package/dist/queue/core/index.d.ts +548 -0
  76. package/dist/queue/core/index.js +391 -0
  77. package/dist/queue/core/index.js.map +1 -0
  78. package/dist/queue/redis/index.d.ts +28 -0
  79. package/dist/queue/redis/index.js +43 -0
  80. package/dist/queue/redis/index.js.map +1 -0
  81. package/dist/scheduler/index.d.ts +7 -7
  82. package/dist/scheduler/index.js +1 -393
  83. package/dist/scheduler/index.js.map +1 -1
  84. package/dist/security/index.d.ts +1 -1
  85. package/dist/security/index.js +2 -1413
  86. package/dist/security/index.js.map +1 -1
  87. package/dist/{server-auth → server/auth}/index.browser.js +6 -6
  88. package/dist/server/auth/index.browser.js.map +1 -0
  89. package/dist/{server-auth → server/auth}/index.d.ts +175 -164
  90. package/dist/server/auth/index.js +742 -0
  91. package/dist/server/auth/index.js.map +1 -0
  92. package/dist/{server-cache → server/cache}/index.d.ts +2 -2
  93. package/dist/{server-cache → server/cache}/index.js +2 -2
  94. package/dist/server/cache/index.js.map +1 -0
  95. package/dist/{server-compress → server/compress}/index.d.ts +2 -2
  96. package/dist/{server-compress → server/compress}/index.js +2 -2
  97. package/dist/server/compress/index.js.map +1 -0
  98. package/dist/{server-cookies → server/cookies}/index.browser.js +3 -3
  99. package/dist/server/cookies/index.browser.js.map +1 -0
  100. package/dist/{server-cookies → server/cookies}/index.d.ts +4 -4
  101. package/dist/{server-cookies → server/cookies}/index.js +9 -5
  102. package/dist/server/cookies/index.js.map +1 -0
  103. package/dist/server/{index.browser.js → core/index.browser.js} +14 -14
  104. package/dist/server/core/index.browser.js.map +1 -0
  105. package/dist/server/{index.d.ts → core/index.d.ts} +46 -37
  106. package/dist/server/{index.js → core/index.js} +47 -33
  107. package/dist/server/core/index.js.map +1 -0
  108. package/dist/{server-cors → server/cors}/index.d.ts +3 -3
  109. package/dist/{server-cors → server/cors}/index.js +3 -3
  110. package/dist/server/cors/index.js.map +1 -0
  111. package/dist/{server-health → server/health}/index.d.ts +3 -3
  112. package/dist/{server-health → server/health}/index.js +3 -3
  113. package/dist/server/health/index.js.map +1 -0
  114. package/dist/{server-helmet → server/helmet}/index.d.ts +2 -2
  115. package/dist/{server-helmet → server/helmet}/index.js +2 -2
  116. package/dist/server/helmet/index.js.map +1 -0
  117. package/dist/{server-links → server/links}/index.browser.js +5 -5
  118. package/dist/server/links/index.browser.js.map +1 -0
  119. package/dist/{server-links → server/links}/index.d.ts +40 -40
  120. package/dist/{server-links → server/links}/index.js +7 -7
  121. package/dist/server/links/index.js.map +1 -0
  122. package/dist/{server-metrics → server/metrics}/index.d.ts +2 -2
  123. package/dist/server/metrics/index.js +74 -0
  124. package/dist/server/metrics/index.js.map +1 -0
  125. package/dist/{server-multipart → server/multipart}/index.d.ts +2 -2
  126. package/dist/{server-multipart → server/multipart}/index.js +2 -2
  127. package/dist/server/multipart/index.js.map +1 -0
  128. package/dist/{server-proxy → server/proxy}/index.d.ts +3 -3
  129. package/dist/{server-proxy → server/proxy}/index.js +3 -3
  130. package/dist/server/proxy/index.js.map +1 -0
  131. package/dist/{server-rate-limit → server/rate-limit}/index.d.ts +4 -4
  132. package/dist/{server-rate-limit → server/rate-limit}/index.js +4 -4
  133. package/dist/server/rate-limit/index.js.map +1 -0
  134. package/dist/{server-security → server/security}/index.browser.js +1 -1
  135. package/dist/server/security/index.browser.js.map +1 -0
  136. package/dist/{server-security → server/security}/index.d.ts +4 -4
  137. package/dist/{server-security → server/security}/index.js +4 -4
  138. package/dist/server/security/index.js.map +1 -0
  139. package/dist/{server-static → server/static}/index.d.ts +3 -3
  140. package/dist/{server-static → server/static}/index.js +3 -3
  141. package/dist/server/static/index.js.map +1 -0
  142. package/dist/{server-swagger → server/swagger}/index.d.ts +3 -3
  143. package/dist/{server-swagger → server/swagger}/index.js +4 -4
  144. package/dist/server/swagger/index.js.map +1 -0
  145. package/dist/thread/index.js +2 -2
  146. package/dist/thread/index.js.map +1 -1
  147. package/dist/topic/{index.d.ts → core/index.d.ts} +6 -6
  148. package/dist/topic/{index.js → core/index.js} +6 -6
  149. package/dist/topic/core/index.js.map +1 -0
  150. package/dist/{topic-redis → topic/redis}/index.d.ts +2 -2
  151. package/dist/{topic-redis → topic/redis}/index.js +2 -2
  152. package/dist/topic/redis/index.js.map +1 -0
  153. package/dist/vite/index.d.ts +13 -2
  154. package/dist/vite/index.js +114 -50
  155. package/dist/vite/index.js.map +1 -1
  156. package/dist/websocket/index.browser.js +3 -3
  157. package/dist/websocket/index.browser.js.map +1 -1
  158. package/dist/websocket/index.js +4 -4
  159. package/dist/websocket/index.js.map +1 -1
  160. package/package.json +160 -156
  161. package/src/api/audits/controllers/AuditController.ts +186 -0
  162. package/src/api/audits/entities/audits.ts +132 -0
  163. package/src/api/audits/index.browser.ts +18 -0
  164. package/src/api/audits/index.ts +58 -0
  165. package/src/api/audits/primitives/$audit.ts +159 -0
  166. package/src/api/audits/schemas/auditQuerySchema.ts +23 -0
  167. package/src/api/audits/schemas/auditResourceSchema.ts +9 -0
  168. package/src/api/audits/schemas/createAuditSchema.ts +27 -0
  169. package/src/api/audits/services/AuditService.ts +412 -0
  170. package/src/{api-files → api/files}/index.ts +1 -0
  171. package/src/api/parameters/controllers/ConfigController.ts +324 -0
  172. package/src/api/parameters/entities/parameters.ts +113 -0
  173. package/src/api/parameters/index.ts +60 -0
  174. package/src/api/parameters/primitives/$config.ts +351 -0
  175. package/src/api/parameters/schedulers/ConfigActivationScheduler.ts +30 -0
  176. package/src/api/parameters/services/ConfigStore.ts +491 -0
  177. package/src/{api-users → api/users}/atoms/realmAuthSettingsAtom.ts +19 -0
  178. package/src/{api-users → api/users}/controllers/UserRealmController.ts +0 -2
  179. package/src/{api-users → api/users}/index.ts +2 -0
  180. package/src/{api-users → api/users}/primitives/$userRealm.ts +18 -3
  181. package/src/{api-users → api/users}/providers/UserRealmProvider.ts +12 -10
  182. package/src/{api-users → api/users}/services/RegistrationService.ts +2 -1
  183. package/src/{api-users → api/users}/services/SessionService.ts +4 -0
  184. package/src/{api-users → api/users}/services/UserService.ts +3 -0
  185. package/src/{api-verifications → api/verifications}/index.ts +9 -1
  186. package/src/bin/index.ts +1 -0
  187. package/src/cli/apps/AlephaPackageBuilderCli.ts +73 -48
  188. package/src/cli/assets/appRouterTs.ts +1 -1
  189. package/src/cli/assets/biomeJson.ts +2 -2
  190. package/src/cli/assets/dummySpecTs.ts +7 -0
  191. package/src/cli/assets/editorconfig.ts +13 -0
  192. package/src/cli/assets/indexHtml.ts +1 -1
  193. package/src/cli/assets/mainBrowserTs.ts +1 -1
  194. package/src/cli/assets/mainTs.ts +14 -0
  195. package/src/cli/assets/viteConfigTs.ts +1 -1
  196. package/src/cli/commands/BiomeCommands.ts +2 -0
  197. package/src/cli/commands/CoreCommands.ts +38 -15
  198. package/src/cli/commands/VerifyCommands.ts +6 -2
  199. package/src/cli/commands/ViteCommands.ts +28 -18
  200. package/src/cli/services/AlephaCliUtils.ts +243 -37
  201. package/src/command/helpers/Asker.ts +0 -1
  202. package/src/command/primitives/$command.ts +67 -0
  203. package/src/command/providers/CliProvider.ts +39 -8
  204. package/src/core/Alepha.ts +40 -30
  205. package/src/core/helpers/jsonSchemaToTypeBox.ts +307 -0
  206. package/src/core/index.shared.ts +1 -0
  207. package/src/core/index.ts +30 -3
  208. package/src/core/providers/EventManager.ts +1 -1
  209. package/src/core/providers/SchemaValidator.ts +1 -1
  210. package/src/core/providers/StateManager.ts +23 -12
  211. package/src/core/providers/TypeProvider.ts +26 -34
  212. package/src/logger/index.ts +8 -6
  213. package/src/logger/primitives/$logger.ts +1 -1
  214. package/src/logger/providers/{SimpleFormatterProvider.ts → PrettyFormatterProvider.ts} +10 -1
  215. package/src/orm/index.ts +6 -0
  216. package/src/orm/services/PgRelationManager.ts +2 -2
  217. package/src/orm/services/PostgresModelBuilder.ts +11 -7
  218. package/src/orm/services/Repository.ts +16 -7
  219. package/src/orm/services/SqliteModelBuilder.ts +10 -0
  220. package/src/queue/{index.ts → core/index.ts} +2 -3
  221. package/src/queue/{primitives → core/primitives}/$queue.ts +17 -162
  222. package/src/queue/core/providers/MemoryQueueProvider.ts +19 -0
  223. package/src/queue/core/providers/QueueProvider.ts +23 -0
  224. package/src/queue/core/providers/WorkerProvider.ts +244 -0
  225. package/src/queue/redis/providers/RedisQueueProvider.ts +31 -0
  226. package/src/{server-auth → server/auth}/primitives/$auth.ts +7 -0
  227. package/src/{server-auth → server/auth}/providers/ServerAuthProvider.ts +51 -8
  228. package/src/{server-cookies → server/cookies}/index.ts +2 -1
  229. package/src/server/{index.ts → core/index.ts} +7 -0
  230. package/src/server/{primitives → core/primitives}/$action.ts +10 -1
  231. package/src/server/{providers → core/providers}/ServerBodyParserProvider.ts +11 -5
  232. package/src/server/{providers → core/providers}/ServerRouterProvider.ts +13 -7
  233. package/src/{server-rate-limit → server/rate-limit}/index.ts +1 -1
  234. package/src/{server-swagger → server/swagger}/providers/ServerSwaggerProvider.ts +1 -0
  235. package/src/thread/primitives/$thread.ts +2 -2
  236. package/src/vite/index.ts +0 -2
  237. package/src/vite/tasks/buildServer.ts +3 -4
  238. package/src/vite/tasks/copyAssets.ts +32 -8
  239. package/src/vite/tasks/generateCloudflare.ts +35 -19
  240. package/src/vite/tasks/generateDocker.ts +18 -4
  241. package/src/vite/tasks/generateSitemap.ts +5 -7
  242. package/src/vite/tasks/generateVercel.ts +76 -41
  243. package/src/vite/tasks/runAlepha.ts +16 -1
  244. package/src/websocket/providers/NodeWebSocketServerProvider.ts +3 -11
  245. package/src/websocket/services/WebSocketClient.ts +3 -3
  246. package/dist/api-files/index.browser.js.map +0 -1
  247. package/dist/api-files/index.js.map +0 -1
  248. package/dist/api-jobs/index.browser.js.map +0 -1
  249. package/dist/api-jobs/index.js.map +0 -1
  250. package/dist/api-notifications/index.browser.js.map +0 -1
  251. package/dist/api-notifications/index.d.ts +0 -327
  252. package/dist/api-notifications/index.js.map +0 -1
  253. package/dist/api-parameters/index.browser.js +0 -29
  254. package/dist/api-parameters/index.browser.js.map +0 -1
  255. package/dist/api-parameters/index.d.ts +0 -83
  256. package/dist/api-parameters/index.js +0 -63
  257. package/dist/api-parameters/index.js.map +0 -1
  258. package/dist/api-users/index.browser.js.map +0 -1
  259. package/dist/api-users/index.js.map +0 -1
  260. package/dist/api-verifications/index.browser.js.map +0 -1
  261. package/dist/api-verifications/index.d.ts +0 -229
  262. package/dist/api-verifications/index.js.map +0 -1
  263. package/dist/cache/index.js.map +0 -1
  264. package/dist/cache-redis/index.js.map +0 -1
  265. package/dist/cli/dist-BlfFtOk2.js +0 -2770
  266. package/dist/cli/dist-BlfFtOk2.js.map +0 -1
  267. package/dist/lock/index.js.map +0 -1
  268. package/dist/lock-redis/index.js.map +0 -1
  269. package/dist/queue/index.d.ts +0 -1265
  270. package/dist/queue/index.js +0 -1037
  271. package/dist/queue/index.js.map +0 -1
  272. package/dist/queue-redis/index.d.ts +0 -82
  273. package/dist/queue-redis/index.js +0 -872
  274. package/dist/queue-redis/index.js.map +0 -1
  275. package/dist/server/index.browser.js.map +0 -1
  276. package/dist/server/index.js.map +0 -1
  277. package/dist/server-auth/index.browser.js.map +0 -1
  278. package/dist/server-auth/index.js +0 -1943
  279. package/dist/server-auth/index.js.map +0 -1
  280. package/dist/server-cache/index.js.map +0 -1
  281. package/dist/server-compress/index.js.map +0 -1
  282. package/dist/server-cookies/index.browser.js.map +0 -1
  283. package/dist/server-cookies/index.js.map +0 -1
  284. package/dist/server-cors/index.js.map +0 -1
  285. package/dist/server-health/index.js.map +0 -1
  286. package/dist/server-helmet/index.js.map +0 -1
  287. package/dist/server-links/index.browser.js.map +0 -1
  288. package/dist/server-links/index.js.map +0 -1
  289. package/dist/server-metrics/index.js +0 -4532
  290. package/dist/server-metrics/index.js.map +0 -1
  291. package/dist/server-multipart/index.js.map +0 -1
  292. package/dist/server-proxy/index.js.map +0 -1
  293. package/dist/server-rate-limit/index.js.map +0 -1
  294. package/dist/server-security/index.browser.js.map +0 -1
  295. package/dist/server-security/index.js.map +0 -1
  296. package/dist/server-static/index.js.map +0 -1
  297. package/dist/server-swagger/index.js.map +0 -1
  298. package/dist/topic/index.js.map +0 -1
  299. package/dist/topic-redis/index.js.map +0 -1
  300. package/src/api-parameters/controllers/ParameterController.ts +0 -45
  301. package/src/api-parameters/entities/parameters.ts +0 -30
  302. package/src/api-parameters/index.ts +0 -21
  303. package/src/api-parameters/primitives/$config.ts +0 -79
  304. package/src/api-parameters/services/ParameterStore.ts +0 -23
  305. package/src/queue/interfaces/QueueJob.ts +0 -459
  306. package/src/queue/providers/MemoryQueueProvider.ts +0 -850
  307. package/src/queue/providers/QueueProvider.ts +0 -319
  308. package/src/queue/providers/WorkerProvider.ts +0 -344
  309. package/src/queue-redis/providers/RedisQueueProvider.ts +0 -1209
  310. /package/src/{api-files → api/files}/controllers/FileController.ts +0 -0
  311. /package/src/{api-files → api/files}/controllers/StorageStatsController.ts +0 -0
  312. /package/src/{api-files → api/files}/entities/files.ts +0 -0
  313. /package/src/{api-files → api/files}/index.browser.ts +0 -0
  314. /package/src/{api-files → api/files}/jobs/FileJobs.ts +0 -0
  315. /package/src/{api-files → api/files}/schemas/fileQuerySchema.ts +0 -0
  316. /package/src/{api-files → api/files}/schemas/fileResourceSchema.ts +0 -0
  317. /package/src/{api-files → api/files}/schemas/storageStatsSchema.ts +0 -0
  318. /package/src/{api-files → api/files}/services/FileService.ts +0 -0
  319. /package/src/{api-jobs → api/jobs}/controllers/JobController.ts +0 -0
  320. /package/src/{api-jobs → api/jobs}/entities/jobExecutions.ts +0 -0
  321. /package/src/{api-jobs → api/jobs}/index.browser.ts +0 -0
  322. /package/src/{api-jobs → api/jobs}/index.ts +0 -0
  323. /package/src/{api-jobs → api/jobs}/primitives/$job.ts +0 -0
  324. /package/src/{api-jobs → api/jobs}/providers/JobProvider.ts +0 -0
  325. /package/src/{api-jobs → api/jobs}/schemas/jobExecutionQuerySchema.ts +0 -0
  326. /package/src/{api-jobs → api/jobs}/schemas/jobExecutionResourceSchema.ts +0 -0
  327. /package/src/{api-jobs → api/jobs}/schemas/triggerJobSchema.ts +0 -0
  328. /package/src/{api-jobs → api/jobs}/services/JobService.ts +0 -0
  329. /package/src/{api-notifications → api/notifications}/controllers/NotificationController.ts +0 -0
  330. /package/src/{api-notifications → api/notifications}/entities/notifications.ts +0 -0
  331. /package/src/{api-notifications → api/notifications}/index.browser.ts +0 -0
  332. /package/src/{api-notifications → api/notifications}/index.ts +0 -0
  333. /package/src/{api-notifications → api/notifications}/jobs/NotificationJobs.ts +0 -0
  334. /package/src/{api-notifications → api/notifications}/primitives/$notification.ts +0 -0
  335. /package/src/{api-notifications → api/notifications}/queues/NotificationQueues.ts +0 -0
  336. /package/src/{api-notifications → api/notifications}/schemas/notificationContactPreferencesSchema.ts +0 -0
  337. /package/src/{api-notifications → api/notifications}/schemas/notificationContactSchema.ts +0 -0
  338. /package/src/{api-notifications → api/notifications}/schemas/notificationCreateSchema.ts +0 -0
  339. /package/src/{api-notifications → api/notifications}/schemas/notificationQuerySchema.ts +0 -0
  340. /package/src/{api-notifications → api/notifications}/services/NotificationSenderService.ts +0 -0
  341. /package/src/{api-notifications → api/notifications}/services/NotificationService.ts +0 -0
  342. /package/src/{api-parameters → api/parameters}/index.browser.ts +0 -0
  343. /package/src/{api-users → api/users}/controllers/IdentityController.ts +0 -0
  344. /package/src/{api-users → api/users}/controllers/SessionController.ts +0 -0
  345. /package/src/{api-users → api/users}/controllers/UserController.ts +0 -0
  346. /package/src/{api-users → api/users}/entities/identities.ts +0 -0
  347. /package/src/{api-users → api/users}/entities/sessions.ts +0 -0
  348. /package/src/{api-users → api/users}/entities/users.ts +0 -0
  349. /package/src/{api-users → api/users}/index.browser.ts +0 -0
  350. /package/src/{api-users → api/users}/notifications/UserNotifications.ts +0 -0
  351. /package/src/{api-users → api/users}/schemas/completePasswordResetRequestSchema.ts +0 -0
  352. /package/src/{api-users → api/users}/schemas/completeRegistrationRequestSchema.ts +0 -0
  353. /package/src/{api-users → api/users}/schemas/createUserSchema.ts +0 -0
  354. /package/src/{api-users → api/users}/schemas/identityQuerySchema.ts +0 -0
  355. /package/src/{api-users → api/users}/schemas/identityResourceSchema.ts +0 -0
  356. /package/src/{api-users → api/users}/schemas/loginSchema.ts +0 -0
  357. /package/src/{api-users → api/users}/schemas/passwordResetIntentResponseSchema.ts +0 -0
  358. /package/src/{api-users → api/users}/schemas/registerQuerySchema.ts +0 -0
  359. /package/src/{api-users → api/users}/schemas/registerRequestSchema.ts +0 -0
  360. /package/src/{api-users → api/users}/schemas/registerResponseSchema.ts +0 -0
  361. /package/src/{api-users → api/users}/schemas/registerSchema.ts +0 -0
  362. /package/src/{api-users → api/users}/schemas/registrationIntentResponseSchema.ts +0 -0
  363. /package/src/{api-users → api/users}/schemas/resetPasswordSchema.ts +0 -0
  364. /package/src/{api-users → api/users}/schemas/sessionQuerySchema.ts +0 -0
  365. /package/src/{api-users → api/users}/schemas/sessionResourceSchema.ts +0 -0
  366. /package/src/{api-users → api/users}/schemas/updateUserSchema.ts +0 -0
  367. /package/src/{api-users → api/users}/schemas/userQuerySchema.ts +0 -0
  368. /package/src/{api-users → api/users}/schemas/userRealmConfigSchema.ts +0 -0
  369. /package/src/{api-users → api/users}/schemas/userResourceSchema.ts +0 -0
  370. /package/src/{api-users → api/users}/services/CredentialService.ts +0 -0
  371. /package/src/{api-users → api/users}/services/IdentityService.ts +0 -0
  372. /package/src/{api-users → api/users}/services/SessionCrudService.ts +0 -0
  373. /package/src/{api-verifications → api/verifications}/controllers/VerificationController.ts +0 -0
  374. /package/src/{api-verifications → api/verifications}/entities/verifications.ts +0 -0
  375. /package/src/{api-verifications → api/verifications}/index.browser.ts +0 -0
  376. /package/src/{api-verifications → api/verifications}/jobs/VerificationJobs.ts +0 -0
  377. /package/src/{api-verifications → api/verifications}/parameters/VerificationParameters.ts +0 -0
  378. /package/src/{api-verifications → api/verifications}/schemas/requestVerificationCodeResponseSchema.ts +0 -0
  379. /package/src/{api-verifications → api/verifications}/schemas/validateVerificationCodeResponseSchema.ts +0 -0
  380. /package/src/{api-verifications → api/verifications}/schemas/verificationSettingsSchema.ts +0 -0
  381. /package/src/{api-verifications → api/verifications}/schemas/verificationTypeEnumSchema.ts +0 -0
  382. /package/src/{api-verifications → api/verifications}/services/VerificationService.ts +0 -0
  383. /package/src/cache/{errors → core/errors}/CacheError.ts +0 -0
  384. /package/src/cache/{index.ts → core/index.ts} +0 -0
  385. /package/src/cache/{primitives → core/primitives}/$cache.ts +0 -0
  386. /package/src/cache/{providers → core/providers}/CacheProvider.ts +0 -0
  387. /package/src/cache/{providers → core/providers}/MemoryCacheProvider.ts +0 -0
  388. /package/src/{cache-redis → cache/redis}/index.ts +0 -0
  389. /package/src/{cache-redis → cache/redis}/providers/RedisCacheProvider.ts +0 -0
  390. /package/src/lock/{index.ts → core/index.ts} +0 -0
  391. /package/src/lock/{primitives → core/primitives}/$lock.ts +0 -0
  392. /package/src/lock/{providers → core/providers}/LockProvider.ts +0 -0
  393. /package/src/lock/{providers → core/providers}/LockTopicProvider.ts +0 -0
  394. /package/src/lock/{providers → core/providers}/MemoryLockProvider.ts +0 -0
  395. /package/src/{lock-redis → lock/redis}/index.ts +0 -0
  396. /package/src/{lock-redis → lock/redis}/providers/RedisLockProvider.ts +0 -0
  397. /package/src/queue/{primitives → core/primitives}/$consumer.ts +0 -0
  398. /package/src/{queue-redis → queue/redis}/index.ts +0 -0
  399. /package/src/{server-auth → server/auth}/constants/routes.ts +0 -0
  400. /package/src/{server-auth → server/auth}/index.browser.ts +0 -0
  401. /package/src/{server-auth → server/auth}/index.shared.ts +0 -0
  402. /package/src/{server-auth → server/auth}/index.ts +0 -0
  403. /package/src/{server-auth → server/auth}/primitives/$authApple.ts +0 -0
  404. /package/src/{server-auth → server/auth}/primitives/$authCredentials.ts +0 -0
  405. /package/src/{server-auth → server/auth}/primitives/$authGithub.ts +0 -0
  406. /package/src/{server-auth → server/auth}/primitives/$authGoogle.ts +0 -0
  407. /package/src/{server-auth → server/auth}/schemas/authenticationProviderSchema.ts +0 -0
  408. /package/src/{server-auth → server/auth}/schemas/tokenResponseSchema.ts +0 -0
  409. /package/src/{server-auth → server/auth}/schemas/tokensSchema.ts +0 -0
  410. /package/src/{server-auth → server/auth}/schemas/userinfoResponseSchema.ts +0 -0
  411. /package/src/{server-cache → server/cache}/index.ts +0 -0
  412. /package/src/{server-cache → server/cache}/providers/ServerCacheProvider.ts +0 -0
  413. /package/src/{server-compress → server/compress}/index.ts +0 -0
  414. /package/src/{server-compress → server/compress}/providers/ServerCompressProvider.ts +0 -0
  415. /package/src/{server-cookies → server/cookies}/index.browser.ts +0 -0
  416. /package/src/{server-cookies → server/cookies}/primitives/$cookie.browser.ts +0 -0
  417. /package/src/{server-cookies → server/cookies}/primitives/$cookie.ts +0 -0
  418. /package/src/{server-cookies → server/cookies}/providers/ServerCookiesProvider.ts +0 -0
  419. /package/src/{server-cookies → server/cookies}/services/CookieParser.ts +0 -0
  420. /package/src/server/{constants → core/constants}/routeMethods.ts +0 -0
  421. /package/src/server/{errors → core/errors}/BadRequestError.ts +0 -0
  422. /package/src/server/{errors → core/errors}/ConflictError.ts +0 -0
  423. /package/src/server/{errors → core/errors}/ForbiddenError.ts +0 -0
  424. /package/src/server/{errors → core/errors}/HttpError.ts +0 -0
  425. /package/src/server/{errors → core/errors}/NotFoundError.ts +0 -0
  426. /package/src/server/{errors → core/errors}/UnauthorizedError.ts +0 -0
  427. /package/src/server/{errors → core/errors}/ValidationError.ts +0 -0
  428. /package/src/server/{helpers → core/helpers}/ServerReply.ts +0 -0
  429. /package/src/server/{helpers → core/helpers}/isMultipart.ts +0 -0
  430. /package/src/server/{index.browser.ts → core/index.browser.ts} +0 -0
  431. /package/src/server/{index.shared.ts → core/index.shared.ts} +0 -0
  432. /package/src/server/{interfaces → core/interfaces}/ServerRequest.ts +0 -0
  433. /package/src/server/{primitives → core/primitives}/$route.ts +0 -0
  434. /package/src/server/{providers → core/providers}/BunHttpServerProvider.ts +0 -0
  435. /package/src/server/{providers → core/providers}/NodeHttpServerProvider.ts +0 -0
  436. /package/src/server/{providers → core/providers}/ServerLoggerProvider.ts +0 -0
  437. /package/src/server/{providers → core/providers}/ServerNotReadyProvider.ts +0 -0
  438. /package/src/server/{providers → core/providers}/ServerProvider.ts +0 -0
  439. /package/src/server/{providers → core/providers}/ServerTimingProvider.ts +0 -0
  440. /package/src/server/{schemas → core/schemas}/errorSchema.ts +0 -0
  441. /package/src/server/{schemas → core/schemas}/okSchema.ts +0 -0
  442. /package/src/server/{services → core/services}/HttpClient.ts +0 -0
  443. /package/src/server/{services → core/services}/ServerRequestParser.ts +0 -0
  444. /package/src/server/{services → core/services}/UserAgentParser.ts +0 -0
  445. /package/src/{server-cors → server/cors}/index.ts +0 -0
  446. /package/src/{server-cors → server/cors}/primitives/$cors.ts +0 -0
  447. /package/src/{server-cors → server/cors}/providers/ServerCorsProvider.ts +0 -0
  448. /package/src/{server-health → server/health}/index.ts +0 -0
  449. /package/src/{server-health → server/health}/providers/ServerHealthProvider.ts +0 -0
  450. /package/src/{server-health → server/health}/schemas/healthSchema.ts +0 -0
  451. /package/src/{server-helmet → server/helmet}/index.ts +0 -0
  452. /package/src/{server-helmet → server/helmet}/providers/ServerHelmetProvider.ts +0 -0
  453. /package/src/{server-links → server/links}/index.browser.ts +0 -0
  454. /package/src/{server-links → server/links}/index.ts +0 -0
  455. /package/src/{server-links → server/links}/primitives/$client.ts +0 -0
  456. /package/src/{server-links → server/links}/primitives/$remote.ts +0 -0
  457. /package/src/{server-links → server/links}/providers/LinkProvider.ts +0 -0
  458. /package/src/{server-links → server/links}/providers/RemotePrimitiveProvider.ts +0 -0
  459. /package/src/{server-links → server/links}/providers/ServerLinksProvider.ts +0 -0
  460. /package/src/{server-links → server/links}/schemas/apiLinksResponseSchema.ts +0 -0
  461. /package/src/{server-metrics → server/metrics}/index.ts +0 -0
  462. /package/src/{server-metrics → server/metrics}/providers/ServerMetricsProvider.ts +0 -0
  463. /package/src/{server-multipart → server/multipart}/index.ts +0 -0
  464. /package/src/{server-multipart → server/multipart}/providers/ServerMultipartProvider.ts +0 -0
  465. /package/src/{server-proxy → server/proxy}/index.ts +0 -0
  466. /package/src/{server-proxy → server/proxy}/primitives/$proxy.ts +0 -0
  467. /package/src/{server-proxy → server/proxy}/providers/ServerProxyProvider.ts +0 -0
  468. /package/src/{server-rate-limit → server/rate-limit}/primitives/$rateLimit.ts +0 -0
  469. /package/src/{server-rate-limit → server/rate-limit}/providers/ServerRateLimitProvider.ts +0 -0
  470. /package/src/{server-security → server/security}/index.browser.ts +0 -0
  471. /package/src/{server-security → server/security}/index.ts +0 -0
  472. /package/src/{server-security → server/security}/primitives/$basicAuth.ts +0 -0
  473. /package/src/{server-security → server/security}/providers/ServerBasicAuthProvider.ts +0 -0
  474. /package/src/{server-security → server/security}/providers/ServerSecurityProvider.ts +0 -0
  475. /package/src/{server-static → server/static}/index.ts +0 -0
  476. /package/src/{server-static → server/static}/primitives/$serve.ts +0 -0
  477. /package/src/{server-static → server/static}/providers/ServerStaticProvider.ts +0 -0
  478. /package/src/{server-swagger → server/swagger}/index.ts +0 -0
  479. /package/src/{server-swagger → server/swagger}/primitives/$swagger.ts +0 -0
  480. /package/src/topic/{errors → core/errors}/TopicTimeoutError.ts +0 -0
  481. /package/src/topic/{index.ts → core/index.ts} +0 -0
  482. /package/src/topic/{primitives → core/primitives}/$subscriber.ts +0 -0
  483. /package/src/topic/{primitives → core/primitives}/$topic.ts +0 -0
  484. /package/src/topic/{providers → core/providers}/MemoryTopicProvider.ts +0 -0
  485. /package/src/topic/{providers → core/providers}/TopicProvider.ts +0 -0
  486. /package/src/{topic-redis → topic/redis}/index.ts +0 -0
  487. /package/src/{topic-redis → topic/redis}/providers/RedisTopicProvider.ts +0 -0
@@ -2,6 +2,7 @@ import { spawn } from "node:child_process";
2
2
  import { access, mkdir, readFile, writeFile } from "node:fs/promises";
3
3
  import { join } from "node:path";
4
4
  import { $inject, Alepha, AlephaError } from "alepha";
5
+ import type { RunnerMethod } from "alepha/command";
5
6
  import { FileSystemProvider } from "alepha/file";
6
7
  import { $logger } from "alepha/logger";
7
8
  import type { DrizzleKitProvider, RepositoryProvider } from "alepha/orm";
@@ -9,8 +10,11 @@ import { boot } from "alepha/vite";
9
10
  import { tsImport } from "tsx/esm/api";
10
11
  import { appRouterTs } from "../assets/appRouterTs.ts";
11
12
  import { biomeJson } from "../assets/biomeJson.ts";
13
+ import { dummySpecTs } from "../assets/dummySpecTs.ts";
14
+ import { editorconfig } from "../assets/editorconfig.ts";
12
15
  import { indexHtml } from "../assets/indexHtml.ts";
13
16
  import { mainBrowserTs } from "../assets/mainBrowserTs.ts";
17
+ import { mainTs } from "../assets/mainTs.ts";
14
18
  import { tsconfigJson } from "../assets/tsconfigJson.ts";
15
19
  import { viteConfigTs } from "../assets/viteConfigTs.ts";
16
20
  import { version } from "../version.ts";
@@ -32,10 +36,6 @@ export class AlephaCliUtils {
32
36
  /**
33
37
  * Execute a command using npx with inherited stdio.
34
38
  *
35
- * @param command - The command to execute (will be passed to npx)
36
- * @param env - Optional environment variables to set for the command
37
- * @returns Promise that resolves when the process exits
38
- *
39
39
  * @example
40
40
  * ```ts
41
41
  * const runner = alepha.inject(ProcessRunner);
@@ -44,40 +44,63 @@ export class AlephaCliUtils {
44
44
  */
45
45
  public async exec(
46
46
  command: string,
47
- env: Record<string, string> = {},
47
+ options: {
48
+ env?: Record<string, string>;
49
+ global?: boolean;
50
+ } = {},
48
51
  ): Promise<void> {
49
52
  const root = process.cwd();
50
53
  this.log.debug(`Executing command: ${command}`, { cwd: root });
51
54
 
55
+ const runExec = async (app: string, args: string[]) => {
56
+ const prog = spawn(app, args, {
57
+ stdio: "inherit",
58
+ cwd: root,
59
+ env: {
60
+ ...process.env,
61
+ ...options.env,
62
+ },
63
+ });
64
+
65
+ await new Promise<void>((resolve) =>
66
+ prog.on("exit", () => {
67
+ resolve();
68
+ }),
69
+ );
70
+ };
71
+
72
+ if (options.global) {
73
+ const [app, ...args] = command.split(" ");
74
+ await runExec(app, args);
75
+ return;
76
+ }
77
+
52
78
  const suffix = process.platform === "win32" ? ".cmd" : "";
53
79
  const [app, ...args] = command.split(" ");
54
- const execPath = await this.checkFileExists(
80
+
81
+ // find executable inside project node_modules
82
+ let execPath = await this.checkFileExists(
55
83
  root,
56
84
  `node_modules/.bin/${app}${suffix}`,
57
85
  true,
58
86
  );
59
87
 
88
+ // or, find executable inside alepha package node_modules (pnpm style)
89
+ if (!execPath) {
90
+ execPath = await this.checkFileExists(
91
+ root,
92
+ `node_modules/alepha/node_modules/.bin/${app}${suffix}`,
93
+ true,
94
+ );
95
+ }
96
+
60
97
  if (!execPath) {
61
98
  throw new AlephaError(
62
99
  `Could not find executable for command '${app}'. Make sure the package is installed.`,
63
100
  );
64
101
  }
65
102
 
66
- const prog = spawn(execPath, args, {
67
- stdio: "inherit",
68
- cwd: root,
69
- env: {
70
- ...process.env,
71
- ...env,
72
- // NODE_OPTIONS: "--import tsx",
73
- },
74
- });
75
-
76
- await new Promise<void>((resolve) =>
77
- prog.on("exit", () => {
78
- resolve();
79
- }),
80
- );
103
+ await runExec(execPath, args);
81
104
  }
82
105
 
83
106
  /**
@@ -139,6 +162,22 @@ export class AlephaCliUtils {
139
162
  await this.fs.rm(join(root, "pnpm-lock.yaml"), { force: true });
140
163
  }
141
164
 
165
+ public async ensurePnpm(root: string): Promise<void> {
166
+ // remove lock files from other package managers
167
+ await this.fs.rm(join(root, "package-lock.json"), { force: true });
168
+ await this.fs.rm(join(root, "yarn.lock"), { force: true });
169
+ await this.fs.rm(join(root, ".yarn"), { force: true, recursive: true });
170
+ await this.fs.rm(join(root, ".yarnrc.yml"), { force: true });
171
+ }
172
+
173
+ public async ensureNpm(root: string): Promise<void> {
174
+ // remove lock files from other package managers
175
+ await this.fs.rm(join(root, "pnpm-lock.yaml"), { force: true });
176
+ await this.fs.rm(join(root, "yarn.lock"), { force: true });
177
+ await this.fs.rm(join(root, ".yarn"), { force: true, recursive: true });
178
+ await this.fs.rm(join(root, ".yarnrc.yml"), { force: true });
179
+ }
180
+
142
181
  /**
143
182
  * Generate package.json content with Alepha dependencies.
144
183
  *
@@ -157,6 +196,14 @@ export class AlephaCliUtils {
157
196
 
158
197
  const devDependencies: Record<string, string> = {};
159
198
 
199
+ const scripts: Record<string, string> = {
200
+ dev: "alepha dev",
201
+ build: "alepha build",
202
+ lint: "alepha lint",
203
+ typecheck: "alepha typecheck",
204
+ verify: "alepha verify",
205
+ };
206
+
160
207
  if (modes.ui) {
161
208
  dependencies["@alepha/ui"] = `^${version}`;
162
209
  modes.react = true;
@@ -173,11 +220,7 @@ export class AlephaCliUtils {
173
220
  type: "module",
174
221
  dependencies,
175
222
  devDependencies,
176
- scripts: {
177
- dev: "alepha dev",
178
- build: "alepha build",
179
- verify: "alepha verify",
180
- },
223
+ scripts,
181
224
  };
182
225
  }
183
226
 
@@ -195,16 +238,14 @@ export class AlephaCliUtils {
195
238
  public async ensurePackageJson(
196
239
  root: string,
197
240
  modes: DependencyModes,
198
- ): Promise<void> {
241
+ ): Promise<object> {
199
242
  const packageJsonPath = join(root, "package.json");
200
243
  try {
201
244
  await access(packageJsonPath);
202
245
  } catch (error) {
203
- await writeFile(
204
- packageJsonPath,
205
- JSON.stringify(this.generatePackageJsonContent(modes), null, 2),
206
- );
207
- return;
246
+ const obj = this.generatePackageJsonContent(modes);
247
+ await writeFile(packageJsonPath, JSON.stringify(obj, null, 2));
248
+ return obj;
208
249
  }
209
250
 
210
251
  const content = await readFile(packageJsonPath, "utf8");
@@ -222,6 +263,8 @@ export class AlephaCliUtils {
222
263
  Object.assign(packageJson.scripts, newPackageJson.scripts);
223
264
 
224
265
  await writeFile(packageJsonPath, JSON.stringify(packageJson, null, 2));
266
+
267
+ return packageJson;
225
268
  }
226
269
 
227
270
  public async ensureConfig(
@@ -232,9 +275,10 @@ export class AlephaCliUtils {
232
275
  viteConfigTs?: boolean;
233
276
  indexHtml?: boolean;
234
277
  biomeJson?: boolean;
278
+ editorconfig?: boolean;
235
279
  },
236
- ) {
237
- const tasks: Promise<void>[] = [];
280
+ ): Promise<Array<void | object>> {
281
+ const tasks: Promise<void | object>[] = [];
238
282
 
239
283
  if (opts.packageJson) {
240
284
  tasks.push(
@@ -256,8 +300,11 @@ export class AlephaCliUtils {
256
300
  if (opts.biomeJson) {
257
301
  tasks.push(this.ensureBiomeConfig(root));
258
302
  }
303
+ if (opts.editorconfig) {
304
+ tasks.push(this.ensureEditorConfig(root));
305
+ }
259
306
 
260
- await Promise.all(tasks);
307
+ return await Promise.all(tasks);
261
308
  }
262
309
 
263
310
  /**
@@ -353,6 +400,17 @@ export class AlephaCliUtils {
353
400
  await this.ensureFileExists(root, "biome.json", biomeJson, true);
354
401
  }
355
402
 
403
+ /**
404
+ * Ensure .editorconfig exists in the project.
405
+ *
406
+ * Creates a standard .editorconfig if none exists.
407
+ *
408
+ * @param root - The root directory of the project
409
+ */
410
+ public async ensureEditorConfig(root: string): Promise<void> {
411
+ await this.ensureFileExists(root, ".editorconfig", editorconfig, true);
412
+ }
413
+
356
414
  // ===================================================================================================================
357
415
  // Drizzle ORM & Kit Utilities
358
416
  // ===================================================================================================================
@@ -585,7 +643,9 @@ ${models.map((it: string) => `export const ${it} = models["${it}"];`).join("\n")
585
643
  await this.exec(
586
644
  `drizzle-kit ${options.command} --config=${drizzleConfigJsPath}${flags}`,
587
645
  {
588
- NODE_OPTIONS: "--import tsx",
646
+ env: {
647
+ NODE_OPTIONS: "--import tsx",
648
+ },
589
649
  },
590
650
  );
591
651
  }
@@ -593,7 +653,20 @@ ${models.map((it: string) => `export const ${it} = models["${it}"];`).join("\n")
593
653
 
594
654
  public async getPackageManager(
595
655
  root: string,
596
- ): Promise<"yarn" | "pnpm" | "npm"> {
656
+ flags?: { yarn?: boolean; pnpm?: boolean; npm?: boolean; bun?: boolean },
657
+ ): Promise<"yarn" | "pnpm" | "npm" | "bun"> {
658
+ if (flags?.yarn) {
659
+ return "yarn";
660
+ }
661
+ if (flags?.pnpm) {
662
+ return "pnpm";
663
+ }
664
+ if (flags?.npm) {
665
+ return "npm";
666
+ }
667
+ if (flags?.bun) {
668
+ return "bun";
669
+ }
597
670
  if (await this.checkFileExists(root, "yarn.lock", true)) {
598
671
  return "yarn";
599
672
  }
@@ -635,6 +708,64 @@ ${models.map((it: string) => `export const ${it} = models["${it}"];`).join("\n")
635
708
  return this.fs.exists(join(root, dirName));
636
709
  }
637
710
 
711
+ /**
712
+ * Ensure src/main.ts exists with a minimal Alepha bootstrap.
713
+ *
714
+ * Creates the src directory and main.ts file if the src directory
715
+ * doesn't exist or is empty.
716
+ *
717
+ * @param root - The root directory of the project
718
+ */
719
+ public async ensureSrcMain(root: string): Promise<void> {
720
+ const srcDir = join(root, "src");
721
+ const mainPath = join(srcDir, "main.ts");
722
+
723
+ // Check if src directory exists
724
+ const srcExists = await this.fs.exists(srcDir);
725
+
726
+ if (!srcExists) {
727
+ // Create src directory and main.ts
728
+ await this.fs.mkdir(srcDir, { recursive: true });
729
+ await this.fs.writeFile(mainPath, mainTs());
730
+ return;
731
+ }
732
+
733
+ // Check if src directory is empty
734
+ const files = await this.fs.ls(srcDir);
735
+ if (files.length === 0) {
736
+ await this.fs.writeFile(mainPath, mainTs());
737
+ }
738
+ }
739
+
740
+ /**
741
+ * Ensure test directory exists with a dummy test file.
742
+ *
743
+ * Creates the test directory and a dummy.spec.ts file if the test directory
744
+ * doesn't exist or is empty.
745
+ *
746
+ * @param root - The root directory of the project
747
+ */
748
+ public async ensureTestDir(root: string): Promise<void> {
749
+ const testDir = join(root, "test");
750
+ const dummyPath = join(testDir, "dummy.spec.ts");
751
+
752
+ // Check if test directory exists
753
+ const testExists = await this.fs.exists(testDir);
754
+
755
+ if (!testExists) {
756
+ // Create test directory and dummy.spec.ts
757
+ await this.fs.mkdir(testDir, { recursive: true });
758
+ await this.fs.writeFile(dummyPath, dummySpecTs());
759
+ return;
760
+ }
761
+
762
+ // Check if test directory is empty
763
+ const files = await this.fs.ls(testDir);
764
+ if (files.length === 0) {
765
+ await this.fs.writeFile(dummyPath, dummySpecTs());
766
+ }
767
+ }
768
+
638
769
  async readPackageJson(root: string): Promise<Record<string, any>> {
639
770
  const packageJson = await this.fs
640
771
  .createFile({
@@ -643,9 +774,84 @@ ${models.map((it: string) => `export const ${it} = models["${it}"];`).join("\n")
643
774
  .text();
644
775
  return JSON.parse(packageJson);
645
776
  }
777
+
778
+ /**
779
+ * Check if a dependency is installed in the project.
780
+ *
781
+ * @param root - The root directory of the project
782
+ * @param packageName - The name of the package to check
783
+ * @returns True if the package is in dependencies or devDependencies
784
+ */
785
+ async hasDependency(root: string, packageName: string): Promise<boolean> {
786
+ try {
787
+ const pkg = await this.readPackageJson(root);
788
+ return !!(
789
+ pkg.dependencies?.[packageName] || pkg.devDependencies?.[packageName]
790
+ );
791
+ } catch {
792
+ return false;
793
+ }
794
+ }
795
+
796
+ /**
797
+ * Check if Expo is present in the project.
798
+ *
799
+ * @param root - The root directory of the project
800
+ * @returns True if expo is in dependencies or devDependencies
801
+ */
802
+ async hasExpo(root: string): Promise<boolean> {
803
+ return this.hasDependency(root, "expo");
804
+ }
805
+
806
+ /**
807
+ * Install a dependency if it's missing from the project.
808
+ *
809
+ * Automatically detects the package manager (yarn, pnpm, npm) and installs
810
+ * the package as a dev dependency if not already present.
811
+ */
812
+ async ensureDependency(
813
+ root: string,
814
+ packageName: string,
815
+ options: { dev?: boolean; run?: RunnerMethod } = {},
816
+ ): Promise<void> {
817
+ const { dev = true } = options;
818
+
819
+ if (await this.hasDependency(root, packageName)) {
820
+ this.log.debug(`Dependency '${packageName}' is already installed`);
821
+ return;
822
+ }
823
+
824
+ const pm = await this.getPackageManager(root);
825
+ let cmd: string;
826
+
827
+ switch (pm) {
828
+ case "yarn":
829
+ cmd = `yarn add ${dev ? "-D" : ""} ${packageName}`;
830
+ break;
831
+ case "pnpm":
832
+ cmd = `pnpm add ${dev ? "-D" : ""} ${packageName}`;
833
+ break;
834
+ default:
835
+ cmd = `npm install ${dev ? "--save-dev" : ""} ${packageName}`;
836
+ }
837
+
838
+ cmd = cmd.replace(/\s+/g, " ").trim();
839
+
840
+ if (options.run) {
841
+ // if it's during a Runner flow, just use the runner's run method
842
+ await options.run(cmd, {
843
+ alias: `installing ${packageName}`,
844
+ });
845
+ } else {
846
+ // else, run directly with our util exec method
847
+ this.log.debug(`Installing ${packageName}`);
848
+ await this.exec(cmd, { global: true });
849
+ }
850
+ }
646
851
  }
647
852
 
648
853
  export interface DependencyModes {
649
854
  react?: boolean;
650
855
  ui?: boolean;
856
+ expo?: boolean;
651
857
  }
@@ -40,7 +40,6 @@ export interface AskOptions<T extends TSchema = TString> {
40
40
  }
41
41
 
42
42
  export interface AskMethod {
43
- // biome-ignore lint/style/useShorthandFunctionType: .
44
43
  <T extends TSchema = TString>(
45
44
  question: string,
46
45
  options?: AskOptions<T>,
@@ -82,6 +82,61 @@ export interface CommandPrimitiveOptions<T extends TObject, A extends TSchema> {
82
82
  * Equivalent to setting name to an empty string "".
83
83
  */
84
84
  root?: boolean;
85
+
86
+ /**
87
+ * Run this command's handler BEFORE the specified target command.
88
+ *
89
+ * Pre-hooks are not listed in help and cannot be called directly.
90
+ * They receive the same parsed flags and args as the target command.
91
+ *
92
+ * @example
93
+ * ```ts
94
+ * class BuildCommands {
95
+ * prebuild = $command({
96
+ * pre: "build",
97
+ * handler: async ({ run }) => {
98
+ * await run("cleaning dist folder...", () => fs.rm("dist"));
99
+ * }
100
+ * });
101
+ *
102
+ * build = $command({
103
+ * name: "build",
104
+ * handler: async () => { ... }
105
+ * });
106
+ * }
107
+ * ```
108
+ */
109
+ pre?: string;
110
+
111
+ /**
112
+ * Run this command's handler AFTER the specified target command.
113
+ *
114
+ * Post-hooks are not listed in help and cannot be called directly.
115
+ * They receive the same parsed flags and args as the target command.
116
+ *
117
+ * @example
118
+ * ```ts
119
+ * class BuildCommands {
120
+ * build = $command({
121
+ * name: "build",
122
+ * handler: async () => { ... }
123
+ * });
124
+ *
125
+ * postbuild = $command({
126
+ * post: "build",
127
+ * handler: async ({ run }) => {
128
+ * await run("generating checksums...", generateChecksums);
129
+ * }
130
+ * });
131
+ * }
132
+ * ```
133
+ */
134
+ post?: string;
135
+
136
+ /**
137
+ * If true, this command will be hidden from the help output.
138
+ */
139
+ hide?: boolean;
85
140
  }
86
141
 
87
142
  // ---------------------------------------------------------------------------------------------------------------------
@@ -93,10 +148,22 @@ export class CommandPrimitive<
93
148
  public readonly flags = this.options.flags ?? t.object({});
94
149
  public readonly aliases = this.options.aliases ?? [];
95
150
 
151
+ protected onInit() {
152
+ if (this.options.pre || this.options.post) {
153
+ this.options.hide ??= true;
154
+ }
155
+ }
156
+
96
157
  public get name(): string {
97
158
  if (this.options.root) {
98
159
  return "";
99
160
  }
161
+ if (this.options.pre) {
162
+ return `pre${this.options.pre}`;
163
+ }
164
+ if (this.options.post) {
165
+ return `post${this.options.post}`;
166
+ }
100
167
  return this.options.name ?? `${this.config.propertyKey}`;
101
168
  }
102
169
  }
@@ -169,8 +169,23 @@ export class CliProvider {
169
169
  root: process.cwd(),
170
170
  };
171
171
 
172
+ // Execute pre-hooks
173
+ const preHooks = this.findPreHooks(command.name);
174
+ for (const hook of preHooks) {
175
+ this.log.debug(`Executing pre-hook for '${command.name}'...`);
176
+ await hook.options.handler(args as CommandHandlerArgs<TObject>);
177
+ }
178
+
179
+ // Execute main command
172
180
  await command.options.handler(args as CommandHandlerArgs<TObject>);
173
181
 
182
+ // Execute post-hooks
183
+ const postHooks = this.findPostHooks(command.name);
184
+ for (const hook of postHooks) {
185
+ this.log.debug(`Executing post-hook for '${command.name}'...`);
186
+ await hook.options.handler(args as CommandHandlerArgs<TObject>);
187
+ }
188
+
174
189
  if (command.options.summary !== false) {
175
190
  runner.summary();
176
191
  }
@@ -185,11 +200,25 @@ export class CliProvider {
185
200
  }
186
201
 
187
202
  protected findCommand(name: string): CommandPrimitive<TObject> | undefined {
188
- return this.commands.find(
203
+ return this.commands.findLast(
189
204
  (command) => command.name === name || command.aliases.includes(name),
190
205
  );
191
206
  }
192
207
 
208
+ /**
209
+ * Find all pre-hooks for a command.
210
+ */
211
+ protected findPreHooks(commandName: string): CommandPrimitive<TObject>[] {
212
+ return this.commands.filter((cmd) => cmd.name === `pre${commandName}`);
213
+ }
214
+
215
+ /**
216
+ * Find all post-hooks for a command.
217
+ */
218
+ protected findPostHooks(commandName: string): CommandPrimitive<TObject>[] {
219
+ return this.commands.filter((cmd) => cmd.name === `post${commandName}`);
220
+ }
221
+
193
222
  /**
194
223
  * Get all global flags including those from the root command (name === "")
195
224
  */
@@ -464,8 +493,8 @@ export class CliProvider {
464
493
  const maxCmdLength = this.getMaxCmdLength(this.commands);
465
494
 
466
495
  for (const command of this.commands) {
467
- // skip root command in list
468
- if (command.name === "") {
496
+ // skip root command and hooks in list
497
+ if (command.name === "" || command.options.hide) {
469
498
  continue;
470
499
  }
471
500
 
@@ -495,11 +524,13 @@ export class CliProvider {
495
524
 
496
525
  private getMaxCmdLength(commands: CommandPrimitive[]): number {
497
526
  return Math.max(
498
- ...commands.map((c) => {
499
- const cmdStr = [c.name, ...c.aliases].join(", ");
500
- const argsUsage = this.generateArgsUsage(c.options.args);
501
- return `${cmdStr}${argsUsage}`.length;
502
- }),
527
+ ...commands
528
+ .filter((c) => !c.options.hide && c.name !== "")
529
+ .map((c) => {
530
+ const cmdStr = [c.name, ...c.aliases].join(", ");
531
+ const argsUsage = this.generateArgsUsage(c.options.args);
532
+ return `${cmdStr}${argsUsage}`.length;
533
+ }),
503
534
  );
504
535
  }
505
536