alepha 0.14.2 → 0.14.3

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 (361) hide show
  1. package/dist/api/audits/index.browser.js +5 -5
  2. package/dist/api/audits/index.browser.js.map +1 -1
  3. package/dist/api/audits/index.d.ts +784 -784
  4. package/dist/api/audits/index.d.ts.map +1 -1
  5. package/dist/api/audits/index.js +13 -13
  6. package/dist/api/audits/index.js.map +1 -1
  7. package/dist/api/files/index.browser.js +5 -5
  8. package/dist/api/files/index.browser.js.map +1 -1
  9. package/dist/api/files/index.d.ts +57 -57
  10. package/dist/api/files/index.d.ts.map +1 -1
  11. package/dist/api/files/index.js +71 -71
  12. package/dist/api/files/index.js.map +1 -1
  13. package/dist/api/jobs/index.browser.js +5 -5
  14. package/dist/api/jobs/index.browser.js.map +1 -1
  15. package/dist/api/jobs/index.d.ts +165 -165
  16. package/dist/api/jobs/index.d.ts.map +1 -1
  17. package/dist/api/jobs/index.js +10 -10
  18. package/dist/api/jobs/index.js.map +1 -1
  19. package/dist/api/notifications/index.browser.js +10 -10
  20. package/dist/api/notifications/index.browser.js.map +1 -1
  21. package/dist/api/notifications/index.d.ts +583 -171
  22. package/dist/api/notifications/index.d.ts.map +1 -1
  23. package/dist/api/notifications/index.js +12 -12
  24. package/dist/api/notifications/index.js.map +1 -1
  25. package/dist/api/parameters/index.browser.js +163 -10
  26. package/dist/api/parameters/index.browser.js.map +1 -1
  27. package/dist/api/parameters/index.d.ts +281 -276
  28. package/dist/api/parameters/index.d.ts.map +1 -1
  29. package/dist/api/parameters/index.js +196 -91
  30. package/dist/api/parameters/index.js.map +1 -1
  31. package/dist/api/users/index.browser.js +19 -19
  32. package/dist/api/users/index.browser.js.map +1 -1
  33. package/dist/api/users/index.d.ts +1137 -1123
  34. package/dist/api/users/index.d.ts.map +1 -1
  35. package/dist/api/users/index.js +827 -596
  36. package/dist/api/users/index.js.map +1 -1
  37. package/dist/api/verifications/index.browser.js +6 -6
  38. package/dist/api/verifications/index.browser.js.map +1 -1
  39. package/dist/api/verifications/index.d.ts +13 -13
  40. package/dist/api/verifications/index.d.ts.map +1 -1
  41. package/dist/api/verifications/index.js +6 -6
  42. package/dist/api/verifications/index.js.map +1 -1
  43. package/dist/bin/index.d.ts +1 -2
  44. package/dist/bin/index.js +0 -1
  45. package/dist/bin/index.js.map +1 -1
  46. package/dist/cli/index.d.ts +137 -112
  47. package/dist/cli/index.d.ts.map +1 -1
  48. package/dist/cli/index.js +371 -259
  49. package/dist/cli/index.js.map +1 -1
  50. package/dist/command/index.d.ts +45 -5
  51. package/dist/command/index.d.ts.map +1 -1
  52. package/dist/command/index.js +97 -17
  53. package/dist/command/index.js.map +1 -1
  54. package/dist/core/index.browser.js +14 -18
  55. package/dist/core/index.browser.js.map +1 -1
  56. package/dist/core/index.d.ts +29 -0
  57. package/dist/core/index.d.ts.map +1 -1
  58. package/dist/core/index.js +14 -18
  59. package/dist/core/index.js.map +1 -1
  60. package/dist/core/index.native.js +14 -18
  61. package/dist/core/index.native.js.map +1 -1
  62. package/dist/fake/index.js +195 -168
  63. package/dist/fake/index.js.map +1 -1
  64. package/dist/file/index.d.ts +8 -0
  65. package/dist/file/index.d.ts.map +1 -1
  66. package/dist/file/index.js +3 -0
  67. package/dist/file/index.js.map +1 -1
  68. package/dist/mcp/index.d.ts.map +1 -1
  69. package/dist/orm/index.d.ts +32 -32
  70. package/dist/orm/index.d.ts.map +1 -1
  71. package/dist/orm/index.js +12 -12
  72. package/dist/orm/index.js.map +1 -1
  73. package/dist/security/index.d.ts +1 -1
  74. package/dist/security/index.d.ts.map +1 -1
  75. package/dist/security/index.js +1 -1
  76. package/dist/security/index.js.map +1 -1
  77. package/dist/server/auth/index.d.ts +171 -155
  78. package/dist/server/auth/index.d.ts.map +1 -1
  79. package/dist/server/auth/index.js +0 -1
  80. package/dist/server/auth/index.js.map +1 -1
  81. package/dist/server/compress/index.d.ts.map +1 -1
  82. package/dist/server/compress/index.js +2 -0
  83. package/dist/server/compress/index.js.map +1 -1
  84. package/dist/server/core/index.d.ts.map +1 -1
  85. package/dist/server/core/index.js +1 -1
  86. package/dist/server/core/index.js.map +1 -1
  87. package/dist/server/links/index.browser.js +22 -6
  88. package/dist/server/links/index.browser.js.map +1 -1
  89. package/dist/server/links/index.d.ts +46 -44
  90. package/dist/server/links/index.d.ts.map +1 -1
  91. package/dist/server/links/index.js +24 -41
  92. package/dist/server/links/index.js.map +1 -1
  93. package/dist/server/security/index.d.ts +9 -9
  94. package/dist/server/swagger/index.d.ts +2 -1
  95. package/dist/server/swagger/index.d.ts.map +1 -1
  96. package/dist/server/swagger/index.js +8 -3
  97. package/dist/server/swagger/index.js.map +1 -1
  98. package/dist/vite/index.d.ts.map +1 -1
  99. package/dist/vite/index.js +12 -4
  100. package/dist/vite/index.js.map +1 -1
  101. package/dist/websocket/index.d.ts +7 -7
  102. package/package.json +7 -7
  103. package/src/api/audits/controllers/{AuditController.ts → AdminAuditController.ts} +5 -6
  104. package/src/api/audits/entities/audits.ts +5 -5
  105. package/src/api/audits/index.browser.ts +1 -1
  106. package/src/api/audits/index.ts +3 -3
  107. package/src/api/audits/primitives/$audit.spec.ts +276 -0
  108. package/src/api/audits/services/AuditService.spec.ts +495 -0
  109. package/src/api/files/__tests__/$bucket.spec.ts +91 -0
  110. package/src/api/files/controllers/AdminFileStatsController.spec.ts +166 -0
  111. package/src/api/files/controllers/{StorageStatsController.ts → AdminFileStatsController.ts} +2 -2
  112. package/src/api/files/controllers/FileController.spec.ts +558 -0
  113. package/src/api/files/controllers/FileController.ts +4 -5
  114. package/src/api/files/entities/files.ts +5 -5
  115. package/src/api/files/index.browser.ts +1 -1
  116. package/src/api/files/index.ts +4 -4
  117. package/src/api/files/jobs/FileJobs.spec.ts +52 -0
  118. package/src/api/files/services/FileService.spec.ts +109 -0
  119. package/src/api/jobs/__tests__/JobController.spec.ts +343 -0
  120. package/src/api/jobs/controllers/{JobController.ts → AdminJobController.ts} +2 -2
  121. package/src/api/jobs/entities/jobExecutions.ts +5 -5
  122. package/src/api/jobs/index.ts +3 -3
  123. package/src/api/jobs/primitives/$job.spec.ts +476 -0
  124. package/src/api/notifications/controllers/{NotificationController.ts → AdminNotificationController.ts} +4 -5
  125. package/src/api/notifications/entities/notifications.ts +5 -5
  126. package/src/api/notifications/index.browser.ts +1 -1
  127. package/src/api/notifications/index.ts +4 -4
  128. package/src/api/parameters/controllers/{ConfigController.ts → AdminConfigController.ts} +46 -107
  129. package/src/api/parameters/entities/parameters.ts +7 -17
  130. package/src/api/parameters/index.ts +3 -3
  131. package/src/api/parameters/primitives/$config.spec.ts +356 -0
  132. package/src/api/parameters/schemas/activateConfigBodySchema.ts +12 -0
  133. package/src/api/parameters/schemas/checkScheduledResponseSchema.ts +8 -0
  134. package/src/api/parameters/schemas/configCurrentResponseSchema.ts +13 -0
  135. package/src/api/parameters/schemas/configHistoryResponseSchema.ts +9 -0
  136. package/src/api/parameters/schemas/configNameParamSchema.ts +10 -0
  137. package/src/api/parameters/schemas/configNamesResponseSchema.ts +8 -0
  138. package/src/api/parameters/schemas/configTreeNodeSchema.ts +13 -0
  139. package/src/api/parameters/schemas/configVersionParamSchema.ts +9 -0
  140. package/src/api/parameters/schemas/configVersionResponseSchema.ts +9 -0
  141. package/src/api/parameters/schemas/configsByStatusResponseSchema.ts +9 -0
  142. package/src/api/parameters/schemas/createConfigVersionBodySchema.ts +24 -0
  143. package/src/api/parameters/schemas/index.ts +15 -0
  144. package/src/api/parameters/schemas/parameterResponseSchema.ts +26 -0
  145. package/src/api/parameters/schemas/parameterStatusSchema.ts +13 -0
  146. package/src/api/parameters/schemas/rollbackConfigBodySchema.ts +15 -0
  147. package/src/api/parameters/schemas/statusParamSchema.ts +9 -0
  148. package/src/api/users/__tests__/EmailVerification.spec.ts +369 -0
  149. package/src/api/users/__tests__/PasswordReset.spec.ts +550 -0
  150. package/src/api/users/controllers/AdminIdentityController.spec.ts +365 -0
  151. package/src/api/users/controllers/{IdentityController.ts → AdminIdentityController.ts} +3 -4
  152. package/src/api/users/controllers/AdminSessionController.spec.ts +274 -0
  153. package/src/api/users/controllers/{SessionController.ts → AdminSessionController.ts} +3 -4
  154. package/src/api/users/controllers/AdminUserController.spec.ts +372 -0
  155. package/src/api/users/controllers/AdminUserController.ts +116 -0
  156. package/src/api/users/controllers/UserController.ts +4 -107
  157. package/src/api/users/controllers/UserRealmController.ts +3 -0
  158. package/src/api/users/entities/identities.ts +6 -6
  159. package/src/api/users/entities/sessions.ts +6 -6
  160. package/src/api/users/entities/users.ts +9 -9
  161. package/src/api/users/index.ts +9 -6
  162. package/src/api/users/primitives/$userRealm.ts +13 -8
  163. package/src/api/users/services/CredentialService.spec.ts +509 -0
  164. package/src/api/users/services/CredentialService.ts +46 -0
  165. package/src/api/users/services/IdentityService.ts +15 -0
  166. package/src/api/users/services/RegistrationService.spec.ts +630 -0
  167. package/src/api/users/services/RegistrationService.ts +18 -0
  168. package/src/api/users/services/SessionService.spec.ts +301 -0
  169. package/src/api/users/services/SessionService.ts +110 -1
  170. package/src/api/users/services/UserService.ts +67 -2
  171. package/src/api/verifications/__tests__/CodeVerification.spec.ts +318 -0
  172. package/src/api/verifications/__tests__/LinkVerification.spec.ts +279 -0
  173. package/src/api/verifications/entities/verifications.ts +6 -6
  174. package/src/api/verifications/jobs/VerificationJobs.spec.ts +50 -0
  175. package/src/batch/__tests__/startup-buffering.spec.ts +458 -0
  176. package/src/batch/primitives/$batch.spec.ts +766 -0
  177. package/src/batch/providers/BatchProvider.spec.ts +786 -0
  178. package/src/bin/index.ts +0 -1
  179. package/src/bucket/__tests__/shared.ts +194 -0
  180. package/src/bucket/primitives/$bucket.spec.ts +104 -0
  181. package/src/bucket/providers/FileStorageProvider.spec.ts +13 -0
  182. package/src/bucket/providers/LocalFileStorageProvider.spec.ts +77 -0
  183. package/src/bucket/providers/MemoryFileStorageProvider.spec.ts +82 -0
  184. package/src/cache/core/__tests__/shared.ts +377 -0
  185. package/src/cache/core/primitives/$cache.spec.ts +111 -0
  186. package/src/cache/redis/__tests__/cache-redis.spec.ts +70 -0
  187. package/src/cli/apps/AlephaCli.ts +25 -4
  188. package/src/cli/commands/dev.ts +19 -7
  189. package/src/cli/commands/gen/changelog.spec.ts +315 -0
  190. package/src/cli/commands/{changelog.ts → gen/changelog.ts} +9 -9
  191. package/src/cli/commands/gen/openapi.ts +71 -0
  192. package/src/cli/commands/gen.ts +18 -0
  193. package/src/cli/commands/init.ts +2 -0
  194. package/src/cli/commands/root.ts +12 -3
  195. package/src/cli/commands/typecheck.ts +5 -0
  196. package/src/cli/index.ts +2 -1
  197. package/src/cli/services/AlephaCliUtils.ts +71 -32
  198. package/src/cli/services/GitMessageParser.ts +1 -1
  199. package/src/command/helpers/Asker.spec.ts +127 -0
  200. package/src/command/helpers/Runner.spec.ts +126 -0
  201. package/src/command/primitives/$command.spec.ts +1588 -0
  202. package/src/command/providers/CliProvider.ts +74 -24
  203. package/src/core/Alepha.ts +45 -0
  204. package/src/core/__tests__/Alepha-emit.spec.ts +22 -0
  205. package/src/core/__tests__/Alepha-graph.spec.ts +93 -0
  206. package/src/core/__tests__/Alepha-has.spec.ts +41 -0
  207. package/src/core/__tests__/Alepha-inject.spec.ts +93 -0
  208. package/src/core/__tests__/Alepha-register.spec.ts +81 -0
  209. package/src/core/__tests__/Alepha-start.spec.ts +176 -0
  210. package/src/core/__tests__/Alepha-with.spec.ts +14 -0
  211. package/src/core/__tests__/TypeBox-usecases.spec.ts +35 -0
  212. package/src/core/__tests__/TypeBoxLocale.spec.ts +15 -0
  213. package/src/core/__tests__/descriptor.spec.ts +34 -0
  214. package/src/core/__tests__/fixtures/A.ts +5 -0
  215. package/src/core/__tests__/pagination.spec.ts +77 -0
  216. package/src/core/helpers/jsonSchemaToTypeBox.ts +2 -2
  217. package/src/core/primitives/$atom.spec.ts +43 -0
  218. package/src/core/primitives/$hook.spec.ts +130 -0
  219. package/src/core/primitives/$inject.spec.ts +175 -0
  220. package/src/core/primitives/$module.spec.ts +115 -0
  221. package/src/core/providers/CodecManager.spec.ts +740 -0
  222. package/src/core/providers/EventManager.spec.ts +762 -0
  223. package/src/core/providers/EventManager.ts +4 -0
  224. package/src/core/providers/StateManager.spec.ts +365 -0
  225. package/src/core/providers/TypeProvider.spec.ts +1607 -0
  226. package/src/core/providers/TypeProvider.ts +20 -26
  227. package/src/datetime/primitives/$interval.spec.ts +103 -0
  228. package/src/datetime/providers/DateTimeProvider.spec.ts +86 -0
  229. package/src/email/primitives/$email.spec.ts +175 -0
  230. package/src/email/providers/LocalEmailProvider.spec.ts +341 -0
  231. package/src/fake/__tests__/keyName.example.ts +40 -0
  232. package/src/fake/__tests__/keyName.spec.ts +152 -0
  233. package/src/fake/__tests__/module.example.ts +32 -0
  234. package/src/fake/providers/FakeProvider.spec.ts +438 -0
  235. package/src/file/providers/FileSystemProvider.ts +8 -0
  236. package/src/file/providers/NodeFileSystemProvider.spec.ts +418 -0
  237. package/src/file/providers/NodeFileSystemProvider.ts +5 -0
  238. package/src/file/services/FileDetector.spec.ts +591 -0
  239. package/src/lock/core/__tests__/shared.ts +190 -0
  240. package/src/lock/core/providers/MemoryLockProvider.spec.ts +25 -0
  241. package/src/lock/redis/providers/RedisLockProvider.spec.ts +25 -0
  242. package/src/logger/__tests__/SimpleFormatterProvider.spec.ts +109 -0
  243. package/src/logger/primitives/$logger.spec.ts +108 -0
  244. package/src/logger/services/Logger.spec.ts +295 -0
  245. package/src/mcp/__tests__/errors.spec.ts +175 -0
  246. package/src/mcp/__tests__/integration.spec.ts +450 -0
  247. package/src/mcp/helpers/jsonrpc.spec.ts +380 -0
  248. package/src/mcp/primitives/$prompt.spec.ts +468 -0
  249. package/src/mcp/primitives/$resource.spec.ts +390 -0
  250. package/src/mcp/primitives/$tool.spec.ts +406 -0
  251. package/src/mcp/providers/McpServerProvider.spec.ts +797 -0
  252. package/src/orm/__tests__/$repository-crud.spec.ts +276 -0
  253. package/src/orm/__tests__/$repository-hooks.spec.ts +325 -0
  254. package/src/orm/__tests__/$repository-orderBy.spec.ts +128 -0
  255. package/src/orm/__tests__/$repository-pagination-sort.spec.ts +149 -0
  256. package/src/orm/__tests__/$repository-save.spec.ts +37 -0
  257. package/src/orm/__tests__/ModelBuilder-integration.spec.ts +490 -0
  258. package/src/orm/__tests__/ModelBuilder-types.spec.ts +186 -0
  259. package/src/orm/__tests__/PostgresProvider.spec.ts +46 -0
  260. package/src/orm/__tests__/delete-returning.spec.ts +256 -0
  261. package/src/orm/__tests__/deletedAt.spec.ts +80 -0
  262. package/src/orm/__tests__/enums.spec.ts +315 -0
  263. package/src/orm/__tests__/execute.spec.ts +72 -0
  264. package/src/orm/__tests__/fixtures/bigEntitySchema.ts +65 -0
  265. package/src/orm/__tests__/fixtures/userEntitySchema.ts +27 -0
  266. package/src/orm/__tests__/joins.spec.ts +1114 -0
  267. package/src/orm/__tests__/page.spec.ts +287 -0
  268. package/src/orm/__tests__/primaryKey.spec.ts +87 -0
  269. package/src/orm/__tests__/query-date-encoding.spec.ts +402 -0
  270. package/src/orm/__tests__/ref-auto-onDelete.spec.ts +156 -0
  271. package/src/orm/__tests__/references.spec.ts +102 -0
  272. package/src/orm/__tests__/security.spec.ts +710 -0
  273. package/src/orm/__tests__/sqlite.spec.ts +111 -0
  274. package/src/orm/__tests__/string-operators.spec.ts +429 -0
  275. package/src/orm/__tests__/timestamps.spec.ts +388 -0
  276. package/src/orm/__tests__/validation.spec.ts +183 -0
  277. package/src/orm/__tests__/version.spec.ts +64 -0
  278. package/src/orm/helpers/parseQueryString.spec.ts +196 -0
  279. package/src/orm/primitives/$repository.spec.ts +137 -0
  280. package/src/orm/primitives/$sequence.spec.ts +29 -0
  281. package/src/orm/primitives/$transaction.spec.ts +82 -0
  282. package/src/orm/providers/drivers/BunPostgresProvider.ts +3 -3
  283. package/src/orm/providers/drivers/BunSqliteProvider.ts +1 -1
  284. package/src/orm/providers/drivers/CloudflareD1Provider.ts +1 -1
  285. package/src/orm/providers/drivers/DatabaseProvider.ts +1 -1
  286. package/src/orm/providers/drivers/NodePostgresProvider.ts +3 -3
  287. package/src/orm/providers/drivers/NodeSqliteProvider.ts +1 -1
  288. package/src/orm/providers/drivers/PglitePostgresProvider.ts +2 -2
  289. package/src/orm/services/ModelBuilder.spec.ts +575 -0
  290. package/src/orm/services/Repository.spec.ts +137 -0
  291. package/src/queue/core/__tests__/shared.ts +143 -0
  292. package/src/queue/core/providers/MemoryQueueProvider.spec.ts +23 -0
  293. package/src/queue/core/providers/WorkerProvider.spec.ts +378 -0
  294. package/src/queue/redis/providers/RedisQueueProvider.spec.ts +23 -0
  295. package/src/redis/__tests__/redis.spec.ts +58 -0
  296. package/src/retry/primitives/$retry.spec.ts +234 -0
  297. package/src/retry/providers/RetryProvider.spec.ts +438 -0
  298. package/src/router/__tests__/match.spec.ts +252 -0
  299. package/src/router/providers/RouterProvider.spec.ts +197 -0
  300. package/src/scheduler/__tests__/$scheduler-cron.spec.ts +25 -0
  301. package/src/scheduler/__tests__/$scheduler-interval.spec.ts +25 -0
  302. package/src/scheduler/__tests__/shared.ts +77 -0
  303. package/src/security/__tests__/bug-1-wildcard-after-start.spec.ts +229 -0
  304. package/src/security/__tests__/bug-2-password-validation.spec.ts +245 -0
  305. package/src/security/__tests__/bug-3-regex-vulnerability.spec.ts +407 -0
  306. package/src/security/__tests__/bug-4-oauth2-validation.spec.ts +439 -0
  307. package/src/security/__tests__/multi-layer-permissions.spec.ts +522 -0
  308. package/src/security/primitives/$permission.spec.ts +30 -0
  309. package/src/security/primitives/$permission.ts +2 -2
  310. package/src/security/primitives/$realm.spec.ts +101 -0
  311. package/src/security/primitives/$role.spec.ts +52 -0
  312. package/src/security/primitives/$serviceAccount.spec.ts +61 -0
  313. package/src/security/providers/SecurityProvider.spec.ts +350 -0
  314. package/src/server/auth/providers/ServerAuthProvider.ts +0 -2
  315. package/src/server/cache/providers/ServerCacheProvider.spec.ts +942 -0
  316. package/src/server/compress/providers/ServerCompressProvider.spec.ts +31 -0
  317. package/src/server/compress/providers/ServerCompressProvider.ts +2 -0
  318. package/src/server/cookies/providers/ServerCookiesProvider.spec.ts +253 -0
  319. package/src/server/core/__tests__/ServerRouterProvider-getRoutes.spec.ts +334 -0
  320. package/src/server/core/__tests__/ServerRouterProvider-requestId.spec.ts +129 -0
  321. package/src/server/core/primitives/$action.spec.ts +191 -0
  322. package/src/server/core/primitives/$route.spec.ts +65 -0
  323. package/src/server/core/providers/ServerBodyParserProvider.spec.ts +93 -0
  324. package/src/server/core/providers/ServerLoggerProvider.spec.ts +100 -0
  325. package/src/server/core/providers/ServerProvider.ts +3 -1
  326. package/src/server/core/services/HttpClient.spec.ts +123 -0
  327. package/src/server/core/services/UserAgentParser.spec.ts +111 -0
  328. package/src/server/cors/providers/ServerCorsProvider.spec.ts +481 -0
  329. package/src/server/health/providers/ServerHealthProvider.spec.ts +22 -0
  330. package/src/server/helmet/providers/ServerHelmetProvider.spec.ts +105 -0
  331. package/src/server/links/__tests__/$action.spec.ts +238 -0
  332. package/src/server/links/__tests__/fixtures/CrudApp.ts +122 -0
  333. package/src/server/links/__tests__/requestId.spec.ts +120 -0
  334. package/src/server/links/primitives/$remote.spec.ts +228 -0
  335. package/src/server/links/providers/LinkProvider.spec.ts +54 -0
  336. package/src/server/links/providers/LinkProvider.ts +49 -3
  337. package/src/server/links/providers/ServerLinksProvider.ts +1 -53
  338. package/src/server/links/schemas/apiLinksResponseSchema.ts +7 -0
  339. package/src/server/metrics/providers/ServerMetricsProvider.spec.ts +25 -0
  340. package/src/server/multipart/providers/ServerMultipartProvider.spec.ts +528 -0
  341. package/src/server/proxy/primitives/$proxy.spec.ts +87 -0
  342. package/src/server/rate-limit/__tests__/ActionRateLimit.spec.ts +211 -0
  343. package/src/server/rate-limit/providers/ServerRateLimitProvider.spec.ts +344 -0
  344. package/src/server/security/__tests__/BasicAuth.spec.ts +684 -0
  345. package/src/server/security/__tests__/ServerSecurityProvider-realm.spec.ts +388 -0
  346. package/src/server/security/providers/ServerSecurityProvider.spec.ts +123 -0
  347. package/src/server/static/primitives/$serve.spec.ts +193 -0
  348. package/src/server/swagger/__tests__/ui.spec.ts +52 -0
  349. package/src/server/swagger/primitives/$swagger.spec.ts +193 -0
  350. package/src/server/swagger/providers/ServerSwaggerProvider.ts +18 -8
  351. package/src/sms/primitives/$sms.spec.ts +165 -0
  352. package/src/sms/providers/LocalSmsProvider.spec.ts +224 -0
  353. package/src/sms/providers/MemorySmsProvider.spec.ts +193 -0
  354. package/src/thread/primitives/$thread.spec.ts +186 -0
  355. package/src/topic/core/__tests__/shared.ts +144 -0
  356. package/src/topic/core/providers/MemoryTopicProvider.spec.ts +23 -0
  357. package/src/topic/redis/providers/RedisTopicProvider.spec.ts +23 -0
  358. package/src/vite/plugins/viteAlephaDev.ts +16 -4
  359. package/src/vite/tasks/runAlepha.ts +7 -1
  360. package/src/websocket/__tests__/$websocket-new.spec.ts +195 -0
  361. package/src/websocket/primitives/$channel.spec.ts +30 -0
package/dist/cli/index.js CHANGED
@@ -1,15 +1,15 @@
1
1
  import { createRequire } from "node:module";
2
- import { join } from "node:path";
3
2
  import { $atom, $hook, $inject, $module, $use, Alepha, AlephaError, OPTIONS, t } from "alepha";
4
3
  import { FileSystemProvider } from "alepha/file";
5
4
  import { access, mkdir, readFile, readdir, unlink, writeFile } from "node:fs/promises";
5
+ import { join } from "node:path";
6
6
  import { $command, CliProvider, EnvUtils } from "alepha/command";
7
- import { $logger } from "alepha/logger";
7
+ import { $logger, ConsoleColorProvider } from "alepha/logger";
8
8
  import { boot, buildClient, buildServer, copyAssets, generateCloudflare, generateDocker, generateSitemap, generateVercel, prerenderPages } from "alepha/vite";
9
9
  import { exec, spawn } from "node:child_process";
10
- import { tsImport } from "tsx/esm/api";
11
10
  import { readFileSync } from "node:fs";
12
11
  import { promisify } from "node:util";
12
+ import { ServerSwaggerProvider } from "alepha/server/swagger";
13
13
  import * as os from "node:os";
14
14
 
15
15
  //#region ../../src/cli/assets/appRouterTs.ts
@@ -174,6 +174,7 @@ var AlephaCliUtils = class {
174
174
  log = $logger();
175
175
  fs = $inject(FileSystemProvider);
176
176
  envUtils = $inject(EnvUtils);
177
+ alepha = $inject(Alepha);
177
178
  /**
178
179
  * Execute a command using npx with inherited stdio.
179
180
  *
@@ -235,6 +236,34 @@ var AlephaCliUtils = class {
235
236
  this.log.debug(`Config file written: ${path}`);
236
237
  return path;
237
238
  }
239
+ async removeFiles(root, files) {
240
+ await Promise.all(files.map((file) => this.fs.rm(join(root, file), {
241
+ force: true,
242
+ recursive: true
243
+ })));
244
+ }
245
+ async removeYarn(root) {
246
+ await this.removeFiles(root, [
247
+ ".yarn",
248
+ ".yarnrc.yml",
249
+ ".yarn"
250
+ ]);
251
+ }
252
+ async removePnpm(root) {
253
+ await this.removeFiles(root, ["pnpm-lock.yaml", "pnpm-workspace.yaml"]);
254
+ }
255
+ async removeNpm(root) {
256
+ await this.removeFiles(root, ["package-lock.json"]);
257
+ }
258
+ async removeBun(root) {
259
+ await this.removeFiles(root, ["bun.lockb"]);
260
+ }
261
+ async removeAllPmFilesExcept(root, except) {
262
+ if (except !== "yarn") await this.removeYarn(root);
263
+ if (except !== "pnpm") await this.removePnpm(root);
264
+ if (except !== "npm") await this.removeNpm(root);
265
+ if (except !== "bun") await this.removeBun(root);
266
+ }
238
267
  /**
239
268
  * Ensure Yarn is configured in the project directory.
240
269
  *
@@ -244,26 +273,16 @@ var AlephaCliUtils = class {
244
273
  */
245
274
  async ensureYarn(root) {
246
275
  await this.ensureFileExists(root, ".yarnrc.yml", "nodeLinker: node-modules", false);
247
- await this.fs.rm(join(root, "package-lock.json"), { force: true });
248
- await this.fs.rm(join(root, "pnpm-lock.yaml"), { force: true });
276
+ await this.removeAllPmFilesExcept(root, "yarn");
277
+ }
278
+ async ensureBun(root) {
279
+ await this.removeAllPmFilesExcept(root, "bun");
249
280
  }
250
281
  async ensurePnpm(root) {
251
- await this.fs.rm(join(root, "package-lock.json"), { force: true });
252
- await this.fs.rm(join(root, "yarn.lock"), { force: true });
253
- await this.fs.rm(join(root, ".yarn"), {
254
- force: true,
255
- recursive: true
256
- });
257
- await this.fs.rm(join(root, ".yarnrc.yml"), { force: true });
282
+ await this.removeAllPmFilesExcept(root, "pnpm");
258
283
  }
259
284
  async ensureNpm(root) {
260
- await this.fs.rm(join(root, "pnpm-lock.yaml"), { force: true });
261
- await this.fs.rm(join(root, "yarn.lock"), { force: true });
262
- await this.fs.rm(join(root, ".yarn"), {
263
- force: true,
264
- recursive: true
265
- });
266
- await this.fs.rm(join(root, ".yarnrc.yml"), { force: true });
285
+ await this.removeAllPmFilesExcept(root, "npm");
267
286
  }
268
287
  /**
269
288
  * Generate package.json content with Alepha dependencies.
@@ -418,7 +437,8 @@ var AlephaCliUtils = class {
418
437
  async loadAlephaFromServerEntryFile(rootDir, explicitEntry) {
419
438
  process.env.ALEPHA_CLI_IMPORT = "true";
420
439
  const entry = await boot.getServerEntry(rootDir, explicitEntry);
421
- const mod = await tsImport(entry, { parentURL: import.meta.url });
440
+ delete global.__alepha;
441
+ const mod = await import(entry);
422
442
  this.log.debug(`Load entry: ${entry}`);
423
443
  if (mod.default instanceof Alepha) return {
424
444
  alepha: mod.default,
@@ -470,6 +490,7 @@ ${models.map((it) => `export const ${it} = models["${it}"];`).join("\n")}
470
490
  if (flags?.pnpm) return "pnpm";
471
491
  if (flags?.npm) return "npm";
472
492
  if (flags?.bun) return "bun";
493
+ if (this.alepha.isBun()) return "bun";
473
494
  if (await this.checkFileExists(root, "yarn.lock", true)) return "yarn";
474
495
  if (await this.checkFileExists(root, "pnpm-lock.yaml", true)) return "pnpm";
475
496
  return "npm";
@@ -554,6 +575,23 @@ ${models.map((it) => `export const ${it} = models["${it}"];`).join("\n")}
554
575
  async hasExpo(root) {
555
576
  return this.hasDependency(root, "expo");
556
577
  }
578
+ async getInstallCommand(root, packageName, dev = true) {
579
+ const pm = await this.getPackageManager(root);
580
+ let cmd;
581
+ switch (pm) {
582
+ case "yarn":
583
+ cmd = `yarn add ${dev ? "-D" : ""} ${packageName}`;
584
+ break;
585
+ case "pnpm":
586
+ cmd = `pnpm add ${dev ? "-D" : ""} ${packageName}`;
587
+ break;
588
+ case "bun":
589
+ cmd = `bun add ${dev ? "-d" : ""} ${packageName}`;
590
+ break;
591
+ default: cmd = `npm install ${dev ? "--save-dev" : ""} ${packageName}`;
592
+ }
593
+ return cmd.replace(/\s+/g, " ").trim();
594
+ }
557
595
  /**
558
596
  * Install a dependency if it's missing from the project.
559
597
  *
@@ -566,18 +604,7 @@ ${models.map((it) => `export const ${it} = models["${it}"];`).join("\n")}
566
604
  this.log.debug(`Dependency '${packageName}' is already installed`);
567
605
  return;
568
606
  }
569
- const pm = await this.getPackageManager(root);
570
- let cmd;
571
- switch (pm) {
572
- case "yarn":
573
- cmd = `yarn add ${dev ? "-D" : ""} ${packageName}`;
574
- break;
575
- case "pnpm":
576
- cmd = `pnpm add ${dev ? "-D" : ""} ${packageName}`;
577
- break;
578
- default: cmd = `npm install ${dev ? "--save-dev" : ""} ${packageName}`;
579
- }
580
- cmd = cmd.replace(/\s+/g, " ").trim();
607
+ const cmd = await this.getInstallCommand(root, packageName, dev);
581
608
  if (options.run) await options.run(cmd, { alias: `installing ${packageName}` });
582
609
  else {
583
610
  this.log.debug(`Installing ${packageName}`);
@@ -719,222 +746,6 @@ var BuildCommand = class {
719
746
  });
720
747
  };
721
748
 
722
- //#endregion
723
- //#region ../../src/cli/atoms/changelogOptions.ts
724
- /**
725
- * Default scopes to ignore in changelog generation.
726
- * Commits with these scopes won't appear in release notes.
727
- */
728
- const DEFAULT_IGNORE = [
729
- "project",
730
- "release",
731
- "starter",
732
- "example",
733
- "chore",
734
- "ci",
735
- "build",
736
- "test",
737
- "style"
738
- ];
739
- /**
740
- * Changelog configuration atom.
741
- *
742
- * Configure in `alepha.config.ts`:
743
- * ```ts
744
- * import { changelogOptions } from "alepha/cli";
745
- *
746
- * alepha.set(changelogOptions, {
747
- * ignore: ["project", "release", "chore", "docs"],
748
- * });
749
- * ```
750
- */
751
- const changelogOptions = $atom({
752
- name: "alepha.changelog",
753
- schema: t.object({ ignore: t.optional(t.array(t.string())) }),
754
- default: { ignore: DEFAULT_IGNORE }
755
- });
756
-
757
- //#endregion
758
- //#region ../../src/cli/services/GitMessageParser.ts
759
- /**
760
- * Service for parsing git commit messages into structured format.
761
- *
762
- * Only parses **conventional commits with a scope**:
763
- * - `feat(scope): description` → feature
764
- * - `fix(scope): description` → bug fix
765
- * - `feat(scope)!: description` → breaking change
766
- *
767
- * Commits without scope are ignored, allowing developers to commit
768
- * work-in-progress changes without polluting release notes:
769
- * - `cli: work in progress` → ignored (no type)
770
- * - `fix: quick patch` → ignored (no scope)
771
- * - `feat(cli): add command` → included
772
- */
773
- var GitMessageParser = class {
774
- log = $logger();
775
- /**
776
- * Parse a git commit line into a structured Commit object.
777
- *
778
- * **Format:** `type(scope): description` or `type(scope)!: description`
779
- *
780
- * **Supported types:** feat, fix, docs, refactor, perf, revert
781
- *
782
- * **Breaking changes:** Use `!` before `:` (e.g., `feat(api)!: remove endpoint`)
783
- *
784
- * @returns Commit object or null if not matching/ignored
785
- */
786
- parseCommit(line, config) {
787
- const match = line.match(/^([a-f0-9]+)\s+(.+)$/);
788
- if (!match) return null;
789
- const [, hash, message] = match;
790
- const ignore = config.ignore ?? DEFAULT_IGNORE;
791
- const conventionalMatch = message.match(/^(feat|fix|docs|refactor|perf|revert)\(([^)]+)\)(!)?:\s*(.+)$/i);
792
- if (!conventionalMatch) return null;
793
- const [, type, scope, breakingMark, description] = conventionalMatch;
794
- const baseScope = scope.split("/")[0];
795
- if (ignore.includes(baseScope) || ignore.includes(scope)) return null;
796
- const breaking = breakingMark === "!" || description.toLowerCase().includes("breaking");
797
- return {
798
- hash: hash.substring(0, 8),
799
- type: type.toLowerCase(),
800
- scope,
801
- description: description.trim(),
802
- breaking
803
- };
804
- }
805
- };
806
-
807
- //#endregion
808
- //#region ../../src/cli/commands/changelog.ts
809
- const execAsync = promisify(exec);
810
- /**
811
- * Git provider for executing git commands.
812
- * Can be substituted in tests with a mock implementation.
813
- */
814
- var GitProvider = class {
815
- async exec(cmd, cwd) {
816
- const { stdout } = await execAsync(`git ${cmd}`, { cwd });
817
- return stdout;
818
- }
819
- };
820
- /**
821
- * Changelog command for generating release notes from git commits.
822
- *
823
- * Usage:
824
- * - `alepha changelog` - Show unreleased changes since latest tag to HEAD
825
- * - `alepha changelog --from=1.0.0` - Show changes from version to HEAD
826
- * - `alepha changelog --from=1.0.0 --to=1.1.0` - Show changes between two refs
827
- * - `alepha changelog | tee -a CHANGELOG.md` - Append to file
828
- */
829
- var ChangelogCommand = class {
830
- log = $logger();
831
- git = $inject(GitProvider);
832
- parser = $inject(GitMessageParser);
833
- config = $use(changelogOptions);
834
- /**
835
- * Format a single commit line.
836
- * Example: `- **cli**: add new command (\`abc1234\`)`
837
- * Breaking changes are flagged: `- **cli**: add new command [BREAKING] (\`abc1234\`)`
838
- */
839
- formatCommit(commit) {
840
- const breaking = commit.breaking ? " [BREAKING]" : "";
841
- return `- **${commit.scope}**: ${commit.description}${breaking} (\`${commit.hash}\`)`;
842
- }
843
- /**
844
- * Format the changelog entry with sections.
845
- */
846
- formatEntry(entry) {
847
- const sections = [];
848
- if (entry.features.length > 0) {
849
- sections.push("### Features\n");
850
- for (const commit of entry.features) sections.push(this.formatCommit(commit));
851
- sections.push("");
852
- }
853
- if (entry.fixes.length > 0) {
854
- sections.push("### Bug Fixes\n");
855
- for (const commit of entry.fixes) sections.push(this.formatCommit(commit));
856
- sections.push("");
857
- }
858
- return sections.join("\n");
859
- }
860
- /**
861
- * Parse git log output into a changelog entry.
862
- */
863
- parseCommits(commitsOutput) {
864
- const entry = {
865
- features: [],
866
- fixes: []
867
- };
868
- for (const line of commitsOutput.trim().split("\n")) {
869
- if (!line.trim()) continue;
870
- const commit = this.parser.parseCommit(line, this.config);
871
- if (!commit) {
872
- this.log.trace("Skipping commit", { line });
873
- continue;
874
- }
875
- this.log.trace("Parsed commit", { commit });
876
- if (commit.type === "feat") entry.features.push(commit);
877
- else if (commit.type === "fix") entry.fixes.push(commit);
878
- }
879
- return entry;
880
- }
881
- /**
882
- * Check if entry has any public commits.
883
- */
884
- hasChanges(entry) {
885
- return entry.features.length > 0 || entry.fixes.length > 0;
886
- }
887
- /**
888
- * Get the latest version tag.
889
- */
890
- async getLatestTag(git) {
891
- return (await git("tag --sort=-version:refname")).trim().split("\n").filter((tag) => tag.match(/^\d+\.\d+\.\d+$/))[0] || null;
892
- }
893
- changelog = $command({
894
- name: "changelog",
895
- description: "Generate changelog from conventional commits (outputs to stdout)",
896
- flags: t.object({
897
- from: t.optional(t.string({
898
- aliases: ["f"],
899
- description: "Starting ref (default: latest tag)"
900
- })),
901
- to: t.optional(t.string({
902
- aliases: ["t"],
903
- description: "Ending ref (default: HEAD)"
904
- }))
905
- }),
906
- handler: async ({ flags, root }) => {
907
- const git = (cmd) => this.git.exec(cmd, root);
908
- let fromRef;
909
- if (flags.from) {
910
- fromRef = flags.from;
911
- this.log.debug("Using specified from ref", { from: fromRef });
912
- } else {
913
- const latestTag = await this.getLatestTag(git);
914
- if (!latestTag) {
915
- process.stdout.write("No version tags found in repository\n");
916
- return;
917
- }
918
- fromRef = latestTag;
919
- this.log.debug("Using latest tag", { from: fromRef });
920
- }
921
- const toRef = flags.to || "HEAD";
922
- this.log.debug("Using to ref", { to: toRef });
923
- const commitsOutput = await git(`log ${fromRef}..${toRef} --oneline`);
924
- if (!commitsOutput.trim()) {
925
- process.stdout.write(`No changes in range ${fromRef}..${toRef}\n`);
926
- return;
927
- }
928
- const entry = this.parseCommits(commitsOutput);
929
- if (!this.hasChanges(entry)) {
930
- process.stdout.write(`No public changes in range ${fromRef}..${toRef}\n`);
931
- return;
932
- }
933
- process.stdout.write(this.formatEntry(entry));
934
- }
935
- });
936
- };
937
-
938
749
  //#endregion
939
750
  //#region ../../src/cli/commands/clean.ts
940
751
  var CleanCommand = class {
@@ -1295,6 +1106,7 @@ var DeployCommand = class {
1295
1106
  var DevCommand = class {
1296
1107
  log = $logger();
1297
1108
  utils = $inject(AlephaCliUtils);
1109
+ alepha = $inject(Alepha);
1298
1110
  /**
1299
1111
  * Will run the project in watch mode.
1300
1112
  *
@@ -1320,20 +1132,26 @@ var DevCommand = class {
1320
1132
  }
1321
1133
  const entry = await boot.getServerEntry(root, args);
1322
1134
  this.log.trace("Entry file found", { entry });
1323
- try {
1324
- await access(join(root, "index.html"));
1325
- } catch {
1326
- this.log.trace("No index.html found, running entry file with tsx");
1327
- let cmd = "tsx --watch";
1135
+ if (!await this.isFullstackProject(root)) {
1136
+ const exe = this.alepha.isBun() ? "bun" : "tsx";
1137
+ let cmd = `${exe} --watch`;
1328
1138
  if (await this.utils.exists(root, ".env")) cmd += " --env-file=./.env";
1329
1139
  cmd += ` ${entry}`;
1330
- await this.utils.exec(cmd);
1140
+ await this.utils.exec(cmd, { global: exe === "bun" });
1331
1141
  return;
1332
1142
  }
1333
1143
  await this.utils.ensureDependency(root, "vite");
1334
1144
  await this.utils.exec("vite");
1335
1145
  }
1336
1146
  });
1147
+ async isFullstackProject(root) {
1148
+ try {
1149
+ await access(join(root, "index.html"));
1150
+ return true;
1151
+ } catch {
1152
+ return false;
1153
+ }
1154
+ }
1337
1155
  };
1338
1156
 
1339
1157
  //#endregion
@@ -1351,6 +1169,278 @@ var FormatCommand = class {
1351
1169
  });
1352
1170
  };
1353
1171
 
1172
+ //#endregion
1173
+ //#region ../../src/cli/atoms/changelogOptions.ts
1174
+ /**
1175
+ * Default scopes to ignore in changelog generation.
1176
+ * Commits with these scopes won't appear in release notes.
1177
+ */
1178
+ const DEFAULT_IGNORE = [
1179
+ "project",
1180
+ "release",
1181
+ "starter",
1182
+ "example",
1183
+ "chore",
1184
+ "ci",
1185
+ "build",
1186
+ "test",
1187
+ "style"
1188
+ ];
1189
+ /**
1190
+ * Changelog configuration atom.
1191
+ *
1192
+ * Configure in `alepha.config.ts`:
1193
+ * ```ts
1194
+ * import { changelogOptions } from "alepha/cli";
1195
+ *
1196
+ * alepha.set(changelogOptions, {
1197
+ * ignore: ["project", "release", "chore", "docs"],
1198
+ * });
1199
+ * ```
1200
+ */
1201
+ const changelogOptions = $atom({
1202
+ name: "alepha.changelog",
1203
+ schema: t.object({ ignore: t.optional(t.array(t.string())) }),
1204
+ default: { ignore: DEFAULT_IGNORE }
1205
+ });
1206
+
1207
+ //#endregion
1208
+ //#region ../../src/cli/services/GitMessageParser.ts
1209
+ /**
1210
+ * Service for parsing git commit messages into structured format.
1211
+ *
1212
+ * Only parses **conventional commits with a scope**:
1213
+ * - `feat(scope): description` → feature
1214
+ * - `fix(scope): description` → bug fix
1215
+ * - `feat(scope)!: description` → breaking change
1216
+ *
1217
+ * Commits without scope are ignored, allowing developers to commit
1218
+ * work-in-progress changes without polluting release notes:
1219
+ * - `cli: work in progress` → ignored (no type)
1220
+ * - `fix: quick patch` → ignored (no scope)
1221
+ * - `feat(cli): add command` → included
1222
+ */
1223
+ var GitMessageParser = class {
1224
+ log = $logger();
1225
+ /**
1226
+ * Parse a git commit line into a structured Commit object.
1227
+ *
1228
+ * **Format:** `type(scope): description` or `type(scope)!: description`
1229
+ *
1230
+ * **Supported types:** feat, fix, docs, refactor, perf, revert
1231
+ *
1232
+ * **Breaking changes:** Use `!` before `:` (e.g., `feat(api)!: remove endpoint`)
1233
+ *
1234
+ * @returns Commit object or null if not matching/ignored
1235
+ */
1236
+ parseCommit(line, config) {
1237
+ const match = line.match(/^([a-f0-9]+)\s+(.+)$/);
1238
+ if (!match) return null;
1239
+ const [, hash, message] = match;
1240
+ const ignore = config.ignore ?? DEFAULT_IGNORE;
1241
+ const conventionalMatch = message.match(/^(feat|fix|docs|refactor|perf|revert)\(([^)]+)\)(!)?:\s*(.+)$/i);
1242
+ if (!conventionalMatch) return null;
1243
+ const [, type, scope, breakingMark, description] = conventionalMatch;
1244
+ const baseScope = scope.split("/")[0];
1245
+ if (ignore.includes(baseScope) || ignore.includes(scope)) return null;
1246
+ const breaking = breakingMark === "!" || description.toLowerCase().includes("breaking");
1247
+ return {
1248
+ hash: hash.substring(0, 8),
1249
+ type: type.toLowerCase(),
1250
+ scope,
1251
+ description: description.trim(),
1252
+ breaking
1253
+ };
1254
+ }
1255
+ };
1256
+
1257
+ //#endregion
1258
+ //#region ../../src/cli/commands/gen/changelog.ts
1259
+ const execAsync = promisify(exec);
1260
+ /**
1261
+ * Git provider for executing git commands.
1262
+ * Can be substituted in tests with a mock implementation.
1263
+ */
1264
+ var GitProvider = class {
1265
+ async exec(cmd, cwd) {
1266
+ const { stdout } = await execAsync(`git ${cmd}`, { cwd });
1267
+ return stdout;
1268
+ }
1269
+ };
1270
+ /**
1271
+ * Changelog command for generating release notes from git commits.
1272
+ *
1273
+ * Usage:
1274
+ * - `alepha gen changelog` - Show unreleased changes since latest tag to HEAD
1275
+ * - `alepha gen changelog --from=1.0.0` - Show changes from version to HEAD
1276
+ * - `alepha gen changelog --from=1.0.0 --to=1.1.0` - Show changes between two refs
1277
+ * - `alepha gen changelog | tee -a CHANGELOG.md` - Append to file
1278
+ */
1279
+ var ChangelogCommand = class {
1280
+ log = $logger();
1281
+ git = $inject(GitProvider);
1282
+ parser = $inject(GitMessageParser);
1283
+ config = $use(changelogOptions);
1284
+ /**
1285
+ * Format a single commit line.
1286
+ * Example: `- **cli**: add new command (\`abc1234\`)`
1287
+ * Breaking changes are flagged: `- **cli**: add new command [BREAKING] (\`abc1234\`)`
1288
+ */
1289
+ formatCommit(commit) {
1290
+ const breaking = commit.breaking ? " [BREAKING]" : "";
1291
+ return `- **${commit.scope}**: ${commit.description}${breaking} (\`${commit.hash}\`)`;
1292
+ }
1293
+ /**
1294
+ * Format the changelog entry with sections.
1295
+ */
1296
+ formatEntry(entry) {
1297
+ const sections = [];
1298
+ if (entry.features.length > 0) {
1299
+ sections.push("### Features\n");
1300
+ for (const commit of entry.features) sections.push(this.formatCommit(commit));
1301
+ sections.push("");
1302
+ }
1303
+ if (entry.fixes.length > 0) {
1304
+ sections.push("### Bug Fixes\n");
1305
+ for (const commit of entry.fixes) sections.push(this.formatCommit(commit));
1306
+ sections.push("");
1307
+ }
1308
+ return sections.join("\n");
1309
+ }
1310
+ /**
1311
+ * Parse git log output into a changelog entry.
1312
+ */
1313
+ parseCommits(commitsOutput) {
1314
+ const entry = {
1315
+ features: [],
1316
+ fixes: []
1317
+ };
1318
+ for (const line of commitsOutput.trim().split("\n")) {
1319
+ if (!line.trim()) continue;
1320
+ const commit = this.parser.parseCommit(line, this.config);
1321
+ if (!commit) {
1322
+ this.log.trace("Skipping commit", { line });
1323
+ continue;
1324
+ }
1325
+ this.log.trace("Parsed commit", { commit });
1326
+ if (commit.type === "feat") entry.features.push(commit);
1327
+ else if (commit.type === "fix") entry.fixes.push(commit);
1328
+ }
1329
+ return entry;
1330
+ }
1331
+ /**
1332
+ * Check if entry has any public commits.
1333
+ */
1334
+ hasChanges(entry) {
1335
+ return entry.features.length > 0 || entry.fixes.length > 0;
1336
+ }
1337
+ /**
1338
+ * Get the latest version tag.
1339
+ */
1340
+ async getLatestTag(git) {
1341
+ return (await git("tag --sort=-version:refname")).trim().split("\n").filter((tag) => tag.match(/^\d+\.\d+\.\d+$/))[0] || null;
1342
+ }
1343
+ command = $command({
1344
+ name: "changelog",
1345
+ description: "Generate changelog from conventional commits (outputs to stdout)",
1346
+ flags: t.object({
1347
+ from: t.optional(t.string({
1348
+ aliases: ["f"],
1349
+ description: "Starting ref (default: latest tag)"
1350
+ })),
1351
+ to: t.optional(t.string({
1352
+ aliases: ["t"],
1353
+ description: "Ending ref (default: HEAD)"
1354
+ }))
1355
+ }),
1356
+ handler: async ({ flags, root }) => {
1357
+ const git = (cmd) => this.git.exec(cmd, root);
1358
+ let fromRef;
1359
+ if (flags.from) {
1360
+ fromRef = flags.from;
1361
+ this.log.debug("Using specified from ref", { from: fromRef });
1362
+ } else {
1363
+ const latestTag = await this.getLatestTag(git);
1364
+ if (!latestTag) {
1365
+ process.stdout.write("No version tags found in repository\n");
1366
+ return;
1367
+ }
1368
+ fromRef = latestTag;
1369
+ this.log.debug("Using latest tag", { from: fromRef });
1370
+ }
1371
+ const toRef = flags.to || "HEAD";
1372
+ this.log.debug("Using to ref", { to: toRef });
1373
+ const commitsOutput = await git(`log ${fromRef}..${toRef} --oneline`);
1374
+ if (!commitsOutput.trim()) {
1375
+ process.stdout.write(`No changes in range ${fromRef}..${toRef}\n`);
1376
+ return;
1377
+ }
1378
+ const entry = this.parseCommits(commitsOutput);
1379
+ if (!this.hasChanges(entry)) {
1380
+ process.stdout.write(`No public changes in range ${fromRef}..${toRef}\n`);
1381
+ return;
1382
+ }
1383
+ process.stdout.write(this.formatEntry(entry));
1384
+ }
1385
+ });
1386
+ };
1387
+
1388
+ //#endregion
1389
+ //#region ../../src/cli/commands/gen/openapi.ts
1390
+ var OpenApiCommand = class {
1391
+ log = $logger();
1392
+ utils = $inject(AlephaCliUtils);
1393
+ fs = $inject(FileSystemProvider);
1394
+ command = $command({
1395
+ name: "openapi",
1396
+ description: "Generate OpenAPI specification from actions",
1397
+ flags: t.object({ out: t.optional(t.text({
1398
+ aliases: ["o"],
1399
+ description: "Output file path"
1400
+ })) }),
1401
+ handler: async ({ root, flags }) => {
1402
+ const { alepha } = await this.utils.loadAlephaFromServerEntryFile(root);
1403
+ try {
1404
+ const openapiProvider = alepha.inject(ServerSwaggerProvider);
1405
+ await alepha.events.emit("configure", alepha);
1406
+ let json = openapiProvider.json;
1407
+ if (!json) json = openapiProvider.generateSwaggerDoc({ info: {
1408
+ title: "API Documentation",
1409
+ version: "1.0.0"
1410
+ } });
1411
+ if (!json) {
1412
+ this.log.error("No actions found to generate OpenAPI specification.");
1413
+ return;
1414
+ }
1415
+ if (flags.out) await this.fs.writeFile(this.fs.join(root, flags.out), JSON.stringify(json, null, 2));
1416
+ else this.log.info(JSON.stringify(json, null, 2));
1417
+ } catch (err) {
1418
+ const message = err instanceof Error ? err.message : String(err);
1419
+ if (message.includes("Service not found")) {
1420
+ this.log.error("Missing $swagger() primitive in your server configuration.");
1421
+ return;
1422
+ }
1423
+ this.log.error(`OpenAPI generation failed - ${message}`, { err });
1424
+ }
1425
+ }
1426
+ });
1427
+ };
1428
+
1429
+ //#endregion
1430
+ //#region ../../src/cli/commands/gen.ts
1431
+ var GenCommand = class {
1432
+ changelog = $inject(ChangelogCommand);
1433
+ openapi = $inject(OpenApiCommand);
1434
+ gen = $command({
1435
+ name: "gen",
1436
+ description: "Generate code, documentation, ...",
1437
+ children: [this.changelog.command, this.openapi.command],
1438
+ handler: async ({ help }) => {
1439
+ help();
1440
+ }
1441
+ });
1442
+ };
1443
+
1354
1444
  //#endregion
1355
1445
  //#region ../../src/cli/commands/init.ts
1356
1446
  var InitCommand = class {
@@ -1392,7 +1482,8 @@ var InitCommand = class {
1392
1482
  if (pm === "yarn") {
1393
1483
  await this.utils.ensureYarn(root);
1394
1484
  await run("yarn set version stable");
1395
- } else if (pm === "pnpm") await this.utils.ensurePnpm(root);
1485
+ } else if (pm === "bun") await this.utils.ensureBun(root);
1486
+ else if (pm === "pnpm") await this.utils.ensurePnpm(root);
1396
1487
  else await this.utils.ensureNpm(root);
1397
1488
  await run(`${pm} install`, { alias: `installing dependencies with ${pm}` });
1398
1489
  if (!isExpo) await this.utils.ensureDependency(root, "vite", { run });
@@ -1425,6 +1516,8 @@ var LintCommand = class {
1425
1516
  var RootCommand = class {
1426
1517
  log = $logger();
1427
1518
  cli = $inject(CliProvider);
1519
+ alepha = $inject(Alepha);
1520
+ color = $inject(ConsoleColorProvider);
1428
1521
  /**
1429
1522
  * Called when no command is provided
1430
1523
  */
@@ -1436,7 +1529,9 @@ var RootCommand = class {
1436
1529
  })) }),
1437
1530
  handler: async ({ flags }) => {
1438
1531
  if (flags.version) {
1439
- this.log.info(version);
1532
+ this.log.info(this.color.set("WHITE_BOLD", `Alepha v${version}`));
1533
+ if (this.alepha.isBun()) this.log.info(this.color.set("GREY_DARK", `└─ Bun v${Bun.version}`));
1534
+ else this.log.info(this.color.set("GREY_DARK", `└─ Node ${process.version}`));
1440
1535
  return;
1441
1536
  }
1442
1537
  this.cli.printHelp();
@@ -1499,15 +1594,19 @@ var TestCommand = class {
1499
1594
  //#region ../../src/cli/commands/typecheck.ts
1500
1595
  var TypecheckCommand = class {
1501
1596
  utils = $inject(AlephaCliUtils);
1597
+ log = $logger();
1502
1598
  /**
1503
1599
  * Run TypeScript type checking across the codebase with no emit.
1504
1600
  */
1505
1601
  typecheck = $command({
1506
1602
  name: "typecheck",
1603
+ aliases: ["tc"],
1507
1604
  description: "Check TypeScript types across the codebase",
1508
1605
  handler: async ({ root }) => {
1606
+ this.log.info("Starting TypeScript type checking...");
1509
1607
  await this.utils.ensureDependency(root, "typescript");
1510
1608
  await this.utils.exec("tsc --noEmit");
1609
+ this.log.info("TypeScript type checking completed successfully.");
1511
1610
  }
1512
1611
  });
1513
1612
  };
@@ -1547,13 +1646,26 @@ var VerifyCommand = class {
1547
1646
 
1548
1647
  //#endregion
1549
1648
  //#region ../../src/cli/apps/AlephaCli.ts
1649
+ /**
1650
+ * Register `tsx` when running in Node.js, ignore for Bun.
1651
+ *
1652
+ * It's required to have a full TypeScript support. (mostly .tsx files)
1653
+ */
1654
+ if (typeof Bun === "undefined") {
1655
+ const { register } = await import("tsx/esm/api");
1656
+ register();
1657
+ }
1658
+ /**
1659
+ * Allow to extend Alepha CLI via `alepha.config.ts` file located in the project root.
1660
+ */
1550
1661
  var AlephaCliExtension = class {
1551
1662
  alepha = $inject(Alepha);
1552
1663
  fs = $inject(FileSystemProvider);
1553
1664
  onConfigure = $hook({
1554
1665
  on: "configure",
1555
1666
  handler: async () => {
1556
- const extensionPath = join(process.cwd(), "alepha.config.ts");
1667
+ const root = process.cwd();
1668
+ const extensionPath = this.fs.join(root, "alepha.config.ts");
1557
1669
  if (!await this.fs.exists(extensionPath)) return;
1558
1670
  const { default: Extension } = await import(extensionPath);
1559
1671
  if (typeof Extension !== "function") return;
@@ -1566,7 +1678,6 @@ const AlephaCli = $module({
1566
1678
  services: [
1567
1679
  AlephaCliExtension,
1568
1680
  BuildCommand,
1569
- ChangelogCommand,
1570
1681
  CleanCommand,
1571
1682
  DbCommand,
1572
1683
  DeployCommand,
@@ -1579,6 +1690,7 @@ const AlephaCli = $module({
1579
1690
  TestCommand,
1580
1691
  TypecheckCommand,
1581
1692
  VerifyCommand,
1693
+ GenCommand,
1582
1694
  GitProvider
1583
1695
  ]
1584
1696
  });
@@ -1791,5 +1903,5 @@ const defineConfig = (config) => {
1791
1903
  const defineAlephaConfig = defineConfig;
1792
1904
 
1793
1905
  //#endregion
1794
- export { AlephaCli, AlephaCliUtils, AlephaPackageBuilderCli, BuildCommand, ChangelogCommand, CleanCommand, DEFAULT_IGNORE, DbCommand, DeployCommand, DevCommand, FormatCommand, GitMessageParser, GitProvider, InitCommand, LintCommand, RootCommand, RunCommand, TestCommand, TypecheckCommand, VerifyCommand, analyzeModules, changelogOptions, defineAlephaConfig, defineConfig, version };
1906
+ export { AlephaCli, AlephaCliUtils, AlephaPackageBuilderCli, BuildCommand, ChangelogCommand, CleanCommand, DEFAULT_IGNORE, DbCommand, DeployCommand, DevCommand, FormatCommand, GitMessageParser, GitProvider, InitCommand, LintCommand, OpenApiCommand, RootCommand, RunCommand, TestCommand, TypecheckCommand, VerifyCommand, analyzeModules, changelogOptions, defineAlephaConfig, defineConfig, version };
1795
1907
  //# sourceMappingURL=index.js.map