alepha 0.14.2 → 0.14.4

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 (405) hide show
  1. package/README.md +1 -1
  2. package/dist/api/audits/index.browser.js +5 -5
  3. package/dist/api/audits/index.browser.js.map +1 -1
  4. package/dist/api/audits/index.d.ts +706 -785
  5. package/dist/api/audits/index.d.ts.map +1 -1
  6. package/dist/api/audits/index.js +13 -13
  7. package/dist/api/audits/index.js.map +1 -1
  8. package/dist/api/files/index.browser.js +5 -5
  9. package/dist/api/files/index.browser.js.map +1 -1
  10. package/dist/api/files/index.d.ts +58 -137
  11. package/dist/api/files/index.d.ts.map +1 -1
  12. package/dist/api/files/index.js +71 -71
  13. package/dist/api/files/index.js.map +1 -1
  14. package/dist/api/jobs/index.browser.js +5 -5
  15. package/dist/api/jobs/index.browser.js.map +1 -1
  16. package/dist/api/jobs/index.d.ts +29 -108
  17. package/dist/api/jobs/index.d.ts.map +1 -1
  18. package/dist/api/jobs/index.js +10 -10
  19. package/dist/api/jobs/index.js.map +1 -1
  20. package/dist/api/notifications/index.browser.js +10 -10
  21. package/dist/api/notifications/index.browser.js.map +1 -1
  22. package/dist/api/notifications/index.d.ts +504 -171
  23. package/dist/api/notifications/index.d.ts.map +1 -1
  24. package/dist/api/notifications/index.js +12 -12
  25. package/dist/api/notifications/index.js.map +1 -1
  26. package/dist/api/parameters/index.browser.js +163 -10
  27. package/dist/api/parameters/index.browser.js.map +1 -1
  28. package/dist/api/parameters/index.d.ts +277 -351
  29. package/dist/api/parameters/index.d.ts.map +1 -1
  30. package/dist/api/parameters/index.js +196 -91
  31. package/dist/api/parameters/index.js.map +1 -1
  32. package/dist/api/users/index.browser.js +19 -19
  33. package/dist/api/users/index.browser.js.map +1 -1
  34. package/dist/api/users/index.d.ts +787 -852
  35. package/dist/api/users/index.d.ts.map +1 -1
  36. package/dist/api/users/index.js +827 -596
  37. package/dist/api/users/index.js.map +1 -1
  38. package/dist/api/verifications/index.browser.js +6 -6
  39. package/dist/api/verifications/index.browser.js.map +1 -1
  40. package/dist/api/verifications/index.d.ts +128 -128
  41. package/dist/api/verifications/index.d.ts.map +1 -1
  42. package/dist/api/verifications/index.js +6 -6
  43. package/dist/api/verifications/index.js.map +1 -1
  44. package/dist/bin/index.d.ts +1 -2
  45. package/dist/bin/index.js +0 -1
  46. package/dist/bin/index.js.map +1 -1
  47. package/dist/cli/index.d.ts +252 -131
  48. package/dist/cli/index.d.ts.map +1 -1
  49. package/dist/cli/index.js +595 -395
  50. package/dist/cli/index.js.map +1 -1
  51. package/dist/command/index.d.ts +46 -11
  52. package/dist/command/index.d.ts.map +1 -1
  53. package/dist/command/index.js +99 -19
  54. package/dist/command/index.js.map +1 -1
  55. package/dist/core/index.browser.js +40 -22
  56. package/dist/core/index.browser.js.map +1 -1
  57. package/dist/core/index.d.ts +45 -1
  58. package/dist/core/index.d.ts.map +1 -1
  59. package/dist/core/index.js +40 -22
  60. package/dist/core/index.js.map +1 -1
  61. package/dist/core/index.native.js +40 -22
  62. package/dist/core/index.native.js.map +1 -1
  63. package/dist/fake/index.js +195 -168
  64. package/dist/fake/index.js.map +1 -1
  65. package/dist/file/index.d.ts +8 -0
  66. package/dist/file/index.d.ts.map +1 -1
  67. package/dist/file/index.js +3 -0
  68. package/dist/file/index.js.map +1 -1
  69. package/dist/logger/index.d.ts +1 -1
  70. package/dist/logger/index.d.ts.map +1 -1
  71. package/dist/logger/index.js +12 -2
  72. package/dist/logger/index.js.map +1 -1
  73. package/dist/mcp/index.js +1 -1
  74. package/dist/mcp/index.js.map +1 -1
  75. package/dist/orm/index.d.ts +59 -195
  76. package/dist/orm/index.d.ts.map +1 -1
  77. package/dist/orm/index.js +201 -430
  78. package/dist/orm/index.js.map +1 -1
  79. package/dist/security/index.d.ts +1 -1
  80. package/dist/security/index.d.ts.map +1 -1
  81. package/dist/security/index.js +1 -1
  82. package/dist/security/index.js.map +1 -1
  83. package/dist/server/auth/index.d.ts +171 -155
  84. package/dist/server/auth/index.d.ts.map +1 -1
  85. package/dist/server/auth/index.js +0 -1
  86. package/dist/server/auth/index.js.map +1 -1
  87. package/dist/server/cache/index.d.ts +12 -0
  88. package/dist/server/cache/index.d.ts.map +1 -1
  89. package/dist/server/cache/index.js +55 -2
  90. package/dist/server/cache/index.js.map +1 -1
  91. package/dist/server/compress/index.d.ts +6 -0
  92. package/dist/server/compress/index.d.ts.map +1 -1
  93. package/dist/server/compress/index.js +38 -1
  94. package/dist/server/compress/index.js.map +1 -1
  95. package/dist/server/core/index.browser.js +2 -2
  96. package/dist/server/core/index.browser.js.map +1 -1
  97. package/dist/server/core/index.d.ts +10 -10
  98. package/dist/server/core/index.d.ts.map +1 -1
  99. package/dist/server/core/index.js +7 -4
  100. package/dist/server/core/index.js.map +1 -1
  101. package/dist/server/links/index.browser.js +22 -6
  102. package/dist/server/links/index.browser.js.map +1 -1
  103. package/dist/server/links/index.d.ts +46 -44
  104. package/dist/server/links/index.d.ts.map +1 -1
  105. package/dist/server/links/index.js +24 -41
  106. package/dist/server/links/index.js.map +1 -1
  107. package/dist/server/static/index.d.ts.map +1 -1
  108. package/dist/server/static/index.js +4 -0
  109. package/dist/server/static/index.js.map +1 -1
  110. package/dist/server/swagger/index.d.ts +2 -1
  111. package/dist/server/swagger/index.d.ts.map +1 -1
  112. package/dist/server/swagger/index.js +9 -5
  113. package/dist/server/swagger/index.js.map +1 -1
  114. package/dist/vite/index.d.ts +101 -106
  115. package/dist/vite/index.d.ts.map +1 -1
  116. package/dist/vite/index.js +574 -503
  117. package/dist/vite/index.js.map +1 -1
  118. package/dist/websocket/index.d.ts +7 -7
  119. package/package.json +7 -7
  120. package/src/api/audits/controllers/{AuditController.ts → AdminAuditController.ts} +5 -6
  121. package/src/api/audits/entities/audits.ts +5 -5
  122. package/src/api/audits/index.browser.ts +1 -1
  123. package/src/api/audits/index.ts +3 -3
  124. package/src/api/audits/primitives/$audit.spec.ts +276 -0
  125. package/src/api/audits/services/AuditService.spec.ts +495 -0
  126. package/src/api/files/__tests__/$bucket.spec.ts +91 -0
  127. package/src/api/files/controllers/AdminFileStatsController.spec.ts +166 -0
  128. package/src/api/files/controllers/{StorageStatsController.ts → AdminFileStatsController.ts} +2 -2
  129. package/src/api/files/controllers/FileController.spec.ts +558 -0
  130. package/src/api/files/controllers/FileController.ts +4 -5
  131. package/src/api/files/entities/files.ts +5 -5
  132. package/src/api/files/index.browser.ts +1 -1
  133. package/src/api/files/index.ts +4 -4
  134. package/src/api/files/jobs/FileJobs.spec.ts +52 -0
  135. package/src/api/files/services/FileService.spec.ts +109 -0
  136. package/src/api/jobs/__tests__/JobController.spec.ts +343 -0
  137. package/src/api/jobs/controllers/{JobController.ts → AdminJobController.ts} +2 -2
  138. package/src/api/jobs/entities/jobExecutions.ts +5 -5
  139. package/src/api/jobs/index.ts +3 -3
  140. package/src/api/jobs/primitives/$job.spec.ts +476 -0
  141. package/src/api/notifications/controllers/{NotificationController.ts → AdminNotificationController.ts} +4 -5
  142. package/src/api/notifications/entities/notifications.ts +5 -5
  143. package/src/api/notifications/index.browser.ts +1 -1
  144. package/src/api/notifications/index.ts +4 -4
  145. package/src/api/parameters/controllers/{ConfigController.ts → AdminConfigController.ts} +46 -107
  146. package/src/api/parameters/entities/parameters.ts +7 -17
  147. package/src/api/parameters/index.ts +3 -3
  148. package/src/api/parameters/primitives/$config.spec.ts +356 -0
  149. package/src/api/parameters/schemas/activateConfigBodySchema.ts +12 -0
  150. package/src/api/parameters/schemas/checkScheduledResponseSchema.ts +8 -0
  151. package/src/api/parameters/schemas/configCurrentResponseSchema.ts +13 -0
  152. package/src/api/parameters/schemas/configHistoryResponseSchema.ts +9 -0
  153. package/src/api/parameters/schemas/configNameParamSchema.ts +10 -0
  154. package/src/api/parameters/schemas/configNamesResponseSchema.ts +8 -0
  155. package/src/api/parameters/schemas/configTreeNodeSchema.ts +13 -0
  156. package/src/api/parameters/schemas/configVersionParamSchema.ts +9 -0
  157. package/src/api/parameters/schemas/configVersionResponseSchema.ts +9 -0
  158. package/src/api/parameters/schemas/configsByStatusResponseSchema.ts +9 -0
  159. package/src/api/parameters/schemas/createConfigVersionBodySchema.ts +24 -0
  160. package/src/api/parameters/schemas/index.ts +15 -0
  161. package/src/api/parameters/schemas/parameterResponseSchema.ts +26 -0
  162. package/src/api/parameters/schemas/parameterStatusSchema.ts +13 -0
  163. package/src/api/parameters/schemas/rollbackConfigBodySchema.ts +15 -0
  164. package/src/api/parameters/schemas/statusParamSchema.ts +9 -0
  165. package/src/api/users/__tests__/EmailVerification.spec.ts +369 -0
  166. package/src/api/users/__tests__/PasswordReset.spec.ts +550 -0
  167. package/src/api/users/controllers/AdminIdentityController.spec.ts +365 -0
  168. package/src/api/users/controllers/{IdentityController.ts → AdminIdentityController.ts} +3 -4
  169. package/src/api/users/controllers/AdminSessionController.spec.ts +274 -0
  170. package/src/api/users/controllers/{SessionController.ts → AdminSessionController.ts} +3 -4
  171. package/src/api/users/controllers/AdminUserController.spec.ts +372 -0
  172. package/src/api/users/controllers/AdminUserController.ts +116 -0
  173. package/src/api/users/controllers/UserController.ts +4 -107
  174. package/src/api/users/controllers/UserRealmController.ts +3 -0
  175. package/src/api/users/entities/identities.ts +6 -6
  176. package/src/api/users/entities/sessions.ts +6 -6
  177. package/src/api/users/entities/users.ts +9 -9
  178. package/src/api/users/index.ts +9 -6
  179. package/src/api/users/primitives/$userRealm.ts +13 -8
  180. package/src/api/users/services/CredentialService.spec.ts +509 -0
  181. package/src/api/users/services/CredentialService.ts +46 -0
  182. package/src/api/users/services/IdentityService.ts +15 -0
  183. package/src/api/users/services/RegistrationService.spec.ts +630 -0
  184. package/src/api/users/services/RegistrationService.ts +18 -0
  185. package/src/api/users/services/SessionService.spec.ts +301 -0
  186. package/src/api/users/services/SessionService.ts +110 -1
  187. package/src/api/users/services/UserService.ts +67 -2
  188. package/src/api/verifications/__tests__/CodeVerification.spec.ts +318 -0
  189. package/src/api/verifications/__tests__/LinkVerification.spec.ts +279 -0
  190. package/src/api/verifications/entities/verifications.ts +6 -6
  191. package/src/api/verifications/jobs/VerificationJobs.spec.ts +50 -0
  192. package/src/batch/__tests__/startup-buffering.spec.ts +458 -0
  193. package/src/batch/primitives/$batch.spec.ts +766 -0
  194. package/src/batch/providers/BatchProvider.spec.ts +786 -0
  195. package/src/bin/index.ts +0 -1
  196. package/src/bucket/__tests__/shared.ts +194 -0
  197. package/src/bucket/primitives/$bucket.spec.ts +104 -0
  198. package/src/bucket/providers/FileStorageProvider.spec.ts +13 -0
  199. package/src/bucket/providers/LocalFileStorageProvider.spec.ts +77 -0
  200. package/src/bucket/providers/MemoryFileStorageProvider.spec.ts +82 -0
  201. package/src/cache/core/__tests__/shared.ts +377 -0
  202. package/src/cache/core/primitives/$cache.spec.ts +111 -0
  203. package/src/cache/redis/__tests__/cache-redis.spec.ts +70 -0
  204. package/src/cli/apps/AlephaCli.ts +25 -6
  205. package/src/cli/atoms/buildOptions.ts +88 -0
  206. package/src/cli/commands/build.ts +32 -69
  207. package/src/cli/commands/db.ts +0 -4
  208. package/src/cli/commands/dev.ts +34 -10
  209. package/src/cli/commands/gen/changelog.spec.ts +315 -0
  210. package/src/cli/commands/{changelog.ts → gen/changelog.ts} +9 -9
  211. package/src/cli/commands/gen/env.ts +53 -0
  212. package/src/cli/commands/gen/openapi.ts +71 -0
  213. package/src/cli/commands/gen/resource.ts +15 -0
  214. package/src/cli/commands/gen.ts +24 -0
  215. package/src/cli/commands/init.ts +2 -1
  216. package/src/cli/commands/root.ts +12 -3
  217. package/src/cli/commands/test.ts +0 -1
  218. package/src/cli/commands/typecheck.ts +5 -0
  219. package/src/cli/commands/verify.ts +1 -1
  220. package/src/cli/defineConfig.ts +49 -7
  221. package/src/cli/index.ts +2 -2
  222. package/src/cli/services/AlephaCliUtils.ts +105 -55
  223. package/src/cli/services/GitMessageParser.ts +1 -1
  224. package/src/command/helpers/Asker.spec.ts +127 -0
  225. package/src/command/helpers/Runner.spec.ts +126 -0
  226. package/src/command/helpers/Runner.ts +1 -1
  227. package/src/command/primitives/$command.spec.ts +1588 -0
  228. package/src/command/primitives/$command.ts +0 -6
  229. package/src/command/providers/CliProvider.ts +75 -27
  230. package/src/core/Alepha.ts +87 -0
  231. package/src/core/__tests__/Alepha-emit.spec.ts +22 -0
  232. package/src/core/__tests__/Alepha-graph.spec.ts +93 -0
  233. package/src/core/__tests__/Alepha-has.spec.ts +41 -0
  234. package/src/core/__tests__/Alepha-inject.spec.ts +93 -0
  235. package/src/core/__tests__/Alepha-register.spec.ts +81 -0
  236. package/src/core/__tests__/Alepha-start.spec.ts +176 -0
  237. package/src/core/__tests__/Alepha-with.spec.ts +14 -0
  238. package/src/core/__tests__/TypeBox-usecases.spec.ts +35 -0
  239. package/src/core/__tests__/TypeBoxLocale.spec.ts +15 -0
  240. package/src/core/__tests__/descriptor.spec.ts +34 -0
  241. package/src/core/__tests__/fixtures/A.ts +5 -0
  242. package/src/core/__tests__/pagination.spec.ts +77 -0
  243. package/src/core/helpers/jsonSchemaToTypeBox.ts +2 -2
  244. package/src/core/primitives/$atom.spec.ts +43 -0
  245. package/src/core/primitives/$hook.spec.ts +130 -0
  246. package/src/core/primitives/$inject.spec.ts +175 -0
  247. package/src/core/primitives/$module.spec.ts +115 -0
  248. package/src/core/providers/CodecManager.spec.ts +740 -0
  249. package/src/core/providers/EventManager.spec.ts +762 -0
  250. package/src/core/providers/EventManager.ts +4 -0
  251. package/src/core/providers/StateManager.spec.ts +365 -0
  252. package/src/core/providers/TypeProvider.spec.ts +1607 -0
  253. package/src/core/providers/TypeProvider.ts +20 -26
  254. package/src/datetime/primitives/$interval.spec.ts +103 -0
  255. package/src/datetime/providers/DateTimeProvider.spec.ts +86 -0
  256. package/src/email/primitives/$email.spec.ts +175 -0
  257. package/src/email/providers/LocalEmailProvider.spec.ts +341 -0
  258. package/src/fake/__tests__/keyName.example.ts +40 -0
  259. package/src/fake/__tests__/keyName.spec.ts +152 -0
  260. package/src/fake/__tests__/module.example.ts +32 -0
  261. package/src/fake/providers/FakeProvider.spec.ts +438 -0
  262. package/src/file/providers/FileSystemProvider.ts +8 -0
  263. package/src/file/providers/NodeFileSystemProvider.spec.ts +418 -0
  264. package/src/file/providers/NodeFileSystemProvider.ts +5 -0
  265. package/src/file/services/FileDetector.spec.ts +591 -0
  266. package/src/lock/core/__tests__/shared.ts +190 -0
  267. package/src/lock/core/providers/MemoryLockProvider.spec.ts +25 -0
  268. package/src/lock/redis/providers/RedisLockProvider.spec.ts +25 -0
  269. package/src/logger/__tests__/SimpleFormatterProvider.spec.ts +109 -0
  270. package/src/logger/index.ts +15 -3
  271. package/src/logger/primitives/$logger.spec.ts +108 -0
  272. package/src/logger/services/Logger.spec.ts +295 -0
  273. package/src/mcp/__tests__/errors.spec.ts +175 -0
  274. package/src/mcp/__tests__/integration.spec.ts +450 -0
  275. package/src/mcp/helpers/jsonrpc.spec.ts +380 -0
  276. package/src/mcp/primitives/$prompt.spec.ts +468 -0
  277. package/src/mcp/primitives/$resource.spec.ts +390 -0
  278. package/src/mcp/primitives/$tool.spec.ts +406 -0
  279. package/src/mcp/providers/McpServerProvider.spec.ts +797 -0
  280. package/src/mcp/transports/StdioMcpTransport.ts +1 -1
  281. package/src/orm/__tests__/$repository-crud.spec.ts +276 -0
  282. package/src/orm/__tests__/$repository-hooks.spec.ts +325 -0
  283. package/src/orm/__tests__/$repository-orderBy.spec.ts +128 -0
  284. package/src/orm/__tests__/$repository-pagination-sort.spec.ts +149 -0
  285. package/src/orm/__tests__/$repository-save.spec.ts +37 -0
  286. package/src/orm/__tests__/ModelBuilder-integration.spec.ts +490 -0
  287. package/src/orm/__tests__/ModelBuilder-types.spec.ts +186 -0
  288. package/src/orm/__tests__/PostgresProvider.spec.ts +46 -0
  289. package/src/orm/__tests__/delete-returning.spec.ts +256 -0
  290. package/src/orm/__tests__/deletedAt.spec.ts +80 -0
  291. package/src/orm/__tests__/enums.spec.ts +315 -0
  292. package/src/orm/__tests__/execute.spec.ts +72 -0
  293. package/src/orm/__tests__/fixtures/bigEntitySchema.ts +65 -0
  294. package/src/orm/__tests__/fixtures/userEntitySchema.ts +27 -0
  295. package/src/orm/__tests__/joins.spec.ts +1114 -0
  296. package/src/orm/__tests__/page.spec.ts +287 -0
  297. package/src/orm/__tests__/primaryKey.spec.ts +87 -0
  298. package/src/orm/__tests__/query-date-encoding.spec.ts +402 -0
  299. package/src/orm/__tests__/ref-auto-onDelete.spec.ts +156 -0
  300. package/src/orm/__tests__/references.spec.ts +102 -0
  301. package/src/orm/__tests__/security.spec.ts +710 -0
  302. package/src/orm/__tests__/sqlite.spec.ts +111 -0
  303. package/src/orm/__tests__/string-operators.spec.ts +429 -0
  304. package/src/orm/__tests__/timestamps.spec.ts +388 -0
  305. package/src/orm/__tests__/validation.spec.ts +183 -0
  306. package/src/orm/__tests__/version.spec.ts +64 -0
  307. package/src/orm/helpers/parseQueryString.spec.ts +196 -0
  308. package/src/orm/index.ts +2 -8
  309. package/src/orm/primitives/$repository.spec.ts +137 -0
  310. package/src/orm/primitives/$sequence.spec.ts +29 -0
  311. package/src/orm/primitives/$transaction.spec.ts +82 -0
  312. package/src/orm/providers/drivers/BunPostgresProvider.ts +3 -3
  313. package/src/orm/providers/drivers/BunSqliteProvider.ts +1 -1
  314. package/src/orm/providers/drivers/CloudflareD1Provider.ts +1 -1
  315. package/src/orm/providers/drivers/DatabaseProvider.ts +1 -1
  316. package/src/orm/providers/drivers/NodePostgresProvider.ts +3 -3
  317. package/src/orm/providers/drivers/NodeSqliteProvider.ts +1 -1
  318. package/src/orm/providers/drivers/PglitePostgresProvider.ts +2 -2
  319. package/src/orm/services/ModelBuilder.spec.ts +575 -0
  320. package/src/orm/services/Repository.spec.ts +137 -0
  321. package/src/queue/core/__tests__/shared.ts +143 -0
  322. package/src/queue/core/providers/MemoryQueueProvider.spec.ts +23 -0
  323. package/src/queue/core/providers/WorkerProvider.spec.ts +394 -0
  324. package/src/queue/redis/providers/RedisQueueProvider.spec.ts +23 -0
  325. package/src/redis/__tests__/redis.spec.ts +58 -0
  326. package/src/retry/primitives/$retry.spec.ts +234 -0
  327. package/src/retry/providers/RetryProvider.spec.ts +438 -0
  328. package/src/router/__tests__/match.spec.ts +252 -0
  329. package/src/router/providers/RouterProvider.spec.ts +197 -0
  330. package/src/scheduler/__tests__/$scheduler-cron.spec.ts +25 -0
  331. package/src/scheduler/__tests__/$scheduler-interval.spec.ts +25 -0
  332. package/src/scheduler/__tests__/shared.ts +77 -0
  333. package/src/security/__tests__/bug-1-wildcard-after-start.spec.ts +229 -0
  334. package/src/security/__tests__/bug-2-password-validation.spec.ts +245 -0
  335. package/src/security/__tests__/bug-3-regex-vulnerability.spec.ts +407 -0
  336. package/src/security/__tests__/bug-4-oauth2-validation.spec.ts +439 -0
  337. package/src/security/__tests__/multi-layer-permissions.spec.ts +522 -0
  338. package/src/security/primitives/$permission.spec.ts +30 -0
  339. package/src/security/primitives/$permission.ts +2 -2
  340. package/src/security/primitives/$realm.spec.ts +101 -0
  341. package/src/security/primitives/$role.spec.ts +52 -0
  342. package/src/security/primitives/$serviceAccount.spec.ts +61 -0
  343. package/src/security/providers/SecurityProvider.spec.ts +350 -0
  344. package/src/server/auth/providers/ServerAuthProvider.ts +0 -2
  345. package/src/server/cache/providers/ServerCacheProvider.spec.ts +1125 -0
  346. package/src/server/cache/providers/ServerCacheProvider.ts +94 -9
  347. package/src/server/compress/providers/ServerCompressProvider.spec.ts +31 -0
  348. package/src/server/compress/providers/ServerCompressProvider.ts +63 -2
  349. package/src/server/cookies/providers/ServerCookiesProvider.spec.ts +253 -0
  350. package/src/server/core/__tests__/ServerRouterProvider-getRoutes.spec.ts +334 -0
  351. package/src/server/core/__tests__/ServerRouterProvider-requestId.spec.ts +129 -0
  352. package/src/server/core/helpers/ServerReply.ts +2 -2
  353. package/src/server/core/primitives/$action.spec.ts +191 -0
  354. package/src/server/core/primitives/$route.spec.ts +65 -0
  355. package/src/server/core/providers/ServerBodyParserProvider.spec.ts +93 -0
  356. package/src/server/core/providers/ServerLoggerProvider.spec.ts +100 -0
  357. package/src/server/core/providers/ServerProvider.ts +14 -2
  358. package/src/server/core/services/HttpClient.spec.ts +123 -0
  359. package/src/server/core/services/UserAgentParser.spec.ts +111 -0
  360. package/src/server/cors/providers/ServerCorsProvider.spec.ts +481 -0
  361. package/src/server/health/providers/ServerHealthProvider.spec.ts +22 -0
  362. package/src/server/helmet/providers/ServerHelmetProvider.spec.ts +105 -0
  363. package/src/server/links/__tests__/$action.spec.ts +238 -0
  364. package/src/server/links/__tests__/fixtures/CrudApp.ts +122 -0
  365. package/src/server/links/__tests__/requestId.spec.ts +120 -0
  366. package/src/server/links/primitives/$remote.spec.ts +228 -0
  367. package/src/server/links/providers/LinkProvider.spec.ts +54 -0
  368. package/src/server/links/providers/LinkProvider.ts +49 -3
  369. package/src/server/links/providers/ServerLinksProvider.ts +1 -53
  370. package/src/server/links/schemas/apiLinksResponseSchema.ts +7 -0
  371. package/src/server/metrics/providers/ServerMetricsProvider.spec.ts +25 -0
  372. package/src/server/multipart/providers/ServerMultipartProvider.spec.ts +528 -0
  373. package/src/server/proxy/primitives/$proxy.spec.ts +87 -0
  374. package/src/server/rate-limit/__tests__/ActionRateLimit.spec.ts +211 -0
  375. package/src/server/rate-limit/providers/ServerRateLimitProvider.spec.ts +344 -0
  376. package/src/server/security/__tests__/BasicAuth.spec.ts +684 -0
  377. package/src/server/security/__tests__/ServerSecurityProvider-realm.spec.ts +388 -0
  378. package/src/server/security/providers/ServerSecurityProvider.spec.ts +123 -0
  379. package/src/server/static/primitives/$serve.spec.ts +193 -0
  380. package/src/server/static/providers/ServerStaticProvider.ts +10 -0
  381. package/src/server/swagger/__tests__/ui.spec.ts +52 -0
  382. package/src/server/swagger/primitives/$swagger.spec.ts +193 -0
  383. package/src/server/swagger/providers/ServerSwaggerProvider.ts +19 -12
  384. package/src/sms/primitives/$sms.spec.ts +165 -0
  385. package/src/sms/providers/LocalSmsProvider.spec.ts +224 -0
  386. package/src/sms/providers/MemorySmsProvider.spec.ts +193 -0
  387. package/src/thread/primitives/$thread.spec.ts +186 -0
  388. package/src/topic/core/__tests__/shared.ts +144 -0
  389. package/src/topic/core/providers/MemoryTopicProvider.spec.ts +23 -0
  390. package/src/topic/redis/providers/RedisTopicProvider.spec.ts +23 -0
  391. package/src/vite/helpers/importViteReact.ts +13 -0
  392. package/src/vite/index.ts +1 -21
  393. package/src/vite/plugins/viteAlephaDev.ts +32 -5
  394. package/src/vite/plugins/viteAlephaSsrPreload.ts +222 -0
  395. package/src/vite/tasks/buildClient.ts +11 -0
  396. package/src/vite/tasks/buildServer.ts +47 -3
  397. package/src/vite/tasks/devServer.ts +69 -0
  398. package/src/vite/tasks/index.ts +2 -1
  399. package/src/vite/tasks/runAlepha.ts +7 -1
  400. package/src/websocket/__tests__/$websocket-new.spec.ts +195 -0
  401. package/src/websocket/primitives/$channel.spec.ts +30 -0
  402. package/src/cli/assets/viteConfigTs.ts +0 -14
  403. package/src/cli/commands/run.ts +0 -24
  404. package/src/vite/plugins/viteAlepha.ts +0 -37
  405. package/src/vite/plugins/viteAlephaBuild.ts +0 -281
package/src/cli/index.ts CHANGED
@@ -2,16 +2,16 @@ export * from "./apps/AlephaCli.ts";
2
2
  export * from "./apps/AlephaPackageBuilderCli.ts";
3
3
  export * from "./atoms/changelogOptions.ts";
4
4
  export * from "./commands/build.ts";
5
- export * from "./commands/changelog.ts";
6
5
  export * from "./commands/clean.ts";
7
6
  export * from "./commands/db.ts";
8
7
  export * from "./commands/deploy.ts";
9
8
  export * from "./commands/dev.ts";
10
9
  export * from "./commands/format.ts";
10
+ export * from "./commands/gen/changelog.ts";
11
+ export * from "./commands/gen/openapi.ts";
11
12
  export * from "./commands/init.ts";
12
13
  export * from "./commands/lint.ts";
13
14
  export * from "./commands/root.ts";
14
- export * from "./commands/run.ts";
15
15
  export * from "./commands/test.ts";
16
16
  export * from "./commands/typecheck.ts";
17
17
  export * from "./commands/verify.ts";
@@ -6,7 +6,6 @@ import { EnvUtils, type RunnerMethod } from "alepha/command";
6
6
  import { FileSystemProvider } from "alepha/file";
7
7
  import { $logger } from "alepha/logger";
8
8
  import { boot } from "alepha/vite";
9
- import { tsImport } from "tsx/esm/api";
10
9
  import { appRouterTs } from "../assets/appRouterTs.ts";
11
10
  import { biomeJson } from "../assets/biomeJson.ts";
12
11
  import { dummySpecTs } from "../assets/dummySpecTs.ts";
@@ -15,7 +14,6 @@ import { indexHtml } from "../assets/indexHtml.ts";
15
14
  import { mainBrowserTs } from "../assets/mainBrowserTs.ts";
16
15
  import { mainTs } from "../assets/mainTs.ts";
17
16
  import { tsconfigJson } from "../assets/tsconfigJson.ts";
18
- import { viteConfigTs } from "../assets/viteConfigTs.ts";
19
17
  import { version } from "../version.ts";
20
18
 
21
19
  /**
@@ -32,6 +30,7 @@ export class AlephaCliUtils {
32
30
  protected readonly log = $logger();
33
31
  protected readonly fs = $inject(FileSystemProvider);
34
32
  protected readonly envUtils = $inject(EnvUtils);
33
+ protected readonly alepha = $inject(Alepha);
35
34
 
36
35
  /**
37
36
  * Execute a command using npx with inherited stdio.
@@ -142,6 +141,73 @@ export class AlephaCliUtils {
142
141
  // Package Manager & Project Setup
143
142
  // ===================================================================================================================
144
143
 
144
+ public async editFile(
145
+ root: string,
146
+ name: string,
147
+ editFn: (content: string) => string | Promise<string>,
148
+ ): Promise<void> {
149
+ const filePath = join(root, name);
150
+ try {
151
+ const content = await readFile(filePath, "utf8");
152
+ const newContent = await editFn(content);
153
+ await writeFile(filePath, newContent);
154
+ } catch (error) {
155
+ this.log.debug("Could not edit file", error);
156
+ }
157
+ }
158
+
159
+ public async editJsonFile(
160
+ root: string,
161
+ name: string,
162
+ editFn: (obj: any) => any | Promise<any>,
163
+ ): Promise<void> {
164
+ return await this.editFile(root, name, async (content) => {
165
+ const obj = JSON.parse(content);
166
+ const newObj = await editFn(obj);
167
+ return JSON.stringify(newObj, null, 2);
168
+ });
169
+ }
170
+
171
+ public async removeFiles(root: string, files: string[]): Promise<void> {
172
+ await Promise.all(
173
+ files.map((file) =>
174
+ this.fs.rm(join(root, file), { force: true, recursive: true }),
175
+ ),
176
+ );
177
+ }
178
+
179
+ public async removeYarn(root: string): Promise<void> {
180
+ await this.removeFiles(root, [".yarn", ".yarnrc.yml", "yarn.lock"]);
181
+ await this.editJsonFile(root, "package.json", (pkg) => {
182
+ delete pkg.packageManager;
183
+ });
184
+ }
185
+
186
+ public async removePnpm(root: string): Promise<void> {
187
+ await this.removeFiles(root, ["pnpm-lock.yaml", "pnpm-workspace.yaml"]);
188
+ await this.editJsonFile(root, "package.json", (pkg) => {
189
+ delete pkg.packageManager;
190
+ });
191
+ }
192
+
193
+ public async removeNpm(root: string): Promise<void> {
194
+ await this.removeFiles(root, ["package-lock.json"]);
195
+ }
196
+
197
+ public async removeBun(root: string): Promise<void> {
198
+ await this.removeFiles(root, ["bun.lockb", "bun.lock"]);
199
+ }
200
+
201
+ public async removeAllPmFilesExcept(
202
+ root: string,
203
+ except: string,
204
+ ): Promise<void> {
205
+ if (except !== "yarn") await this.removeYarn(root);
206
+ if (except !== "pnpm") await this.removePnpm(root);
207
+ if (except !== "npm") await this.removeNpm(root);
208
+ if (except !== "bun") await this.removeBun(root);
209
+ }
210
+
145
211
  /**
146
212
  * Ensure Yarn is configured in the project directory.
147
213
  *
@@ -157,25 +223,19 @@ export class AlephaCliUtils {
157
223
  false,
158
224
  );
159
225
 
160
- // remove lock files from other package managers
161
- await this.fs.rm(join(root, "package-lock.json"), { force: true });
162
- await this.fs.rm(join(root, "pnpm-lock.yaml"), { force: true });
226
+ await this.removeAllPmFilesExcept(root, "yarn");
227
+ }
228
+
229
+ public async ensureBun(root: string): Promise<void> {
230
+ await this.removeAllPmFilesExcept(root, "bun");
163
231
  }
164
232
 
165
233
  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 });
234
+ await this.removeAllPmFilesExcept(root, "pnpm");
171
235
  }
172
236
 
173
237
  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 });
238
+ await this.removeAllPmFilesExcept(root, "npm");
179
239
  }
180
240
 
181
241
  /**
@@ -272,7 +332,6 @@ export class AlephaCliUtils {
272
332
  opts: {
273
333
  packageJson?: boolean | DependencyModes;
274
334
  tsconfigJson?: boolean;
275
- viteConfigTs?: boolean;
276
335
  indexHtml?: boolean;
277
336
  biomeJson?: boolean;
278
337
  editorconfig?: boolean;
@@ -291,9 +350,6 @@ export class AlephaCliUtils {
291
350
  if (opts.tsconfigJson) {
292
351
  tasks.push(this.ensureTsConfig(root));
293
352
  }
294
- if (opts.viteConfigTs) {
295
- tasks.push(this.ensureViteConfig(root));
296
- }
297
353
  if (opts.indexHtml) {
298
354
  tasks.push(this.ensureIndexHtml(root));
299
355
  }
@@ -318,23 +374,6 @@ export class AlephaCliUtils {
318
374
  await this.ensureFileExists(root, "tsconfig.json", tsconfigJson, true);
319
375
  }
320
376
 
321
- /**
322
- * Ensure vite.config.ts exists in the project.
323
- *
324
- * Creates a standard Alepha vite.config.ts if none exists.
325
- */
326
- public async ensureViteConfig(
327
- root: string,
328
- serverEntry?: string,
329
- ): Promise<void> {
330
- await this.ensureFileExists(
331
- root,
332
- "vite.config.ts",
333
- viteConfigTs(serverEntry),
334
- false,
335
- );
336
- }
337
-
338
377
  protected async checkFileExists(
339
378
  root: string,
340
379
  name: string,
@@ -436,9 +475,10 @@ export class AlephaCliUtils {
436
475
  process.env.ALEPHA_CLI_IMPORT = "true";
437
476
 
438
477
  const entry = await boot.getServerEntry(rootDir, explicitEntry);
439
- const mod = await tsImport(entry, {
440
- parentURL: import.meta.url,
441
- });
478
+
479
+ delete (global as any).__alepha;
480
+
481
+ const mod = await import(entry);
442
482
 
443
483
  this.log.debug(`Load entry: ${entry}`);
444
484
 
@@ -523,6 +563,9 @@ ${models.map((it: string) => `export const ${it} = models["${it}"];`).join("\n")
523
563
  if (flags?.bun) {
524
564
  return "bun";
525
565
  }
566
+ if (this.alepha.isBun()) {
567
+ return "bun";
568
+ }
526
569
  if (await this.checkFileExists(root, "yarn.lock", true)) {
527
570
  return "yarn";
528
571
  }
@@ -625,7 +668,7 @@ ${models.map((it: string) => `export const ${it} = models["${it}"];`).join("\n")
625
668
  async readPackageJson(root: string): Promise<Record<string, any>> {
626
669
  const packageJson = await this.fs
627
670
  .createFile({
628
- path: join(root, "package.json"),
671
+ path: this.fs.join(root, "package.json"),
629
672
  })
630
673
  .text();
631
674
  return JSON.parse(packageJson);
@@ -659,6 +702,27 @@ ${models.map((it: string) => `export const ${it} = models["${it}"];`).join("\n")
659
702
  return this.hasDependency(root, "expo");
660
703
  }
661
704
 
705
+ async getInstallCommand(root: string, packageName: string, dev = true) {
706
+ const pm = await this.getPackageManager(root);
707
+ let cmd: string;
708
+
709
+ switch (pm) {
710
+ case "yarn":
711
+ cmd = `yarn add ${dev ? "-D" : ""} ${packageName}`;
712
+ break;
713
+ case "pnpm":
714
+ cmd = `pnpm add ${dev ? "-D" : ""} ${packageName}`;
715
+ break;
716
+ case "bun":
717
+ cmd = `bun add ${dev ? "-d" : ""} ${packageName}`;
718
+ break;
719
+ default:
720
+ cmd = `npm install ${dev ? "--save-dev" : ""} ${packageName}`;
721
+ }
722
+
723
+ return cmd.replace(/\s+/g, " ").trim();
724
+ }
725
+
662
726
  /**
663
727
  * Install a dependency if it's missing from the project.
664
728
  *
@@ -677,21 +741,7 @@ ${models.map((it: string) => `export const ${it} = models["${it}"];`).join("\n")
677
741
  return;
678
742
  }
679
743
 
680
- const pm = await this.getPackageManager(root);
681
- let cmd: string;
682
-
683
- switch (pm) {
684
- case "yarn":
685
- cmd = `yarn add ${dev ? "-D" : ""} ${packageName}`;
686
- break;
687
- case "pnpm":
688
- cmd = `pnpm add ${dev ? "-D" : ""} ${packageName}`;
689
- break;
690
- default:
691
- cmd = `npm install ${dev ? "--save-dev" : ""} ${packageName}`;
692
- }
693
-
694
- cmd = cmd.replace(/\s+/g, " ").trim();
744
+ const cmd = await this.getInstallCommand(root, packageName, dev);
695
745
 
696
746
  if (options.run) {
697
747
  // if it's during a Runner flow, just use the runner's run method
@@ -3,7 +3,7 @@ import {
3
3
  type ChangelogOptions,
4
4
  DEFAULT_IGNORE,
5
5
  } from "../atoms/changelogOptions.ts";
6
- import type { Commit } from "../commands/changelog.ts";
6
+ import type { Commit } from "../commands/gen/changelog.ts";
7
7
 
8
8
  /**
9
9
  * Service for parsing git commit messages into structured format.
@@ -0,0 +1,127 @@
1
+ import { Alepha, AlephaError, t } from "alepha";
2
+ import {
3
+ LogDestinationProvider,
4
+ MemoryDestinationProvider,
5
+ } from "alepha/logger";
6
+ import { afterEach, beforeEach, describe, expect, test, vi } from "vitest";
7
+ import { Asker } from "../index.ts";
8
+
9
+ describe("Asker", () => {
10
+ let alepha: Alepha;
11
+ let asker: Asker;
12
+ let mockLogger: MemoryDestinationProvider;
13
+
14
+ const mockPromptInterface = (answers: string[]) => {
15
+ const question = vi.fn();
16
+ for (const answer of answers) {
17
+ question.mockResolvedValueOnce(answer);
18
+ }
19
+ const close = vi.fn();
20
+
21
+ vi.spyOn(
22
+ asker as unknown as { createPromptInterface: () => any },
23
+ "createPromptInterface",
24
+ ).mockReturnValue({
25
+ question,
26
+ close,
27
+ });
28
+
29
+ return { question, close };
30
+ };
31
+
32
+ beforeEach(() => {
33
+ alepha = Alepha.create({
34
+ env: {
35
+ LOG_LEVEL: "info",
36
+ },
37
+ })
38
+ .with({
39
+ provide: LogDestinationProvider,
40
+ use: MemoryDestinationProvider,
41
+ })
42
+ .with(Asker);
43
+
44
+ asker = alepha.inject(Asker);
45
+ mockLogger = alepha.inject(MemoryDestinationProvider);
46
+ mockLogger.clear();
47
+ });
48
+
49
+ afterEach(() => {
50
+ vi.restoreAllMocks();
51
+ });
52
+
53
+ test("returns trimmed string when no schema is provided", async () => {
54
+ const { question, close } = mockPromptInterface([" hello world "]);
55
+
56
+ const result = await asker.ask("What is your name?");
57
+
58
+ expect(result).toBe("hello world");
59
+ expect(question).toHaveBeenCalledTimes(1);
60
+ expect(question).toHaveBeenCalledWith("What is your name?\n> ");
61
+ expect(close).toHaveBeenCalledTimes(1);
62
+ });
63
+
64
+ test("retries until schema validation passes", async () => {
65
+ const { question, close } = mockPromptInterface(["abc", "41"]);
66
+
67
+ const result = await asker.ask("Enter a number", {
68
+ schema: t.number(),
69
+ });
70
+
71
+ expect(result).toBe(41);
72
+ expect(question).toHaveBeenCalledTimes(2);
73
+ expect(close).toHaveBeenCalledTimes(1);
74
+ expect(mockLogger.logs.some((log) => log.level === "ERROR")).toBe(true);
75
+ });
76
+
77
+ test("uses schema defaults when the user provides an empty answer", async () => {
78
+ const { question, close } = mockPromptInterface([""]);
79
+
80
+ const result = await asker.ask("What is your favorite color?", {
81
+ schema: t.text({ default: "blue" }),
82
+ });
83
+
84
+ expect(result).toBe("blue");
85
+ expect(question).toHaveBeenCalledTimes(1);
86
+ expect(close).toHaveBeenCalledTimes(1);
87
+ });
88
+
89
+ test("retries when custom validation throws an AlephaError", async () => {
90
+ const { question, close } = mockPromptInterface(["wrong", "right"]);
91
+
92
+ const result = await asker.ask("Provide the secret", {
93
+ schema: t.text(),
94
+ validate: (value) => {
95
+ if (value !== "right") {
96
+ throw new AlephaError("Invalid secret");
97
+ }
98
+ },
99
+ });
100
+
101
+ expect(result).toBe("right");
102
+ expect(question).toHaveBeenCalledTimes(2);
103
+ expect(close).toHaveBeenCalledTimes(1);
104
+
105
+ const errorLogs = mockLogger.logs.filter((log) => log.level === "ERROR");
106
+ expect(errorLogs).toHaveLength(1);
107
+ expect(errorLogs[0].message).toContain("Invalid secret");
108
+ });
109
+
110
+ test("propagates unexpected errors without logging", async () => {
111
+ const { question, close } = mockPromptInterface(["value"]);
112
+ const unexpectedError = new Error("boom");
113
+
114
+ await expect(
115
+ asker.ask("Trigger failure", {
116
+ schema: t.text(),
117
+ validate: () => {
118
+ throw unexpectedError;
119
+ },
120
+ }),
121
+ ).rejects.toBe(unexpectedError);
122
+
123
+ expect(question).toHaveBeenCalledTimes(1);
124
+ expect(close).toHaveBeenCalledTimes(1);
125
+ expect(mockLogger.logs.some((log) => log.level === "ERROR")).toBe(false);
126
+ });
127
+ });
@@ -0,0 +1,126 @@
1
+ import { Alepha } from "alepha";
2
+ import {
3
+ LogDestinationProvider,
4
+ MemoryDestinationProvider,
5
+ } from "alepha/logger";
6
+ import { afterEach, beforeEach, describe, expect, test, vi } from "vitest";
7
+ import { Runner } from "../index.ts";
8
+
9
+ describe("Runner", () => {
10
+ let mockLogger: MemoryDestinationProvider;
11
+ let runner: Runner;
12
+
13
+ beforeEach(async () => {
14
+ const alepha = Alepha.create({
15
+ env: {
16
+ LOG_LEVEL: "info",
17
+ },
18
+ }).with({
19
+ provide: LogDestinationProvider,
20
+ use: MemoryDestinationProvider,
21
+ });
22
+ // Create a new MockLogger and Runner for each test to ensure isolation
23
+ runner = alepha.inject(Runner);
24
+ mockLogger = alepha.inject(MemoryDestinationProvider);
25
+ });
26
+
27
+ afterEach(() => {
28
+ vi.clearAllMocks();
29
+ });
30
+
31
+ test("should execute a single shell command via run.sh", async () => {
32
+ await runner.run(`echo "hello"`);
33
+
34
+ expect(mockLogger.logs).toHaveLength(2);
35
+ const startLog = mockLogger.logs[0];
36
+ const finishLog = mockLogger.logs[1];
37
+
38
+ expect(startLog.message).toBe("Starting 'echo \"hello\"' ...");
39
+ expect(startLog.level).toBe("INFO");
40
+
41
+ expect(finishLog.message).toMatch(
42
+ /^Finished 'echo "hello"' after \d+\.\ds$/,
43
+ );
44
+ expect(finishLog.level).toBe("INFO");
45
+
46
+ const timers = (runner as any).timers;
47
+ expect(timers).toHaveLength(1);
48
+ expect(timers[0].name).toBe('echo "hello"');
49
+ expect(timers[0].duration).toMatch(/^\d+\.\ds$/);
50
+ });
51
+
52
+ test("should execute a single shell command via run(sh`...`)", async () => {
53
+ await runner.run(`echo "world"`);
54
+ expect(mockLogger.logs[0].message).toBe("Starting 'echo \"world\"' ...");
55
+ expect(mockLogger.logs).toHaveLength(2);
56
+ });
57
+
58
+ test("should execute a single function task via run.fn", async () => {
59
+ const mockFn = vi.fn();
60
+ await runner.run("my-test-function", mockFn);
61
+
62
+ expect(mockFn).toHaveBeenCalledOnce();
63
+ expect(mockLogger.logs).toHaveLength(2);
64
+ expect(mockLogger.logs[0].message).toBe("Starting 'my-test-function' ...");
65
+ expect(mockLogger.logs[1].message).toMatch(
66
+ /^Finished 'my-test-function' after \d+\.\ds$/,
67
+ );
68
+ });
69
+
70
+ test("should execute a single function task via run(fn(...))", async () => {
71
+ const mockFn = vi.fn();
72
+ await runner.run("another-function", mockFn);
73
+ expect(mockFn).toHaveBeenCalledOnce();
74
+ expect(mockLogger.logs).toHaveLength(2);
75
+ });
76
+
77
+ test("should execute an array of tasks in parallel", async () => {
78
+ const fn1 = vi.fn(() => new Promise((res) => setTimeout(res, 20)));
79
+ const fn2 = vi.fn(() => new Promise((res) => setTimeout(res, 20)));
80
+
81
+ await runner.run([
82
+ `echo "parallel sh"`,
83
+ { name: "parallel fn 1", handler: fn1 },
84
+ { name: "parallel fn 2", handler: fn2 },
85
+ ]);
86
+
87
+ expect(fn1).toHaveBeenCalledOnce();
88
+ expect(fn2).toHaveBeenCalledOnce();
89
+ expect(mockLogger.logs).toHaveLength(6); // 3 start, 3 finish logs
90
+ expect((runner as any).timers).toHaveLength(3);
91
+ });
92
+
93
+ test("should throw and log an error for a failing shell command", async () => {
94
+ await expect(runner.run(`exit 1`)).rejects.toThrow("Task 'exit 1' failed");
95
+ });
96
+
97
+ test("should throw and log an error for a failing function task", async () => {
98
+ const error = new Error("Function failed!");
99
+ const failingFn = () => {
100
+ throw error;
101
+ };
102
+
103
+ await expect(runner.run("failing-task", failingFn)).rejects.toThrow(
104
+ "Task 'failing-task' failed",
105
+ );
106
+ });
107
+
108
+ test("summary() should print a formatted table of executed tasks", async () => {
109
+ await runner.run(`echo "Task 1"`);
110
+ await runner.run("A slightly longer task name", () => {});
111
+
112
+ runner.end();
113
+
114
+ const logs = mockLogger.logs
115
+ .slice(4)
116
+ .map((l) => l.message)
117
+ .join("\n");
118
+ });
119
+
120
+ test("summary() should not print a table if no tasks were run", () => {
121
+ runner.end();
122
+
123
+ const logs = mockLogger.logs.map((l) => l.message);
124
+ expect(logs.length).toBe(0);
125
+ });
126
+ });
@@ -179,7 +179,7 @@ export class Runner {
179
179
  /**
180
180
  * Prints a summary of all executed tasks and their durations.
181
181
  */
182
- public summary(): void {
182
+ public end(): void {
183
183
  if (this.useDynamicLogger && this.firstTaskStarted) {
184
184
  this.prettyPrint.endCommand();
185
185
  return;