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
@@ -0,0 +1,550 @@
1
+ import { Alepha } from "alepha";
2
+ import { AlephaApiVerification } from "alepha/api/verifications";
3
+ import { DateTimeProvider } from "alepha/datetime";
4
+ import { AlephaEmail, MemoryEmailProvider } from "alepha/email";
5
+ import { AlephaSecurity, CryptoProvider } from "alepha/security";
6
+ import { BadRequestError } from "alepha/server";
7
+ import { describe, it } from "vitest";
8
+ import {
9
+ AlephaApiUsers,
10
+ CredentialService,
11
+ SessionService,
12
+ UserController,
13
+ } from "../index.ts";
14
+
15
+ const setup = async () => {
16
+ const alepha = Alepha.create({
17
+ env: { LOG_LEVEL: "error" },
18
+ });
19
+
20
+ alepha.with(AlephaSecurity);
21
+ alepha.with(AlephaEmail);
22
+ alepha.with(AlephaApiVerification);
23
+ alepha.with(AlephaApiUsers);
24
+
25
+ await alepha.start();
26
+
27
+ const emailProvider = alepha.inject(MemoryEmailProvider);
28
+ emailProvider.records = [];
29
+
30
+ return {
31
+ alepha,
32
+ credentialService: alepha.inject(CredentialService),
33
+ sessionService: alepha.inject(SessionService),
34
+ cryptoProvider: alepha.inject(CryptoProvider),
35
+ dateTimeProvider: alepha.inject(DateTimeProvider),
36
+ emailProvider,
37
+ actions: alepha.inject(UserController),
38
+ };
39
+ };
40
+
41
+ // Helper to extract code from email
42
+ const extractCode = (emailBody: string): string => {
43
+ // Code is displayed in the email body as a 6-digit number
44
+ const match = emailBody.match(/(\d{6})/);
45
+ if (!match) throw new Error("Code not found in email");
46
+ return match[1];
47
+ };
48
+
49
+ describe("alepha/api/users - Password Reset", () => {
50
+ it("should successfully request password reset and send email", async ({
51
+ expect,
52
+ }) => {
53
+ const { credentialService, cryptoProvider, emailProvider, actions } =
54
+ await setup();
55
+
56
+ // Create a test user with credentials
57
+ const hashedPassword = await cryptoProvider.hashPassword("OldPassword123");
58
+ const user = await credentialService.users().create({
59
+ username: "testuser",
60
+ email: "test@example.com",
61
+ roles: ["user"],
62
+ });
63
+
64
+ await credentialService.identities().create({
65
+ userId: user.id,
66
+ provider: "credentials",
67
+ providerUserId: "test@example.com",
68
+ providerData: { password: hashedPassword },
69
+ });
70
+
71
+ // Request password reset
72
+ const result = await actions.requestPasswordReset({
73
+ body: {
74
+ email: "test@example.com",
75
+ },
76
+ });
77
+
78
+ expect(result.success).toBe(true);
79
+ expect(result.message).toContain("password reset code has been sent");
80
+
81
+ // Verify email was sent via password reset notification
82
+ await expect.poll(() => emailProvider.records.length).toBe(1);
83
+ const email = emailProvider.records[0];
84
+ expect(email.to).toBe("test@example.com");
85
+ expect(email.subject).toBe("Reset your password");
86
+ // Check for 6-digit code in email
87
+ expect(email.body).toMatch(/\d{6}/);
88
+ expect(email.body).toContain("5 minutes"); // Default code verification expiration
89
+ });
90
+
91
+ it("should not reveal if email does not exist", async ({ expect }) => {
92
+ const { emailProvider, actions } = await setup();
93
+
94
+ // Request password reset for non-existent email
95
+ const result = await actions.requestPasswordReset({
96
+ body: {
97
+ email: "nonexistent@example.com",
98
+ },
99
+ });
100
+
101
+ // Should return success to prevent email enumeration
102
+ expect(result.success).toBe(true);
103
+ expect(result.message).toContain("password reset code has been sent");
104
+
105
+ // But no email should be sent
106
+ expect(emailProvider.records).toHaveLength(0);
107
+ });
108
+
109
+ it("should not send email for OAuth-only users", async ({ expect }) => {
110
+ const { credentialService, emailProvider, actions } = await setup();
111
+
112
+ // Create a user with only OAuth identity (no credentials)
113
+ const user = await credentialService.users().create({
114
+ username: "oauthuser",
115
+ email: "oauth@example.com",
116
+ roles: ["user"],
117
+ });
118
+
119
+ await credentialService.identities().create({
120
+ userId: user.id,
121
+ provider: "google",
122
+ providerUserId: "google-123",
123
+ });
124
+
125
+ // Request password reset
126
+ const result = await actions.requestPasswordReset({
127
+ body: {
128
+ email: "oauth@example.com",
129
+ },
130
+ });
131
+
132
+ // Should return success but not send email
133
+ expect(result.success).toBe(true);
134
+ expect(emailProvider.records).toHaveLength(0);
135
+ });
136
+
137
+ it("should validate a valid reset token", async ({ expect }) => {
138
+ const { credentialService, cryptoProvider, emailProvider, actions } =
139
+ await setup();
140
+
141
+ // Create a test user with credentials
142
+ const hashedPassword = await cryptoProvider.hashPassword("OldPassword123");
143
+ const user = await credentialService.users().create({
144
+ username: "testuser",
145
+ email: "test@example.com",
146
+ roles: ["user"],
147
+ });
148
+
149
+ await credentialService.identities().create({
150
+ userId: user.id,
151
+ provider: "credentials",
152
+ providerUserId: "test@example.com",
153
+ providerData: { password: hashedPassword },
154
+ });
155
+
156
+ // Request password reset
157
+ await credentialService.requestPasswordReset("test@example.com");
158
+
159
+ // Extract code from email
160
+ await expect.poll(() => emailProvider.records.length).toBe(1);
161
+ const token = extractCode(emailProvider.records[0].body);
162
+
163
+ // Validate token
164
+ const result = await actions.validateResetToken({
165
+ query: { email: "test@example.com", token },
166
+ });
167
+
168
+ expect(result.valid).toBe(true);
169
+ expect(result.email).toBe("test@example.com");
170
+ });
171
+
172
+ it("should reject invalid reset token", async ({ expect }) => {
173
+ const { actions } = await setup();
174
+
175
+ // Validate invalid token
176
+ const result = await actions.validateResetToken({
177
+ query: {
178
+ email: "test@example.com",
179
+ token: "550e8400-e29b-41d4-a716-446655440000",
180
+ },
181
+ });
182
+
183
+ expect(result.valid).toBe(false);
184
+ expect(result.email).toBeUndefined();
185
+ });
186
+
187
+ it("should reject expired reset token", async ({ expect }) => {
188
+ const {
189
+ credentialService,
190
+ cryptoProvider,
191
+ dateTimeProvider,
192
+ emailProvider,
193
+ actions,
194
+ } = await setup();
195
+
196
+ // Create a test user with credentials
197
+ const hashedPassword = await cryptoProvider.hashPassword("OldPassword123");
198
+ const user = await credentialService.users().create({
199
+ username: "testuser",
200
+ email: "test@example.com",
201
+ roles: ["user"],
202
+ });
203
+
204
+ await credentialService.identities().create({
205
+ userId: user.id,
206
+ provider: "credentials",
207
+ providerUserId: "test@example.com",
208
+ providerData: { password: hashedPassword },
209
+ });
210
+
211
+ // Request password reset
212
+ await credentialService.requestPasswordReset("test@example.com");
213
+
214
+ // Extract code
215
+ await expect.poll(() => emailProvider.records.length).toBe(1);
216
+ const token = extractCode(emailProvider.records[0].body);
217
+
218
+ // Travel forward in time to expire the token (default expiration is 5 minutes for code verification)
219
+ dateTimeProvider.travel(6, "minutes");
220
+
221
+ // Validate expired token
222
+ const result = await actions.validateResetToken({
223
+ query: { email: "test@example.com", token },
224
+ });
225
+
226
+ expect(result.valid).toBe(false);
227
+ expect(result.email).toBeUndefined();
228
+ });
229
+
230
+ it("should successfully reset password with valid token", async ({
231
+ expect,
232
+ }) => {
233
+ const {
234
+ credentialService,
235
+ sessionService,
236
+ cryptoProvider,
237
+ emailProvider,
238
+ actions,
239
+ } = await setup();
240
+
241
+ // Create a test user with credentials
242
+ const hashedPassword = await cryptoProvider.hashPassword("OldPassword123");
243
+ const user = await credentialService.users().create({
244
+ username: "testuser",
245
+ email: "test@example.com",
246
+ roles: ["user"],
247
+ });
248
+
249
+ await credentialService.identities().create({
250
+ userId: user.id,
251
+ provider: "credentials",
252
+ providerUserId: "test@example.com",
253
+ providerData: { password: hashedPassword },
254
+ });
255
+
256
+ // Request password reset
257
+ await credentialService.requestPasswordReset("test@example.com");
258
+
259
+ // Extract code
260
+ await expect.poll(() => emailProvider.records.length).toBe(1);
261
+ const token = extractCode(emailProvider.records[0].body);
262
+
263
+ // Reset password
264
+ const result = await actions.resetPassword({
265
+ body: {
266
+ email: "test@example.com",
267
+ token,
268
+ newPassword: "NewPassword456",
269
+ },
270
+ });
271
+
272
+ expect(result.success).toBe(true);
273
+ expect(result.message).toContain("Password has been reset successfully");
274
+
275
+ // Verify old password no longer works
276
+ await expect(
277
+ sessionService.login("credentials", "test@example.com", "OldPassword123"),
278
+ ).rejects.toThrow();
279
+
280
+ // Verify new password works
281
+ const loggedInUser = await sessionService.login(
282
+ "credentials",
283
+ "test@example.com",
284
+ "NewPassword456",
285
+ );
286
+ expect(loggedInUser?.email).toBe("test@example.com");
287
+ });
288
+
289
+ it("should reject password reset with invalid token", async ({ expect }) => {
290
+ const { actions } = await setup();
291
+
292
+ // Attempt to reset password with invalid token
293
+ await expect(
294
+ actions.resetPassword({
295
+ body: {
296
+ email: "test@example.com",
297
+ token: "550e8400-e29b-41d4-a716-446655440000",
298
+ newPassword: "NewPassword456",
299
+ },
300
+ }),
301
+ ).rejects.toThrowError(BadRequestError);
302
+ });
303
+
304
+ it("should reject password reset with expired token", async ({ expect }) => {
305
+ const {
306
+ credentialService,
307
+ cryptoProvider,
308
+ dateTimeProvider,
309
+ emailProvider,
310
+ actions,
311
+ } = await setup();
312
+
313
+ // Create a test user with credentials
314
+ const hashedPassword = await cryptoProvider.hashPassword("OldPassword123");
315
+ const user = await credentialService.users().create({
316
+ username: "testuser",
317
+ email: "test@example.com",
318
+ roles: ["user"],
319
+ });
320
+
321
+ await credentialService.identities().create({
322
+ userId: user.id,
323
+ provider: "credentials",
324
+ providerUserId: "test@example.com",
325
+ providerData: { password: hashedPassword },
326
+ });
327
+
328
+ // Request password reset
329
+ await credentialService.requestPasswordReset("test@example.com");
330
+
331
+ // Extract code
332
+ await expect.poll(() => emailProvider.records.length).toBe(1);
333
+ const token = extractCode(emailProvider.records[0].body);
334
+
335
+ // Travel forward in time to expire the token (5 minutes for code)
336
+ dateTimeProvider.travel(6, "minutes");
337
+
338
+ // Attempt to reset password with expired token
339
+ await expect(
340
+ actions.resetPassword({
341
+ body: {
342
+ email: "test@example.com",
343
+ token,
344
+ newPassword: "NewPassword456",
345
+ },
346
+ }),
347
+ ).rejects.toThrowError(BadRequestError);
348
+ });
349
+
350
+ it("should not allow token reuse after successful password reset", async ({
351
+ expect,
352
+ }) => {
353
+ const { credentialService, cryptoProvider, emailProvider, actions } =
354
+ await setup();
355
+
356
+ // Create a test user with credentials
357
+ const hashedPassword = await cryptoProvider.hashPassword("OldPassword123");
358
+ const user = await credentialService.users().create({
359
+ username: "testuser",
360
+ email: "test@example.com",
361
+ roles: ["user"],
362
+ });
363
+
364
+ await credentialService.identities().create({
365
+ userId: user.id,
366
+ provider: "credentials",
367
+ providerUserId: "test@example.com",
368
+ providerData: { password: hashedPassword },
369
+ });
370
+
371
+ // Request password reset
372
+ await credentialService.requestPasswordReset("test@example.com");
373
+
374
+ // Extract code
375
+ await expect.poll(() => emailProvider.records.length).toBe(1);
376
+ const token = extractCode(emailProvider.records[0].body);
377
+
378
+ // Reset password
379
+ await actions.resetPassword({
380
+ body: {
381
+ email: "test@example.com",
382
+ token,
383
+ newPassword: "NewPassword456",
384
+ },
385
+ });
386
+
387
+ // Attempt to use the same token again should fail
388
+ await expect(
389
+ actions.resetPassword({
390
+ body: {
391
+ email: "test@example.com",
392
+ token,
393
+ newPassword: "AnotherPassword789",
394
+ },
395
+ }),
396
+ ).rejects.toThrowError(BadRequestError);
397
+ });
398
+
399
+ it("should invalidate all sessions after password reset", async ({
400
+ expect,
401
+ }) => {
402
+ const {
403
+ credentialService,
404
+ sessionService,
405
+ cryptoProvider,
406
+ emailProvider,
407
+ actions,
408
+ } = await setup();
409
+
410
+ // Create a test user with credentials
411
+ const hashedPassword = await cryptoProvider.hashPassword("OldPassword123");
412
+ const user = await credentialService.users().create({
413
+ username: "testuser",
414
+ email: "test@example.com",
415
+ roles: ["user"],
416
+ });
417
+
418
+ await credentialService.identities().create({
419
+ userId: user.id,
420
+ provider: "credentials",
421
+ providerUserId: "test@example.com",
422
+ providerData: { password: hashedPassword },
423
+ });
424
+
425
+ // Create some sessions
426
+ await sessionService.createSession(user, 3600);
427
+ await sessionService.createSession(user, 3600);
428
+
429
+ // Verify sessions exist
430
+ const existingSessions = await sessionService.sessions().findMany({
431
+ where: { userId: { eq: user.id } },
432
+ });
433
+ expect(existingSessions).toHaveLength(2);
434
+
435
+ // Request password reset and reset password
436
+ await credentialService.requestPasswordReset("test@example.com");
437
+
438
+ await expect.poll(() => emailProvider.records.length).toBe(1);
439
+ const token = extractCode(emailProvider.records[0].body);
440
+
441
+ await actions.resetPassword({
442
+ body: {
443
+ email: "test@example.com",
444
+ token,
445
+ newPassword: "NewPassword456",
446
+ },
447
+ });
448
+
449
+ // Verify all sessions are deleted
450
+ const remainingSessions = await sessionService.sessions().findMany({
451
+ where: { userId: { eq: user.id } },
452
+ });
453
+ expect(remainingSessions).toHaveLength(0);
454
+ });
455
+
456
+ it("should enforce minimum password length", async ({ expect }) => {
457
+ const { credentialService, cryptoProvider, emailProvider, actions } =
458
+ await setup();
459
+
460
+ // Create a test user with credentials
461
+ const hashedPassword = await cryptoProvider.hashPassword("OldPassword123");
462
+ const user = await credentialService.users().create({
463
+ username: "testuser",
464
+ email: "test@example.com",
465
+ roles: ["user"],
466
+ });
467
+
468
+ await credentialService.identities().create({
469
+ userId: user.id,
470
+ provider: "credentials",
471
+ providerUserId: "test@example.com",
472
+ providerData: { password: hashedPassword },
473
+ });
474
+
475
+ // Request password reset
476
+ await credentialService.requestPasswordReset("test@example.com");
477
+
478
+ await expect.poll(() => emailProvider.records.length).toBe(1);
479
+ const token = extractCode(emailProvider.records[0].body);
480
+
481
+ // Attempt to reset with short password (less than 8 characters)
482
+ await expect(
483
+ actions.resetPassword({
484
+ body: {
485
+ email: "test@example.com",
486
+ token,
487
+ newPassword: "Short1", // Only 6 characters
488
+ },
489
+ }),
490
+ ).rejects.toThrow();
491
+ });
492
+
493
+ it("should respect rate limiting on password reset requests", async ({
494
+ expect,
495
+ }) => {
496
+ const {
497
+ credentialService,
498
+ cryptoProvider,
499
+ dateTimeProvider,
500
+ emailProvider,
501
+ actions,
502
+ } = await setup();
503
+
504
+ // Create a test user with credentials
505
+ const hashedPassword = await cryptoProvider.hashPassword("OldPassword123");
506
+ const user = await credentialService.users().create({
507
+ username: "testuser",
508
+ email: "test@example.com",
509
+ roles: ["user"],
510
+ });
511
+
512
+ await credentialService.identities().create({
513
+ userId: user.id,
514
+ provider: "credentials",
515
+ providerUserId: "test@example.com",
516
+ providerData: { password: hashedPassword },
517
+ });
518
+
519
+ // Request password reset multiple times within cooldown period
520
+ await actions.requestPasswordReset({
521
+ body: {
522
+ email: "test@example.com",
523
+ },
524
+ });
525
+
526
+ await expect.poll(() => emailProvider.records.length).toBe(1);
527
+
528
+ // Second request should be silently ignored (cooldown)
529
+ await actions.requestPasswordReset({
530
+ body: {
531
+ email: "test@example.com",
532
+ },
533
+ });
534
+
535
+ // Still only 1 email
536
+ expect(emailProvider.records.length).toBe(1);
537
+
538
+ // Wait for cooldown to pass (90 seconds default)
539
+ dateTimeProvider.travel(91, "seconds");
540
+
541
+ // Now should work
542
+ await actions.requestPasswordReset({
543
+ body: {
544
+ email: "test@example.com",
545
+ },
546
+ });
547
+
548
+ await expect.poll(() => emailProvider.records.length).toBe(2);
549
+ });
550
+ });