alepha 0.14.1 → 0.14.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (402) hide show
  1. package/README.md +3 -3
  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 +784 -784
  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 +57 -57
  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 +165 -165
  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 +583 -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 +281 -276
  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 +778 -764
  35. package/dist/api/users/index.d.ts.map +1 -1
  36. package/dist/api/users/index.js +831 -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 +125 -125
  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/batch/index.js.map +1 -1
  45. package/dist/bin/index.d.ts +1 -2
  46. package/dist/bin/index.js +0 -1
  47. package/dist/bin/index.js.map +1 -1
  48. package/dist/cache/core/index.js.map +1 -1
  49. package/dist/cli/index.d.ts +249 -218
  50. package/dist/cli/index.d.ts.map +1 -1
  51. package/dist/cli/index.js +951 -821
  52. package/dist/cli/index.js.map +1 -1
  53. package/dist/command/index.d.ts +40 -0
  54. package/dist/command/index.d.ts.map +1 -1
  55. package/dist/command/index.js +97 -17
  56. package/dist/command/index.js.map +1 -1
  57. package/dist/core/index.browser.js +14 -18
  58. package/dist/core/index.browser.js.map +1 -1
  59. package/dist/core/index.d.ts +29 -0
  60. package/dist/core/index.d.ts.map +1 -1
  61. package/dist/core/index.js +21 -24
  62. package/dist/core/index.js.map +1 -1
  63. package/dist/core/index.native.js +21 -24
  64. package/dist/core/index.native.js.map +1 -1
  65. package/dist/datetime/index.js.map +1 -1
  66. package/dist/fake/index.js +195 -168
  67. package/dist/fake/index.js.map +1 -1
  68. package/dist/file/index.d.ts +8 -0
  69. package/dist/file/index.d.ts.map +1 -1
  70. package/dist/file/index.js +3 -0
  71. package/dist/file/index.js.map +1 -1
  72. package/dist/lock/redis/index.js.map +1 -1
  73. package/dist/logger/index.js.map +1 -1
  74. package/dist/mcp/index.d.ts.map +1 -1
  75. package/dist/mcp/index.js.map +1 -1
  76. package/dist/orm/index.browser.js +26 -5
  77. package/dist/orm/index.browser.js.map +1 -1
  78. package/dist/orm/index.d.ts +146 -121
  79. package/dist/orm/index.d.ts.map +1 -1
  80. package/dist/orm/index.js +49 -24
  81. package/dist/orm/index.js.map +1 -1
  82. package/dist/redis/index.js.map +1 -1
  83. package/dist/retry/index.js.map +1 -1
  84. package/dist/router/index.js.map +1 -1
  85. package/dist/scheduler/index.d.ts +6 -6
  86. package/dist/scheduler/index.js.map +1 -1
  87. package/dist/security/index.d.ts +29 -29
  88. package/dist/security/index.d.ts.map +1 -1
  89. package/dist/security/index.js +1 -1
  90. package/dist/security/index.js.map +1 -1
  91. package/dist/server/auth/index.d.ts +171 -155
  92. package/dist/server/auth/index.d.ts.map +1 -1
  93. package/dist/server/auth/index.js +0 -1
  94. package/dist/server/auth/index.js.map +1 -1
  95. package/dist/server/cache/index.js.map +1 -1
  96. package/dist/server/compress/index.d.ts.map +1 -1
  97. package/dist/server/compress/index.js +2 -0
  98. package/dist/server/compress/index.js.map +1 -1
  99. package/dist/server/cookies/index.browser.js.map +1 -1
  100. package/dist/server/cookies/index.js.map +1 -1
  101. package/dist/server/core/index.browser.js.map +1 -1
  102. package/dist/server/core/index.d.ts.map +1 -1
  103. package/dist/server/core/index.js +1 -1
  104. package/dist/server/core/index.js.map +1 -1
  105. package/dist/server/health/index.d.ts +17 -17
  106. package/dist/server/helmet/index.js.map +1 -1
  107. package/dist/server/links/index.browser.js +22 -6
  108. package/dist/server/links/index.browser.js.map +1 -1
  109. package/dist/server/links/index.d.ts +46 -44
  110. package/dist/server/links/index.d.ts.map +1 -1
  111. package/dist/server/links/index.js +24 -41
  112. package/dist/server/links/index.js.map +1 -1
  113. package/dist/server/multipart/index.js.map +1 -1
  114. package/dist/server/rate-limit/index.js.map +1 -1
  115. package/dist/server/security/index.js.map +1 -1
  116. package/dist/server/swagger/index.d.ts +2 -1
  117. package/dist/server/swagger/index.d.ts.map +1 -1
  118. package/dist/server/swagger/index.js +8 -3
  119. package/dist/server/swagger/index.js.map +1 -1
  120. package/dist/thread/index.js.map +1 -1
  121. package/dist/topic/core/index.js.map +1 -1
  122. package/dist/vite/index.d.ts.map +1 -1
  123. package/dist/vite/index.js +12 -4
  124. package/dist/vite/index.js.map +1 -1
  125. package/dist/websocket/index.browser.js.map +1 -1
  126. package/dist/websocket/index.js.map +1 -1
  127. package/package.json +7 -7
  128. package/src/api/audits/controllers/{AuditController.ts → AdminAuditController.ts} +5 -6
  129. package/src/api/audits/entities/audits.ts +5 -5
  130. package/src/api/audits/index.browser.ts +1 -1
  131. package/src/api/audits/index.ts +3 -3
  132. package/src/api/audits/primitives/$audit.spec.ts +276 -0
  133. package/src/api/audits/services/AuditService.spec.ts +495 -0
  134. package/src/api/files/__tests__/$bucket.spec.ts +91 -0
  135. package/src/api/files/controllers/AdminFileStatsController.spec.ts +166 -0
  136. package/src/api/files/controllers/{StorageStatsController.ts → AdminFileStatsController.ts} +2 -2
  137. package/src/api/files/controllers/FileController.spec.ts +558 -0
  138. package/src/api/files/controllers/FileController.ts +4 -5
  139. package/src/api/files/entities/files.ts +5 -5
  140. package/src/api/files/index.browser.ts +1 -1
  141. package/src/api/files/index.ts +4 -4
  142. package/src/api/files/jobs/FileJobs.spec.ts +52 -0
  143. package/src/api/files/services/FileService.spec.ts +109 -0
  144. package/src/api/jobs/__tests__/JobController.spec.ts +343 -0
  145. package/src/api/jobs/controllers/{JobController.ts → AdminJobController.ts} +2 -2
  146. package/src/api/jobs/entities/jobExecutions.ts +5 -5
  147. package/src/api/jobs/index.ts +3 -3
  148. package/src/api/jobs/primitives/$job.spec.ts +476 -0
  149. package/src/api/notifications/controllers/{NotificationController.ts → AdminNotificationController.ts} +4 -5
  150. package/src/api/notifications/entities/notifications.ts +5 -5
  151. package/src/api/notifications/index.browser.ts +1 -1
  152. package/src/api/notifications/index.ts +4 -4
  153. package/src/api/parameters/controllers/{ConfigController.ts → AdminConfigController.ts} +46 -107
  154. package/src/api/parameters/entities/parameters.ts +7 -17
  155. package/src/api/parameters/index.ts +3 -3
  156. package/src/api/parameters/primitives/$config.spec.ts +356 -0
  157. package/src/api/parameters/schemas/activateConfigBodySchema.ts +12 -0
  158. package/src/api/parameters/schemas/checkScheduledResponseSchema.ts +8 -0
  159. package/src/api/parameters/schemas/configCurrentResponseSchema.ts +13 -0
  160. package/src/api/parameters/schemas/configHistoryResponseSchema.ts +9 -0
  161. package/src/api/parameters/schemas/configNameParamSchema.ts +10 -0
  162. package/src/api/parameters/schemas/configNamesResponseSchema.ts +8 -0
  163. package/src/api/parameters/schemas/configTreeNodeSchema.ts +13 -0
  164. package/src/api/parameters/schemas/configVersionParamSchema.ts +9 -0
  165. package/src/api/parameters/schemas/configVersionResponseSchema.ts +9 -0
  166. package/src/api/parameters/schemas/configsByStatusResponseSchema.ts +9 -0
  167. package/src/api/parameters/schemas/createConfigVersionBodySchema.ts +24 -0
  168. package/src/api/parameters/schemas/index.ts +15 -0
  169. package/src/api/parameters/schemas/parameterResponseSchema.ts +26 -0
  170. package/src/api/parameters/schemas/parameterStatusSchema.ts +13 -0
  171. package/src/api/parameters/schemas/rollbackConfigBodySchema.ts +15 -0
  172. package/src/api/parameters/schemas/statusParamSchema.ts +9 -0
  173. package/src/api/users/__tests__/EmailVerification.spec.ts +369 -0
  174. package/src/api/users/__tests__/PasswordReset.spec.ts +550 -0
  175. package/src/api/users/controllers/AdminIdentityController.spec.ts +365 -0
  176. package/src/api/users/controllers/{IdentityController.ts → AdminIdentityController.ts} +3 -4
  177. package/src/api/users/controllers/AdminSessionController.spec.ts +274 -0
  178. package/src/api/users/controllers/{SessionController.ts → AdminSessionController.ts} +3 -4
  179. package/src/api/users/controllers/AdminUserController.spec.ts +372 -0
  180. package/src/api/users/controllers/AdminUserController.ts +116 -0
  181. package/src/api/users/controllers/UserController.ts +4 -107
  182. package/src/api/users/controllers/UserRealmController.ts +3 -0
  183. package/src/api/users/entities/identities.ts +6 -6
  184. package/src/api/users/entities/sessions.ts +6 -6
  185. package/src/api/users/entities/users.ts +9 -9
  186. package/src/api/users/index.ts +13 -6
  187. package/src/api/users/primitives/$userRealm.ts +13 -8
  188. package/src/api/users/services/CredentialService.spec.ts +509 -0
  189. package/src/api/users/services/CredentialService.ts +46 -0
  190. package/src/api/users/services/IdentityService.ts +15 -0
  191. package/src/api/users/services/RegistrationService.spec.ts +630 -0
  192. package/src/api/users/services/RegistrationService.ts +18 -0
  193. package/src/api/users/services/SessionService.spec.ts +301 -0
  194. package/src/api/users/services/SessionService.ts +110 -1
  195. package/src/api/users/services/UserService.ts +67 -2
  196. package/src/api/verifications/__tests__/CodeVerification.spec.ts +318 -0
  197. package/src/api/verifications/__tests__/LinkVerification.spec.ts +279 -0
  198. package/src/api/verifications/entities/verifications.ts +6 -6
  199. package/src/api/verifications/jobs/VerificationJobs.spec.ts +50 -0
  200. package/src/batch/__tests__/startup-buffering.spec.ts +458 -0
  201. package/src/batch/primitives/$batch.spec.ts +766 -0
  202. package/src/batch/providers/BatchProvider.spec.ts +786 -0
  203. package/src/bin/index.ts +0 -1
  204. package/src/bucket/__tests__/shared.ts +194 -0
  205. package/src/bucket/primitives/$bucket.spec.ts +104 -0
  206. package/src/bucket/providers/FileStorageProvider.spec.ts +13 -0
  207. package/src/bucket/providers/LocalFileStorageProvider.spec.ts +77 -0
  208. package/src/bucket/providers/MemoryFileStorageProvider.spec.ts +82 -0
  209. package/src/cache/core/__tests__/shared.ts +377 -0
  210. package/src/cache/core/primitives/$cache.spec.ts +111 -0
  211. package/src/cache/redis/__tests__/cache-redis.spec.ts +70 -0
  212. package/src/cli/apps/AlephaCli.ts +54 -16
  213. package/src/cli/apps/AlephaPackageBuilderCli.ts +2 -1
  214. package/src/cli/assets/appRouterTs.ts +1 -1
  215. package/src/cli/commands/{ViteCommands.ts → build.ts} +2 -105
  216. package/src/cli/commands/clean.ts +14 -0
  217. package/src/cli/commands/{DrizzleCommands.ts → db.ts} +10 -117
  218. package/src/cli/commands/{DeployCommands.ts → deploy.ts} +1 -1
  219. package/src/cli/commands/dev.ts +69 -0
  220. package/src/cli/commands/format.ts +17 -0
  221. package/src/cli/commands/gen/changelog.spec.ts +315 -0
  222. package/src/cli/commands/{ChangelogCommands.ts → gen/changelog.ts} +16 -31
  223. package/src/cli/commands/gen/openapi.ts +71 -0
  224. package/src/cli/commands/gen.ts +18 -0
  225. package/src/cli/commands/{CoreCommands.ts → init.ts} +4 -40
  226. package/src/cli/commands/lint.ts +17 -0
  227. package/src/cli/commands/root.ts +41 -0
  228. package/src/cli/commands/run.ts +24 -0
  229. package/src/cli/commands/test.ts +42 -0
  230. package/src/cli/commands/typecheck.ts +24 -0
  231. package/src/cli/commands/{VerifyCommands.ts → verify.ts} +1 -13
  232. package/src/cli/defineConfig.ts +10 -1
  233. package/src/cli/index.ts +17 -7
  234. package/src/cli/services/AlephaCliUtils.ts +71 -32
  235. package/src/cli/services/GitMessageParser.ts +1 -1
  236. package/src/command/helpers/Asker.spec.ts +127 -0
  237. package/src/command/helpers/Runner.spec.ts +126 -0
  238. package/src/command/primitives/$command.spec.ts +1588 -0
  239. package/src/command/providers/CliProvider.ts +74 -24
  240. package/src/core/Alepha.ts +52 -4
  241. package/src/core/__tests__/Alepha-emit.spec.ts +22 -0
  242. package/src/core/__tests__/Alepha-graph.spec.ts +93 -0
  243. package/src/core/__tests__/Alepha-has.spec.ts +41 -0
  244. package/src/core/__tests__/Alepha-inject.spec.ts +93 -0
  245. package/src/core/__tests__/Alepha-register.spec.ts +81 -0
  246. package/src/core/__tests__/Alepha-start.spec.ts +176 -0
  247. package/src/core/__tests__/Alepha-with.spec.ts +14 -0
  248. package/src/core/__tests__/TypeBox-usecases.spec.ts +35 -0
  249. package/src/core/__tests__/TypeBoxLocale.spec.ts +15 -0
  250. package/src/core/__tests__/descriptor.spec.ts +34 -0
  251. package/src/core/__tests__/fixtures/A.ts +5 -0
  252. package/src/core/__tests__/pagination.spec.ts +77 -0
  253. package/src/core/helpers/jsonSchemaToTypeBox.ts +2 -2
  254. package/src/core/primitives/$atom.spec.ts +43 -0
  255. package/src/core/primitives/$hook.spec.ts +130 -0
  256. package/src/core/primitives/$inject.spec.ts +175 -0
  257. package/src/core/primitives/$module.spec.ts +115 -0
  258. package/src/core/providers/CodecManager.spec.ts +740 -0
  259. package/src/core/providers/EventManager.spec.ts +762 -0
  260. package/src/core/providers/EventManager.ts +4 -0
  261. package/src/core/providers/StateManager.spec.ts +365 -0
  262. package/src/core/providers/TypeProvider.spec.ts +1607 -0
  263. package/src/core/providers/TypeProvider.ts +20 -26
  264. package/src/datetime/primitives/$interval.spec.ts +103 -0
  265. package/src/datetime/providers/DateTimeProvider.spec.ts +86 -0
  266. package/src/email/primitives/$email.spec.ts +175 -0
  267. package/src/email/providers/LocalEmailProvider.spec.ts +341 -0
  268. package/src/fake/__tests__/keyName.example.ts +40 -0
  269. package/src/fake/__tests__/keyName.spec.ts +152 -0
  270. package/src/fake/__tests__/module.example.ts +32 -0
  271. package/src/fake/providers/FakeProvider.spec.ts +438 -0
  272. package/src/file/providers/FileSystemProvider.ts +8 -0
  273. package/src/file/providers/NodeFileSystemProvider.spec.ts +418 -0
  274. package/src/file/providers/NodeFileSystemProvider.ts +5 -0
  275. package/src/file/services/FileDetector.spec.ts +591 -0
  276. package/src/lock/core/__tests__/shared.ts +190 -0
  277. package/src/lock/core/providers/MemoryLockProvider.spec.ts +25 -0
  278. package/src/lock/redis/providers/RedisLockProvider.spec.ts +25 -0
  279. package/src/logger/__tests__/SimpleFormatterProvider.spec.ts +109 -0
  280. package/src/logger/primitives/$logger.spec.ts +108 -0
  281. package/src/logger/services/Logger.spec.ts +295 -0
  282. package/src/mcp/__tests__/errors.spec.ts +175 -0
  283. package/src/mcp/__tests__/integration.spec.ts +450 -0
  284. package/src/mcp/helpers/jsonrpc.spec.ts +380 -0
  285. package/src/mcp/primitives/$prompt.spec.ts +468 -0
  286. package/src/mcp/primitives/$resource.spec.ts +390 -0
  287. package/src/mcp/primitives/$tool.spec.ts +406 -0
  288. package/src/mcp/providers/McpServerProvider.spec.ts +797 -0
  289. package/src/orm/__tests__/$repository-crud.spec.ts +276 -0
  290. package/src/orm/__tests__/$repository-hooks.spec.ts +325 -0
  291. package/src/orm/__tests__/$repository-orderBy.spec.ts +128 -0
  292. package/src/orm/__tests__/$repository-pagination-sort.spec.ts +149 -0
  293. package/src/orm/__tests__/$repository-save.spec.ts +37 -0
  294. package/src/orm/__tests__/ModelBuilder-integration.spec.ts +490 -0
  295. package/src/orm/__tests__/ModelBuilder-types.spec.ts +186 -0
  296. package/src/orm/__tests__/PostgresProvider.spec.ts +46 -0
  297. package/src/orm/__tests__/delete-returning.spec.ts +256 -0
  298. package/src/orm/__tests__/deletedAt.spec.ts +80 -0
  299. package/src/orm/__tests__/enums.spec.ts +315 -0
  300. package/src/orm/__tests__/execute.spec.ts +72 -0
  301. package/src/orm/__tests__/fixtures/bigEntitySchema.ts +65 -0
  302. package/src/orm/__tests__/fixtures/userEntitySchema.ts +27 -0
  303. package/src/orm/__tests__/joins.spec.ts +1114 -0
  304. package/src/orm/__tests__/page.spec.ts +287 -0
  305. package/src/orm/__tests__/primaryKey.spec.ts +87 -0
  306. package/src/orm/__tests__/query-date-encoding.spec.ts +402 -0
  307. package/src/orm/__tests__/ref-auto-onDelete.spec.ts +156 -0
  308. package/src/orm/__tests__/references.spec.ts +102 -0
  309. package/src/orm/__tests__/security.spec.ts +710 -0
  310. package/src/orm/__tests__/sqlite.spec.ts +111 -0
  311. package/src/orm/__tests__/string-operators.spec.ts +429 -0
  312. package/src/orm/__tests__/timestamps.spec.ts +388 -0
  313. package/src/orm/__tests__/validation.spec.ts +183 -0
  314. package/src/orm/__tests__/version.spec.ts +64 -0
  315. package/src/orm/helpers/parseQueryString.spec.ts +196 -0
  316. package/src/orm/index.browser.ts +1 -1
  317. package/src/orm/index.ts +10 -6
  318. package/src/orm/primitives/$repository.spec.ts +137 -0
  319. package/src/orm/primitives/$sequence.spec.ts +29 -0
  320. package/src/orm/primitives/$transaction.spec.ts +82 -0
  321. package/src/orm/providers/{PostgresTypeProvider.ts → DatabaseTypeProvider.ts} +25 -3
  322. package/src/orm/providers/drivers/BunPostgresProvider.ts +3 -3
  323. package/src/orm/providers/drivers/BunSqliteProvider.ts +1 -1
  324. package/src/orm/providers/drivers/CloudflareD1Provider.ts +1 -1
  325. package/src/orm/providers/drivers/DatabaseProvider.ts +1 -1
  326. package/src/orm/providers/drivers/NodePostgresProvider.ts +3 -3
  327. package/src/orm/providers/drivers/NodeSqliteProvider.ts +1 -1
  328. package/src/orm/providers/drivers/PglitePostgresProvider.ts +2 -2
  329. package/src/orm/services/ModelBuilder.spec.ts +575 -0
  330. package/src/orm/services/Repository.spec.ts +137 -0
  331. package/src/queue/core/__tests__/shared.ts +143 -0
  332. package/src/queue/core/providers/MemoryQueueProvider.spec.ts +23 -0
  333. package/src/queue/core/providers/WorkerProvider.spec.ts +378 -0
  334. package/src/queue/redis/providers/RedisQueueProvider.spec.ts +23 -0
  335. package/src/redis/__tests__/redis.spec.ts +58 -0
  336. package/src/retry/primitives/$retry.spec.ts +234 -0
  337. package/src/retry/providers/RetryProvider.spec.ts +438 -0
  338. package/src/router/__tests__/match.spec.ts +252 -0
  339. package/src/router/providers/RouterProvider.spec.ts +197 -0
  340. package/src/scheduler/__tests__/$scheduler-cron.spec.ts +25 -0
  341. package/src/scheduler/__tests__/$scheduler-interval.spec.ts +25 -0
  342. package/src/scheduler/__tests__/shared.ts +77 -0
  343. package/src/security/__tests__/bug-1-wildcard-after-start.spec.ts +229 -0
  344. package/src/security/__tests__/bug-2-password-validation.spec.ts +245 -0
  345. package/src/security/__tests__/bug-3-regex-vulnerability.spec.ts +407 -0
  346. package/src/security/__tests__/bug-4-oauth2-validation.spec.ts +439 -0
  347. package/src/security/__tests__/multi-layer-permissions.spec.ts +522 -0
  348. package/src/security/primitives/$permission.spec.ts +30 -0
  349. package/src/security/primitives/$permission.ts +2 -2
  350. package/src/security/primitives/$realm.spec.ts +101 -0
  351. package/src/security/primitives/$role.spec.ts +52 -0
  352. package/src/security/primitives/$serviceAccount.spec.ts +61 -0
  353. package/src/security/providers/SecurityProvider.spec.ts +350 -0
  354. package/src/server/auth/providers/ServerAuthProvider.ts +0 -2
  355. package/src/server/cache/providers/ServerCacheProvider.spec.ts +942 -0
  356. package/src/server/compress/providers/ServerCompressProvider.spec.ts +31 -0
  357. package/src/server/compress/providers/ServerCompressProvider.ts +2 -0
  358. package/src/server/cookies/providers/ServerCookiesProvider.spec.ts +253 -0
  359. package/src/server/core/__tests__/ServerRouterProvider-getRoutes.spec.ts +334 -0
  360. package/src/server/core/__tests__/ServerRouterProvider-requestId.spec.ts +129 -0
  361. package/src/server/core/primitives/$action.spec.ts +191 -0
  362. package/src/server/core/primitives/$route.spec.ts +65 -0
  363. package/src/server/core/providers/ServerBodyParserProvider.spec.ts +93 -0
  364. package/src/server/core/providers/ServerLoggerProvider.spec.ts +100 -0
  365. package/src/server/core/providers/ServerProvider.ts +3 -1
  366. package/src/server/core/services/HttpClient.spec.ts +123 -0
  367. package/src/server/core/services/UserAgentParser.spec.ts +111 -0
  368. package/src/server/cors/providers/ServerCorsProvider.spec.ts +481 -0
  369. package/src/server/health/providers/ServerHealthProvider.spec.ts +22 -0
  370. package/src/server/helmet/providers/ServerHelmetProvider.spec.ts +105 -0
  371. package/src/server/links/__tests__/$action.spec.ts +238 -0
  372. package/src/server/links/__tests__/fixtures/CrudApp.ts +122 -0
  373. package/src/server/links/__tests__/requestId.spec.ts +120 -0
  374. package/src/server/links/primitives/$remote.spec.ts +228 -0
  375. package/src/server/links/providers/LinkProvider.spec.ts +54 -0
  376. package/src/server/links/providers/LinkProvider.ts +49 -3
  377. package/src/server/links/providers/ServerLinksProvider.ts +1 -53
  378. package/src/server/links/schemas/apiLinksResponseSchema.ts +7 -0
  379. package/src/server/metrics/providers/ServerMetricsProvider.spec.ts +25 -0
  380. package/src/server/multipart/providers/ServerMultipartProvider.spec.ts +528 -0
  381. package/src/server/proxy/primitives/$proxy.spec.ts +87 -0
  382. package/src/server/rate-limit/__tests__/ActionRateLimit.spec.ts +211 -0
  383. package/src/server/rate-limit/providers/ServerRateLimitProvider.spec.ts +344 -0
  384. package/src/server/security/__tests__/BasicAuth.spec.ts +684 -0
  385. package/src/server/security/__tests__/ServerSecurityProvider-realm.spec.ts +388 -0
  386. package/src/server/security/providers/ServerSecurityProvider.spec.ts +123 -0
  387. package/src/server/static/primitives/$serve.spec.ts +193 -0
  388. package/src/server/swagger/__tests__/ui.spec.ts +52 -0
  389. package/src/server/swagger/primitives/$swagger.spec.ts +193 -0
  390. package/src/server/swagger/providers/ServerSwaggerProvider.ts +18 -8
  391. package/src/sms/primitives/$sms.spec.ts +165 -0
  392. package/src/sms/providers/LocalSmsProvider.spec.ts +224 -0
  393. package/src/sms/providers/MemorySmsProvider.spec.ts +193 -0
  394. package/src/thread/primitives/$thread.spec.ts +186 -0
  395. package/src/topic/core/__tests__/shared.ts +144 -0
  396. package/src/topic/core/providers/MemoryTopicProvider.spec.ts +23 -0
  397. package/src/topic/redis/providers/RedisTopicProvider.spec.ts +23 -0
  398. package/src/vite/plugins/viteAlephaDev.ts +16 -4
  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/commands/BiomeCommands.ts +0 -29
@@ -0,0 +1,229 @@
1
+ import { Alepha } from "alepha";
2
+ import { describe, expect, it } from "vitest";
3
+ import { SecurityError, SecurityProvider } from "../index.ts";
4
+
5
+ /**
6
+ * Bug #1: Multi-layer Wildcard Permission Validation Fails After App Start
7
+ *
8
+ * Issue: When creating roles with multi-layer wildcard permissions (e.g., "admin:api:*")
9
+ * after app.start(), the validation logic only checked if parts[1] === "*", which fails
10
+ * for deeper wildcards.
11
+ *
12
+ * Expected: Multi-layer wildcards should be validated correctly by checking if any
13
+ * permission exists with the matching group prefix.
14
+ */
15
+ describe("Bug #1: Multi-layer Wildcard Permission Validation After App Start", () => {
16
+ it("should allow creating role with 2-layer wildcard after app start", async () => {
17
+ const app = Alepha.create();
18
+ const sec = app.inject(SecurityProvider);
19
+
20
+ sec.createPermission("hello:hey");
21
+ sec.createPermission("hello:ho");
22
+
23
+ await app.start();
24
+
25
+ // This should work - 2-layer wildcard with existing permissions
26
+ expect(() =>
27
+ sec.createRole({
28
+ name: "superuser",
29
+ permissions: [{ name: "hello:*" }],
30
+ }),
31
+ ).not.toThrow();
32
+
33
+ expect(sec.can("superuser", "hello:hey")).toEqual(true);
34
+ expect(sec.can("superuser", "hello:ho")).toEqual(true);
35
+ });
36
+
37
+ it("should allow creating role with 3-layer wildcard after app start", async () => {
38
+ const app = Alepha.create();
39
+ const sec = app.inject(SecurityProvider);
40
+
41
+ sec.createPermission("admin:api:users");
42
+ sec.createPermission("admin:api:posts");
43
+
44
+ await app.start();
45
+
46
+ // This is the bug - should work but previously failed
47
+ expect(() =>
48
+ sec.createRole({
49
+ name: "api-admin",
50
+ permissions: [{ name: "admin:api:*" }],
51
+ }),
52
+ ).not.toThrow();
53
+
54
+ expect(sec.can("api-admin", "admin:api:users")).toEqual(true);
55
+ expect(sec.can("api-admin", "admin:api:posts")).toEqual(true);
56
+ });
57
+
58
+ it("should allow creating role with 4-layer wildcard after app start", async () => {
59
+ const app = Alepha.create();
60
+ const sec = app.inject(SecurityProvider);
61
+
62
+ sec.createPermission("admin:api:v1:users");
63
+ sec.createPermission("admin:api:v1:posts");
64
+
65
+ await app.start();
66
+
67
+ // Deep wildcard should work
68
+ expect(() =>
69
+ sec.createRole({
70
+ name: "api-v1-admin",
71
+ permissions: [{ name: "admin:api:v1:*" }],
72
+ }),
73
+ ).not.toThrow();
74
+
75
+ expect(sec.can("api-v1-admin", "admin:api:v1:users")).toEqual(true);
76
+ expect(sec.can("api-v1-admin", "admin:api:v1:posts")).toEqual(true);
77
+ });
78
+
79
+ it("should allow wildcard that matches nested groups", async () => {
80
+ const app = Alepha.create();
81
+ const sec = app.inject(SecurityProvider);
82
+
83
+ // Create permissions with different nesting levels under same prefix
84
+ sec.createPermission("admin:api:users:read");
85
+ sec.createPermission("admin:api:users:write");
86
+ sec.createPermission("admin:api:posts:delete");
87
+
88
+ await app.start();
89
+
90
+ // Wildcard at intermediate level should work
91
+ expect(() =>
92
+ sec.createRole({
93
+ name: "api-manager",
94
+ permissions: [{ name: "admin:api:*" }],
95
+ }),
96
+ ).not.toThrow();
97
+
98
+ expect(sec.can("api-manager", "admin:api:users:read")).toEqual(true);
99
+ expect(sec.can("api-manager", "admin:api:users:write")).toEqual(true);
100
+ expect(sec.can("api-manager", "admin:api:posts:delete")).toEqual(true);
101
+ });
102
+
103
+ it("should reject wildcard when no matching permissions exist", async () => {
104
+ const app = Alepha.create();
105
+ const sec = app.inject(SecurityProvider);
106
+
107
+ sec.createPermission("hello:hey");
108
+
109
+ await app.start();
110
+
111
+ // This should fail - no permissions match "admin:*"
112
+ expect(() =>
113
+ sec.createRole({
114
+ name: "admin",
115
+ permissions: [{ name: "admin:*" }],
116
+ }),
117
+ ).toThrow(SecurityError);
118
+
119
+ expect(() =>
120
+ sec.createRole({
121
+ name: "admin-api",
122
+ permissions: [{ name: "admin:api:*" }],
123
+ }),
124
+ ).toThrow(SecurityError);
125
+ });
126
+
127
+ it("should allow global wildcard after app start", async () => {
128
+ const app = Alepha.create();
129
+ const sec = app.inject(SecurityProvider);
130
+
131
+ sec.createPermission("anything");
132
+
133
+ await app.start();
134
+
135
+ // Global wildcard should always work
136
+ expect(() =>
137
+ sec.createRole({
138
+ name: "admin",
139
+ permissions: [{ name: "*" }],
140
+ }),
141
+ ).not.toThrow();
142
+
143
+ expect(sec.can("admin", "anything")).toEqual(true);
144
+ });
145
+
146
+ it("should allow exact permission match after app start", async () => {
147
+ const app = Alepha.create();
148
+ const sec = app.inject(SecurityProvider);
149
+
150
+ sec.createPermission("admin:api:users:read");
151
+
152
+ await app.start();
153
+
154
+ // Exact permission should work
155
+ expect(() =>
156
+ sec.createRole({
157
+ name: "reader",
158
+ permissions: [{ name: "admin:api:users:read" }],
159
+ }),
160
+ ).not.toThrow();
161
+
162
+ expect(sec.can("reader", "admin:api:users:read")).toEqual(true);
163
+ });
164
+
165
+ it("should reject exact permission when it doesn't exist", async () => {
166
+ const app = Alepha.create();
167
+ const sec = app.inject(SecurityProvider);
168
+
169
+ sec.createPermission("hello:hey");
170
+
171
+ await app.start();
172
+
173
+ // Non-existent exact permission should fail
174
+ expect(() =>
175
+ sec.createRole({
176
+ name: "user",
177
+ permissions: [{ name: "admin:api:users:read" }],
178
+ }),
179
+ ).toThrow(SecurityError);
180
+ });
181
+
182
+ it("should handle mixed wildcards and exact permissions", async () => {
183
+ const app = Alepha.create();
184
+ const sec = app.inject(SecurityProvider);
185
+
186
+ sec.createPermission("admin:api:users:read");
187
+ sec.createPermission("admin:api:posts:write");
188
+ sec.createPermission("public:read");
189
+
190
+ await app.start();
191
+
192
+ // Mix of wildcard and exact should work if all exist
193
+ expect(() =>
194
+ sec.createRole({
195
+ name: "mixed",
196
+ permissions: [
197
+ { name: "admin:api:*" }, // wildcard - should match
198
+ { name: "public:read" }, // exact - exists
199
+ ],
200
+ }),
201
+ ).not.toThrow();
202
+
203
+ expect(sec.can("mixed", "admin:api:users:read")).toEqual(true);
204
+ expect(sec.can("mixed", "public:read")).toEqual(true);
205
+ });
206
+
207
+ it("should handle wildcard at exact group level", async () => {
208
+ const app = Alepha.create();
209
+ const sec = app.inject(SecurityProvider);
210
+
211
+ // Permission with exact group "admin:api"
212
+ sec.createPermission({ group: "admin:api", name: "execute" });
213
+ // Permission with nested group "admin:api:users"
214
+ sec.createPermission({ group: "admin:api:users", name: "read" });
215
+
216
+ await app.start();
217
+
218
+ // Wildcard "admin:api:*" should match both
219
+ expect(() =>
220
+ sec.createRole({
221
+ name: "api-all",
222
+ permissions: [{ name: "admin:api:*" }],
223
+ }),
224
+ ).not.toThrow();
225
+
226
+ expect(sec.can("api-all", "admin:api:execute")).toEqual(true);
227
+ expect(sec.can("api-all", "admin:api:users:read")).toEqual(true);
228
+ });
229
+ });
@@ -0,0 +1,245 @@
1
+ import { Alepha } from "alepha";
2
+ import { describe, expect, it } from "vitest";
3
+ import { CryptoProvider } from "../index.ts";
4
+
5
+ /**
6
+ * Bug #2: Password Verification Missing Input Validation
7
+ *
8
+ * Issue: The verifyPassword method didn't validate input format before processing,
9
+ * leading to crashes when:
10
+ * - stored hash is malformed (missing colon, wrong format)
11
+ * - stored hash has incorrect length
12
+ * - timingSafeEqual throws when buffer lengths differ
13
+ *
14
+ * Expected: All invalid inputs should return false gracefully instead of throwing.
15
+ */
16
+ describe("Bug #2: Password Verification Missing Input Validation", () => {
17
+ it("should verify valid password correctly", async () => {
18
+ const app = Alepha.create();
19
+ const crypto = app.inject(CryptoProvider);
20
+
21
+ const password = "mySecurePassword123!";
22
+ const hashed = await crypto.hashPassword(password);
23
+
24
+ const isValid = await crypto.verifyPassword(password, hashed);
25
+ expect(isValid).toBe(true);
26
+
27
+ const isInvalid = await crypto.verifyPassword("wrongPassword", hashed);
28
+ expect(isInvalid).toBe(false);
29
+ });
30
+
31
+ it("should return false for malformed hash with no colon", async () => {
32
+ const app = Alepha.create();
33
+ const crypto = app.inject(CryptoProvider);
34
+
35
+ const malformed = "notavalidhashwithoutcolon";
36
+
37
+ // Should not throw, should return false
38
+ const result = await crypto.verifyPassword("password", malformed);
39
+ expect(result).toBe(false);
40
+ });
41
+
42
+ it("should return false for hash with multiple colons", async () => {
43
+ const app = Alepha.create();
44
+ const crypto = app.inject(CryptoProvider);
45
+
46
+ const malformed = "salt:hash:extra";
47
+
48
+ const result = await crypto.verifyPassword("password", malformed);
49
+ expect(result).toBe(false);
50
+ });
51
+
52
+ it("should return false for empty string", async () => {
53
+ const app = Alepha.create();
54
+ const crypto = app.inject(CryptoProvider);
55
+
56
+ const result = await crypto.verifyPassword("password", "");
57
+ expect(result).toBe(false);
58
+ });
59
+
60
+ it("should return false for hash with empty salt", async () => {
61
+ const app = Alepha.create();
62
+ const crypto = app.inject(CryptoProvider);
63
+
64
+ const malformed = ":somehashvalue";
65
+
66
+ const result = await crypto.verifyPassword("password", malformed);
67
+ expect(result).toBe(false);
68
+ });
69
+
70
+ it("should return false for hash with empty hash value", async () => {
71
+ const app = Alepha.create();
72
+ const crypto = app.inject(CryptoProvider);
73
+
74
+ const malformed = "somesalt:";
75
+
76
+ const result = await crypto.verifyPassword("password", malformed);
77
+ expect(result).toBe(false);
78
+ });
79
+
80
+ it("should return false for just a colon", async () => {
81
+ const app = Alepha.create();
82
+ const crypto = app.inject(CryptoProvider);
83
+
84
+ const malformed = ":";
85
+
86
+ const result = await crypto.verifyPassword("password", malformed);
87
+ expect(result).toBe(false);
88
+ });
89
+
90
+ it("should return false for invalid hex in hash portion", async () => {
91
+ const app = Alepha.create();
92
+ const crypto = app.inject(CryptoProvider);
93
+
94
+ // Valid salt, but hash contains non-hex characters
95
+ const malformed = "validSalt123:notHexChars!@#";
96
+
97
+ const result = await crypto.verifyPassword("password", malformed);
98
+ expect(result).toBe(false);
99
+ });
100
+
101
+ it("should return false for odd-length hex string", async () => {
102
+ const app = Alepha.create();
103
+ const crypto = app.inject(CryptoProvider);
104
+
105
+ // Hex strings must have even length (2 chars per byte)
106
+ const malformed = "salt:abc"; // 3 chars, odd
107
+
108
+ const result = await crypto.verifyPassword("password", malformed);
109
+ expect(result).toBe(false);
110
+ });
111
+
112
+ it("should return false for hash with wrong length", async () => {
113
+ const app = Alepha.create();
114
+ const crypto = app.inject(CryptoProvider);
115
+
116
+ // Valid hex, but wrong length (scrypt produces 64 bytes = 128 hex chars)
117
+ const malformed = "salt:abcd"; // Only 4 hex chars = 2 bytes
118
+
119
+ const result = await crypto.verifyPassword("password", malformed);
120
+ expect(result).toBe(false);
121
+ });
122
+
123
+ it("should return false for corrupted but well-formed hash", async () => {
124
+ const app = Alepha.create();
125
+ const crypto = app.inject(CryptoProvider);
126
+
127
+ const password = "testPassword";
128
+ const hashed = await crypto.hashPassword(password);
129
+
130
+ // Corrupt the hash by changing one character
131
+ const removedChar = hashed.slice(-1);
132
+ const corrupted = hashed.slice(0, -1) + (removedChar === "0" ? "1" : "0");
133
+
134
+ const result = await crypto.verifyPassword(password, corrupted);
135
+ expect(result).toBe(false);
136
+ });
137
+
138
+ it("should return false for null or undefined input", async () => {
139
+ const app = Alepha.create();
140
+ const crypto = app.inject(CryptoProvider);
141
+
142
+ // @ts-expect-error - testing runtime behavior
143
+ const resultNull = await crypto.verifyPassword("password", null);
144
+ expect(resultNull).toBe(false);
145
+
146
+ // @ts-expect-error - testing runtime behavior
147
+ const resultUndefined = await crypto.verifyPassword("password", undefined);
148
+ expect(resultUndefined).toBe(false);
149
+ });
150
+
151
+ it("should return false for non-string input", async () => {
152
+ const app = Alepha.create();
153
+ const crypto = app.inject(CryptoProvider);
154
+
155
+ // @ts-expect-error - testing runtime behavior
156
+ const resultNumber = await crypto.verifyPassword("password", 12345);
157
+ expect(resultNumber).toBe(false);
158
+
159
+ // @ts-expect-error - testing runtime behavior
160
+ const resultObject = await crypto.verifyPassword("password", {
161
+ hash: "test",
162
+ });
163
+ expect(resultObject).toBe(false);
164
+ });
165
+
166
+ it("should handle special characters in salt gracefully", async () => {
167
+ const app = Alepha.create();
168
+ const crypto = app.inject(CryptoProvider);
169
+
170
+ // If somehow a salt with special chars got stored
171
+ const malformed =
172
+ "salt\nwith\nnewlines:0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef";
173
+
174
+ // Should not crash, should return false (likely during scrypt or comparison)
175
+ const result = await crypto.verifyPassword("password", malformed);
176
+ expect(result).toBe(false);
177
+ });
178
+
179
+ it("should validate format before attempting expensive scrypt operation", async () => {
180
+ const app = Alepha.create();
181
+ const crypto = app.inject(CryptoProvider);
182
+
183
+ // These should fail fast without calling scrypt
184
+ const invalidFormats = [
185
+ "no-colon-at-all",
186
+ "too:many:colons:here",
187
+ ":no-salt",
188
+ "no-hash:",
189
+ ":",
190
+ "",
191
+ "salt:invalidhex!",
192
+ "salt:abc", // odd length
193
+ ];
194
+
195
+ for (const invalid of invalidFormats) {
196
+ const result = await crypto.verifyPassword("password", invalid);
197
+ expect(result).toBe(false);
198
+ }
199
+ });
200
+
201
+ it("should properly handle valid hash format with correct verification", async () => {
202
+ const app = Alepha.create();
203
+ const crypto = app.inject(CryptoProvider);
204
+
205
+ // Test multiple passwords
206
+ const passwords = [
207
+ "simple",
208
+ "with spaces",
209
+ "special!@#$%^&*()",
210
+ "emoji🔐🔑",
211
+ `${"very".repeat(100)}long`,
212
+ ];
213
+
214
+ for (const password of passwords) {
215
+ const hashed = await crypto.hashPassword(password);
216
+
217
+ // Verify format is correct (salt:hash with 128 hex chars for hash)
218
+ expect(hashed).toMatch(/^[0-9a-f]+:[0-9a-f]{128}$/i);
219
+
220
+ // Correct password should verify
221
+ expect(await crypto.verifyPassword(password, hashed)).toBe(true);
222
+
223
+ // Wrong password should not verify
224
+ expect(await crypto.verifyPassword(`${password}wrong`, hashed)).toBe(
225
+ false,
226
+ );
227
+ }
228
+ });
229
+
230
+ it("should prevent timing attacks with constant-time comparison", async () => {
231
+ const app = Alepha.create();
232
+ const crypto = app.inject(CryptoProvider);
233
+
234
+ const password = "testPassword";
235
+ const hashed = await crypto.hashPassword(password);
236
+
237
+ // Both wrong passwords should take similar time (constant-time comparison)
238
+ // This is a behavioral test - we're just checking they both return false
239
+ const wrongPassword1 = "x";
240
+ const wrongPassword2 = "x".repeat(100);
241
+
242
+ expect(await crypto.verifyPassword(wrongPassword1, hashed)).toBe(false);
243
+ expect(await crypto.verifyPassword(wrongPassword2, hashed)).toBe(false);
244
+ });
245
+ });