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,211 @@
1
+ import { Alepha } from "alepha";
2
+ import { AlephaCache } from "alepha/cache";
3
+ import { $action, AlephaServer, HttpError } from "alepha/server";
4
+ import { afterEach, beforeEach, describe, expect, it } from "vitest";
5
+ import { $rateLimit, AlephaServerRateLimit } from "../index.ts";
6
+
7
+ describe("Action Rate Limiting", () => {
8
+ let alepha: Alepha;
9
+
10
+ class TestApp {
11
+ // Action with rate limiting enabled via options
12
+ limitedAction = $action({
13
+ rateLimit: { max: 2, windowMs: 1000 },
14
+ handler: () => "success",
15
+ });
16
+
17
+ // Action with custom key generator
18
+ userBasedAction = $action({
19
+ rateLimit: {
20
+ max: 3,
21
+ windowMs: 2000,
22
+ keyGenerator: (req) => `user:${req.headers["user-id"] || "anonymous"}`,
23
+ },
24
+ handler: () => "user success",
25
+ });
26
+
27
+ // Action without rate limiting
28
+ unlimitedAction = $action({
29
+ handler: () => "unlimited success",
30
+ });
31
+
32
+ // Rate limit primitive usage
33
+ customRateLimit = $rateLimit({ max: 1, windowMs: 500 });
34
+
35
+ primitiveAction = $action({
36
+ handler: async (request) => {
37
+ const result = await this.customRateLimit.check(request, {
38
+ max: 1,
39
+ windowMs: 500,
40
+ });
41
+ if (!result.allowed) {
42
+ throw new HttpError({
43
+ status: 429,
44
+ message: `Rate limit exceeded. Reset in ${result.retryAfter}s`,
45
+ });
46
+ }
47
+ return "primitive success";
48
+ },
49
+ });
50
+ }
51
+
52
+ beforeEach(async () => {
53
+ alepha = Alepha.create()
54
+ .with(AlephaCache)
55
+ .with(AlephaServer)
56
+ .with(AlephaServerRateLimit)
57
+ .with(TestApp);
58
+
59
+ await alepha.start();
60
+ });
61
+
62
+ afterEach(async () => {
63
+ await alepha.stop();
64
+ });
65
+
66
+ describe("Action rateLimit option", () => {
67
+ it("should allow requests within rate limit", async () => {
68
+ const app = alepha.inject(TestApp);
69
+
70
+ const result1 = await app.limitedAction.run({});
71
+ expect(result1).toBe("success");
72
+
73
+ const result2 = await app.limitedAction.run({});
74
+ expect(result2).toBe("success");
75
+ });
76
+
77
+ it("should block requests exceeding rate limit", async () => {
78
+ const app = alepha.inject(TestApp);
79
+
80
+ // First two requests should succeed
81
+ await app.limitedAction.run({});
82
+ await app.limitedAction.run({});
83
+
84
+ // Third request should be rate limited
85
+ await expect(app.limitedAction.run({})).rejects.toThrow(
86
+ "Too Many Requests",
87
+ );
88
+ });
89
+
90
+ it("should use custom key generator", async () => {
91
+ const app = alepha.inject(TestApp);
92
+
93
+ // Test that the custom key generator allows more requests per user
94
+ // since each user gets their own rate limit bucket
95
+ const result1 = await app.userBasedAction.run({});
96
+ expect(result1).toBe("user success");
97
+
98
+ const result2 = await app.userBasedAction.run({});
99
+ expect(result2).toBe("user success");
100
+
101
+ const result3 = await app.userBasedAction.run({});
102
+ expect(result3).toBe("user success");
103
+
104
+ // Fourth request should be blocked (limit is 3)
105
+ await expect(app.userBasedAction.run({})).rejects.toThrow(
106
+ "Too Many Requests",
107
+ );
108
+ });
109
+
110
+ it("should not affect unlimited actions", async () => {
111
+ const app = alepha.inject(TestApp);
112
+
113
+ // Should be able to make many requests to unlimited action
114
+ for (let i = 0; i < 10; i++) {
115
+ const result = await app.unlimitedAction.run({});
116
+ expect(result).toBe("unlimited success");
117
+ }
118
+ });
119
+
120
+ it("should reset rate limit after window expires", async () => {
121
+ const app = alepha.inject(TestApp);
122
+
123
+ // Use up the rate limit
124
+ await app.limitedAction.run({});
125
+ await app.limitedAction.run({});
126
+
127
+ // Should be blocked
128
+ await expect(app.limitedAction.run({})).rejects.toThrow(
129
+ "Too Many Requests",
130
+ );
131
+
132
+ // Wait for the window to expire (1000ms + buffer)
133
+ await new Promise((resolve) => setTimeout(resolve, 1100));
134
+
135
+ // Should be allowed again
136
+ const result = await app.limitedAction.run({});
137
+ expect(result).toBe("success");
138
+ });
139
+ });
140
+
141
+ describe("$rateLimit primitive", () => {
142
+ it("should create rate limit primitive with options", () => {
143
+ const app = alepha.inject(TestApp);
144
+
145
+ expect(app.customRateLimit).toBeDefined();
146
+ expect(app.customRateLimit.name).toBe("customRateLimit");
147
+ expect(app.customRateLimit.options.max).toBe(1);
148
+ expect(app.customRateLimit.options.windowMs).toBe(500);
149
+ });
150
+
151
+ it("should handle rate limiting in custom action logic", async () => {
152
+ const app = alepha.inject(TestApp);
153
+
154
+ // First request should succeed
155
+ const result1 = await app.primitiveAction.run({});
156
+ expect(result1).toBe("primitive success");
157
+
158
+ // Second request should be blocked by custom logic
159
+ await expect(app.primitiveAction.run({})).rejects.toThrow(
160
+ "Rate limit exceeded",
161
+ );
162
+ });
163
+ });
164
+
165
+ describe("Integration", () => {
166
+ it("should integrate rate limiting with action hooks", async () => {
167
+ const app = alepha.inject(TestApp);
168
+
169
+ // Just verify that the hook is working by checking that rate limiting is applied
170
+ await app.limitedAction.run({});
171
+ await app.limitedAction.run({});
172
+
173
+ // Third request should trigger rate limiting
174
+ await expect(app.limitedAction.run({})).rejects.toThrow(
175
+ "Too Many Requests",
176
+ );
177
+ });
178
+ });
179
+
180
+ describe("Performance and edge cases", () => {
181
+ it("should handle concurrent requests correctly", async () => {
182
+ const app = alepha.inject(TestApp);
183
+
184
+ // Test sequential requests to avoid race conditions in testing
185
+ let successCount = 0;
186
+ let rateLimitedCount = 0;
187
+
188
+ for (let i = 0; i < 5; i++) {
189
+ try {
190
+ await app.limitedAction.run({});
191
+ successCount++;
192
+ } catch (e: any) {
193
+ if (e.message === "Too Many Requests") {
194
+ rateLimitedCount++;
195
+ }
196
+ }
197
+ }
198
+
199
+ expect(successCount).toBe(2);
200
+ expect(rateLimitedCount).toBe(3);
201
+ });
202
+
203
+ it("should handle missing IP gracefully", async () => {
204
+ const app = alepha.inject(TestApp);
205
+
206
+ // Should still work with default IP handling
207
+ const result = await app.limitedAction.run({});
208
+ expect(result).toBe("success");
209
+ });
210
+ });
211
+ });
@@ -0,0 +1,344 @@
1
+ import { Alepha } from "alepha";
2
+ import { AlephaCache } from "alepha/cache";
3
+ import {
4
+ $action,
5
+ AlephaServer,
6
+ ServerProvider,
7
+ type ServerRequest,
8
+ } from "alepha/server";
9
+ import { afterEach, beforeEach, describe, expect, it, test } from "vitest";
10
+ import {
11
+ $rateLimit,
12
+ AlephaServerRateLimit,
13
+ rateLimitOptions,
14
+ ServerRateLimitProvider,
15
+ } from "../index.ts";
16
+
17
+ describe("ServerRateLimitProvider", () => {
18
+ let alepha: Alepha;
19
+ let provider: ServerRateLimitProvider;
20
+
21
+ beforeEach(async () => {
22
+ alepha = Alepha.create().with(AlephaCache);
23
+ provider = alepha.inject(ServerRateLimitProvider);
24
+ await alepha.start();
25
+ });
26
+
27
+ afterEach(async () => {
28
+ await alepha.stop();
29
+ });
30
+
31
+ const createMockRequest = (ip: string = "127.0.0.1"): ServerRequest =>
32
+ ({
33
+ ip,
34
+ headers: {},
35
+ method: "GET",
36
+ url: "/test",
37
+ path: "/test",
38
+ query: {},
39
+ params: {},
40
+ body: undefined,
41
+ }) as any;
42
+
43
+ it("should allow requests within limit", async () => {
44
+ const req = createMockRequest();
45
+ const result = await provider.checkLimit(req, { max: 5, windowMs: 60000 });
46
+
47
+ expect(result.allowed).toBe(true);
48
+ expect(result.limit).toBe(5);
49
+ expect(result.remaining).toBe(4);
50
+ });
51
+
52
+ it("should block requests exceeding limit", async () => {
53
+ const req = createMockRequest();
54
+ const options = { max: 2, windowMs: 60000 };
55
+
56
+ // First request should be allowed
57
+ const result1 = await provider.checkLimit(req, options);
58
+ expect(result1.allowed).toBe(true);
59
+ expect(result1.remaining).toBe(1);
60
+
61
+ // Second request should be allowed
62
+ const result2 = await provider.checkLimit(req, options);
63
+ expect(result2.allowed).toBe(true);
64
+ expect(result2.remaining).toBe(0);
65
+
66
+ // Third request should be blocked
67
+ const result3 = await provider.checkLimit(req, options);
68
+ expect(result3.allowed).toBe(false);
69
+ expect(result3.remaining).toBe(0);
70
+ expect(result3.retryAfter).toBeGreaterThan(0);
71
+ });
72
+
73
+ it("should handle different IPs separately", async () => {
74
+ const req1 = createMockRequest("192.168.1.1");
75
+ const req2 = createMockRequest("192.168.1.2");
76
+ const options = { max: 1, windowMs: 60000 };
77
+
78
+ // Both requests should be allowed as they come from different IPs
79
+ const result1 = await provider.checkLimit(req1, options);
80
+ const result2 = await provider.checkLimit(req2, options);
81
+
82
+ expect(result1.allowed).toBe(true);
83
+ expect(result2.allowed).toBe(true);
84
+ });
85
+
86
+ it("should extract IP from x-forwarded-for header", async () => {
87
+ const options = { max: 1, windowMs: 60000 };
88
+
89
+ // First request with x-forwarded-for: 203.0.113.1
90
+ const req1 = createMockRequest("127.0.0.1");
91
+ req1.headers["x-forwarded-for"] = "203.0.113.1, 192.168.1.1";
92
+
93
+ const result1 = await provider.checkLimit(req1, options);
94
+ expect(result1.allowed).toBe(true);
95
+
96
+ // Second request with same x-forwarded-for should be blocked
97
+ const req2 = createMockRequest("127.0.0.1");
98
+ req2.headers["x-forwarded-for"] = "203.0.113.1, 192.168.1.1";
99
+
100
+ const result2 = await provider.checkLimit(req2, options);
101
+ expect(result2.allowed).toBe(false);
102
+
103
+ // Request with different x-forwarded-for should be allowed
104
+ const req3 = createMockRequest("127.0.0.1");
105
+ req3.headers["x-forwarded-for"] = "198.51.100.1, 192.168.1.1";
106
+
107
+ const result3 = await provider.checkLimit(req3, options);
108
+ expect(result3.allowed).toBe(true);
109
+ });
110
+ });
111
+
112
+ describe("ServerRateLimitProvider Module Integration", () => {
113
+ let alepha: Alepha;
114
+ let provider: ServerRateLimitProvider;
115
+
116
+ class TestApp {
117
+ test = $action({
118
+ handler: () => "success",
119
+ });
120
+ }
121
+
122
+ beforeEach(async () => {
123
+ alepha = Alepha.create()
124
+ .with(AlephaCache)
125
+ .with(AlephaServer)
126
+ .with(AlephaServerRateLimit)
127
+ .with(TestApp);
128
+ provider = alepha.inject(ServerRateLimitProvider);
129
+ await alepha.start();
130
+ });
131
+
132
+ afterEach(async () => {
133
+ await alepha.stop();
134
+ });
135
+
136
+ it("should integrate with Alepha framework successfully", async () => {
137
+ expect(provider).toBeDefined();
138
+ expect(provider).toBeInstanceOf(ServerRateLimitProvider);
139
+ expect(typeof provider.checkLimit).toBe("function");
140
+ });
141
+
142
+ it("should work with real action requests", async () => {
143
+ // Configure rate limit for testing
144
+ alepha.store.mut(rateLimitOptions, () => ({
145
+ max: 10,
146
+ windowMs: 60000,
147
+ }));
148
+
149
+ const app = alepha.inject(TestApp);
150
+
151
+ // First request should succeed
152
+ const result = await app.test.run({});
153
+ expect(result).toBe("success");
154
+
155
+ // Multiple requests should still work within limit
156
+ for (let i = 0; i < 5; i++) {
157
+ const result = await app.test.run({});
158
+ expect(result).toBe("success");
159
+ }
160
+ });
161
+ });
162
+
163
+ // ---------------------------------------------------------------------------------------------------------------------
164
+
165
+ describe("$rateLimit primitive", () => {
166
+ let alepha: Alepha;
167
+ let server: ServerProvider;
168
+
169
+ afterEach(async () => {
170
+ if (alepha) {
171
+ await alepha.stop();
172
+ }
173
+ });
174
+
175
+ test("should apply path-specific rate limit to matching routes", async () => {
176
+ class AppWithRateLimit {
177
+ // Path-specific rate limit for /api/v1/* routes
178
+ apiRateLimit = $rateLimit({
179
+ paths: ["/api/v1/*"],
180
+ max: 2,
181
+ windowMs: 60000,
182
+ });
183
+
184
+ // $action with path "/v1/data" creates route at "/api/v1/data"
185
+ apiAction = $action({
186
+ path: "/v1/data",
187
+ method: "POST",
188
+ handler: () => "success",
189
+ });
190
+ }
191
+
192
+ alepha = Alepha.create()
193
+ .with(AlephaCache)
194
+ .with(AlephaServer)
195
+ .with(AlephaServerRateLimit)
196
+ .with(AppWithRateLimit);
197
+
198
+ server = alepha.inject(ServerProvider);
199
+ await alepha.start();
200
+
201
+ // First two requests should succeed
202
+ const response1 = await fetch(`${server.hostname}/api/v1/data`, {
203
+ method: "POST",
204
+ });
205
+ expect(response1.status).toBe(200);
206
+ expect(response1.headers.get("x-ratelimit-limit")).toBe("2");
207
+ expect(response1.headers.get("x-ratelimit-remaining")).toBe("1");
208
+
209
+ const response2 = await fetch(`${server.hostname}/api/v1/data`, {
210
+ method: "POST",
211
+ });
212
+ expect(response2.status).toBe(200);
213
+ expect(response2.headers.get("x-ratelimit-remaining")).toBe("0");
214
+
215
+ // Third request should be rate limited
216
+ const response3 = await fetch(`${server.hostname}/api/v1/data`, {
217
+ method: "POST",
218
+ });
219
+ expect(response3.status).toBe(429);
220
+ expect(response3.headers.get("retry-after")).toBeDefined();
221
+ });
222
+
223
+ test("should register rate limit configs with provider", async () => {
224
+ class RegistrationApp {
225
+ limit1 = $rateLimit({
226
+ name: "api-limit",
227
+ paths: ["/api/*"],
228
+ max: 100,
229
+ });
230
+
231
+ limit2 = $rateLimit({
232
+ name: "admin-limit",
233
+ paths: ["/admin/*"],
234
+ max: 10,
235
+ });
236
+ }
237
+
238
+ alepha = Alepha.create()
239
+ .with(AlephaCache)
240
+ .with(AlephaServer)
241
+ .with(AlephaServerRateLimit)
242
+ .with(RegistrationApp);
243
+
244
+ const rateLimitProvider = alepha.inject(ServerRateLimitProvider);
245
+ await alepha.start();
246
+
247
+ expect(rateLimitProvider.registeredConfigs).toHaveLength(2);
248
+ expect(rateLimitProvider.registeredConfigs[0].name).toBe("api-limit");
249
+ expect(rateLimitProvider.registeredConfigs[1].name).toBe("admin-limit");
250
+ });
251
+
252
+ test("should apply different rate limits to different paths", async () => {
253
+ class MultiRateLimitApp {
254
+ // Strict limit for admin routes
255
+ adminLimit = $rateLimit({
256
+ paths: ["/api/admin/*"],
257
+ max: 1,
258
+ windowMs: 60000,
259
+ });
260
+
261
+ // Lenient limit for public routes
262
+ publicLimit = $rateLimit({
263
+ paths: ["/api/public/*"],
264
+ max: 10,
265
+ windowMs: 60000,
266
+ });
267
+
268
+ adminAction = $action({
269
+ path: "/admin/users",
270
+ method: "GET",
271
+ handler: () => "admin",
272
+ });
273
+
274
+ publicAction = $action({
275
+ path: "/public/status",
276
+ method: "GET",
277
+ handler: () => "public",
278
+ });
279
+ }
280
+
281
+ alepha = Alepha.create()
282
+ .with(AlephaCache)
283
+ .with(AlephaServer)
284
+ .with(AlephaServerRateLimit)
285
+ .with(MultiRateLimitApp);
286
+
287
+ server = alepha.inject(ServerProvider);
288
+ await alepha.start();
289
+
290
+ // Admin route should have max: 1
291
+ const adminResponse1 = await fetch(`${server.hostname}/api/admin/users`);
292
+ expect(adminResponse1.status).toBe(200);
293
+ expect(adminResponse1.headers.get("x-ratelimit-limit")).toBe("1");
294
+
295
+ // Second admin request should be rate limited
296
+ const adminResponse2 = await fetch(`${server.hostname}/api/admin/users`);
297
+ expect(adminResponse2.status).toBe(429);
298
+
299
+ // Public route should have max: 10
300
+ const publicResponse = await fetch(`${server.hostname}/api/public/status`);
301
+ expect(publicResponse.status).toBe(200);
302
+ expect(publicResponse.headers.get("x-ratelimit-limit")).toBe("10");
303
+ });
304
+
305
+ test("should handle multiple paths in single $rateLimit primitive", async () => {
306
+ class MultiPathApp {
307
+ apiLimit = $rateLimit({
308
+ paths: ["/api/v1/*", "/api/v2/*"],
309
+ max: 5,
310
+ windowMs: 60000,
311
+ });
312
+
313
+ action1 = $action({
314
+ path: "/v1/data",
315
+ method: "GET",
316
+ handler: () => "v1",
317
+ });
318
+
319
+ action2 = $action({
320
+ path: "/v2/data",
321
+ method: "GET",
322
+ handler: () => "v2",
323
+ });
324
+ }
325
+
326
+ alepha = Alepha.create()
327
+ .with(AlephaCache)
328
+ .with(AlephaServer)
329
+ .with(AlephaServerRateLimit)
330
+ .with(MultiPathApp);
331
+
332
+ server = alepha.inject(ServerProvider);
333
+ await alepha.start();
334
+
335
+ // Both paths should have max: 5
336
+ const v1Response = await fetch(`${server.hostname}/api/v1/data`);
337
+ expect(v1Response.status).toBe(200);
338
+ expect(v1Response.headers.get("x-ratelimit-limit")).toBe("5");
339
+
340
+ const v2Response = await fetch(`${server.hostname}/api/v2/data`);
341
+ expect(v2Response.status).toBe(200);
342
+ expect(v2Response.headers.get("x-ratelimit-limit")).toBe("5");
343
+ });
344
+ });