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,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
+ });
@@ -0,0 +1,129 @@
1
+ import { Alepha } from "alepha";
2
+ import { beforeEach, describe, it } from "vitest";
3
+ import { $action, HttpClient, HttpError, ServerProvider } from "../index.ts";
4
+
5
+ class TestApp {
6
+ // HttpError with custom message
7
+ httpError = $action({
8
+ handler: () => {
9
+ throw new HttpError({
10
+ message: "Custom error message",
11
+ status: 400,
12
+ });
13
+ },
14
+ });
15
+
16
+ // Generic Error without status (500)
17
+ genericError = $action({
18
+ handler: () => {
19
+ throw new Error("Something went wrong");
20
+ },
21
+ });
22
+ }
23
+
24
+ describe("ServerRouterProvider - requestId", () => {
25
+ let alepha: Alepha;
26
+ let client: HttpClient;
27
+ let hostname: string;
28
+
29
+ beforeEach(async () => {
30
+ alepha = Alepha.create().with(TestApp);
31
+ client = alepha.inject(HttpClient);
32
+ await alepha.start();
33
+ hostname = alepha.inject(ServerProvider).hostname;
34
+ });
35
+
36
+ it("should include requestId in raw HTTP error response for HttpError", async ({
37
+ expect,
38
+ }) => {
39
+ // Make raw HTTP request to see the actual JSON response
40
+ const response = await fetch(`${hostname}/api/httpError`, {
41
+ headers: {
42
+ "x-request-id": "test-request-123",
43
+ },
44
+ });
45
+
46
+ expect(response.status).toBe(400);
47
+
48
+ const responseText = await response.text();
49
+ const responseJson = JSON.parse(responseText);
50
+
51
+ // Check that the raw HTTP response includes requestId
52
+ expect(responseJson).toMatchObject({
53
+ message: "Custom error message",
54
+ status: 400,
55
+ error: "BadRequestError",
56
+ requestId: "test-request-123",
57
+ });
58
+ });
59
+
60
+ it("should include requestId in raw HTTP error response for generic error", async ({
61
+ expect,
62
+ }) => {
63
+ // Make raw HTTP request to see the actual JSON response
64
+ const response = await fetch(`${hostname}/api/genericError`, {
65
+ headers: {
66
+ "x-request-id": "test-request-789",
67
+ },
68
+ });
69
+
70
+ expect(response.status).toBe(500);
71
+
72
+ const responseText = await response.text();
73
+ const responseJson = JSON.parse(responseText);
74
+
75
+ // Check that the raw HTTP response includes requestId
76
+ expect(responseJson).toMatchObject({
77
+ status: 500,
78
+ error: "InternalServerError",
79
+ message: "Something went wrong",
80
+ requestId: "test-request-789",
81
+ });
82
+ });
83
+
84
+ it("should auto-generate requestId in raw response when not provided", async ({
85
+ expect,
86
+ }) => {
87
+ // Make raw HTTP request without providing requestId
88
+ const response = await fetch(`${hostname}/api/genericError`);
89
+
90
+ expect(response.status).toBe(500);
91
+
92
+ const responseText = await response.text();
93
+ const responseJson = JSON.parse(responseText);
94
+
95
+ // Check that the raw HTTP response includes an auto-generated requestId
96
+ expect(responseJson).toMatchObject({
97
+ status: 500,
98
+ error: "InternalServerError",
99
+ message: "Something went wrong",
100
+ });
101
+
102
+ // Should have a requestId even when not provided in headers
103
+ expect(responseJson.requestId).toBeDefined();
104
+ expect(typeof responseJson.requestId).toBe("string");
105
+ expect(responseJson.requestId.length).toBeGreaterThan(0);
106
+ });
107
+
108
+ it("should properly handle error with requestId through HttpClient", async ({
109
+ expect,
110
+ }) => {
111
+ try {
112
+ await client.fetch(`${hostname}/api/httpError`, {
113
+ headers: {
114
+ "x-request-id": "test-request-client",
115
+ },
116
+ });
117
+ // Should not reach here
118
+ expect(true).toBe(false);
119
+ } catch (error) {
120
+ if (error instanceof HttpError) {
121
+ const errorJson = HttpError.toJSON(error);
122
+ expect(errorJson.requestId).toBe("test-request-client");
123
+ } else {
124
+ // For now, let's see what we actually get
125
+ expect(error).toBeInstanceOf(Error);
126
+ }
127
+ }
128
+ });
129
+ });
@@ -12,9 +12,9 @@ export class ServerReply {
12
12
  public body?: any;
13
13
 
14
14
  /**
15
- * Redirect to a given URL with optional status code (default 302).
15
+ * Redirect to a given URL with optional status code (default 301).
16
16
  */
17
- public redirect(url: string, status: number = 302): void {
17
+ public redirect(url: string, status: number = 301): void {
18
18
  this.status = status;
19
19
  this.headers.location = url;
20
20
  }
@@ -0,0 +1,191 @@
1
+ import { Alepha, t } from "alepha";
2
+ import { FileSystemProvider } from "alepha/file";
3
+ import { describe, test } from "vitest";
4
+ import { $action } from "../index.ts";
5
+
6
+ describe("$action", () => {
7
+ test("should expose api", async ({ expect }) => {
8
+ class Api {
9
+ hello = $action({
10
+ schema: {
11
+ params: t.object({
12
+ name: t.text(),
13
+ }),
14
+ query: t.object({
15
+ transform: t.optional(t.enum(["uppercase"])),
16
+ }),
17
+ response: t.object({
18
+ message: t.text(),
19
+ }),
20
+ },
21
+ handler: ({ params, query }) => {
22
+ const message = `Hello ${params.name}`;
23
+ if (query.transform === "uppercase") {
24
+ return {
25
+ message: message.toUpperCase(),
26
+ };
27
+ }
28
+ return { message };
29
+ },
30
+ });
31
+ }
32
+
33
+ const alepha = Alepha.create();
34
+ const app = alepha.inject(Api);
35
+ await alepha.start();
36
+
37
+ expect(await app.hello.run({ params: { name: "John" } })).toStrictEqual({
38
+ message: "Hello John",
39
+ });
40
+
41
+ expect(
42
+ await app.hello.run({
43
+ params: { name: "John" },
44
+ query: { transform: "uppercase" },
45
+ }),
46
+ ).toStrictEqual({
47
+ message: "HELLO JOHN",
48
+ });
49
+
50
+ expect(
51
+ await app.hello.fetch({ params: { name: "John" } }).then((it) => it.data),
52
+ ).toStrictEqual({
53
+ message: "Hello John",
54
+ });
55
+
56
+ expect(
57
+ await app.hello
58
+ .fetch({
59
+ params: { name: "John" },
60
+ query: { transform: "uppercase" },
61
+ })
62
+ .then((it) => it.data),
63
+ ).toStrictEqual({
64
+ message: "HELLO JOHN",
65
+ });
66
+ });
67
+
68
+ test("should not be exposed when disabled", async ({ expect }) => {
69
+ const alepha = Alepha.create();
70
+ class TestApp {
71
+ a1 = $action({
72
+ handler: () => "ok:a1",
73
+ });
74
+ a2 = $action({
75
+ handler: () => "ok:a2",
76
+ disabled: true,
77
+ });
78
+ }
79
+ const app = alepha.inject(TestApp);
80
+ await alepha.start();
81
+
82
+ expect(await app.a1.fetch({}).then((it) => it.data)).toBe("ok:a1");
83
+ expect(await app.a2.fetch({}).then((it) => it.data)).toBe("Not Found");
84
+ // note: $action disabled is callable locally
85
+ expect(await app.a2.run({})).toBe("ok:a2");
86
+ });
87
+
88
+ test("should return nothing", async ({ expect }) => {
89
+ const alepha = Alepha.create();
90
+ class TestApp {
91
+ test = $action({
92
+ schema: {
93
+ response: t.void(), // force no response
94
+ },
95
+ handler: () => {},
96
+ });
97
+ }
98
+ const app = alepha.inject(TestApp);
99
+ await alepha.start();
100
+
101
+ expect(await app.test.run({})).toStrictEqual(undefined);
102
+ expect(await app.test.fetch({}).then((it) => it.data)).toStrictEqual(
103
+ undefined,
104
+ );
105
+
106
+ const response = await app.test.fetch({});
107
+ expect(response.status).toBe(204); // No Content
108
+ });
109
+
110
+ test("should return an object", async ({ expect }) => {
111
+ const alepha = Alepha.create();
112
+ class TestApp {
113
+ test = $action({
114
+ schema: {
115
+ response: t.json(),
116
+ },
117
+ handler: () => ({
118
+ ok: true,
119
+ }),
120
+ });
121
+ }
122
+ const app = alepha.inject(TestApp);
123
+ await alepha.start();
124
+
125
+ expect(await app.test()).toStrictEqual({ ok: true });
126
+ expect(await app.test.run({})).toStrictEqual({ ok: true });
127
+ expect(await app.test.fetch({}).then((it) => it.data)).toStrictEqual({
128
+ ok: true,
129
+ });
130
+ });
131
+
132
+ test("should return a file", async ({ expect }) => {
133
+ const alepha = Alepha.create();
134
+ const fileSystem = alepha.inject(FileSystemProvider);
135
+ class TestApp {
136
+ test = $action({
137
+ schema: {
138
+ response: t.file(), // expect a file response
139
+ },
140
+ handler: () =>
141
+ fileSystem.createFile({
142
+ buffer: Buffer.from("hello"),
143
+ name: "hello.txt",
144
+ type: "text/plain",
145
+ }),
146
+ });
147
+ }
148
+ const app = alepha.inject(TestApp);
149
+ await alepha.start();
150
+
151
+ expect(await app.test().then((it) => it.text())).toBe("hello");
152
+ expect(await app.test.run().then((it) => it.text())).toBe("hello");
153
+ expect(await app.test.fetch({}).then((it) => it.data.text())).toBe("hello");
154
+
155
+ const file = await app.test.run({});
156
+ expect(file.name).toBe("hello.txt");
157
+ expect(file.type).toBe("text/plain");
158
+ });
159
+
160
+ test("should filter fields", async ({ expect }) => {
161
+ const alepha = Alepha.create();
162
+ const fileSystem = alepha.inject(FileSystemProvider);
163
+ class TestApp {
164
+ test = $action({
165
+ schema: {
166
+ body: t.object({
167
+ extra: t.text(),
168
+ }),
169
+ response: t.string(),
170
+ },
171
+ handler: ({ body }) => JSON.stringify(body),
172
+ });
173
+ }
174
+ const app = alepha.inject(TestApp);
175
+ await alepha.start();
176
+
177
+ expect(
178
+ await app.test.run({
179
+ body: { extra: "some extra", invalid: "nope" },
180
+ } as any),
181
+ ).toBe(JSON.stringify({ extra: "some extra" }));
182
+
183
+ expect(
184
+ await app.test
185
+ .fetch({
186
+ body: { extra: "some extra", invalid: "nope" },
187
+ } as any)
188
+ .then((it) => it.data),
189
+ ).toBe(JSON.stringify({ extra: "some extra" }));
190
+ });
191
+ });