alepha 0.14.2 → 0.14.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (361) hide show
  1. package/dist/api/audits/index.browser.js +5 -5
  2. package/dist/api/audits/index.browser.js.map +1 -1
  3. package/dist/api/audits/index.d.ts +784 -784
  4. package/dist/api/audits/index.d.ts.map +1 -1
  5. package/dist/api/audits/index.js +13 -13
  6. package/dist/api/audits/index.js.map +1 -1
  7. package/dist/api/files/index.browser.js +5 -5
  8. package/dist/api/files/index.browser.js.map +1 -1
  9. package/dist/api/files/index.d.ts +57 -57
  10. package/dist/api/files/index.d.ts.map +1 -1
  11. package/dist/api/files/index.js +71 -71
  12. package/dist/api/files/index.js.map +1 -1
  13. package/dist/api/jobs/index.browser.js +5 -5
  14. package/dist/api/jobs/index.browser.js.map +1 -1
  15. package/dist/api/jobs/index.d.ts +165 -165
  16. package/dist/api/jobs/index.d.ts.map +1 -1
  17. package/dist/api/jobs/index.js +10 -10
  18. package/dist/api/jobs/index.js.map +1 -1
  19. package/dist/api/notifications/index.browser.js +10 -10
  20. package/dist/api/notifications/index.browser.js.map +1 -1
  21. package/dist/api/notifications/index.d.ts +583 -171
  22. package/dist/api/notifications/index.d.ts.map +1 -1
  23. package/dist/api/notifications/index.js +12 -12
  24. package/dist/api/notifications/index.js.map +1 -1
  25. package/dist/api/parameters/index.browser.js +163 -10
  26. package/dist/api/parameters/index.browser.js.map +1 -1
  27. package/dist/api/parameters/index.d.ts +281 -276
  28. package/dist/api/parameters/index.d.ts.map +1 -1
  29. package/dist/api/parameters/index.js +196 -91
  30. package/dist/api/parameters/index.js.map +1 -1
  31. package/dist/api/users/index.browser.js +19 -19
  32. package/dist/api/users/index.browser.js.map +1 -1
  33. package/dist/api/users/index.d.ts +1137 -1123
  34. package/dist/api/users/index.d.ts.map +1 -1
  35. package/dist/api/users/index.js +827 -596
  36. package/dist/api/users/index.js.map +1 -1
  37. package/dist/api/verifications/index.browser.js +6 -6
  38. package/dist/api/verifications/index.browser.js.map +1 -1
  39. package/dist/api/verifications/index.d.ts +13 -13
  40. package/dist/api/verifications/index.d.ts.map +1 -1
  41. package/dist/api/verifications/index.js +6 -6
  42. package/dist/api/verifications/index.js.map +1 -1
  43. package/dist/bin/index.d.ts +1 -2
  44. package/dist/bin/index.js +0 -1
  45. package/dist/bin/index.js.map +1 -1
  46. package/dist/cli/index.d.ts +137 -112
  47. package/dist/cli/index.d.ts.map +1 -1
  48. package/dist/cli/index.js +371 -259
  49. package/dist/cli/index.js.map +1 -1
  50. package/dist/command/index.d.ts +45 -5
  51. package/dist/command/index.d.ts.map +1 -1
  52. package/dist/command/index.js +97 -17
  53. package/dist/command/index.js.map +1 -1
  54. package/dist/core/index.browser.js +14 -18
  55. package/dist/core/index.browser.js.map +1 -1
  56. package/dist/core/index.d.ts +29 -0
  57. package/dist/core/index.d.ts.map +1 -1
  58. package/dist/core/index.js +14 -18
  59. package/dist/core/index.js.map +1 -1
  60. package/dist/core/index.native.js +14 -18
  61. package/dist/core/index.native.js.map +1 -1
  62. package/dist/fake/index.js +195 -168
  63. package/dist/fake/index.js.map +1 -1
  64. package/dist/file/index.d.ts +8 -0
  65. package/dist/file/index.d.ts.map +1 -1
  66. package/dist/file/index.js +3 -0
  67. package/dist/file/index.js.map +1 -1
  68. package/dist/mcp/index.d.ts.map +1 -1
  69. package/dist/orm/index.d.ts +32 -32
  70. package/dist/orm/index.d.ts.map +1 -1
  71. package/dist/orm/index.js +12 -12
  72. package/dist/orm/index.js.map +1 -1
  73. package/dist/security/index.d.ts +1 -1
  74. package/dist/security/index.d.ts.map +1 -1
  75. package/dist/security/index.js +1 -1
  76. package/dist/security/index.js.map +1 -1
  77. package/dist/server/auth/index.d.ts +171 -155
  78. package/dist/server/auth/index.d.ts.map +1 -1
  79. package/dist/server/auth/index.js +0 -1
  80. package/dist/server/auth/index.js.map +1 -1
  81. package/dist/server/compress/index.d.ts.map +1 -1
  82. package/dist/server/compress/index.js +2 -0
  83. package/dist/server/compress/index.js.map +1 -1
  84. package/dist/server/core/index.d.ts.map +1 -1
  85. package/dist/server/core/index.js +1 -1
  86. package/dist/server/core/index.js.map +1 -1
  87. package/dist/server/links/index.browser.js +22 -6
  88. package/dist/server/links/index.browser.js.map +1 -1
  89. package/dist/server/links/index.d.ts +46 -44
  90. package/dist/server/links/index.d.ts.map +1 -1
  91. package/dist/server/links/index.js +24 -41
  92. package/dist/server/links/index.js.map +1 -1
  93. package/dist/server/security/index.d.ts +9 -9
  94. package/dist/server/swagger/index.d.ts +2 -1
  95. package/dist/server/swagger/index.d.ts.map +1 -1
  96. package/dist/server/swagger/index.js +8 -3
  97. package/dist/server/swagger/index.js.map +1 -1
  98. package/dist/vite/index.d.ts.map +1 -1
  99. package/dist/vite/index.js +12 -4
  100. package/dist/vite/index.js.map +1 -1
  101. package/dist/websocket/index.d.ts +7 -7
  102. package/package.json +7 -7
  103. package/src/api/audits/controllers/{AuditController.ts → AdminAuditController.ts} +5 -6
  104. package/src/api/audits/entities/audits.ts +5 -5
  105. package/src/api/audits/index.browser.ts +1 -1
  106. package/src/api/audits/index.ts +3 -3
  107. package/src/api/audits/primitives/$audit.spec.ts +276 -0
  108. package/src/api/audits/services/AuditService.spec.ts +495 -0
  109. package/src/api/files/__tests__/$bucket.spec.ts +91 -0
  110. package/src/api/files/controllers/AdminFileStatsController.spec.ts +166 -0
  111. package/src/api/files/controllers/{StorageStatsController.ts → AdminFileStatsController.ts} +2 -2
  112. package/src/api/files/controllers/FileController.spec.ts +558 -0
  113. package/src/api/files/controllers/FileController.ts +4 -5
  114. package/src/api/files/entities/files.ts +5 -5
  115. package/src/api/files/index.browser.ts +1 -1
  116. package/src/api/files/index.ts +4 -4
  117. package/src/api/files/jobs/FileJobs.spec.ts +52 -0
  118. package/src/api/files/services/FileService.spec.ts +109 -0
  119. package/src/api/jobs/__tests__/JobController.spec.ts +343 -0
  120. package/src/api/jobs/controllers/{JobController.ts → AdminJobController.ts} +2 -2
  121. package/src/api/jobs/entities/jobExecutions.ts +5 -5
  122. package/src/api/jobs/index.ts +3 -3
  123. package/src/api/jobs/primitives/$job.spec.ts +476 -0
  124. package/src/api/notifications/controllers/{NotificationController.ts → AdminNotificationController.ts} +4 -5
  125. package/src/api/notifications/entities/notifications.ts +5 -5
  126. package/src/api/notifications/index.browser.ts +1 -1
  127. package/src/api/notifications/index.ts +4 -4
  128. package/src/api/parameters/controllers/{ConfigController.ts → AdminConfigController.ts} +46 -107
  129. package/src/api/parameters/entities/parameters.ts +7 -17
  130. package/src/api/parameters/index.ts +3 -3
  131. package/src/api/parameters/primitives/$config.spec.ts +356 -0
  132. package/src/api/parameters/schemas/activateConfigBodySchema.ts +12 -0
  133. package/src/api/parameters/schemas/checkScheduledResponseSchema.ts +8 -0
  134. package/src/api/parameters/schemas/configCurrentResponseSchema.ts +13 -0
  135. package/src/api/parameters/schemas/configHistoryResponseSchema.ts +9 -0
  136. package/src/api/parameters/schemas/configNameParamSchema.ts +10 -0
  137. package/src/api/parameters/schemas/configNamesResponseSchema.ts +8 -0
  138. package/src/api/parameters/schemas/configTreeNodeSchema.ts +13 -0
  139. package/src/api/parameters/schemas/configVersionParamSchema.ts +9 -0
  140. package/src/api/parameters/schemas/configVersionResponseSchema.ts +9 -0
  141. package/src/api/parameters/schemas/configsByStatusResponseSchema.ts +9 -0
  142. package/src/api/parameters/schemas/createConfigVersionBodySchema.ts +24 -0
  143. package/src/api/parameters/schemas/index.ts +15 -0
  144. package/src/api/parameters/schemas/parameterResponseSchema.ts +26 -0
  145. package/src/api/parameters/schemas/parameterStatusSchema.ts +13 -0
  146. package/src/api/parameters/schemas/rollbackConfigBodySchema.ts +15 -0
  147. package/src/api/parameters/schemas/statusParamSchema.ts +9 -0
  148. package/src/api/users/__tests__/EmailVerification.spec.ts +369 -0
  149. package/src/api/users/__tests__/PasswordReset.spec.ts +550 -0
  150. package/src/api/users/controllers/AdminIdentityController.spec.ts +365 -0
  151. package/src/api/users/controllers/{IdentityController.ts → AdminIdentityController.ts} +3 -4
  152. package/src/api/users/controllers/AdminSessionController.spec.ts +274 -0
  153. package/src/api/users/controllers/{SessionController.ts → AdminSessionController.ts} +3 -4
  154. package/src/api/users/controllers/AdminUserController.spec.ts +372 -0
  155. package/src/api/users/controllers/AdminUserController.ts +116 -0
  156. package/src/api/users/controllers/UserController.ts +4 -107
  157. package/src/api/users/controllers/UserRealmController.ts +3 -0
  158. package/src/api/users/entities/identities.ts +6 -6
  159. package/src/api/users/entities/sessions.ts +6 -6
  160. package/src/api/users/entities/users.ts +9 -9
  161. package/src/api/users/index.ts +9 -6
  162. package/src/api/users/primitives/$userRealm.ts +13 -8
  163. package/src/api/users/services/CredentialService.spec.ts +509 -0
  164. package/src/api/users/services/CredentialService.ts +46 -0
  165. package/src/api/users/services/IdentityService.ts +15 -0
  166. package/src/api/users/services/RegistrationService.spec.ts +630 -0
  167. package/src/api/users/services/RegistrationService.ts +18 -0
  168. package/src/api/users/services/SessionService.spec.ts +301 -0
  169. package/src/api/users/services/SessionService.ts +110 -1
  170. package/src/api/users/services/UserService.ts +67 -2
  171. package/src/api/verifications/__tests__/CodeVerification.spec.ts +318 -0
  172. package/src/api/verifications/__tests__/LinkVerification.spec.ts +279 -0
  173. package/src/api/verifications/entities/verifications.ts +6 -6
  174. package/src/api/verifications/jobs/VerificationJobs.spec.ts +50 -0
  175. package/src/batch/__tests__/startup-buffering.spec.ts +458 -0
  176. package/src/batch/primitives/$batch.spec.ts +766 -0
  177. package/src/batch/providers/BatchProvider.spec.ts +786 -0
  178. package/src/bin/index.ts +0 -1
  179. package/src/bucket/__tests__/shared.ts +194 -0
  180. package/src/bucket/primitives/$bucket.spec.ts +104 -0
  181. package/src/bucket/providers/FileStorageProvider.spec.ts +13 -0
  182. package/src/bucket/providers/LocalFileStorageProvider.spec.ts +77 -0
  183. package/src/bucket/providers/MemoryFileStorageProvider.spec.ts +82 -0
  184. package/src/cache/core/__tests__/shared.ts +377 -0
  185. package/src/cache/core/primitives/$cache.spec.ts +111 -0
  186. package/src/cache/redis/__tests__/cache-redis.spec.ts +70 -0
  187. package/src/cli/apps/AlephaCli.ts +25 -4
  188. package/src/cli/commands/dev.ts +19 -7
  189. package/src/cli/commands/gen/changelog.spec.ts +315 -0
  190. package/src/cli/commands/{changelog.ts → gen/changelog.ts} +9 -9
  191. package/src/cli/commands/gen/openapi.ts +71 -0
  192. package/src/cli/commands/gen.ts +18 -0
  193. package/src/cli/commands/init.ts +2 -0
  194. package/src/cli/commands/root.ts +12 -3
  195. package/src/cli/commands/typecheck.ts +5 -0
  196. package/src/cli/index.ts +2 -1
  197. package/src/cli/services/AlephaCliUtils.ts +71 -32
  198. package/src/cli/services/GitMessageParser.ts +1 -1
  199. package/src/command/helpers/Asker.spec.ts +127 -0
  200. package/src/command/helpers/Runner.spec.ts +126 -0
  201. package/src/command/primitives/$command.spec.ts +1588 -0
  202. package/src/command/providers/CliProvider.ts +74 -24
  203. package/src/core/Alepha.ts +45 -0
  204. package/src/core/__tests__/Alepha-emit.spec.ts +22 -0
  205. package/src/core/__tests__/Alepha-graph.spec.ts +93 -0
  206. package/src/core/__tests__/Alepha-has.spec.ts +41 -0
  207. package/src/core/__tests__/Alepha-inject.spec.ts +93 -0
  208. package/src/core/__tests__/Alepha-register.spec.ts +81 -0
  209. package/src/core/__tests__/Alepha-start.spec.ts +176 -0
  210. package/src/core/__tests__/Alepha-with.spec.ts +14 -0
  211. package/src/core/__tests__/TypeBox-usecases.spec.ts +35 -0
  212. package/src/core/__tests__/TypeBoxLocale.spec.ts +15 -0
  213. package/src/core/__tests__/descriptor.spec.ts +34 -0
  214. package/src/core/__tests__/fixtures/A.ts +5 -0
  215. package/src/core/__tests__/pagination.spec.ts +77 -0
  216. package/src/core/helpers/jsonSchemaToTypeBox.ts +2 -2
  217. package/src/core/primitives/$atom.spec.ts +43 -0
  218. package/src/core/primitives/$hook.spec.ts +130 -0
  219. package/src/core/primitives/$inject.spec.ts +175 -0
  220. package/src/core/primitives/$module.spec.ts +115 -0
  221. package/src/core/providers/CodecManager.spec.ts +740 -0
  222. package/src/core/providers/EventManager.spec.ts +762 -0
  223. package/src/core/providers/EventManager.ts +4 -0
  224. package/src/core/providers/StateManager.spec.ts +365 -0
  225. package/src/core/providers/TypeProvider.spec.ts +1607 -0
  226. package/src/core/providers/TypeProvider.ts +20 -26
  227. package/src/datetime/primitives/$interval.spec.ts +103 -0
  228. package/src/datetime/providers/DateTimeProvider.spec.ts +86 -0
  229. package/src/email/primitives/$email.spec.ts +175 -0
  230. package/src/email/providers/LocalEmailProvider.spec.ts +341 -0
  231. package/src/fake/__tests__/keyName.example.ts +40 -0
  232. package/src/fake/__tests__/keyName.spec.ts +152 -0
  233. package/src/fake/__tests__/module.example.ts +32 -0
  234. package/src/fake/providers/FakeProvider.spec.ts +438 -0
  235. package/src/file/providers/FileSystemProvider.ts +8 -0
  236. package/src/file/providers/NodeFileSystemProvider.spec.ts +418 -0
  237. package/src/file/providers/NodeFileSystemProvider.ts +5 -0
  238. package/src/file/services/FileDetector.spec.ts +591 -0
  239. package/src/lock/core/__tests__/shared.ts +190 -0
  240. package/src/lock/core/providers/MemoryLockProvider.spec.ts +25 -0
  241. package/src/lock/redis/providers/RedisLockProvider.spec.ts +25 -0
  242. package/src/logger/__tests__/SimpleFormatterProvider.spec.ts +109 -0
  243. package/src/logger/primitives/$logger.spec.ts +108 -0
  244. package/src/logger/services/Logger.spec.ts +295 -0
  245. package/src/mcp/__tests__/errors.spec.ts +175 -0
  246. package/src/mcp/__tests__/integration.spec.ts +450 -0
  247. package/src/mcp/helpers/jsonrpc.spec.ts +380 -0
  248. package/src/mcp/primitives/$prompt.spec.ts +468 -0
  249. package/src/mcp/primitives/$resource.spec.ts +390 -0
  250. package/src/mcp/primitives/$tool.spec.ts +406 -0
  251. package/src/mcp/providers/McpServerProvider.spec.ts +797 -0
  252. package/src/orm/__tests__/$repository-crud.spec.ts +276 -0
  253. package/src/orm/__tests__/$repository-hooks.spec.ts +325 -0
  254. package/src/orm/__tests__/$repository-orderBy.spec.ts +128 -0
  255. package/src/orm/__tests__/$repository-pagination-sort.spec.ts +149 -0
  256. package/src/orm/__tests__/$repository-save.spec.ts +37 -0
  257. package/src/orm/__tests__/ModelBuilder-integration.spec.ts +490 -0
  258. package/src/orm/__tests__/ModelBuilder-types.spec.ts +186 -0
  259. package/src/orm/__tests__/PostgresProvider.spec.ts +46 -0
  260. package/src/orm/__tests__/delete-returning.spec.ts +256 -0
  261. package/src/orm/__tests__/deletedAt.spec.ts +80 -0
  262. package/src/orm/__tests__/enums.spec.ts +315 -0
  263. package/src/orm/__tests__/execute.spec.ts +72 -0
  264. package/src/orm/__tests__/fixtures/bigEntitySchema.ts +65 -0
  265. package/src/orm/__tests__/fixtures/userEntitySchema.ts +27 -0
  266. package/src/orm/__tests__/joins.spec.ts +1114 -0
  267. package/src/orm/__tests__/page.spec.ts +287 -0
  268. package/src/orm/__tests__/primaryKey.spec.ts +87 -0
  269. package/src/orm/__tests__/query-date-encoding.spec.ts +402 -0
  270. package/src/orm/__tests__/ref-auto-onDelete.spec.ts +156 -0
  271. package/src/orm/__tests__/references.spec.ts +102 -0
  272. package/src/orm/__tests__/security.spec.ts +710 -0
  273. package/src/orm/__tests__/sqlite.spec.ts +111 -0
  274. package/src/orm/__tests__/string-operators.spec.ts +429 -0
  275. package/src/orm/__tests__/timestamps.spec.ts +388 -0
  276. package/src/orm/__tests__/validation.spec.ts +183 -0
  277. package/src/orm/__tests__/version.spec.ts +64 -0
  278. package/src/orm/helpers/parseQueryString.spec.ts +196 -0
  279. package/src/orm/primitives/$repository.spec.ts +137 -0
  280. package/src/orm/primitives/$sequence.spec.ts +29 -0
  281. package/src/orm/primitives/$transaction.spec.ts +82 -0
  282. package/src/orm/providers/drivers/BunPostgresProvider.ts +3 -3
  283. package/src/orm/providers/drivers/BunSqliteProvider.ts +1 -1
  284. package/src/orm/providers/drivers/CloudflareD1Provider.ts +1 -1
  285. package/src/orm/providers/drivers/DatabaseProvider.ts +1 -1
  286. package/src/orm/providers/drivers/NodePostgresProvider.ts +3 -3
  287. package/src/orm/providers/drivers/NodeSqliteProvider.ts +1 -1
  288. package/src/orm/providers/drivers/PglitePostgresProvider.ts +2 -2
  289. package/src/orm/services/ModelBuilder.spec.ts +575 -0
  290. package/src/orm/services/Repository.spec.ts +137 -0
  291. package/src/queue/core/__tests__/shared.ts +143 -0
  292. package/src/queue/core/providers/MemoryQueueProvider.spec.ts +23 -0
  293. package/src/queue/core/providers/WorkerProvider.spec.ts +378 -0
  294. package/src/queue/redis/providers/RedisQueueProvider.spec.ts +23 -0
  295. package/src/redis/__tests__/redis.spec.ts +58 -0
  296. package/src/retry/primitives/$retry.spec.ts +234 -0
  297. package/src/retry/providers/RetryProvider.spec.ts +438 -0
  298. package/src/router/__tests__/match.spec.ts +252 -0
  299. package/src/router/providers/RouterProvider.spec.ts +197 -0
  300. package/src/scheduler/__tests__/$scheduler-cron.spec.ts +25 -0
  301. package/src/scheduler/__tests__/$scheduler-interval.spec.ts +25 -0
  302. package/src/scheduler/__tests__/shared.ts +77 -0
  303. package/src/security/__tests__/bug-1-wildcard-after-start.spec.ts +229 -0
  304. package/src/security/__tests__/bug-2-password-validation.spec.ts +245 -0
  305. package/src/security/__tests__/bug-3-regex-vulnerability.spec.ts +407 -0
  306. package/src/security/__tests__/bug-4-oauth2-validation.spec.ts +439 -0
  307. package/src/security/__tests__/multi-layer-permissions.spec.ts +522 -0
  308. package/src/security/primitives/$permission.spec.ts +30 -0
  309. package/src/security/primitives/$permission.ts +2 -2
  310. package/src/security/primitives/$realm.spec.ts +101 -0
  311. package/src/security/primitives/$role.spec.ts +52 -0
  312. package/src/security/primitives/$serviceAccount.spec.ts +61 -0
  313. package/src/security/providers/SecurityProvider.spec.ts +350 -0
  314. package/src/server/auth/providers/ServerAuthProvider.ts +0 -2
  315. package/src/server/cache/providers/ServerCacheProvider.spec.ts +942 -0
  316. package/src/server/compress/providers/ServerCompressProvider.spec.ts +31 -0
  317. package/src/server/compress/providers/ServerCompressProvider.ts +2 -0
  318. package/src/server/cookies/providers/ServerCookiesProvider.spec.ts +253 -0
  319. package/src/server/core/__tests__/ServerRouterProvider-getRoutes.spec.ts +334 -0
  320. package/src/server/core/__tests__/ServerRouterProvider-requestId.spec.ts +129 -0
  321. package/src/server/core/primitives/$action.spec.ts +191 -0
  322. package/src/server/core/primitives/$route.spec.ts +65 -0
  323. package/src/server/core/providers/ServerBodyParserProvider.spec.ts +93 -0
  324. package/src/server/core/providers/ServerLoggerProvider.spec.ts +100 -0
  325. package/src/server/core/providers/ServerProvider.ts +3 -1
  326. package/src/server/core/services/HttpClient.spec.ts +123 -0
  327. package/src/server/core/services/UserAgentParser.spec.ts +111 -0
  328. package/src/server/cors/providers/ServerCorsProvider.spec.ts +481 -0
  329. package/src/server/health/providers/ServerHealthProvider.spec.ts +22 -0
  330. package/src/server/helmet/providers/ServerHelmetProvider.spec.ts +105 -0
  331. package/src/server/links/__tests__/$action.spec.ts +238 -0
  332. package/src/server/links/__tests__/fixtures/CrudApp.ts +122 -0
  333. package/src/server/links/__tests__/requestId.spec.ts +120 -0
  334. package/src/server/links/primitives/$remote.spec.ts +228 -0
  335. package/src/server/links/providers/LinkProvider.spec.ts +54 -0
  336. package/src/server/links/providers/LinkProvider.ts +49 -3
  337. package/src/server/links/providers/ServerLinksProvider.ts +1 -53
  338. package/src/server/links/schemas/apiLinksResponseSchema.ts +7 -0
  339. package/src/server/metrics/providers/ServerMetricsProvider.spec.ts +25 -0
  340. package/src/server/multipart/providers/ServerMultipartProvider.spec.ts +528 -0
  341. package/src/server/proxy/primitives/$proxy.spec.ts +87 -0
  342. package/src/server/rate-limit/__tests__/ActionRateLimit.spec.ts +211 -0
  343. package/src/server/rate-limit/providers/ServerRateLimitProvider.spec.ts +344 -0
  344. package/src/server/security/__tests__/BasicAuth.spec.ts +684 -0
  345. package/src/server/security/__tests__/ServerSecurityProvider-realm.spec.ts +388 -0
  346. package/src/server/security/providers/ServerSecurityProvider.spec.ts +123 -0
  347. package/src/server/static/primitives/$serve.spec.ts +193 -0
  348. package/src/server/swagger/__tests__/ui.spec.ts +52 -0
  349. package/src/server/swagger/primitives/$swagger.spec.ts +193 -0
  350. package/src/server/swagger/providers/ServerSwaggerProvider.ts +18 -8
  351. package/src/sms/primitives/$sms.spec.ts +165 -0
  352. package/src/sms/providers/LocalSmsProvider.spec.ts +224 -0
  353. package/src/sms/providers/MemorySmsProvider.spec.ts +193 -0
  354. package/src/thread/primitives/$thread.spec.ts +186 -0
  355. package/src/topic/core/__tests__/shared.ts +144 -0
  356. package/src/topic/core/providers/MemoryTopicProvider.spec.ts +23 -0
  357. package/src/topic/redis/providers/RedisTopicProvider.spec.ts +23 -0
  358. package/src/vite/plugins/viteAlephaDev.ts +16 -4
  359. package/src/vite/tasks/runAlepha.ts +7 -1
  360. package/src/websocket/__tests__/$websocket-new.spec.ts +195 -0
  361. package/src/websocket/primitives/$channel.spec.ts +30 -0
@@ -0,0 +1,31 @@
1
+ import { Alepha } from "alepha";
2
+ import { $action, ServerProvider } from "alepha/server";
3
+ import { describe, it } from "vitest";
4
+ import { AlephaServerCompress } from "../index.ts";
5
+
6
+ class App {
7
+ hello = $action({
8
+ handler: () => "Hello, world!",
9
+ });
10
+ }
11
+
12
+ const a1 = Alepha.create().with(App).with(AlephaServerCompress);
13
+ const a2 = Alepha.create().with(App);
14
+
15
+ describe("ServerCompressProvider", () => {
16
+ it("should compress responses when enabled", async ({ expect }) => {
17
+ const serv1 = a1.inject(ServerProvider);
18
+ const serv2 = a2.inject(ServerProvider);
19
+
20
+ const resp1 = await fetch(`${serv1.hostname}/api/hello`, {
21
+ headers: { "Accept-Encoding": "gzip" },
22
+ });
23
+
24
+ const resp2 = await fetch(`${serv2.hostname}/api/hello`, {
25
+ headers: { "Accept-Encoding": "gzip" },
26
+ });
27
+
28
+ expect(resp1.headers.get("content-encoding")).toBe("gzip");
29
+ expect(resp2.headers.get("content-encoding")).toBeNull();
30
+ });
31
+ });
@@ -125,11 +125,13 @@ export class ServerCompressProvider {
125
125
  this.setHeaders(response, encoding);
126
126
  response.headers["content-length"] = compressed.length.toString();
127
127
  response.body = compressed;
128
+ return;
128
129
  }
129
130
 
130
131
  if (typeof body === "object" && body instanceof Readable) {
131
132
  this.setHeaders(response, encoding);
132
133
  response.body = body.pipe(compressor.stream({ params }));
134
+ return;
133
135
  }
134
136
 
135
137
  if (typeof body === "object" && body instanceof ReadableStream) {
@@ -0,0 +1,253 @@
1
+ import { Alepha, t } from "alepha";
2
+ import { $action, AlephaServer } from "alepha/server";
3
+ import { describe, expect, test } from "vitest";
4
+ import { $cookie, AlephaServerCookies } from "../index.ts";
5
+
6
+ // A strong, 32-character secret for testing purposes
7
+ const TEST_COOKIE_SECRET = "DCf6DvpLAfwy8XdPRucMO4tPS6dVCHob";
8
+
9
+ // --- Test Application Setup ---
10
+
11
+ class CookieTestApp {
12
+ // 1. Basic Cookie
13
+ session = $cookie({
14
+ name: "session",
15
+ schema: t.object({ userId: t.number(), role: t.text() }),
16
+ });
17
+
18
+ // 2. Signed Cookie
19
+ signed = $cookie({
20
+ name: "signed_session",
21
+ schema: t.text(),
22
+ sign: true,
23
+ });
24
+
25
+ // 3. Encrypted Cookie
26
+ encrypted = $cookie({
27
+ name: "encrypted_secret",
28
+ schema: t.object({ apiKey: t.text() }),
29
+ encrypt: true,
30
+ });
31
+
32
+ // 4. Compressed, Signed, and Encrypted Cookie with TTL
33
+ secure_all = $cookie({
34
+ name: "ultra_secure",
35
+ schema: t.object({ data: t.text() }),
36
+ compress: true,
37
+ sign: true,
38
+ encrypt: true,
39
+ ttl: [1, "hour"],
40
+ });
41
+
42
+ // An action to test the cookie functionality in a request cycle
43
+ cookie_test = $action({
44
+ schema: {
45
+ response: t.object({
46
+ incomingSession: t.optional(this.session.options.schema),
47
+ reqCookies: t.object({
48
+ req: t.record(t.text(), t.text()),
49
+ res: t.record(t.text(), t.any()),
50
+ }),
51
+ }),
52
+ },
53
+ handler: ({ cookies }) => {
54
+ // Set some cookies
55
+ this.session.set({ userId: 123, role: "admin" });
56
+ this.signed.set("i-am-signed");
57
+ this.encrypted.set({ apiKey: "secret-key" });
58
+ this.secure_all.set({ data: "super sensitive data" });
59
+
60
+ // Read a cookie from the request
61
+ const incomingSession = this.session.get({ cookies });
62
+
63
+ // Delete a cookie
64
+ if (incomingSession?.role === "guest") {
65
+ this.signed.del();
66
+ }
67
+
68
+ return { incomingSession, reqCookies: cookies };
69
+ },
70
+ });
71
+ }
72
+
73
+ const alepha = Alepha.create({
74
+ env: {
75
+ COOKIE_SECRET: TEST_COOKIE_SECRET,
76
+ },
77
+ })
78
+ .with(AlephaServer)
79
+ .with(AlephaServerCookies);
80
+
81
+ const app = alepha.inject(CookieTestApp);
82
+
83
+ // Helper to simulate a request and capture the response headers
84
+ const makeRequest = async (incomingCookieHeader = "") => {
85
+ const response = await app.cookie_test.fetch(
86
+ {},
87
+ {
88
+ request: { headers: { cookie: incomingCookieHeader } },
89
+ },
90
+ );
91
+ return {
92
+ data: response.data,
93
+ // The fetch client in tests might not handle multiple headers the same way a browser does.
94
+ // We get the raw header to properly check it.
95
+ setCookieHeader: response.raw?.headers.get("set-cookie"),
96
+ };
97
+ };
98
+
99
+ describe("ServerCookiesProvider", () => {
100
+ test("should set and get a basic cookie", async () => {
101
+ const { data, setCookieHeader } = await makeRequest();
102
+
103
+ // The handler receives no initial cookie
104
+ expect(data.incomingSession).toBeUndefined();
105
+
106
+ // Check if the response sets the cookie correctly
107
+ expect(setCookieHeader).toBeDefined();
108
+ const decodedValue = JSON.parse(
109
+ decodeURIComponent(setCookieHeader!.match(/session=([^;]*)/)![1]),
110
+ );
111
+ expect(decodedValue).toEqual({ userId: 123, role: "admin" });
112
+ });
113
+
114
+ test("should correctly read an incoming cookie", async () => {
115
+ const sessionData = { userId: 456, role: "user" };
116
+ const cookieHeader = `session=${encodeURIComponent(JSON.stringify(sessionData))}`;
117
+
118
+ const { data } = await makeRequest(cookieHeader);
119
+
120
+ // The handler should have received and parsed the cookie
121
+ expect(data.incomingSession).toEqual(sessionData);
122
+ });
123
+
124
+ test("should set and get a signed cookie", async () => {
125
+ const { setCookieHeader } = await makeRequest();
126
+ const signedCookie = setCookieHeader!.match(/signed_session=([^;]*)/)![1];
127
+
128
+ // Make a new request with the signed cookie
129
+ const { data } = await makeRequest(`signed_session=${signedCookie}`);
130
+
131
+ // The `get` method should successfully validate the signature and return the value
132
+ expect(app.signed.get({ cookies: data.reqCookies })).toBe("i-am-signed");
133
+ });
134
+
135
+ test("should reject a tampered signed cookie", async () => {
136
+ const { setCookieHeader } = await makeRequest();
137
+ let tamperedCookie = setCookieHeader!.match(/signed_session=([^;]*)/)![1];
138
+ tamperedCookie += "tampered"; // alter the cookie value
139
+
140
+ const { data } = await makeRequest(`signed_session=${tamperedCookie}`);
141
+
142
+ // The get should fail and return undefined
143
+ expect(app.signed.get({ cookies: data.reqCookies })).toBeUndefined();
144
+ });
145
+
146
+ test("should set and get an encrypted cookie", async () => {
147
+ const { setCookieHeader } = await makeRequest();
148
+ const encryptedCookie = setCookieHeader!.match(
149
+ /encrypted_secret=([^;]*)/,
150
+ )![1];
151
+
152
+ // The value should not be plain text
153
+ expect(decodeURIComponent(encryptedCookie)).not.toContain("secret-key");
154
+
155
+ const { data } = await makeRequest(`encrypted_secret=${encryptedCookie}`);
156
+
157
+ expect(app.encrypted.get({ cookies: data.reqCookies })).toEqual({
158
+ apiKey: "secret-key",
159
+ });
160
+ });
161
+
162
+ test("should reject a tampered encrypted cookie", async () => {
163
+ const { setCookieHeader } = await makeRequest();
164
+ const tamperedCookie = setCookieHeader!.match(
165
+ /encrypted_secret=([^;]*)/,
166
+ )![1];
167
+
168
+ const { data } = await makeRequest(
169
+ `encrypted_secret=aa${tamperedCookie}aa`,
170
+ );
171
+
172
+ // The get should fail (throw internally) and return undefined
173
+ expect(app.encrypted.get({ cookies: data.reqCookies })).toBeUndefined();
174
+ });
175
+
176
+ test("should handle a combination of compress, sign, and encrypt", async () => {
177
+ const { setCookieHeader } = await makeRequest();
178
+ const secureCookie = setCookieHeader!.match(/ultra_secure=([^;]*)/)![1];
179
+
180
+ const { data } = await makeRequest(`ultra_secure=${secureCookie}`);
181
+
182
+ expect(app.secure_all.get({ cookies: data.reqCookies })).toEqual({
183
+ data: "super sensitive data",
184
+ });
185
+ });
186
+
187
+ test("should delete a cookie", async () => {
188
+ const sessionData = { userId: 789, role: "guest" };
189
+ const cookieHeader = `session=${encodeURIComponent(JSON.stringify(sessionData))}`;
190
+
191
+ const { setCookieHeader } = await makeRequest(cookieHeader);
192
+
193
+ // The handler should detect role === 'guest' and delete the signed cookie
194
+ expect(setCookieHeader).toContain("signed_session=; Path=/; Max-Age=0");
195
+ });
196
+
197
+ test("should serialize all cookie attributes correctly", async () => {
198
+ class AttrApp {
199
+ advanced = $cookie({
200
+ name: "advanced",
201
+ schema: t.text(),
202
+ path: "/admin",
203
+ ttl: [30, "minutes"],
204
+ httpOnly: true,
205
+ secure: true,
206
+ sameSite: "strict",
207
+ domain: "example.com",
208
+ });
209
+ test = $action({
210
+ handler: () => {
211
+ this.advanced.set("value");
212
+ },
213
+ });
214
+ }
215
+
216
+ const attrAlepha = Alepha.create({
217
+ env: { COOKIE_SECRET: TEST_COOKIE_SECRET },
218
+ })
219
+ .with(AlephaServer)
220
+ .with(AlephaServerCookies)
221
+ .with(AttrApp);
222
+
223
+ await attrAlepha.start();
224
+
225
+ const response = await attrAlepha.inject(AttrApp).test.fetch();
226
+ const setCookieHeader = response.headers.get("set-cookie");
227
+ expect(setCookieHeader).toContain("Max-Age=1800");
228
+ expect(setCookieHeader).toContain("Path=/admin");
229
+ expect(setCookieHeader).toContain("HttpOnly");
230
+ expect(setCookieHeader).toContain("SameSite=strict");
231
+ expect(setCookieHeader).toContain("Domain=example.com");
232
+ // Secure flag is not added in tests unless protocol is https, which is handled by the provider
233
+ });
234
+
235
+ // test("should throw if secret is missing for secure cookies", async () => {
236
+ // class AppWithMissingSecret {
237
+ // badCookie = $cookie({
238
+ // name: "bad",
239
+ // schema: t.text(),
240
+ // sign: true,
241
+ // });
242
+ // }
243
+ //
244
+ // const alephaWithoutSecret = Alepha.create()
245
+ // .with(AlephaServer)
246
+ // .with(AlephaServerCookies)
247
+ // .with(AppWithMissingSecret);
248
+ //
249
+ // await expect(() => alephaWithoutSecret.start()).rejects.toThrow(
250
+ // /COOKIE_SECRET environment variable is not set/,
251
+ // );
252
+ // });
253
+ });
@@ -0,0 +1,334 @@
1
+ import { Alepha, t } from "alepha";
2
+ import { describe, it } from "vitest";
3
+ import { $action, $route, ServerRouterProvider } from "../index.ts";
4
+
5
+ describe("ServerRouterProvider - getRoutes", () => {
6
+ it("should return all routes when no pattern is provided", async ({
7
+ expect,
8
+ }) => {
9
+ const alepha = Alepha.create();
10
+
11
+ class TestApp {
12
+ action1 = $action({
13
+ path: "/users",
14
+ schema: { response: t.object({ id: t.integer() }) },
15
+ handler: () => ({ id: 1 }),
16
+ });
17
+
18
+ action2 = $action({
19
+ path: "/posts",
20
+ schema: { response: t.object({ id: t.integer() }) },
21
+ handler: () => ({ id: 1 }),
22
+ });
23
+
24
+ route1 = $route({
25
+ path: "/health",
26
+ handler: () => "OK",
27
+ });
28
+ }
29
+
30
+ await alepha.with(TestApp).start();
31
+
32
+ const routerProvider = alepha.inject(ServerRouterProvider);
33
+ const routes = routerProvider.getRoutes();
34
+
35
+ expect(routes.length).toBeGreaterThanOrEqual(3);
36
+ });
37
+
38
+ it("should return routes matching wildcard pattern", async ({ expect }) => {
39
+ const alepha = Alepha.create();
40
+
41
+ class TestApp {
42
+ users = $action({
43
+ path: "/users",
44
+ schema: { response: t.object({ id: t.integer() }) },
45
+ handler: () => ({ id: 1 }),
46
+ });
47
+
48
+ userDetail = $action({
49
+ path: "/users/:id",
50
+ schema: { response: t.object({ id: t.integer() }) },
51
+ handler: () => ({ id: 1 }),
52
+ });
53
+
54
+ posts = $action({
55
+ path: "/posts",
56
+ schema: { response: t.object({ id: t.integer() }) },
57
+ handler: () => ({ id: 1 }),
58
+ });
59
+
60
+ health = $route({
61
+ path: "/health",
62
+ handler: () => "OK",
63
+ });
64
+ }
65
+
66
+ await alepha.with(TestApp).start();
67
+
68
+ const routerProvider = alepha.inject(ServerRouterProvider);
69
+ const routes = routerProvider.getRoutes("/api/*");
70
+
71
+ // Should include the actions under /api/*
72
+ const paths = routes.map((r) => r.path);
73
+ expect(paths.length).toBeGreaterThanOrEqual(3);
74
+ expect(paths.some((p) => p.includes("/users"))).toBe(true);
75
+ expect(paths.some((p) => p.includes("/posts"))).toBe(true);
76
+ // health route should not match /api/*
77
+ expect(paths.some((p) => p === "/GET/health")).toBe(false);
78
+ });
79
+
80
+ it("should return empty array when pattern doesn't match any routes", async ({
81
+ expect,
82
+ }) => {
83
+ const alepha = Alepha.create();
84
+
85
+ class TestApp {
86
+ users = $action({
87
+ path: "/users",
88
+ schema: { response: t.object({ id: t.integer() }) },
89
+ handler: () => ({ id: 1 }),
90
+ });
91
+
92
+ posts = $action({
93
+ path: "/posts",
94
+ schema: { response: t.object({ id: t.integer() }) },
95
+ handler: () => ({ id: 1 }),
96
+ });
97
+ }
98
+
99
+ await alepha.with(TestApp).start();
100
+
101
+ const routerProvider = alepha.inject(ServerRouterProvider);
102
+ const routes = routerProvider.getRoutes("/v2/*");
103
+
104
+ expect(routes).toHaveLength(0);
105
+ });
106
+
107
+ it("should return empty array when exact pattern doesn't match", async ({
108
+ expect,
109
+ }) => {
110
+ const alepha = Alepha.create();
111
+
112
+ class TestApp {
113
+ users = $action({
114
+ path: "/users",
115
+ schema: { response: t.object({ id: t.integer() }) },
116
+ handler: () => ({ id: 1 }),
117
+ });
118
+ }
119
+
120
+ await alepha.with(TestApp).start();
121
+
122
+ const routerProvider = alepha.inject(ServerRouterProvider);
123
+ const routes = routerProvider.getRoutes("/admin");
124
+
125
+ expect(routes).toHaveLength(0);
126
+ });
127
+
128
+ it("should differentiate between exact match and wildcard match patterns", async ({
129
+ expect,
130
+ }) => {
131
+ const alepha = Alepha.create();
132
+
133
+ class TestApp {
134
+ apiInfo = $action({
135
+ path: "/api-info",
136
+ schema: { response: t.object({ id: t.integer() }) },
137
+ handler: () => ({ id: 1 }),
138
+ });
139
+
140
+ apiUsers = $action({
141
+ path: "/api-users",
142
+ schema: { response: t.object({ id: t.integer() }) },
143
+ handler: () => ({ id: 1 }),
144
+ });
145
+
146
+ settings = $route({
147
+ path: "/settings",
148
+ handler: () => "OK",
149
+ });
150
+ }
151
+
152
+ await alepha.with(TestApp).start();
153
+
154
+ const routerProvider = alepha.inject(ServerRouterProvider);
155
+
156
+ // Wildcard pattern matches multiple routes
157
+ const wildcardRoutes = routerProvider.getRoutes("/api/*");
158
+ expect(wildcardRoutes.length).toBeGreaterThan(0);
159
+ });
160
+
161
+ it("should return multiple routes for deep nested paths", async ({
162
+ expect,
163
+ }) => {
164
+ const alepha = Alepha.create();
165
+
166
+ class TestApp {
167
+ level1 = $action({
168
+ path: "/v1/users",
169
+ schema: { response: t.object({ id: t.integer() }) },
170
+ handler: () => ({ id: 1 }),
171
+ });
172
+
173
+ level2 = $action({
174
+ path: "/v1/users/:id/posts",
175
+ schema: { response: t.object({ id: t.integer() }) },
176
+ handler: () => ({ id: 1 }),
177
+ });
178
+
179
+ level3 = $action({
180
+ path: "/v1/users/:id/posts/:postId/comments",
181
+ schema: { response: t.object({ id: t.integer() }) },
182
+ handler: () => ({ id: 1 }),
183
+ });
184
+
185
+ v2 = $action({
186
+ path: "/v2/users",
187
+ schema: { response: t.object({ id: t.integer() }) },
188
+ handler: () => ({ id: 1 }),
189
+ });
190
+ }
191
+
192
+ await alepha.with(TestApp).start();
193
+
194
+ const routerProvider = alepha.inject(ServerRouterProvider);
195
+ const routes = routerProvider.getRoutes("/api/*");
196
+
197
+ // Should find nested routes under /api/*
198
+ expect(routes.length).toBeGreaterThanOrEqual(2);
199
+ const paths = routes.map((r) => r.path);
200
+ expect(paths.some((p) => p.includes("v1"))).toBe(true);
201
+ expect(paths.some((p) => p.includes("v2"))).toBe(true);
202
+ });
203
+
204
+ it("should match all routes with root wildcard pattern", async ({
205
+ expect,
206
+ }) => {
207
+ const alepha = Alepha.create();
208
+
209
+ class TestApp {
210
+ health = $route({
211
+ path: "/health",
212
+ schema: { response: t.object({ status: t.string() }) },
213
+ handler: () => ({ status: "ok" }),
214
+ });
215
+
216
+ about = $route({
217
+ path: "/about",
218
+ schema: { response: t.object({ name: t.string() }) },
219
+ handler: () => ({ name: "app" }),
220
+ });
221
+
222
+ users = $action({
223
+ path: "/users",
224
+ schema: { response: t.object({ id: t.integer() }) },
225
+ handler: () => ({ id: 1 }),
226
+ });
227
+ }
228
+
229
+ await alepha.with(TestApp).start();
230
+
231
+ const routerProvider = alepha.inject(ServerRouterProvider);
232
+ const routes = routerProvider.getRoutes("/*");
233
+
234
+ expect(routes.length).toBeGreaterThanOrEqual(3);
235
+ });
236
+
237
+ it("should correctly filter by path prefix", async ({ expect }) => {
238
+ const alepha = Alepha.create();
239
+
240
+ class TestApp {
241
+ publicApi = $action({
242
+ path: "/public/info",
243
+ schema: { response: t.object({ id: t.integer() }) },
244
+ handler: () => ({ id: 1 }),
245
+ });
246
+
247
+ adminApi = $action({
248
+ path: "/admin/users",
249
+ schema: { response: t.object({ id: t.integer() }) },
250
+ handler: () => ({ id: 1 }),
251
+ });
252
+
253
+ privateRoute = $route({
254
+ path: "/private",
255
+ handler: () => "private",
256
+ });
257
+ }
258
+
259
+ await alepha.with(TestApp).start();
260
+
261
+ const routerProvider = alepha.inject(ServerRouterProvider);
262
+
263
+ // Get routes matching /api/* pattern
264
+ const apiRoutes = routerProvider.getRoutes("/api/*");
265
+ expect(apiRoutes.length).toBeGreaterThan(0);
266
+
267
+ // Get routes matching a specific non-api pattern
268
+ const privateRoutes = routerProvider.getRoutes("/private");
269
+ expect(privateRoutes.length).toBeGreaterThanOrEqual(0);
270
+ });
271
+
272
+ it("should handle routes with method-specific paths", async ({ expect }) => {
273
+ const alepha = Alepha.create();
274
+
275
+ class TestApp {
276
+ getUsers = $action({
277
+ method: "GET",
278
+ path: "/users",
279
+ schema: { response: t.array(t.object({ id: t.integer() })) },
280
+ handler: () => [],
281
+ });
282
+
283
+ createUser = $action({
284
+ method: "POST",
285
+ path: "/users",
286
+ schema: { response: t.object({ id: t.integer() }) },
287
+ handler: () => ({ id: 1 }),
288
+ });
289
+
290
+ updateUser = $action({
291
+ method: "PATCH",
292
+ path: "/users/:id",
293
+ schema: { response: t.object({ id: t.integer() }) },
294
+ handler: () => ({ id: 1 }),
295
+ });
296
+ }
297
+
298
+ await alepha.with(TestApp).start();
299
+
300
+ const routerProvider = alepha.inject(ServerRouterProvider);
301
+ const routes = routerProvider.getRoutes("/api/*");
302
+
303
+ // Should return routes with different HTTP methods for /users path
304
+ expect(routes.length).toBeGreaterThanOrEqual(2);
305
+ const paths = routes.map((r) => r.path);
306
+ expect(paths.some((p) => p.includes("/users"))).toBe(true);
307
+ });
308
+
309
+ it("should be case-sensitive for path matching", async ({ expect }) => {
310
+ const alepha = Alepha.create();
311
+
312
+ class TestApp {
313
+ users = $action({
314
+ path: "/users",
315
+ schema: { response: t.object({ id: t.integer() }) },
316
+ handler: () => ({ id: 1 }),
317
+ });
318
+
319
+ users2 = $action({
320
+ path: "/Users",
321
+ schema: { response: t.object({ id: t.integer() }) },
322
+ handler: () => ({ id: 1 }),
323
+ });
324
+ }
325
+
326
+ await alepha.with(TestApp).start();
327
+
328
+ const routerProvider = alepha.inject(ServerRouterProvider);
329
+ const allRoutes = routerProvider.getRoutes();
330
+
331
+ // Both routes should exist
332
+ expect(allRoutes.length).toBeGreaterThanOrEqual(2);
333
+ });
334
+ });