alepha 0.13.6 → 0.13.8

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 (487) hide show
  1. package/README.md +5 -2
  2. package/assets/swagger-ui/swagger-ui-bundle.js +1 -1
  3. package/assets/swagger-ui/swagger-ui-standalone-preset.js +1 -1
  4. package/assets/swagger-ui/swagger-ui.css +1 -1
  5. package/dist/api/audits/index.browser.js +116 -0
  6. package/dist/api/audits/index.browser.js.map +1 -0
  7. package/dist/api/audits/index.d.ts +1194 -0
  8. package/dist/api/audits/index.js +674 -0
  9. package/dist/api/audits/index.js.map +1 -0
  10. package/dist/{api-files → api/files}/index.browser.js +5 -5
  11. package/dist/api/files/index.browser.js.map +1 -0
  12. package/dist/{api-files → api/files}/index.d.ts +16 -9
  13. package/dist/{api-files → api/files}/index.js +10 -10
  14. package/dist/api/files/index.js.map +1 -0
  15. package/dist/{api-jobs → api/jobs}/index.browser.js +5 -5
  16. package/dist/api/jobs/index.browser.js.map +1 -0
  17. package/dist/{api-jobs → api/jobs}/index.d.ts +35 -35
  18. package/dist/{api-jobs → api/jobs}/index.js +9 -9
  19. package/dist/api/jobs/index.js.map +1 -0
  20. package/dist/{api-notifications → api/notifications}/index.browser.js +11 -11
  21. package/dist/api/notifications/index.browser.js.map +1 -0
  22. package/dist/api/notifications/index.d.ts +327 -0
  23. package/dist/{api-notifications → api/notifications}/index.js +11 -11
  24. package/dist/api/notifications/index.js.map +1 -0
  25. package/dist/api/parameters/index.browser.js +60 -0
  26. package/dist/api/parameters/index.browser.js.map +1 -0
  27. package/dist/api/parameters/index.d.ts +761 -0
  28. package/dist/api/parameters/index.js +877 -0
  29. package/dist/api/parameters/index.js.map +1 -0
  30. package/dist/{api-users → api/users}/index.browser.js +6 -6
  31. package/dist/api/users/index.browser.js.map +1 -0
  32. package/dist/{api-users → api/users}/index.d.ts +259 -247
  33. package/dist/{api-users → api/users}/index.js +125 -112
  34. package/dist/api/users/index.js.map +1 -0
  35. package/dist/{api-verifications → api/verifications}/index.browser.js +5 -5
  36. package/dist/api/verifications/index.browser.js.map +1 -0
  37. package/dist/api/verifications/index.d.ts +248 -0
  38. package/dist/{api-verifications → api/verifications}/index.js +13 -12
  39. package/dist/api/verifications/index.js.map +1 -0
  40. package/dist/bin/index.js +1 -0
  41. package/dist/bin/index.js.map +1 -1
  42. package/dist/cache/{index.d.ts → core/index.d.ts} +4 -4
  43. package/dist/cache/{index.js → core/index.js} +5 -5
  44. package/dist/cache/core/index.js.map +1 -0
  45. package/dist/{cache-redis → cache/redis}/index.d.ts +2 -2
  46. package/dist/{cache-redis → cache/redis}/index.js +2 -2
  47. package/dist/cache/redis/index.js.map +1 -0
  48. package/dist/cli/index.d.ts +71 -9
  49. package/dist/cli/index.js +280 -79
  50. package/dist/cli/index.js.map +1 -1
  51. package/dist/command/index.d.ts +63 -2
  52. package/dist/command/index.js +30 -3
  53. package/dist/command/index.js.map +1 -1
  54. package/dist/core/index.browser.js +241 -61
  55. package/dist/core/index.browser.js.map +1 -1
  56. package/dist/core/index.d.ts +170 -90
  57. package/dist/core/index.js +264 -67
  58. package/dist/core/index.js.map +1 -1
  59. package/dist/core/index.native.js +248 -65
  60. package/dist/core/index.native.js.map +1 -1
  61. package/dist/email/index.js +15 -10554
  62. package/dist/email/index.js.map +1 -1
  63. package/dist/lock/{index.d.ts → core/index.d.ts} +5 -5
  64. package/dist/lock/{index.js → core/index.js} +5 -5
  65. package/dist/lock/core/index.js.map +1 -0
  66. package/dist/{lock-redis → lock/redis}/index.d.ts +2 -2
  67. package/dist/{lock-redis → lock/redis}/index.js +2 -2
  68. package/dist/lock/redis/index.js.map +1 -0
  69. package/dist/logger/index.d.ts +4 -4
  70. package/dist/logger/index.js +77 -72
  71. package/dist/logger/index.js.map +1 -1
  72. package/dist/orm/index.d.ts +5 -1
  73. package/dist/orm/index.js +24 -7
  74. package/dist/orm/index.js.map +1 -1
  75. package/dist/queue/core/index.d.ts +548 -0
  76. package/dist/queue/core/index.js +391 -0
  77. package/dist/queue/core/index.js.map +1 -0
  78. package/dist/queue/redis/index.d.ts +28 -0
  79. package/dist/queue/redis/index.js +43 -0
  80. package/dist/queue/redis/index.js.map +1 -0
  81. package/dist/scheduler/index.d.ts +7 -7
  82. package/dist/scheduler/index.js +1 -393
  83. package/dist/scheduler/index.js.map +1 -1
  84. package/dist/security/index.d.ts +1 -1
  85. package/dist/security/index.js +2 -1413
  86. package/dist/security/index.js.map +1 -1
  87. package/dist/{server-auth → server/auth}/index.browser.js +6 -6
  88. package/dist/server/auth/index.browser.js.map +1 -0
  89. package/dist/{server-auth → server/auth}/index.d.ts +175 -164
  90. package/dist/server/auth/index.js +742 -0
  91. package/dist/server/auth/index.js.map +1 -0
  92. package/dist/{server-cache → server/cache}/index.d.ts +2 -2
  93. package/dist/{server-cache → server/cache}/index.js +2 -2
  94. package/dist/server/cache/index.js.map +1 -0
  95. package/dist/{server-compress → server/compress}/index.d.ts +2 -2
  96. package/dist/{server-compress → server/compress}/index.js +2 -2
  97. package/dist/server/compress/index.js.map +1 -0
  98. package/dist/{server-cookies → server/cookies}/index.browser.js +3 -3
  99. package/dist/server/cookies/index.browser.js.map +1 -0
  100. package/dist/{server-cookies → server/cookies}/index.d.ts +4 -4
  101. package/dist/{server-cookies → server/cookies}/index.js +9 -5
  102. package/dist/server/cookies/index.js.map +1 -0
  103. package/dist/server/{index.browser.js → core/index.browser.js} +14 -14
  104. package/dist/server/core/index.browser.js.map +1 -0
  105. package/dist/server/{index.d.ts → core/index.d.ts} +46 -37
  106. package/dist/server/{index.js → core/index.js} +47 -33
  107. package/dist/server/core/index.js.map +1 -0
  108. package/dist/{server-cors → server/cors}/index.d.ts +3 -3
  109. package/dist/{server-cors → server/cors}/index.js +3 -3
  110. package/dist/server/cors/index.js.map +1 -0
  111. package/dist/{server-health → server/health}/index.d.ts +3 -3
  112. package/dist/{server-health → server/health}/index.js +3 -3
  113. package/dist/server/health/index.js.map +1 -0
  114. package/dist/{server-helmet → server/helmet}/index.d.ts +2 -2
  115. package/dist/{server-helmet → server/helmet}/index.js +2 -2
  116. package/dist/server/helmet/index.js.map +1 -0
  117. package/dist/{server-links → server/links}/index.browser.js +5 -5
  118. package/dist/server/links/index.browser.js.map +1 -0
  119. package/dist/{server-links → server/links}/index.d.ts +40 -40
  120. package/dist/{server-links → server/links}/index.js +7 -7
  121. package/dist/server/links/index.js.map +1 -0
  122. package/dist/{server-metrics → server/metrics}/index.d.ts +2 -2
  123. package/dist/server/metrics/index.js +74 -0
  124. package/dist/server/metrics/index.js.map +1 -0
  125. package/dist/{server-multipart → server/multipart}/index.d.ts +2 -2
  126. package/dist/{server-multipart → server/multipart}/index.js +2 -2
  127. package/dist/server/multipart/index.js.map +1 -0
  128. package/dist/{server-proxy → server/proxy}/index.d.ts +3 -3
  129. package/dist/{server-proxy → server/proxy}/index.js +3 -3
  130. package/dist/server/proxy/index.js.map +1 -0
  131. package/dist/{server-rate-limit → server/rate-limit}/index.d.ts +4 -4
  132. package/dist/{server-rate-limit → server/rate-limit}/index.js +4 -4
  133. package/dist/server/rate-limit/index.js.map +1 -0
  134. package/dist/{server-security → server/security}/index.browser.js +1 -1
  135. package/dist/server/security/index.browser.js.map +1 -0
  136. package/dist/{server-security → server/security}/index.d.ts +4 -4
  137. package/dist/{server-security → server/security}/index.js +4 -4
  138. package/dist/server/security/index.js.map +1 -0
  139. package/dist/{server-static → server/static}/index.d.ts +3 -3
  140. package/dist/{server-static → server/static}/index.js +3 -3
  141. package/dist/server/static/index.js.map +1 -0
  142. package/dist/{server-swagger → server/swagger}/index.d.ts +3 -3
  143. package/dist/{server-swagger → server/swagger}/index.js +4 -4
  144. package/dist/server/swagger/index.js.map +1 -0
  145. package/dist/thread/index.js +2 -2
  146. package/dist/thread/index.js.map +1 -1
  147. package/dist/topic/{index.d.ts → core/index.d.ts} +6 -6
  148. package/dist/topic/{index.js → core/index.js} +6 -6
  149. package/dist/topic/core/index.js.map +1 -0
  150. package/dist/{topic-redis → topic/redis}/index.d.ts +2 -2
  151. package/dist/{topic-redis → topic/redis}/index.js +2 -2
  152. package/dist/topic/redis/index.js.map +1 -0
  153. package/dist/vite/index.d.ts +13 -2
  154. package/dist/vite/index.js +114 -50
  155. package/dist/vite/index.js.map +1 -1
  156. package/dist/websocket/index.browser.js +3 -3
  157. package/dist/websocket/index.browser.js.map +1 -1
  158. package/dist/websocket/index.js +4 -4
  159. package/dist/websocket/index.js.map +1 -1
  160. package/package.json +160 -156
  161. package/src/api/audits/controllers/AuditController.ts +186 -0
  162. package/src/api/audits/entities/audits.ts +132 -0
  163. package/src/api/audits/index.browser.ts +18 -0
  164. package/src/api/audits/index.ts +58 -0
  165. package/src/api/audits/primitives/$audit.ts +159 -0
  166. package/src/api/audits/schemas/auditQuerySchema.ts +23 -0
  167. package/src/api/audits/schemas/auditResourceSchema.ts +9 -0
  168. package/src/api/audits/schemas/createAuditSchema.ts +27 -0
  169. package/src/api/audits/services/AuditService.ts +412 -0
  170. package/src/{api-files → api/files}/index.ts +1 -0
  171. package/src/api/parameters/controllers/ConfigController.ts +324 -0
  172. package/src/api/parameters/entities/parameters.ts +113 -0
  173. package/src/api/parameters/index.ts +60 -0
  174. package/src/api/parameters/primitives/$config.ts +351 -0
  175. package/src/api/parameters/schedulers/ConfigActivationScheduler.ts +30 -0
  176. package/src/api/parameters/services/ConfigStore.ts +491 -0
  177. package/src/{api-users → api/users}/atoms/realmAuthSettingsAtom.ts +19 -0
  178. package/src/{api-users → api/users}/controllers/UserRealmController.ts +0 -2
  179. package/src/{api-users → api/users}/index.ts +2 -0
  180. package/src/{api-users → api/users}/primitives/$userRealm.ts +18 -3
  181. package/src/{api-users → api/users}/providers/UserRealmProvider.ts +12 -10
  182. package/src/{api-users → api/users}/services/RegistrationService.ts +2 -1
  183. package/src/{api-users → api/users}/services/SessionService.ts +4 -0
  184. package/src/{api-users → api/users}/services/UserService.ts +3 -0
  185. package/src/{api-verifications → api/verifications}/index.ts +9 -1
  186. package/src/bin/index.ts +1 -0
  187. package/src/cli/apps/AlephaPackageBuilderCli.ts +73 -48
  188. package/src/cli/assets/appRouterTs.ts +1 -1
  189. package/src/cli/assets/biomeJson.ts +2 -2
  190. package/src/cli/assets/dummySpecTs.ts +7 -0
  191. package/src/cli/assets/editorconfig.ts +13 -0
  192. package/src/cli/assets/indexHtml.ts +1 -1
  193. package/src/cli/assets/mainBrowserTs.ts +1 -1
  194. package/src/cli/assets/mainTs.ts +14 -0
  195. package/src/cli/assets/viteConfigTs.ts +1 -1
  196. package/src/cli/commands/BiomeCommands.ts +2 -0
  197. package/src/cli/commands/CoreCommands.ts +38 -15
  198. package/src/cli/commands/VerifyCommands.ts +6 -2
  199. package/src/cli/commands/ViteCommands.ts +28 -18
  200. package/src/cli/services/AlephaCliUtils.ts +243 -37
  201. package/src/command/helpers/Asker.ts +0 -1
  202. package/src/command/primitives/$command.ts +67 -0
  203. package/src/command/providers/CliProvider.ts +39 -8
  204. package/src/core/Alepha.ts +40 -30
  205. package/src/core/helpers/jsonSchemaToTypeBox.ts +307 -0
  206. package/src/core/index.shared.ts +1 -0
  207. package/src/core/index.ts +30 -3
  208. package/src/core/providers/EventManager.ts +1 -1
  209. package/src/core/providers/SchemaValidator.ts +1 -1
  210. package/src/core/providers/StateManager.ts +23 -12
  211. package/src/core/providers/TypeProvider.ts +26 -34
  212. package/src/logger/index.ts +8 -6
  213. package/src/logger/primitives/$logger.ts +1 -1
  214. package/src/logger/providers/{SimpleFormatterProvider.ts → PrettyFormatterProvider.ts} +10 -1
  215. package/src/orm/index.ts +6 -0
  216. package/src/orm/services/PgRelationManager.ts +2 -2
  217. package/src/orm/services/PostgresModelBuilder.ts +11 -7
  218. package/src/orm/services/Repository.ts +16 -7
  219. package/src/orm/services/SqliteModelBuilder.ts +10 -0
  220. package/src/queue/{index.ts → core/index.ts} +2 -3
  221. package/src/queue/{primitives → core/primitives}/$queue.ts +17 -162
  222. package/src/queue/core/providers/MemoryQueueProvider.ts +19 -0
  223. package/src/queue/core/providers/QueueProvider.ts +23 -0
  224. package/src/queue/core/providers/WorkerProvider.ts +244 -0
  225. package/src/queue/redis/providers/RedisQueueProvider.ts +31 -0
  226. package/src/{server-auth → server/auth}/primitives/$auth.ts +7 -0
  227. package/src/{server-auth → server/auth}/providers/ServerAuthProvider.ts +51 -8
  228. package/src/{server-cookies → server/cookies}/index.ts +2 -1
  229. package/src/server/{index.ts → core/index.ts} +7 -0
  230. package/src/server/{primitives → core/primitives}/$action.ts +10 -1
  231. package/src/server/{providers → core/providers}/ServerBodyParserProvider.ts +11 -5
  232. package/src/server/{providers → core/providers}/ServerRouterProvider.ts +13 -7
  233. package/src/{server-rate-limit → server/rate-limit}/index.ts +1 -1
  234. package/src/{server-swagger → server/swagger}/providers/ServerSwaggerProvider.ts +1 -0
  235. package/src/thread/primitives/$thread.ts +2 -2
  236. package/src/vite/index.ts +0 -2
  237. package/src/vite/tasks/buildServer.ts +3 -4
  238. package/src/vite/tasks/copyAssets.ts +32 -8
  239. package/src/vite/tasks/generateCloudflare.ts +35 -19
  240. package/src/vite/tasks/generateDocker.ts +18 -4
  241. package/src/vite/tasks/generateSitemap.ts +5 -7
  242. package/src/vite/tasks/generateVercel.ts +76 -41
  243. package/src/vite/tasks/runAlepha.ts +16 -1
  244. package/src/websocket/providers/NodeWebSocketServerProvider.ts +3 -11
  245. package/src/websocket/services/WebSocketClient.ts +3 -3
  246. package/dist/api-files/index.browser.js.map +0 -1
  247. package/dist/api-files/index.js.map +0 -1
  248. package/dist/api-jobs/index.browser.js.map +0 -1
  249. package/dist/api-jobs/index.js.map +0 -1
  250. package/dist/api-notifications/index.browser.js.map +0 -1
  251. package/dist/api-notifications/index.d.ts +0 -327
  252. package/dist/api-notifications/index.js.map +0 -1
  253. package/dist/api-parameters/index.browser.js +0 -29
  254. package/dist/api-parameters/index.browser.js.map +0 -1
  255. package/dist/api-parameters/index.d.ts +0 -83
  256. package/dist/api-parameters/index.js +0 -63
  257. package/dist/api-parameters/index.js.map +0 -1
  258. package/dist/api-users/index.browser.js.map +0 -1
  259. package/dist/api-users/index.js.map +0 -1
  260. package/dist/api-verifications/index.browser.js.map +0 -1
  261. package/dist/api-verifications/index.d.ts +0 -229
  262. package/dist/api-verifications/index.js.map +0 -1
  263. package/dist/cache/index.js.map +0 -1
  264. package/dist/cache-redis/index.js.map +0 -1
  265. package/dist/cli/dist-BlfFtOk2.js +0 -2770
  266. package/dist/cli/dist-BlfFtOk2.js.map +0 -1
  267. package/dist/lock/index.js.map +0 -1
  268. package/dist/lock-redis/index.js.map +0 -1
  269. package/dist/queue/index.d.ts +0 -1265
  270. package/dist/queue/index.js +0 -1037
  271. package/dist/queue/index.js.map +0 -1
  272. package/dist/queue-redis/index.d.ts +0 -82
  273. package/dist/queue-redis/index.js +0 -872
  274. package/dist/queue-redis/index.js.map +0 -1
  275. package/dist/server/index.browser.js.map +0 -1
  276. package/dist/server/index.js.map +0 -1
  277. package/dist/server-auth/index.browser.js.map +0 -1
  278. package/dist/server-auth/index.js +0 -1943
  279. package/dist/server-auth/index.js.map +0 -1
  280. package/dist/server-cache/index.js.map +0 -1
  281. package/dist/server-compress/index.js.map +0 -1
  282. package/dist/server-cookies/index.browser.js.map +0 -1
  283. package/dist/server-cookies/index.js.map +0 -1
  284. package/dist/server-cors/index.js.map +0 -1
  285. package/dist/server-health/index.js.map +0 -1
  286. package/dist/server-helmet/index.js.map +0 -1
  287. package/dist/server-links/index.browser.js.map +0 -1
  288. package/dist/server-links/index.js.map +0 -1
  289. package/dist/server-metrics/index.js +0 -4532
  290. package/dist/server-metrics/index.js.map +0 -1
  291. package/dist/server-multipart/index.js.map +0 -1
  292. package/dist/server-proxy/index.js.map +0 -1
  293. package/dist/server-rate-limit/index.js.map +0 -1
  294. package/dist/server-security/index.browser.js.map +0 -1
  295. package/dist/server-security/index.js.map +0 -1
  296. package/dist/server-static/index.js.map +0 -1
  297. package/dist/server-swagger/index.js.map +0 -1
  298. package/dist/topic/index.js.map +0 -1
  299. package/dist/topic-redis/index.js.map +0 -1
  300. package/src/api-parameters/controllers/ParameterController.ts +0 -45
  301. package/src/api-parameters/entities/parameters.ts +0 -30
  302. package/src/api-parameters/index.ts +0 -21
  303. package/src/api-parameters/primitives/$config.ts +0 -79
  304. package/src/api-parameters/services/ParameterStore.ts +0 -23
  305. package/src/queue/interfaces/QueueJob.ts +0 -459
  306. package/src/queue/providers/MemoryQueueProvider.ts +0 -850
  307. package/src/queue/providers/QueueProvider.ts +0 -319
  308. package/src/queue/providers/WorkerProvider.ts +0 -344
  309. package/src/queue-redis/providers/RedisQueueProvider.ts +0 -1209
  310. /package/src/{api-files → api/files}/controllers/FileController.ts +0 -0
  311. /package/src/{api-files → api/files}/controllers/StorageStatsController.ts +0 -0
  312. /package/src/{api-files → api/files}/entities/files.ts +0 -0
  313. /package/src/{api-files → api/files}/index.browser.ts +0 -0
  314. /package/src/{api-files → api/files}/jobs/FileJobs.ts +0 -0
  315. /package/src/{api-files → api/files}/schemas/fileQuerySchema.ts +0 -0
  316. /package/src/{api-files → api/files}/schemas/fileResourceSchema.ts +0 -0
  317. /package/src/{api-files → api/files}/schemas/storageStatsSchema.ts +0 -0
  318. /package/src/{api-files → api/files}/services/FileService.ts +0 -0
  319. /package/src/{api-jobs → api/jobs}/controllers/JobController.ts +0 -0
  320. /package/src/{api-jobs → api/jobs}/entities/jobExecutions.ts +0 -0
  321. /package/src/{api-jobs → api/jobs}/index.browser.ts +0 -0
  322. /package/src/{api-jobs → api/jobs}/index.ts +0 -0
  323. /package/src/{api-jobs → api/jobs}/primitives/$job.ts +0 -0
  324. /package/src/{api-jobs → api/jobs}/providers/JobProvider.ts +0 -0
  325. /package/src/{api-jobs → api/jobs}/schemas/jobExecutionQuerySchema.ts +0 -0
  326. /package/src/{api-jobs → api/jobs}/schemas/jobExecutionResourceSchema.ts +0 -0
  327. /package/src/{api-jobs → api/jobs}/schemas/triggerJobSchema.ts +0 -0
  328. /package/src/{api-jobs → api/jobs}/services/JobService.ts +0 -0
  329. /package/src/{api-notifications → api/notifications}/controllers/NotificationController.ts +0 -0
  330. /package/src/{api-notifications → api/notifications}/entities/notifications.ts +0 -0
  331. /package/src/{api-notifications → api/notifications}/index.browser.ts +0 -0
  332. /package/src/{api-notifications → api/notifications}/index.ts +0 -0
  333. /package/src/{api-notifications → api/notifications}/jobs/NotificationJobs.ts +0 -0
  334. /package/src/{api-notifications → api/notifications}/primitives/$notification.ts +0 -0
  335. /package/src/{api-notifications → api/notifications}/queues/NotificationQueues.ts +0 -0
  336. /package/src/{api-notifications → api/notifications}/schemas/notificationContactPreferencesSchema.ts +0 -0
  337. /package/src/{api-notifications → api/notifications}/schemas/notificationContactSchema.ts +0 -0
  338. /package/src/{api-notifications → api/notifications}/schemas/notificationCreateSchema.ts +0 -0
  339. /package/src/{api-notifications → api/notifications}/schemas/notificationQuerySchema.ts +0 -0
  340. /package/src/{api-notifications → api/notifications}/services/NotificationSenderService.ts +0 -0
  341. /package/src/{api-notifications → api/notifications}/services/NotificationService.ts +0 -0
  342. /package/src/{api-parameters → api/parameters}/index.browser.ts +0 -0
  343. /package/src/{api-users → api/users}/controllers/IdentityController.ts +0 -0
  344. /package/src/{api-users → api/users}/controllers/SessionController.ts +0 -0
  345. /package/src/{api-users → api/users}/controllers/UserController.ts +0 -0
  346. /package/src/{api-users → api/users}/entities/identities.ts +0 -0
  347. /package/src/{api-users → api/users}/entities/sessions.ts +0 -0
  348. /package/src/{api-users → api/users}/entities/users.ts +0 -0
  349. /package/src/{api-users → api/users}/index.browser.ts +0 -0
  350. /package/src/{api-users → api/users}/notifications/UserNotifications.ts +0 -0
  351. /package/src/{api-users → api/users}/schemas/completePasswordResetRequestSchema.ts +0 -0
  352. /package/src/{api-users → api/users}/schemas/completeRegistrationRequestSchema.ts +0 -0
  353. /package/src/{api-users → api/users}/schemas/createUserSchema.ts +0 -0
  354. /package/src/{api-users → api/users}/schemas/identityQuerySchema.ts +0 -0
  355. /package/src/{api-users → api/users}/schemas/identityResourceSchema.ts +0 -0
  356. /package/src/{api-users → api/users}/schemas/loginSchema.ts +0 -0
  357. /package/src/{api-users → api/users}/schemas/passwordResetIntentResponseSchema.ts +0 -0
  358. /package/src/{api-users → api/users}/schemas/registerQuerySchema.ts +0 -0
  359. /package/src/{api-users → api/users}/schemas/registerRequestSchema.ts +0 -0
  360. /package/src/{api-users → api/users}/schemas/registerResponseSchema.ts +0 -0
  361. /package/src/{api-users → api/users}/schemas/registerSchema.ts +0 -0
  362. /package/src/{api-users → api/users}/schemas/registrationIntentResponseSchema.ts +0 -0
  363. /package/src/{api-users → api/users}/schemas/resetPasswordSchema.ts +0 -0
  364. /package/src/{api-users → api/users}/schemas/sessionQuerySchema.ts +0 -0
  365. /package/src/{api-users → api/users}/schemas/sessionResourceSchema.ts +0 -0
  366. /package/src/{api-users → api/users}/schemas/updateUserSchema.ts +0 -0
  367. /package/src/{api-users → api/users}/schemas/userQuerySchema.ts +0 -0
  368. /package/src/{api-users → api/users}/schemas/userRealmConfigSchema.ts +0 -0
  369. /package/src/{api-users → api/users}/schemas/userResourceSchema.ts +0 -0
  370. /package/src/{api-users → api/users}/services/CredentialService.ts +0 -0
  371. /package/src/{api-users → api/users}/services/IdentityService.ts +0 -0
  372. /package/src/{api-users → api/users}/services/SessionCrudService.ts +0 -0
  373. /package/src/{api-verifications → api/verifications}/controllers/VerificationController.ts +0 -0
  374. /package/src/{api-verifications → api/verifications}/entities/verifications.ts +0 -0
  375. /package/src/{api-verifications → api/verifications}/index.browser.ts +0 -0
  376. /package/src/{api-verifications → api/verifications}/jobs/VerificationJobs.ts +0 -0
  377. /package/src/{api-verifications → api/verifications}/parameters/VerificationParameters.ts +0 -0
  378. /package/src/{api-verifications → api/verifications}/schemas/requestVerificationCodeResponseSchema.ts +0 -0
  379. /package/src/{api-verifications → api/verifications}/schemas/validateVerificationCodeResponseSchema.ts +0 -0
  380. /package/src/{api-verifications → api/verifications}/schemas/verificationSettingsSchema.ts +0 -0
  381. /package/src/{api-verifications → api/verifications}/schemas/verificationTypeEnumSchema.ts +0 -0
  382. /package/src/{api-verifications → api/verifications}/services/VerificationService.ts +0 -0
  383. /package/src/cache/{errors → core/errors}/CacheError.ts +0 -0
  384. /package/src/cache/{index.ts → core/index.ts} +0 -0
  385. /package/src/cache/{primitives → core/primitives}/$cache.ts +0 -0
  386. /package/src/cache/{providers → core/providers}/CacheProvider.ts +0 -0
  387. /package/src/cache/{providers → core/providers}/MemoryCacheProvider.ts +0 -0
  388. /package/src/{cache-redis → cache/redis}/index.ts +0 -0
  389. /package/src/{cache-redis → cache/redis}/providers/RedisCacheProvider.ts +0 -0
  390. /package/src/lock/{index.ts → core/index.ts} +0 -0
  391. /package/src/lock/{primitives → core/primitives}/$lock.ts +0 -0
  392. /package/src/lock/{providers → core/providers}/LockProvider.ts +0 -0
  393. /package/src/lock/{providers → core/providers}/LockTopicProvider.ts +0 -0
  394. /package/src/lock/{providers → core/providers}/MemoryLockProvider.ts +0 -0
  395. /package/src/{lock-redis → lock/redis}/index.ts +0 -0
  396. /package/src/{lock-redis → lock/redis}/providers/RedisLockProvider.ts +0 -0
  397. /package/src/queue/{primitives → core/primitives}/$consumer.ts +0 -0
  398. /package/src/{queue-redis → queue/redis}/index.ts +0 -0
  399. /package/src/{server-auth → server/auth}/constants/routes.ts +0 -0
  400. /package/src/{server-auth → server/auth}/index.browser.ts +0 -0
  401. /package/src/{server-auth → server/auth}/index.shared.ts +0 -0
  402. /package/src/{server-auth → server/auth}/index.ts +0 -0
  403. /package/src/{server-auth → server/auth}/primitives/$authApple.ts +0 -0
  404. /package/src/{server-auth → server/auth}/primitives/$authCredentials.ts +0 -0
  405. /package/src/{server-auth → server/auth}/primitives/$authGithub.ts +0 -0
  406. /package/src/{server-auth → server/auth}/primitives/$authGoogle.ts +0 -0
  407. /package/src/{server-auth → server/auth}/schemas/authenticationProviderSchema.ts +0 -0
  408. /package/src/{server-auth → server/auth}/schemas/tokenResponseSchema.ts +0 -0
  409. /package/src/{server-auth → server/auth}/schemas/tokensSchema.ts +0 -0
  410. /package/src/{server-auth → server/auth}/schemas/userinfoResponseSchema.ts +0 -0
  411. /package/src/{server-cache → server/cache}/index.ts +0 -0
  412. /package/src/{server-cache → server/cache}/providers/ServerCacheProvider.ts +0 -0
  413. /package/src/{server-compress → server/compress}/index.ts +0 -0
  414. /package/src/{server-compress → server/compress}/providers/ServerCompressProvider.ts +0 -0
  415. /package/src/{server-cookies → server/cookies}/index.browser.ts +0 -0
  416. /package/src/{server-cookies → server/cookies}/primitives/$cookie.browser.ts +0 -0
  417. /package/src/{server-cookies → server/cookies}/primitives/$cookie.ts +0 -0
  418. /package/src/{server-cookies → server/cookies}/providers/ServerCookiesProvider.ts +0 -0
  419. /package/src/{server-cookies → server/cookies}/services/CookieParser.ts +0 -0
  420. /package/src/server/{constants → core/constants}/routeMethods.ts +0 -0
  421. /package/src/server/{errors → core/errors}/BadRequestError.ts +0 -0
  422. /package/src/server/{errors → core/errors}/ConflictError.ts +0 -0
  423. /package/src/server/{errors → core/errors}/ForbiddenError.ts +0 -0
  424. /package/src/server/{errors → core/errors}/HttpError.ts +0 -0
  425. /package/src/server/{errors → core/errors}/NotFoundError.ts +0 -0
  426. /package/src/server/{errors → core/errors}/UnauthorizedError.ts +0 -0
  427. /package/src/server/{errors → core/errors}/ValidationError.ts +0 -0
  428. /package/src/server/{helpers → core/helpers}/ServerReply.ts +0 -0
  429. /package/src/server/{helpers → core/helpers}/isMultipart.ts +0 -0
  430. /package/src/server/{index.browser.ts → core/index.browser.ts} +0 -0
  431. /package/src/server/{index.shared.ts → core/index.shared.ts} +0 -0
  432. /package/src/server/{interfaces → core/interfaces}/ServerRequest.ts +0 -0
  433. /package/src/server/{primitives → core/primitives}/$route.ts +0 -0
  434. /package/src/server/{providers → core/providers}/BunHttpServerProvider.ts +0 -0
  435. /package/src/server/{providers → core/providers}/NodeHttpServerProvider.ts +0 -0
  436. /package/src/server/{providers → core/providers}/ServerLoggerProvider.ts +0 -0
  437. /package/src/server/{providers → core/providers}/ServerNotReadyProvider.ts +0 -0
  438. /package/src/server/{providers → core/providers}/ServerProvider.ts +0 -0
  439. /package/src/server/{providers → core/providers}/ServerTimingProvider.ts +0 -0
  440. /package/src/server/{schemas → core/schemas}/errorSchema.ts +0 -0
  441. /package/src/server/{schemas → core/schemas}/okSchema.ts +0 -0
  442. /package/src/server/{services → core/services}/HttpClient.ts +0 -0
  443. /package/src/server/{services → core/services}/ServerRequestParser.ts +0 -0
  444. /package/src/server/{services → core/services}/UserAgentParser.ts +0 -0
  445. /package/src/{server-cors → server/cors}/index.ts +0 -0
  446. /package/src/{server-cors → server/cors}/primitives/$cors.ts +0 -0
  447. /package/src/{server-cors → server/cors}/providers/ServerCorsProvider.ts +0 -0
  448. /package/src/{server-health → server/health}/index.ts +0 -0
  449. /package/src/{server-health → server/health}/providers/ServerHealthProvider.ts +0 -0
  450. /package/src/{server-health → server/health}/schemas/healthSchema.ts +0 -0
  451. /package/src/{server-helmet → server/helmet}/index.ts +0 -0
  452. /package/src/{server-helmet → server/helmet}/providers/ServerHelmetProvider.ts +0 -0
  453. /package/src/{server-links → server/links}/index.browser.ts +0 -0
  454. /package/src/{server-links → server/links}/index.ts +0 -0
  455. /package/src/{server-links → server/links}/primitives/$client.ts +0 -0
  456. /package/src/{server-links → server/links}/primitives/$remote.ts +0 -0
  457. /package/src/{server-links → server/links}/providers/LinkProvider.ts +0 -0
  458. /package/src/{server-links → server/links}/providers/RemotePrimitiveProvider.ts +0 -0
  459. /package/src/{server-links → server/links}/providers/ServerLinksProvider.ts +0 -0
  460. /package/src/{server-links → server/links}/schemas/apiLinksResponseSchema.ts +0 -0
  461. /package/src/{server-metrics → server/metrics}/index.ts +0 -0
  462. /package/src/{server-metrics → server/metrics}/providers/ServerMetricsProvider.ts +0 -0
  463. /package/src/{server-multipart → server/multipart}/index.ts +0 -0
  464. /package/src/{server-multipart → server/multipart}/providers/ServerMultipartProvider.ts +0 -0
  465. /package/src/{server-proxy → server/proxy}/index.ts +0 -0
  466. /package/src/{server-proxy → server/proxy}/primitives/$proxy.ts +0 -0
  467. /package/src/{server-proxy → server/proxy}/providers/ServerProxyProvider.ts +0 -0
  468. /package/src/{server-rate-limit → server/rate-limit}/primitives/$rateLimit.ts +0 -0
  469. /package/src/{server-rate-limit → server/rate-limit}/providers/ServerRateLimitProvider.ts +0 -0
  470. /package/src/{server-security → server/security}/index.browser.ts +0 -0
  471. /package/src/{server-security → server/security}/index.ts +0 -0
  472. /package/src/{server-security → server/security}/primitives/$basicAuth.ts +0 -0
  473. /package/src/{server-security → server/security}/providers/ServerBasicAuthProvider.ts +0 -0
  474. /package/src/{server-security → server/security}/providers/ServerSecurityProvider.ts +0 -0
  475. /package/src/{server-static → server/static}/index.ts +0 -0
  476. /package/src/{server-static → server/static}/primitives/$serve.ts +0 -0
  477. /package/src/{server-static → server/static}/providers/ServerStaticProvider.ts +0 -0
  478. /package/src/{server-swagger → server/swagger}/index.ts +0 -0
  479. /package/src/{server-swagger → server/swagger}/primitives/$swagger.ts +0 -0
  480. /package/src/topic/{errors → core/errors}/TopicTimeoutError.ts +0 -0
  481. /package/src/topic/{index.ts → core/index.ts} +0 -0
  482. /package/src/topic/{primitives → core/primitives}/$subscriber.ts +0 -0
  483. /package/src/topic/{primitives → core/primitives}/$topic.ts +0 -0
  484. /package/src/topic/{providers → core/providers}/MemoryTopicProvider.ts +0 -0
  485. /package/src/topic/{providers → core/providers}/TopicProvider.ts +0 -0
  486. /package/src/{topic-redis → topic/redis}/index.ts +0 -0
  487. /package/src/{topic-redis → topic/redis}/providers/RedisTopicProvider.ts +0 -0
@@ -8,7 +8,7 @@ import { $cache } from "alepha/cache";
8
8
  import { createServer } from "node:http";
9
9
  import { createBrotliDecompress, createGunzip, createInflate } from "node:zlib";
10
10
 
11
- //#region ../../src/server/helpers/isMultipart.ts
11
+ //#region ../../src/server/core/helpers/isMultipart.ts
12
12
  /**
13
13
  * Checks if the route has multipart/form-data request body.
14
14
  */
@@ -22,7 +22,7 @@ const isMultipart = (options) => {
22
22
  };
23
23
 
24
24
  //#endregion
25
- //#region ../../src/server/helpers/ServerReply.ts
25
+ //#region ../../src/server/core/helpers/ServerReply.ts
26
26
  /**
27
27
  * Helper for building server replies.
28
28
  */
@@ -61,7 +61,7 @@ var ServerReply = class {
61
61
  };
62
62
 
63
63
  //#endregion
64
- //#region ../../src/server/errors/HttpError.ts
64
+ //#region ../../src/server/core/errors/HttpError.ts
65
65
  const isHttpError = (error, status) => {
66
66
  if (!(!!error && typeof error === "object" && "message" in error && typeof error.message === "string" && "status" in error && typeof error.status === "number")) return false;
67
67
  if (status) return error.status === status;
@@ -122,7 +122,7 @@ const errorNameByStatus = {
122
122
  };
123
123
 
124
124
  //#endregion
125
- //#region ../../src/server/errors/ValidationError.ts
125
+ //#region ../../src/server/core/errors/ValidationError.ts
126
126
  var ValidationError = class extends HttpError {
127
127
  constructor(message = "Validation has failed", cause) {
128
128
  super({
@@ -133,7 +133,7 @@ var ValidationError = class extends HttpError {
133
133
  };
134
134
 
135
135
  //#endregion
136
- //#region ../../src/server/services/UserAgentParser.ts
136
+ //#region ../../src/server/core/services/UserAgentParser.ts
137
137
  /**
138
138
  * Simple User-Agent parser to detect OS, browser, and device type.
139
139
  * This parser is not exhaustive and may not cover all edge cases.
@@ -205,7 +205,7 @@ var UserAgentParser = class {
205
205
  };
206
206
 
207
207
  //#endregion
208
- //#region ../../src/server/services/ServerRequestParser.ts
208
+ //#region ../../src/server/core/services/ServerRequestParser.ts
209
209
  var ServerRequestParser = class {
210
210
  alepha = $inject(Alepha);
211
211
  userAgentParser = $inject(UserAgentParser);
@@ -245,7 +245,7 @@ var ServerRequestParser = class {
245
245
  };
246
246
 
247
247
  //#endregion
248
- //#region ../../src/server/providers/ServerTimingProvider.ts
248
+ //#region ../../src/server/core/providers/ServerTimingProvider.ts
249
249
  var ServerTimingProvider = class {
250
250
  log = $logger();
251
251
  alepha = $inject(Alepha);
@@ -315,7 +315,7 @@ var ServerTimingProvider = class {
315
315
  };
316
316
 
317
317
  //#endregion
318
- //#region ../../src/server/providers/ServerRouterProvider.ts
318
+ //#region ../../src/server/core/providers/ServerRouterProvider.ts
319
319
  /**
320
320
  * Main router for all routes on the server side.
321
321
  *
@@ -510,7 +510,9 @@ var ServerRouterProvider = class extends RouterProvider {
510
510
  } catch (error) {
511
511
  throw new ValidationError("Invalid request header", error);
512
512
  }
513
- if (route.schema?.body) try {
513
+ if (route.schema?.body) if (t.schema.isString(route.schema.body)) {
514
+ if (typeof request.body !== "string") throw new ValidationError("Request body is not a string");
515
+ } else try {
514
516
  request.body = this.alepha.codec.decode(route.schema.body, request.body);
515
517
  } catch (error) {
516
518
  throw new ValidationError("Invalid request body", error);
@@ -519,7 +521,7 @@ var ServerRouterProvider = class extends RouterProvider {
519
521
  };
520
522
 
521
523
  //#endregion
522
- //#region ../../src/server/providers/ServerProvider.ts
524
+ //#region ../../src/server/core/providers/ServerProvider.ts
523
525
  /**
524
526
  * Base server provider to handle incoming requests and route them.
525
527
  *
@@ -703,7 +705,7 @@ var ServerProvider = class {
703
705
  };
704
706
 
705
707
  //#endregion
706
- //#region ../../src/server/schemas/errorSchema.ts
708
+ //#region ../../src/server/core/schemas/errorSchema.ts
707
709
  const errorSchema = t.object({
708
710
  error: t.text({ description: "HTTP error name" }),
709
711
  status: t.integer({ description: "HTTP status code" }),
@@ -729,7 +731,7 @@ const errorSchema = t.object({
729
731
  });
730
732
 
731
733
  //#endregion
732
- //#region ../../src/server/services/HttpClient.ts
734
+ //#region ../../src/server/core/services/HttpClient.ts
733
735
  var HttpClient = class {
734
736
  log = $logger();
735
737
  alepha = $inject(Alepha);
@@ -941,7 +943,7 @@ var HttpClient = class {
941
943
  };
942
944
 
943
945
  //#endregion
944
- //#region ../../src/server/primitives/$action.ts
946
+ //#region ../../src/server/core/primitives/$action.ts
945
947
  /**
946
948
  * Creates a server action primitive for defining type-safe HTTP endpoints.
947
949
  *
@@ -957,7 +959,16 @@ var HttpClient = class {
957
959
  * - Automatic content-type handling (JSON, form-data, plain text)
958
960
  *
959
961
  * **URL Generation**
960
- * Actions are prefixed with `/api` by default (configurable via `SERVER_API_PREFIX`).
962
+ *
963
+ * **Important:** All `$action` paths are automatically prefixed with `/api`.
964
+ *
965
+ * ```ts
966
+ * $action({ path: "/users" }) // → GET /api/users
967
+ * $action({ path: "/users/:id" }) // → GET /api/users/:id
968
+ * $action({ path: "/hello" }) // → GET /api/hello
969
+ * ```
970
+ *
971
+ * This prefix is configurable via the `SERVER_API_PREFIX` environment variable.
961
972
  * HTTP method defaults to GET, or POST if body schema is provided.
962
973
  *
963
974
  * **Common Use Cases**
@@ -1137,7 +1148,7 @@ var ActionPrimitive = class extends Primitive {
1137
1148
  $action[KIND] = ActionPrimitive;
1138
1149
 
1139
1150
  //#endregion
1140
- //#region ../../src/server/primitives/$route.ts
1151
+ //#region ../../src/server/core/primitives/$route.ts
1141
1152
  /**
1142
1153
  * Create a basic endpoint.
1143
1154
  *
@@ -1158,7 +1169,7 @@ var RoutePrimitive = class extends Primitive {
1158
1169
  $route[KIND] = RoutePrimitive;
1159
1170
 
1160
1171
  //#endregion
1161
- //#region ../../src/server/providers/BunHttpServerProvider.ts
1172
+ //#region ../../src/server/core/providers/BunHttpServerProvider.ts
1162
1173
  const envSchema$2 = t.object({
1163
1174
  SERVER_PORT: t.integer({
1164
1175
  default: 3e3,
@@ -1255,7 +1266,7 @@ var BunHttpServerProvider = class extends ServerProvider {
1255
1266
  };
1256
1267
 
1257
1268
  //#endregion
1258
- //#region ../../src/server/providers/NodeHttpServerProvider.ts
1269
+ //#region ../../src/server/core/providers/NodeHttpServerProvider.ts
1259
1270
  const envSchema$1 = t.object({
1260
1271
  SERVER_PORT: t.integer({
1261
1272
  default: 3e3,
@@ -1338,7 +1349,7 @@ var NodeHttpServerProvider = class extends ServerProvider {
1338
1349
  };
1339
1350
 
1340
1351
  //#endregion
1341
- //#region ../../src/server/providers/ServerBodyParserProvider.ts
1352
+ //#region ../../src/server/core/providers/ServerBodyParserProvider.ts
1342
1353
  const envSchema = t.object({
1343
1354
  SERVER_BODY_PARSER_INFLATE: t.boolean({
1344
1355
  default: true,
@@ -1363,7 +1374,7 @@ var ServerBodyParserProvider = class {
1363
1374
  else if (request.raw.node?.req) stream = ReadableStream$1.from(request.raw.node.req);
1364
1375
  if (!stream) return;
1365
1376
  if (route.schema?.body) try {
1366
- const body = await this.parse(stream, request.headers);
1377
+ const body = await this.parse(stream, request.headers, route.schema.body);
1367
1378
  if (body) request.body = body;
1368
1379
  } catch (error) {
1369
1380
  if (error instanceof HttpError) throw error;
@@ -1374,12 +1385,12 @@ var ServerBodyParserProvider = class {
1374
1385
  }
1375
1386
  }
1376
1387
  });
1377
- async parse(stream, headers) {
1388
+ async parse(stream, headers, schema) {
1378
1389
  const contentType = headers["content-type"];
1379
1390
  const contentEncoding = headers["content-encoding"];
1380
1391
  if (!contentType) return void 0;
1392
+ if (contentType.startsWith("text/plain") || t.schema.isString(schema)) return this.parseText(stream, contentEncoding);
1381
1393
  if (contentType.startsWith("application/json")) return this.parseJson(stream, contentEncoding);
1382
- if (contentType.startsWith("text/plain")) return this.parseText(stream, contentEncoding);
1383
1394
  if (contentType.startsWith("application/x-www-form-urlencoded")) return this.parseUrlEncoded(stream, contentEncoding);
1384
1395
  }
1385
1396
  async parseText(stream, contentEncoding) {
@@ -1453,7 +1464,7 @@ var ServerBodyParserProvider = class {
1453
1464
  };
1454
1465
 
1455
1466
  //#endregion
1456
- //#region ../../src/server/providers/ServerLoggerProvider.ts
1467
+ //#region ../../src/server/core/providers/ServerLoggerProvider.ts
1457
1468
  var ServerLoggerProvider = class {
1458
1469
  log = $logger();
1459
1470
  alepha = $inject(Alepha);
@@ -1499,7 +1510,7 @@ var ServerLoggerProvider = class {
1499
1510
  };
1500
1511
 
1501
1512
  //#endregion
1502
- //#region ../../src/server/providers/ServerNotReadyProvider.ts
1513
+ //#region ../../src/server/core/providers/ServerNotReadyProvider.ts
1503
1514
  /**
1504
1515
  * On every request, this provider checks if the server is ready.
1505
1516
  *
@@ -1524,7 +1535,7 @@ var ServerNotReadyProvider = class {
1524
1535
  };
1525
1536
 
1526
1537
  //#endregion
1527
- //#region ../../src/server/constants/routeMethods.ts
1538
+ //#region ../../src/server/core/constants/routeMethods.ts
1528
1539
  const routeMethods = [
1529
1540
  "GET",
1530
1541
  "POST",
@@ -1538,7 +1549,7 @@ const routeMethods = [
1538
1549
  ];
1539
1550
 
1540
1551
  //#endregion
1541
- //#region ../../src/server/errors/BadRequestError.ts
1552
+ //#region ../../src/server/core/errors/BadRequestError.ts
1542
1553
  var BadRequestError = class extends HttpError {
1543
1554
  constructor(message = "Invalid request body", cause) {
1544
1555
  super({
@@ -1549,7 +1560,7 @@ var BadRequestError = class extends HttpError {
1549
1560
  };
1550
1561
 
1551
1562
  //#endregion
1552
- //#region ../../src/server/errors/ConflictError.ts
1563
+ //#region ../../src/server/core/errors/ConflictError.ts
1553
1564
  var ConflictError = class extends HttpError {
1554
1565
  constructor(message = "Entity already exists", cause) {
1555
1566
  super({
@@ -1560,7 +1571,7 @@ var ConflictError = class extends HttpError {
1560
1571
  };
1561
1572
 
1562
1573
  //#endregion
1563
- //#region ../../src/server/errors/ForbiddenError.ts
1574
+ //#region ../../src/server/core/errors/ForbiddenError.ts
1564
1575
  var ForbiddenError = class extends HttpError {
1565
1576
  constructor(message = "No permission to access this resource", cause) {
1566
1577
  super({
@@ -1571,7 +1582,7 @@ var ForbiddenError = class extends HttpError {
1571
1582
  };
1572
1583
 
1573
1584
  //#endregion
1574
- //#region ../../src/server/errors/NotFoundError.ts
1585
+ //#region ../../src/server/core/errors/NotFoundError.ts
1575
1586
  var NotFoundError = class extends HttpError {
1576
1587
  constructor(message = "Resource not found", cause) {
1577
1588
  super({
@@ -1582,7 +1593,7 @@ var NotFoundError = class extends HttpError {
1582
1593
  };
1583
1594
 
1584
1595
  //#endregion
1585
- //#region ../../src/server/errors/UnauthorizedError.ts
1596
+ //#region ../../src/server/core/errors/UnauthorizedError.ts
1586
1597
  var UnauthorizedError = class extends HttpError {
1587
1598
  name = "UnauthorizedError";
1588
1599
  constructor(message = "Not allowed to access this resource", cause) {
@@ -1594,7 +1605,7 @@ var UnauthorizedError = class extends HttpError {
1594
1605
  };
1595
1606
 
1596
1607
  //#endregion
1597
- //#region ../../src/server/schemas/okSchema.ts
1608
+ //#region ../../src/server/core/schemas/okSchema.ts
1598
1609
  const okSchema = t.object({
1599
1610
  ok: t.boolean({ description: "True when operation succeed" }),
1600
1611
  id: t.optional(t.union([t.text(), t.integer()])),
@@ -1605,7 +1616,7 @@ const okSchema = t.object({
1605
1616
  });
1606
1617
 
1607
1618
  //#endregion
1608
- //#region ../../src/server/index.ts
1619
+ //#region ../../src/server/core/index.ts
1609
1620
  /**
1610
1621
  * Provides high-performance HTTP server capabilities with declarative routing and action primitives.
1611
1622
  *
@@ -1628,7 +1639,10 @@ const AlephaServer = $module({
1628
1639
  ServerLoggerProvider,
1629
1640
  ServerNotReadyProvider,
1630
1641
  ServerTimingProvider,
1631
- HttpClient
1642
+ HttpClient,
1643
+ UserAgentParser,
1644
+ ServerRequestParser,
1645
+ ServerRouterProvider
1632
1646
  ],
1633
1647
  register: (alepha) => {
1634
1648
  if (!alepha.isServerless() && !alepha.isViteDev()) if (alepha.isBun()) alepha.with({
@@ -1650,5 +1664,5 @@ const AlephaServer = $module({
1650
1664
  });
1651
1665
 
1652
1666
  //#endregion
1653
- export { $action, $route, ActionPrimitive, AlephaServer, BadRequestError, BunHttpServerProvider, ConflictError, ForbiddenError, HttpClient, HttpError, NodeHttpServerProvider, NotFoundError, RoutePrimitive, ServerLoggerProvider, ServerNotReadyProvider, ServerProvider, ServerReply, ServerRouterProvider, ServerTimingProvider, UnauthorizedError, ValidationError, errorNameByStatus, errorSchema, isHttpError, isMultipart, okSchema, routeMethods };
1667
+ export { $action, $route, ActionPrimitive, AlephaServer, BadRequestError, BunHttpServerProvider, ConflictError, ForbiddenError, HttpClient, HttpError, NodeHttpServerProvider, NotFoundError, RoutePrimitive, ServerLoggerProvider, ServerNotReadyProvider, ServerProvider, ServerReply, ServerRouterProvider, ServerTimingProvider, UnauthorizedError, UserAgentParser, ValidationError, errorNameByStatus, errorSchema, isHttpError, isMultipart, okSchema, routeMethods };
1654
1668
  //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":["properties: Record<string, any>","json: Record<string, unknown>","errorNameByStatus: Record<number, string>","os: UserAgentInfo[\"os\"]","browser: UserAgentInfo[\"browser\"]","device: UserAgentInfo[\"device\"]","NodeWebStream","NodeStream","query: Record<string, any>","request: ServerRequestData","headers: Record<string, string>","request: RequestInit","headers: Record<string, string>","fetchResponse: FetchResponse","options","envSchema","serverActionRequest: Partial<ServerRequest>","response: any","envSchema","envSchema","stream: ReadableStream | undefined","WebStream","result: Record<string, string>","chunks: Uint8Array[]","data: Record<string, string>"],"sources":["../../../src/server/core/helpers/isMultipart.ts","../../../src/server/core/helpers/ServerReply.ts","../../../src/server/core/errors/HttpError.ts","../../../src/server/core/errors/ValidationError.ts","../../../src/server/core/services/UserAgentParser.ts","../../../src/server/core/services/ServerRequestParser.ts","../../../src/server/core/providers/ServerTimingProvider.ts","../../../src/server/core/providers/ServerRouterProvider.ts","../../../src/server/core/providers/ServerProvider.ts","../../../src/server/core/schemas/errorSchema.ts","../../../src/server/core/services/HttpClient.ts","../../../src/server/core/primitives/$action.ts","../../../src/server/core/primitives/$route.ts","../../../src/server/core/providers/BunHttpServerProvider.ts","../../../src/server/core/providers/NodeHttpServerProvider.ts","../../../src/server/core/providers/ServerBodyParserProvider.ts","../../../src/server/core/providers/ServerLoggerProvider.ts","../../../src/server/core/providers/ServerNotReadyProvider.ts","../../../src/server/core/constants/routeMethods.ts","../../../src/server/core/errors/BadRequestError.ts","../../../src/server/core/errors/ConflictError.ts","../../../src/server/core/errors/ForbiddenError.ts","../../../src/server/core/errors/NotFoundError.ts","../../../src/server/core/errors/UnauthorizedError.ts","../../../src/server/core/schemas/okSchema.ts","../../../src/server/core/index.ts"],"sourcesContent":["import type { RequestConfigSchema } from \"../interfaces/ServerRequest.ts\";\n\n/**\n * Checks if the route has multipart/form-data request body.\n */\nexport const isMultipart = (options: {\n schema?: RequestConfigSchema;\n requestBodyType?: string;\n}): boolean => {\n if (options.requestBodyType === \"multipart/form-data\") {\n return true;\n }\n\n if (options.schema?.body && \"properties\" in options.schema.body) {\n const properties: Record<string, any> = options.schema.body.properties;\n for (const key in properties) {\n if (properties[key].format === \"binary\") {\n return true;\n }\n }\n }\n\n return false;\n};\n","/**\n * Helper for building server replies.\n */\nexport class ServerReply {\n // TODO: make it private\n public headers: Record<string, string> & {\n \"set-cookie\"?: string[];\n } = {};\n\n public status?: number; // default 200, or 204 (no content)\n\n public body?: any;\n\n /**\n * Redirect to a given URL with optional status code (default 302).\n */\n public redirect(url: string, status: number = 302): void {\n this.status = status;\n this.headers.location = url;\n }\n\n // TODO: check if status / header is already set and throw an error if so (for allow to override with force flag)\n\n /**\n * Set the response status code.\n */\n public setStatus(status: number): this {\n this.status = status;\n return this;\n }\n\n /**\n * Set a response header.\n */\n public setHeader(name: string, value: string): this {\n this.headers[name.toLowerCase()] = value;\n return this;\n }\n\n /**\n * Set the response body.\n */\n public setBody(body: any): this {\n this.body = body;\n return this;\n }\n}\n","import { AlephaError } from \"alepha\";\nimport type { ErrorSchema } from \"../schemas/errorSchema.ts\";\n\nexport const isHttpError = (\n error: unknown,\n status?: number,\n): error is HttpErrorLike => {\n const isError =\n !!error &&\n typeof error === \"object\" &&\n \"message\" in error &&\n typeof error.message === \"string\" &&\n \"status\" in error &&\n typeof error.status === \"number\";\n\n if (!isError) {\n return false;\n }\n\n if (status) {\n return (error as HttpErrorLike).status === status;\n }\n\n return true;\n};\n\nexport class HttpError extends AlephaError {\n public name = \"HttpError\";\n\n static is = isHttpError;\n\n static toJSON(error: HttpError): ErrorSchema {\n const json: Record<string, unknown> = {\n error: error.error,\n status: error.status,\n message: error.message,\n };\n\n if (error.details) json.details = error.details;\n if (error.requestId) json.requestId = error.requestId;\n if (error.reason) json.cause = error.reason;\n\n return json as ErrorSchema;\n }\n\n public readonly error: string;\n public readonly status: number;\n\n public readonly requestId?: string;\n public readonly details?: string;\n public readonly reason?: {\n name: string;\n message: string;\n };\n\n constructor(options: Partial<ErrorSchema>, cause?: unknown) {\n super(options.message, {\n cause,\n });\n\n this.status = options.status ?? 500;\n this.details = options.details;\n this.requestId = options.requestId;\n\n if (typeof options.cause === \"object\") {\n this.reason = {\n name: (options.cause as { name: string }).name,\n message: (options.cause as { message: string }).message,\n };\n } else if (cause instanceof Error) {\n this.reason = {\n name: cause.name,\n message: cause.message,\n };\n }\n\n if (this.constructor.name === \"HttpError\") {\n this.error =\n options.error ?? errorNameByStatus[this.status] ?? \"HttpError\";\n } else {\n this.error = this.constructor.name;\n }\n }\n}\n\nexport const errorNameByStatus: Record<number, string> = {\n 400: \"BadRequestError\",\n 401: \"UnauthorizedError\",\n 403: \"ForbiddenError\",\n 404: \"NotFoundError\",\n 405: \"MethodNotAllowedError\",\n 409: \"ConflictError\",\n 410: \"GoneError\",\n 413: \"PayloadTooLargeError\",\n 415: \"UnsupportedMediaTypeError\",\n 429: \"TooManyRequestsError\",\n 500: \"InternalServerError\",\n 501: \"NotImplementedError\",\n 502: \"BadGatewayError\",\n 503: \"ServiceUnavailableError\",\n 504: \"GatewayTimeoutError\",\n};\n\nexport interface HttpErrorLike extends Error {\n status: number;\n}\n","import { HttpError } from \"./HttpError.ts\";\n\nexport class ValidationError extends HttpError {\n constructor(message = \"Validation has failed\", cause?: unknown) {\n super(\n {\n message,\n status: 400,\n },\n cause,\n );\n }\n}\n","export interface UserAgentInfo {\n os:\n | \"Windows\"\n | \"Android\"\n | \"Ubuntu\"\n | \"MacOS\"\n | \"iOS\"\n | \"Linux\"\n | \"FreeBSD\"\n | \"OpenBSD\"\n | \"ChromeOS\"\n | \"BlackBerry\"\n | \"Symbian\"\n | \"Windows Phone\";\n browser:\n | \"Chrome\"\n | \"Firefox\"\n | \"Safari\"\n | \"Edge\"\n | \"Opera\"\n | \"Internet Explorer\"\n | \"Brave\"\n | \"Vivaldi\"\n | \"Samsung Browser\"\n | \"UC Browser\"\n | \"Yandex\";\n device: \"MOBILE\" | \"DESKTOP\" | \"TABLET\";\n}\n\n/**\n * Simple User-Agent parser to detect OS, browser, and device type.\n * This parser is not exhaustive and may not cover all edge cases.\n *\n * Use result for non\n */\nexport class UserAgentParser {\n public parse(userAgent: string = \"\"): UserAgentInfo {\n const ua = userAgent.toLowerCase();\n\n // Default values\n let os: UserAgentInfo[\"os\"] = \"Windows\";\n let browser: UserAgentInfo[\"browser\"] = \"Chrome\";\n let device: UserAgentInfo[\"device\"] = \"DESKTOP\";\n\n // Detect OS - Order matters for specificity\n if (ua.includes(\"windows phone\")) {\n os = \"Windows Phone\";\n } else if (ua.includes(\"windows\")) {\n os = \"Windows\";\n } else if (ua.includes(\"android\")) {\n os = \"Android\";\n } else if (\n ua.includes(\"iphone\") ||\n ua.includes(\"ipad\") ||\n ua.includes(\"ipod\") ||\n (ua.includes(\"ios\") && !ua.includes(\"android\"))\n ) {\n os = \"iOS\";\n } else if (\n ua.includes(\"mac os\") ||\n ua.includes(\"macos\") ||\n ua.includes(\"macintosh\")\n ) {\n os = \"MacOS\";\n } else if (ua.includes(\"cros\") || ua.includes(\"chromeos\")) {\n os = \"ChromeOS\";\n } else if (ua.includes(\"ubuntu\")) {\n os = \"Ubuntu\";\n } else if (ua.includes(\"freebsd\")) {\n os = \"FreeBSD\";\n } else if (ua.includes(\"openbsd\")) {\n os = \"OpenBSD\";\n } else if (ua.includes(\"blackberry\") || ua.includes(\"bb10\")) {\n os = \"BlackBerry\";\n } else if (ua.includes(\"symbian\") || ua.includes(\"symbos\")) {\n os = \"Symbian\";\n } else if (ua.includes(\"linux\") || ua.includes(\"x11\")) {\n os = \"Linux\";\n }\n\n // Detect Browser/browser - Order matters, check most specific first\n if (ua.includes(\"yabrowser\") || ua.includes(\"yandex\")) {\n browser = \"Yandex\";\n } else if (ua.includes(\"brave\")) {\n browser = \"Brave\";\n } else if (ua.includes(\"vivaldi\")) {\n browser = \"Vivaldi\";\n } else if (ua.includes(\"samsungbrowser\") || ua.includes(\"samsung\")) {\n browser = \"Samsung Browser\";\n } else if (ua.includes(\"ucbrowser\") || ua.includes(\"uc browser\")) {\n browser = \"UC Browser\";\n } else if (\n ua.includes(\"opera\") ||\n ua.includes(\"opr/\") ||\n ua.includes(\"opios\")\n ) {\n browser = \"Opera\";\n } else if (\n ua.includes(\"edg/\") ||\n ua.includes(\"edge\") ||\n ua.includes(\"edgios\")\n ) {\n browser = \"Edge\";\n } else if (ua.includes(\"firefox\") && !ua.includes(\"seamonkey\")) {\n browser = \"Firefox\";\n } else if (ua.includes(\"trident\") || ua.includes(\"msie\")) {\n browser = \"Internet Explorer\";\n } else if (\n ua.includes(\"safari\") &&\n !ua.includes(\"chrome\") &&\n !ua.includes(\"chromium\")\n ) {\n browser = \"Safari\";\n } else if (\n ua.includes(\"chrome\") ||\n ua.includes(\"chromium\") ||\n ua.includes(\"crios\")\n ) {\n browser = \"Chrome\";\n }\n\n // Detect Device Type\n const mobileKeywords = [\n \"mobile\",\n \"android\",\n \"iphone\",\n \"ipod\",\n \"blackberry\",\n \"windows phone\",\n \"opera mini\",\n \"iemobile\",\n \"mobile safari\",\n \"nokia\",\n \"symbian\",\n ];\n\n const tabletKeywords = [\n \"ipad\",\n \"tablet\",\n \"kindle\",\n \"silk\",\n \"gt-p\",\n \"sm-t\",\n \"nexus 7\",\n \"nexus 10\",\n ];\n\n const isTablet = tabletKeywords.some((keyword) => ua.includes(keyword));\n const isMobile = mobileKeywords.some((keyword) => ua.includes(keyword));\n\n if (isTablet) {\n device = \"TABLET\";\n } else if (isMobile) {\n device = \"MOBILE\";\n } else {\n device = \"DESKTOP\";\n }\n\n return { os, browser, device };\n }\n}\n","import { $inject, Alepha } from \"alepha\";\nimport { ServerReply } from \"../helpers/ServerReply.ts\";\nimport type {\n ServerRequest,\n ServerRequestData,\n} from \"../interfaces/ServerRequest.ts\";\nimport { UserAgentParser } from \"./UserAgentParser.ts\";\n\nexport class ServerRequestParser {\n protected readonly alepha = $inject(Alepha);\n protected readonly userAgentParser = $inject(UserAgentParser);\n\n public createServerRequest(rawRequest: ServerRequestData): ServerRequest {\n const self = this;\n return {\n method: rawRequest.method,\n url: rawRequest.url,\n raw: rawRequest.raw,\n headers: rawRequest.headers,\n query: rawRequest.query,\n params: rawRequest.params,\n // body will be filled by body parser middleware\n body: null,\n metadata: {},\n requestId: this.getRequestId(rawRequest) || crypto.randomUUID(),\n reply: this.alepha.inject(ServerReply, { lifetime: \"transient\" }),\n get ip() {\n return self.getRequestIp(rawRequest);\n },\n get userAgent() {\n return self.getRequestUserAgent(rawRequest);\n },\n } as ServerRequest;\n }\n\n public getRequestId(request: ServerRequestData): string | undefined {\n return request.headers[\"x-request-id\"];\n }\n\n public getRequestUserAgent(request: ServerRequestData) {\n return this.userAgentParser.parse(request.headers[\"user-agent\"]);\n }\n\n public getRequestIp(request: ServerRequestData): string | undefined {\n // check for the 'x-forwarded-for' header first, which is commonly used\n // in proxy setups to forward the original client's IP address.\n\n // https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/X-Forwarded-For\n\n const forwardedFor = request.headers[\"x-forwarded-for\"];\n if (forwardedFor) {\n // The 'x-forwarded-for' header can contain multiple IPs, so we take the first one.\n return Array.isArray(forwardedFor)\n ? forwardedFor[0]\n : forwardedFor.split(\",\")[0].trim();\n }\n\n const xRealIP = request.headers[\"x-real-ip\"];\n if (xRealIP) {\n return Array.isArray(xRealIP) ? xRealIP[0] : xRealIP;\n }\n }\n}\n","import { $hook, $inject, Alepha } from \"alepha\";\nimport { $logger } from \"alepha/logger\";\nimport type { ServerRequest } from \"../interfaces/ServerRequest.ts\";\n\ntype TimingMap = Record<string, [number, number]>;\n\nexport class ServerTimingProvider {\n protected readonly log = $logger();\n protected readonly alepha = $inject(Alepha);\n\n public options = {\n prefix: this.alepha.env.APP_NAME\n ? `${this.alepha.env.APP_NAME.toLowerCase()}-`\n : \"\",\n disabled: this.alepha.isProduction(),\n };\n\n public readonly onRequest = $hook({\n priority: \"first\",\n on: \"server:onRequest\",\n handler: async ({ request }) => {\n if (this.options.disabled) {\n return;\n }\n\n request.metadata.timing = {};\n request.metadata.timing[this.handlerName] = [Date.now()];\n },\n });\n\n public readonly onResponse = $hook({\n priority: \"last\",\n on: \"server:onResponse\",\n handler: async ({ request }) => {\n if (this.options.disabled) {\n return;\n }\n\n if (request.metadata.timing) {\n this.setDuration(this.handlerName, request.metadata.timing);\n\n let timingHeader = \"\";\n\n for (const [name, [start, duration]] of Object.entries(\n request.metadata.timing as TimingMap,\n )) {\n if (typeof start !== \"number\" || typeof duration !== \"number\") {\n this.log.warn(\n `Invalid timing for '${name}': [${start}, ${duration}]`,\n );\n continue;\n }\n\n const formattedName =\n this.options.prefix + name.replace(/[^a-zA-Z0-9-]/g, \"-\");\n timingHeader += `${formattedName};dur=${duration}, `;\n }\n\n if (request.reply.headers[\"Server-Timing\"]) {\n request.reply.headers[\"Server-Timing\"] += `, ${timingHeader}`;\n } else {\n request.reply.headers[\"Server-Timing\"] = timingHeader;\n }\n }\n },\n });\n\n protected get handlerName() {\n return `request`;\n }\n\n public beginTiming(name: string): void {\n if (this.options.disabled) {\n return;\n }\n\n const request = this.alepha.context.get<ServerRequest>(\"request\");\n if (!request) {\n return;\n }\n\n request.metadata ??= {};\n request.metadata.timing ??= {};\n request.metadata.timing[name] = [Date.now()];\n }\n\n public endTiming(name: string): void {\n if (this.options.disabled) {\n return;\n }\n\n const request = this.alepha.context.get<ServerRequest>(\"request\");\n if (!request) {\n return;\n }\n\n if (!request.metadata?.timing || !(name in request.metadata.timing)) {\n this.log.warn(`No timing found for '${name}'.`);\n return;\n }\n\n const start = request.metadata.timing[name]?.[0];\n if (typeof start !== \"number\") {\n this.log.warn(`Invalid timing start for '${name}': ${start}`);\n return;\n }\n\n this.setDuration(name, request.metadata.timing);\n }\n\n protected setDuration(name: string, timing: TimingMap): void {\n timing[name] = [timing[name][0], Date.now() - timing[name][0]];\n }\n}\n","import { Readable as NodeStream } from \"node:stream\";\nimport { ReadableStream as NodeWebStream } from \"node:stream/web\";\nimport { $inject, Alepha, isFileLike, isTypeFile, isUUID, t } from \"alepha\";\nimport { $logger } from \"alepha/logger\";\nimport { RouterProvider } from \"alepha/router\";\nimport type { RouteMethod } from \"../constants/routeMethods.ts\";\nimport { errorNameByStatus, HttpError } from \"../errors/HttpError.ts\";\nimport { ValidationError } from \"../errors/ValidationError.ts\";\nimport type { ServerReply } from \"../helpers/ServerReply.ts\";\nimport type {\n RequestConfigSchema,\n ResponseKind,\n ServerRequest,\n ServerRequestConfig,\n ServerRoute,\n ServerRouteMatcher,\n} from \"../interfaces/ServerRequest.ts\";\nimport { ServerRequestParser } from \"../services/ServerRequestParser.ts\";\nimport { ServerTimingProvider } from \"./ServerTimingProvider.ts\";\n\n/**\n * Main router for all routes on the server side.\n *\n * - $route => generic route\n * - $action => action route (for API calls)\n * - $page => React route (for SSR)\n */\nexport class ServerRouterProvider extends RouterProvider<ServerRouteMatcher> {\n protected readonly log = $logger();\n protected readonly alepha = $inject(Alepha);\n protected readonly routes: ServerRoute[] = [];\n protected readonly serverTimingProvider = $inject(ServerTimingProvider);\n protected readonly serverRequestParser = $inject(ServerRequestParser);\n\n /**\n * Get all registered routes, optionally filtered by a pattern.\n *\n * Pattern accept simple wildcard '*' at the end.\n * Example: '/api/*' will match all routes starting with '/api/' but '/api/' will match only that exact route.\n */\n public getRoutes(pattern?: string): ServerRoute[] {\n if (pattern) {\n if (pattern.endsWith(\"*\")) {\n const basePattern = pattern.slice(0, -1);\n return this.routes.filter((route) =>\n route.path.startsWith(basePattern),\n );\n } else {\n return this.routes.filter((route) => route.path === pattern);\n }\n }\n return this.routes;\n }\n\n public createRoute<TConfig extends RequestConfigSchema = RequestConfigSchema>(\n route: ServerRoute<TConfig>,\n ): void {\n route.method ??= \"GET\";\n route.method = route.method.toUpperCase() as RouteMethod;\n\n this.routes.push(route);\n\n const path = `/${route.method}/${route.path}`.replace(/\\/+/g, \"/\");\n const responseKind = this.getResponseType(route.schema);\n\n this.log.trace(`Create route ${path}`);\n\n this.push({\n path,\n handler: (rawRequest) => {\n const request =\n this.serverRequestParser.createServerRequest(rawRequest);\n\n return this.alepha.context.run(\n () => this.processRequest(request, route, responseKind),\n {\n context: this.getContextId(rawRequest.headers),\n },\n );\n },\n });\n }\n\n protected getContextId(headers: Record<string, string>): string {\n const contextId = headers[\"x-request-id\"] || headers[\"x-correlation-id\"];\n // TODO: check if it's not overkill, just checking length might be enough?\n // some cloud providers generate non-UUID request ids\n if (isUUID(contextId)) {\n return contextId;\n }\n\n return crypto.randomUUID();\n }\n\n protected async processRequest(\n request: ServerRequest,\n route: ServerRoute,\n responseKind: ResponseKind,\n ) {\n await this.runRouteHandler(route, request, responseKind).catch((error) => {\n return this.errorHandler(route, request, error as Error);\n });\n\n await this.alepha.events.emit(\n \"server:onSend\",\n {\n request,\n route,\n },\n {\n catch: true, // avoid unhandled rejection\n },\n );\n\n // create response\n const response = {\n status: request.reply.status ?? (request.reply.body ? 200 : 204),\n headers: request.reply.headers,\n body: request.reply.body as any,\n };\n\n await this.alepha.events.emit(\n \"server:onResponse\",\n {\n request,\n route,\n response,\n },\n {\n catch: true, // avoid unhandled rejection\n },\n );\n\n return response;\n }\n\n protected async runRouteHandler(\n route: ServerRoute,\n request: ServerRequest,\n responseKind: ResponseKind,\n ) {\n // there are some built-in hooks that are called before the request is handled\n // - ServerBodyParserProvider (parse body)\n // - ServerSecurityProvider (build user from headers)\n // - ServerLoggerProvider (log request)\n\n await this.alepha.events.emit(\n \"server:onRequest\", // this hook will fill request.user and request.cookies\n {\n request,\n route,\n },\n {\n log: false,\n },\n );\n\n if (\n request.reply.body ||\n (request.reply.status && request.reply.status >= 200)\n ) {\n // if the body is already set, we can skip the handler\n // this is useful for middlewares that set the body\n return;\n }\n\n // request is ready to be used -> inject to context\n this.alepha.context.set<ServerRequest>(\"request\", request as ServerRequest);\n\n // validate request\n this.serverTimingProvider.beginTiming(\"validateRequest\");\n try {\n this.validateRequest(route, request);\n } finally {\n this.serverTimingProvider.endTiming(\"validateRequest\");\n }\n\n // call the handler only if the body is not set yet\n this.serverTimingProvider.beginTiming(\"runHandler\");\n try {\n const result = await route.handler(request);\n if (result) {\n request.reply.body = result;\n }\n } finally {\n this.serverTimingProvider.endTiming(\"runHandler\");\n }\n\n // serialize response\n this.serverTimingProvider.beginTiming(\"serializeResponse\");\n try {\n this.serializeResponse(route, request.reply, responseKind);\n } finally {\n this.serverTimingProvider.endTiming(\"serializeResponse\");\n }\n }\n\n public serializeResponse(\n route: ServerRoute,\n reply: ServerReply,\n responseKind: ResponseKind,\n ): void {\n if (responseKind === \"json\" && route.schema?.response) {\n reply.headers[\"content-type\"] = \"application/json\";\n reply.body = this.alepha.codec.encode(route.schema.response, reply.body, {\n as: \"string\",\n });\n return;\n }\n\n if (responseKind === \"file\") {\n if (!isFileLike(reply.body)) {\n throw new HttpError({\n status: 500,\n message: \"Invalid response body - not a file\",\n });\n }\n reply.headers[\"content-type\"] = reply.body.type;\n reply.headers[\"content-disposition\"] =\n `attachment; filename=\"${reply.body.name.replaceAll('\"', \"\")}\"`;\n reply.body = reply.body.stream();\n return;\n }\n\n if (responseKind === \"text\") {\n reply.body = String(reply.body);\n if (reply.body.startsWith(\"<!DOCTYPE html>\")) {\n reply.headers[\"content-type\"] ??= \"text/html; charset=UTF-8\";\n } else {\n reply.headers[\"content-type\"] ??= \"text/plain\";\n }\n return;\n }\n\n if (reply.body == null || responseKind === \"void\") {\n delete reply.headers[\"content-type\"];\n reply.body = undefined;\n return;\n }\n\n if (Buffer.isBuffer(reply.body)) {\n reply.headers[\"content-type\"] ??= \"application/octet-stream\";\n return;\n }\n\n if (\n reply.body instanceof NodeWebStream ||\n reply.body instanceof NodeStream\n ) {\n // set content-type to application/octet-stream if not set\n reply.headers[\"content-type\"] ??= \"application/octet-stream\";\n return;\n }\n\n reply.headers[\"content-type\"] ??= \"text/plain\";\n reply.body = String(reply.body);\n return;\n }\n\n protected getResponseType(schema?: RequestConfigSchema): ResponseKind {\n if (schema?.response) {\n if (\n t.schema.isObject(schema.response) ||\n t.schema.isRecord(schema.response) ||\n t.schema.isArray(schema.response)\n ) {\n return \"json\";\n }\n\n if (\n t.schema.isString(schema.response) ||\n t.schema.isInteger(schema.response) ||\n t.schema.isNumber(schema.response) ||\n t.schema.isBoolean(schema.response)\n ) {\n return \"text\";\n }\n\n if (isTypeFile(schema.response)) {\n return \"file\";\n }\n\n if (t.schema.isVoid(schema.response)) {\n return \"void\";\n }\n }\n\n return \"any\";\n }\n\n protected async errorHandler(\n route: ServerRoute,\n request: ServerRequest,\n error: Error,\n ) {\n // reset body, which is probably invalid,\n // it can be filled by server:onError hook or by the default handler below\n request.reply.body = null;\n\n await this.alepha.events.emit(\n \"server:onError\",\n {\n request,\n route,\n error,\n },\n {\n log: false,\n },\n );\n\n if (!request.reply.body && !request.reply.status) {\n if (error instanceof HttpError) {\n request.reply.status = error.status;\n request.reply.headers[\"content-type\"] = \"application/json\";\n request.reply.body = JSON.stringify({\n ...HttpError.toJSON(error),\n requestId: request.requestId,\n });\n } else {\n if (\n \"status\" in error &&\n typeof error.status === \"number\" &&\n !!errorNameByStatus[error.status]\n ) {\n request.reply.status = error.status;\n request.reply.headers[\"content-type\"] = \"application/json\";\n request.reply.body = JSON.stringify({\n status: error.status,\n error: errorNameByStatus[error.status],\n message: (error as Error).message,\n requestId: request.requestId,\n });\n return;\n }\n\n request.reply.status = 500;\n request.reply.headers[\"content-type\"] = \"application/json\";\n request.reply.body = JSON.stringify({\n status: 500,\n error: \"InternalServerError\",\n message: (error as Error).message,\n requestId: request.requestId,\n });\n }\n }\n }\n\n public validateRequest(\n route: { schema?: RequestConfigSchema },\n request: ServerRequestConfig,\n ) {\n if (route.schema?.params) {\n try {\n request.params = this.alepha.codec.validate(\n route.schema.params,\n request.params,\n ) as any;\n } catch (error) {\n throw new ValidationError(\"Invalid request params\", error);\n }\n }\n\n if (route.schema?.query) {\n try {\n // we parse one by one to use the TypeBox coercion (e.g., number from string)\n const query: Record<string, any> = {};\n for (const key in route.schema.query.properties) {\n if (request.query[key] != null) {\n query[key] = this.alepha.codec.decode(\n route.schema.query.properties[key],\n request.query[key],\n );\n }\n }\n request.query = query;\n } catch (error) {\n throw new ValidationError(\"Invalid request query\", error);\n }\n }\n\n if (route.schema?.headers) {\n try {\n request.headers = this.alepha.codec.validate(\n route.schema.headers,\n request.headers,\n ) as any;\n } catch (error) {\n throw new ValidationError(\"Invalid request header\", error);\n }\n }\n\n if (route.schema?.body) {\n if (t.schema.isString(route.schema.body)) {\n if (typeof request.body !== \"string\") {\n throw new ValidationError(\"Request body is not a string\");\n }\n } else {\n try {\n request.body = this.alepha.codec.decode(\n route.schema.body,\n request.body,\n );\n } catch (error) {\n throw new ValidationError(\"Invalid request body\", error);\n }\n }\n }\n }\n}\n","import { Readable } from \"node:stream\";\nimport { $hook, $inject, Alepha } from \"alepha\";\nimport { DateTimeProvider } from \"alepha/datetime\";\nimport { $logger } from \"alepha/logger\";\nimport type { Route } from \"alepha/router\";\nimport type { RouteMethod } from \"../constants/routeMethods.ts\";\nimport type {\n NodeRequestEvent,\n ServerRequestData,\n WebRequestEvent,\n} from \"../interfaces/ServerRequest.ts\";\nimport { ServerRouterProvider } from \"./ServerRouterProvider.ts\";\n\n/**\n * Base server provider to handle incoming requests and route them.\n *\n * This is the default implementation for serverless environments.\n *\n * ServerProvider supports both Node.js HTTP requests and Web (Fetch API) requests.\n */\nexport class ServerProvider {\n protected readonly log = $logger();\n protected readonly alepha = $inject(Alepha);\n protected readonly dateTimeProvider = $inject(DateTimeProvider);\n protected readonly router = $inject(ServerRouterProvider);\n\n protected readonly internalServerErrorMessage = \"Internal Server Error\";\n\n public get hostname(): string {\n return \"\"; // no hostname in serverless mode\n }\n\n /**\n * When a Node.js HTTP request is received from outside. (Vercel, AWS Lambda, etc.)\n */\n protected readonly onNodeRequest = $hook({\n on: \"node:request\",\n handler: (ev) => this.handleNodeRequest(ev),\n });\n\n /**\n * When a Web (Fetch API) request is received from outside. (Netlify, Cloudflare Workers, etc.)\n */\n protected readonly onWebRequest = $hook({\n on: \"web:request\",\n handler: (ev) => {\n return this.handleWebRequest(ev);\n },\n });\n\n /**\n * Handle Node.js HTTP request event.\n *\n * Technically, we just convert Node.js request to Web Standard Request.\n */\n public async handleNodeRequest(\n nodeRequestEvent: NodeRequestEvent,\n ): Promise<void> {\n const { req, res } = nodeRequestEvent;\n const { route, params } = this.router.match(`/${req.method}${req.url}`);\n\n if (this.isViteNotFound(req.url, route, params)) {\n return;\n }\n\n if (!route) {\n // if no route is found, return basic 404\n // note: you should not use this in production, use a custom 404 page instead by adding a route /*\n res.writeHead(404, { \"content-type\": \"text/plain\" });\n res.end(\"Not Found\");\n return;\n }\n\n const headers = (req.headers ?? {}) as Record<string, string>;\n const proto = headers[\"x-forwarded-proto\"] === \"https\" ? \"https\" : \"http\";\n const url = new URL(`${proto}://${headers.host}${req.url}`);\n const query = Object.fromEntries(url.searchParams.entries());\n const method = (req.method?.toUpperCase() ?? \"GET\") as RouteMethod;\n\n const request: ServerRequestData = {\n method,\n url,\n headers,\n params: params ?? {},\n query,\n raw: { node: nodeRequestEvent },\n };\n\n const response = await route.handler(request).catch(() => {\n return {\n status: 500,\n headers: { \"content-type\": \"text/plain\" },\n body: this.internalServerErrorMessage,\n };\n });\n\n // empty body - just send status & headers\n if (!response.body) {\n res.writeHead(response.status, response.headers).end();\n return;\n }\n\n // if response.body is string or buffer\n if (typeof response.body === \"string\" || Buffer.isBuffer(response.body)) {\n res.writeHead(response.status, response.headers).end(response.body);\n return;\n }\n\n // if response.body is node stream\n if (response.body instanceof Readable) {\n res.writeHead(response.status, response.headers);\n response.body.pipe(res);\n return;\n }\n\n // if response.body is web stream\n if (response.body instanceof ReadableStream) {\n res.writeHead(response.status, response.headers);\n try {\n for await (const chunk of response.body) {\n res.write(chunk);\n }\n } catch (error) {\n this.log.error(\"Error piping proxy response stream\", error);\n } finally {\n res.end();\n }\n return;\n }\n\n // not supported response body type\n\n this.log.error(\"Unknown response body type:\", typeof response.body);\n res.writeHead(500, { \"content-type\": \"text/plain\" });\n res.end(this.internalServerErrorMessage);\n }\n\n /**\n * Handle Web (Fetch API) request event.\n */\n public async handleWebRequest(ev: WebRequestEvent): Promise<void> {\n const req = ev.req;\n const url = new URL(req.url);\n const { route, params } = this.router.match(\n `/${req.method}${url.pathname}`,\n );\n\n if (this.isViteNotFound(req.url, route, params)) {\n return;\n }\n\n if (!route) {\n // if no route is found, return basic 404\n // note: you should not use this in production, use a custom 404 page instead by adding a route /*\n ev.res = new Response(\"Not Found\", {\n status: 404,\n headers: { \"content-type\": \"text/plain\" },\n });\n return;\n }\n\n const headers: Record<string, string> = {};\n\n req.headers.forEach((value, key) => {\n headers[key] = value;\n });\n\n const query = Object.fromEntries(url.searchParams.entries());\n const method = (req.method.toUpperCase() ?? \"GET\") as RouteMethod;\n const request: ServerRequestData = {\n method,\n url,\n headers,\n params: params || {},\n query,\n raw: { web: ev },\n };\n\n const response = await route.handler(request).catch(() => {\n return {\n status: 500,\n headers: { \"content-type\": \"text/plain\" },\n body: this.internalServerErrorMessage,\n };\n });\n\n // empty body - just send status & headers\n if (!response.body) {\n ev.res = new Response(null, {\n status: response.status,\n headers: response.headers,\n });\n return;\n }\n\n // if response.body is string or buffer\n if (typeof response.body === \"string\") {\n ev.res = new Response(response.body, {\n status: response.status,\n headers: response.headers,\n });\n return;\n }\n\n if (Buffer.isBuffer(response.body)) {\n ev.res = new Response(response.body.buffer as ArrayBuffer, {\n status: response.status,\n headers: response.headers,\n });\n return;\n }\n\n // if response.body is node stream\n if (response.body instanceof Readable) {\n ev.res = new Response(Readable.toWeb(response.body) as ReadableStream, {\n status: response.status,\n headers: response.headers,\n });\n return;\n }\n\n // if response.body is web stream\n if (response.body instanceof ReadableStream) {\n ev.res = new Response(response.body, {\n status: response.status,\n headers: response.headers,\n });\n return;\n }\n\n // not supported response body type\n this.log.error(`Unknown response body type: ${typeof response.body}`);\n ev.res = new Response(this.internalServerErrorMessage, {\n status: 500,\n headers: { \"content-type\": \"text/plain\" },\n });\n }\n\n /**\n * Helper for Vite development mode to let Vite handle (or not) 404.\n */\n protected isViteNotFound(\n url?: string,\n route?: Route,\n params?: Record<string, string>,\n ): boolean {\n if (this.alepha.isViteDev()) {\n if (!route) {\n return true;\n }\n\n url = url?.split(\"?\")[0];\n\n if (!!params?.[\"*\"] && `/${params?.[\"*\"]}` === url) {\n return true;\n }\n }\n\n return false;\n }\n}\n","import { type Static, t } from \"alepha\";\n\nexport const errorSchema = t.object(\n {\n error: t.text({ description: \"HTTP error name\" }),\n status: t.integer({\n description: \"HTTP status code\",\n }),\n message: t.text({\n description: \"Short text which describe the error\",\n size: \"rich\",\n }),\n details: t.optional(\n t.text({\n description: \"Detailed description of the error\",\n size: \"rich\",\n }),\n ),\n requestId: t.optional(t.text()),\n cause: t.optional(\n t.object({\n name: t.text(),\n message: t.text({\n description: \"Cause Error message\",\n size: \"rich\",\n }),\n }),\n ),\n },\n {\n title: \"HttpError\",\n description: \"Generic response after a failed operation\",\n },\n);\n\nexport type ErrorSchema = Static<typeof errorSchema>;\n","import {\n $inject,\n Alepha,\n type FileLike,\n isFileLike,\n type Static,\n type TObject,\n type TSchema,\n} from \"alepha\";\nimport { $cache } from \"alepha/cache\";\nimport type { DurationLike } from \"alepha/datetime\";\nimport { $logger } from \"alepha/logger\";\nimport { HttpError } from \"../errors/HttpError.ts\";\nimport { isMultipart } from \"../helpers/isMultipart.ts\";\nimport type {\n ServerRequestConfigEntry,\n TRequestBody,\n TResponseBody,\n} from \"../interfaces/ServerRequest.ts\";\nimport type { ClientRequestOptions } from \"../primitives/$action.ts\";\nimport { errorSchema } from \"../schemas/errorSchema.ts\";\n\nexport class HttpClient {\n protected readonly log = $logger();\n protected readonly alepha = $inject(Alepha);\n\n public readonly cache = $cache<HttpClientCache>();\n\n protected readonly pendingRequests: HttpClientPendingRequests = {};\n\n public async fetchAction(args: FetchActionArgs): Promise<FetchResponse> {\n const route = args.action; // our link to fetch\n const options = args.options ?? {}; // fetch standard options, cache, etc.\n const config = args.config ?? {}; // params, query, body, etc.\n const host = args.host ?? \"\"; // remote host, e.g. \"https://api.example.com\" or empty (for browser)\n\n const request: RequestInit = {\n ...options.request,\n };\n\n const method = route.method;\n const headers: Record<string, string> = {};\n const url = this.url(host, route, config);\n\n await this.alepha.events.emit(\"client:onRequest\", {\n route,\n config,\n options,\n headers,\n request,\n });\n\n request.method ??= method;\n\n await this.body(request, headers, route, config);\n\n request.headers = {\n ...config.headers,\n ...Object.fromEntries(new Headers(request.headers).entries()),\n ...headers,\n };\n\n return await this.fetch(url, {\n ...request,\n schema: route.schema,\n ...options,\n });\n }\n\n public async fetch<T extends TSchema>(\n url: string,\n request: RequestInitWithOptions<T> = {}, // standard options\n ): Promise<FetchResponse<Static<T>>> {\n const options = {\n cache: request.localCache,\n schema: request.schema?.response,\n key: request.key,\n };\n\n request.method ??= \"GET\";\n\n this.log.trace(\"Request\", {\n url,\n method: request.method,\n body: request.body,\n headers: request.headers,\n options,\n });\n\n // Only add automatic ETag if user didn't explicitly provide headers\n const cached = await this.cache.get(url);\n if (cached && request.method === \"GET\") {\n if (cached.etag) {\n request.headers = new Headers(request.headers);\n if (!request.headers.has(\"if-none-match\")) {\n request.headers.set(\"if-none-match\", cached.etag);\n }\n } else {\n return {\n data: cached.data as Static<T>,\n status: 200,\n statusText: \"OK\",\n headers: new Headers(),\n };\n }\n }\n\n await this.alepha.events.emit(\"client:beforeFetch\", {\n url,\n options,\n request,\n });\n\n // make a key for the request\n // this will be used to check if the request is already pending\n const key =\n options.key ??\n JSON.stringify({\n url,\n method: request.method,\n body: request.body,\n });\n\n const existing = this.pendingRequests[key];\n if (existing) {\n this.log.info(\"Request already pending\", key);\n return existing;\n }\n\n this.pendingRequests[key] = fetch(url, request)\n .then(async (response) => {\n this.log.debug(\"Response\", {\n url,\n status: response.status,\n });\n\n const fetchResponse: FetchResponse = {\n data: await this.responseData(response, options),\n status: response.status,\n statusText: response.statusText,\n headers: response.headers,\n raw: response,\n };\n\n if (request.method === \"GET\") {\n if (options.cache) {\n await this.cache.set(\n url,\n { data: fetchResponse.data },\n typeof options.cache === \"boolean\" ? undefined : options.cache,\n );\n } else if (!this.alepha.isBrowser()) {\n // only cache etag on server, browser can handle etag itself\n const etag = response.headers.get(\"etag\") ?? undefined;\n if (etag) {\n await this.cache.set(url, { data: fetchResponse.data, etag });\n }\n }\n }\n\n return fetchResponse;\n })\n .finally(() => {\n delete this.pendingRequests[key];\n });\n\n return this.pendingRequests[key];\n }\n\n protected url(\n host: string,\n action: HttpAction,\n args: ServerRequestConfigEntry,\n ) {\n let url = host;\n\n if (action.prefix) {\n url += action.prefix;\n }\n\n url += action.path;\n url = this.pathVariables(url, action, args);\n url = this.queryParams(url, action, args);\n\n return url;\n }\n\n protected async body(\n init: RequestInit,\n headers: Record<string, string>,\n action: HttpAction,\n args: ServerRequestConfigEntry = {},\n ) {\n const hasHeader =\n typeof init.headers === \"object\" &&\n \"content-type\" in init.headers &&\n init.headers[\"content-type\"] === \"multipart/form-data\";\n\n if (hasHeader || isMultipart(action)) {\n if (typeof init.headers === \"object\" && \"content-type\" in init.headers) {\n delete init.headers[\"content-type\"]; // fetch() will fill this for us\n }\n\n const formData = new FormData();\n\n for (const [key, value] of Object.entries(args.body ?? {})) {\n if (typeof value === \"string\") {\n formData.append(key, value);\n continue;\n }\n if (value instanceof Blob) {\n formData.append(key, value);\n continue;\n }\n if (isFileLike(value)) {\n // FileLike must be transformed to WebFile\n formData.append(\n key,\n new File([await value.arrayBuffer()], value.name, {\n type: value.type,\n }),\n );\n }\n }\n\n init.body = formData;\n\n return;\n }\n\n if (!init.body && action.schema?.body) {\n headers[\"content-type\"] = \"application/json\";\n init.body = this.alepha.codec.encode(action.schema?.body, args.body, {\n as: \"string\",\n });\n }\n }\n\n protected async responseData(\n response: Response,\n options: FetchOptions,\n ): Promise<any> {\n if (response.status === 304) {\n let cacheKey = response.url;\n if (typeof window !== \"undefined\") {\n cacheKey = cacheKey.replace(window.location.origin, \"\");\n }\n\n const cached = await this.cache.get(cacheKey);\n if (cached) {\n return cached.data;\n }\n\n // if no cached data (etag-only routes), return empty string\n return \"\";\n }\n\n if (response.status === 204) {\n return;\n }\n\n if (this.isMaybeFile(response)) {\n return this.createFileLike(response);\n }\n\n if (response.headers.get(\"Content-Type\")?.startsWith(\"text/\")) {\n return await response.text();\n }\n\n if (response.headers.get(\"Content-Type\") === \"application/json\") {\n const json = await response.json();\n\n if (response.status >= 400) {\n const jsonError = this.alepha.codec.decode(errorSchema, json);\n const error = new HttpError(jsonError);\n\n await this.alepha.events.emit(\"client:onError\", {\n error,\n });\n\n throw error;\n }\n\n if (options.schema) {\n return this.alepha.codec.decode(options.schema, json);\n }\n\n return json;\n }\n\n if (response.status >= 400) {\n const error = new HttpError({\n status: response.status,\n message: `An error occurred while fetching the resource. (${response.statusText})`,\n });\n\n await this.alepha.events.emit(\"client:onError\", {\n error,\n });\n\n throw error;\n }\n\n return response;\n }\n\n protected isMaybeFile(response: Response): boolean {\n const contentType = response.headers.get(\"Content-Type\");\n if (!contentType) {\n return false;\n }\n\n if (response.headers.get(\"Content-Disposition\")?.includes(\"attachment\")) {\n return true; // If Content-Disposition indicates an attachment, treat it as a file\n }\n\n return (\n contentType.startsWith(\"application/octet-stream\") ||\n contentType.startsWith(\"application/pdf\") ||\n contentType.startsWith(\"application/zip\") ||\n contentType.startsWith(\"image/\") ||\n contentType.startsWith(\"video/\") ||\n contentType.startsWith(\"audio/\")\n );\n }\n\n protected createFileLike(response: Response, defaultFileName = \"\"): FileLike {\n const match = (response.headers.get(\"Content-Disposition\") ?? \"\").match(\n /filename=\"(.+)\"/,\n );\n return {\n name: match?.[1] ? match[1] : defaultFileName,\n type: response.headers.get(\"Content-Type\") ?? \"application/octet-stream\",\n size: Number(response.headers.get(\"Content-Length\") ?? 0),\n lastModified: Date.now(),\n stream: () => {\n throw new Error(\"Not implemented\");\n },\n arrayBuffer: async () => {\n return await response.arrayBuffer();\n },\n text: async () => {\n return await response.text();\n },\n };\n }\n\n public pathVariables(\n url: string,\n action: { schema?: { params?: TObject } },\n args: ServerRequestConfigEntry = {},\n ): string {\n if (typeof args.params === \"object\") {\n const params = action.schema?.params\n ? (this.alepha.codec.decode(\n action.schema.params,\n args.params,\n ) as Record<string, any>)\n : args.params;\n\n for (const key of Object.keys(params)) {\n url = url.replace(`:${key}`, params[key]);\n url = url.replace(`{${key}}`, params[key]);\n }\n }\n\n return url;\n }\n\n public queryParams(\n url: string,\n action: { schema?: { query?: TObject } },\n args: ServerRequestConfigEntry = {},\n ): string {\n if (typeof args.query === \"object\") {\n const query = action.schema?.query\n ? this.alepha.codec.decode(action.schema.query, args.query ?? {})\n : args.query;\n\n for (const key of Object.keys(query)) {\n if (query[key] === undefined) {\n delete query[key];\n }\n if (typeof query[key] === \"object\") {\n query[key] = JSON.stringify(query[key]);\n }\n }\n\n return `${url}?${new URLSearchParams(\n query as Record<string, string>,\n ).toString()}`;\n }\n return url;\n }\n}\n\n// ---------------------------------------------------------------------------------------------------------------------\n\nexport interface FetchOptions<T extends TSchema = TSchema> {\n /**\n * Key to identify the request in the pending requests.\n */\n key?: string;\n\n /**\n * The schema to validate the response against.\n */\n schema?: {\n response?: T;\n };\n\n /**\n * Built-in cache options.\n */\n localCache?: boolean | number | DurationLike;\n}\n\nexport type RequestInitWithOptions<T extends TSchema = TSchema> = RequestInit &\n FetchOptions<T>;\n\nexport interface FetchResponse<T = any> {\n data: T;\n status: number;\n statusText: string;\n headers: Headers;\n raw?: Response;\n}\n\nexport type HttpClientPendingRequests = Record<\n string,\n Promise<any> | undefined\n>;\n\ninterface HttpClientCache {\n data: any;\n etag?: string;\n}\n\nexport interface FetchActionArgs {\n action: HttpAction;\n host?: string;\n config?: ServerRequestConfigEntry;\n options?: ClientRequestOptions;\n}\n\nexport interface HttpAction {\n method?: string;\n prefix?: string;\n path: string;\n requestBodyType?: string;\n schema?: {\n params?: TObject;\n query?: TObject;\n body?: TRequestBody;\n response?: TResponseBody;\n };\n}\n","import {\n $env,\n $inject,\n type Async,\n createPrimitive,\n isTypeFile,\n KIND,\n Primitive,\n type Static,\n type TObject,\n type TSchema,\n t,\n} from \"alepha\";\nimport { $logger } from \"alepha/logger\";\nimport type { RouteMethod } from \"../constants/routeMethods.ts\";\nimport { isMultipart } from \"../helpers/isMultipart.ts\";\nimport { ServerReply } from \"../helpers/ServerReply.ts\";\nimport type {\n RequestConfigSchema,\n ServerRequest,\n ServerResponseBody,\n ServerRoute,\n} from \"../interfaces/ServerRequest.ts\";\nimport { ServerProvider } from \"../providers/ServerProvider.ts\";\nimport { ServerRouterProvider } from \"../providers/ServerRouterProvider.ts\";\nimport {\n type FetchOptions,\n type FetchResponse,\n HttpClient,\n} from \"../services/HttpClient.ts\";\n\n/**\n * Creates a server action primitive for defining type-safe HTTP endpoints.\n *\n * Server actions are the core building blocks for REST APIs in Alepha, providing declarative\n * HTTP endpoints with full type safety, automatic validation, and OpenAPI documentation.\n *\n * **Key Features**\n * - Full TypeScript inference for request/response types\n * - Automatic schema validation using TypeBox\n * - Convention-based URL generation with customizable paths\n * - Direct invocation (`run()`) or HTTP requests (`fetch()`)\n * - Built-in authentication and authorization support\n * - Automatic content-type handling (JSON, form-data, plain text)\n *\n * **URL Generation**\n *\n * **Important:** All `$action` paths are automatically prefixed with `/api`.\n *\n * ```ts\n * $action({ path: \"/users\" }) // → GET /api/users\n * $action({ path: \"/users/:id\" }) // → GET /api/users/:id\n * $action({ path: \"/hello\" }) // → GET /api/hello\n * ```\n *\n * This prefix is configurable via the `SERVER_API_PREFIX` environment variable.\n * HTTP method defaults to GET, or POST if body schema is provided.\n *\n * **Common Use Cases**\n * - CRUD operations with type safety\n * - File upload and download endpoints\n * - Microservice communication\n *\n * @example\n * ```ts\n * class UserController {\n * getUsers = $action({\n * path: \"/users\",\n * schema: {\n * query: t.object({\n * page: t.optional(t.number({ default: 1 })),\n * limit: t.optional(t.number({ default: 10 }))\n * }),\n * response: t.object({\n * users: t.array(t.object({\n * id: t.text(),\n * name: t.text(),\n * email: t.text()\n * })),\n * total: t.number()\n * })\n * },\n * handler: async ({ query }) => {\n * const users = await this.userService.findUsers(query);\n * return { users: users.items, total: users.total };\n * }\n * });\n *\n * createUser = $action({\n * method: \"POST\",\n * path: \"/users\",\n * schema: {\n * body: t.object({\n * name: t.text(),\n * email: t.text({ format: \"email\" })\n * }),\n * response: t.object({ id: t.text(), name: t.text() })\n * },\n * handler: async ({ body }) => {\n * return await this.userService.create(body);\n * }\n * });\n * }\n * ```\n */\nexport const $action = <TConfig extends RequestConfigSchema>(\n options: ActionPrimitiveOptions<TConfig>,\n): ActionPrimitiveFn<TConfig> => {\n const instance = createPrimitive(ActionPrimitive<TConfig>, options);\n const fn = (\n config?: ClientRequestEntry<TConfig>,\n options?: ClientRequestOptions,\n ) => {\n return instance.run(config, options);\n };\n Object.defineProperty(fn, \"name\", {\n get(): string {\n return instance.options.name || instance.config.propertyKey;\n },\n });\n return Object.setPrototypeOf(fn, instance) as ActionPrimitiveFn<TConfig>;\n};\n\n// ----------------------------------------------------------------------------------------------------------\n\nexport interface ActionPrimitiveOptions<TConfig extends RequestConfigSchema>\n extends Omit<ServerRoute, \"handler\" | \"path\" | \"schema\" | \"mapParams\"> {\n /**\n * Name of the action.\n *\n * - It will be used to generate the route path if `path` is not provided.\n * - It will be used to generate the permission name if `security` is enabled.\n */\n name?: string;\n\n /**\n * Group actions together.\n *\n * - If not provided, the service name containing the route will be used.\n * - It will be used as Tag for documentation purposes.\n * - It will be used for permission name generation if `security` is enabled.\n *\n * @example\n * ```ts\n * // group = \"MyController\"\n * class MyController {\n * \thello = $action({ handler: () => \"Hello World\" });\n * }\n *\n * // group = \"users\"\n * class MyOtherController {\n * group = \"users\";\n * a1 = $action({ handler: () => \"Action 1\", group: this.group });\n * a2 = $action({ handler: () => \"Action 2\", group: this.group });\n * }\n * ```\n */\n group?: string;\n\n /**\n * Pathname of the route. If not provided, property key is used.\n */\n path?: string;\n\n /**\n * The route method.\n *\n * - If not provided, it will be set to \"GET\" by default.\n * - If not provider and a body is provided, it will be set to \"POST\".\n *\n * Wildcard methods are not supported for now. (e.g. \"ALL\", \"ANY\", etc.)\n */\n method?: RouteMethod;\n\n /**\n * The config schema of the route.\n * - body: The request body schema.\n * - params: Path variables schema.\n * - query: The request query-params schema.\n * - response: The response schema.\n */\n schema?: TConfig;\n\n /**\n * A short description of the action. Used for documentation purposes.\n */\n description?: string;\n\n /**\n * Disable the route. Useful with env variables do disable one specific route.\n * Route won't be available in the API but can still be called locally!\n */\n disabled?: boolean;\n\n /**\n * Main route handler. This is where the route logic is implemented.\n */\n handler: ServerActionHandler<TConfig>;\n}\n\n// ----------------------------------------------------------------------------------------------------------\n\nconst envSchema = t.object({\n SERVER_API_PREFIX: t.text({\n description: \"Prefix for all API routes (e.g. $action).\",\n default: \"/api\",\n }),\n});\n\nexport class ActionPrimitive<\n TConfig extends RequestConfigSchema,\n> extends Primitive<ActionPrimitiveOptions<TConfig>> {\n protected readonly log = $logger();\n protected readonly env = $env(envSchema);\n protected readonly httpClient = $inject(HttpClient);\n protected readonly serverProvider = $inject(ServerProvider);\n protected readonly serverRouterProvider = $inject(ServerRouterProvider);\n\n protected onInit() {\n if (this.options.disabled) {\n this.log.debug(\n `Action '${this.name}' is disabled. It won't be available in the API.`,\n );\n return;\n }\n this.serverRouterProvider.createRoute(this.route);\n }\n\n public get prefix() {\n return this.env.SERVER_API_PREFIX;\n }\n\n public get route(): ServerRoute {\n return {\n ...(this.options as any), // TODO: fix schema.header mapping\n method: this.method,\n path: `${this.prefix}${this.path}`,\n } as ServerRoute;\n }\n\n /**\n * Returns the name of the action.\n */\n public get name(): string {\n return this.options.name || this.config.propertyKey;\n }\n\n /**\n * Returns the group of the action. (e.g. \"orders\", \"admin\", etc.)\n */\n public get group(): string {\n return this.options.group || this.config.service.name;\n }\n\n /**\n * Returns the HTTP method of the action.\n */\n public get method(): RouteMethod {\n return this.options.method || (this.options.schema?.body ? \"POST\" : \"GET\");\n }\n\n /**\n * Returns the path of the action.\n *\n * Path is prefixed by `/api` by default.\n */\n public get path(): string {\n if (this.options.path) {\n return this.options.path;\n }\n\n let path = `/${this.name}`;\n\n if (this.options.schema?.params) {\n for (const [key] of Object.entries(\n this.options.schema.params.properties,\n )) {\n path += `/:${key}`;\n }\n }\n\n return path;\n }\n\n public get schema(): TConfig | undefined {\n return this.options.schema;\n }\n\n public getBodyContentType(): string | undefined {\n if (this.options.schema?.body) {\n // TODO: move to `alepha.server.multipart` module ?\n if (isMultipart(this.options)) {\n return \"multipart/form-data\";\n }\n\n if (t.schema.isString(this.options.schema.body)) {\n // if body is a string, we assume it's plain text\n return \"text/plain\";\n }\n\n if (\n t.schema.isObject(this.options.schema.body) ||\n t.schema.isArray(this.options.schema.body) ||\n t.schema.isRecord(this.options.schema.body)\n )\n // if body is an object or array, we assume it's JSON\n return \"application/json\";\n }\n }\n\n /**\n * Call the action handler directly.\n * There is no HTTP layer involved.\n */\n public async run(\n config?: ClientRequestEntry<TConfig>,\n options: ClientRequestOptions = {}, // most of the options are ignored here\n ): Promise<ClientRequestResponse<TConfig>> {\n const handler = this.options.handler;\n const {\n body,\n params = {},\n query = {},\n headers = {},\n } = (config ?? {}) as ClientRequestEntryContainer<RequestConfigSchema>;\n const reply = new ServerReply();\n const method = this.method;\n\n // we use localhost as the base URL for the action\n const url = new URL(`http://localhost${this.path ?? \"\"}`);\n\n const serverActionRequest: Partial<ServerRequest> = {\n method,\n url,\n body,\n params,\n query,\n headers,\n reply,\n metadata: {},\n };\n\n await this.alepha.events.emit(\"action:onRequest\", {\n action: this,\n request: serverActionRequest as ServerRequest,\n options,\n });\n\n if (serverActionRequest.reply?.body) {\n return serverActionRequest.reply.body as ClientRequestResponse<TConfig>;\n }\n\n if (serverActionRequest.query && this.options.schema?.query) {\n serverActionRequest.query = this.alepha.codec.encode(\n this.options.schema.query,\n serverActionRequest.query,\n );\n }\n\n if (serverActionRequest.headers && this.options.schema?.headers) {\n serverActionRequest.headers = this.alepha.codec.encode(\n this.options.schema.headers,\n serverActionRequest.headers,\n ) as Record<string, any>;\n }\n\n if (serverActionRequest.body && this.options.schema?.body) {\n serverActionRequest.body = this.alepha.codec.encode(\n this.options.schema.body,\n serverActionRequest.body,\n ) as unknown;\n }\n\n if (serverActionRequest.params && this.options.schema?.params) {\n serverActionRequest.params = this.alepha.codec.encode(\n this.options.schema.params,\n serverActionRequest.params,\n ) as Record<string, any>;\n }\n\n this.serverRouterProvider.validateRequest(\n this.options,\n serverActionRequest as ServerRequest,\n );\n\n let response: any = await handler(\n serverActionRequest as ServerActionRequest<TConfig>,\n );\n\n // we validate response just to remove undeclared properties from response\n if (\n this.options.schema?.response &&\n // skip validation if response is expected as file\n !isTypeFile(this.options.schema.response)\n ) {\n response = this.alepha.codec.validate(\n this.options.schema.response,\n response,\n );\n }\n\n await this.alepha.events.emit(\"action:onResponse\", {\n action: this,\n request: serverActionRequest as ServerRequest,\n options,\n response,\n });\n\n return response;\n }\n\n /**\n * Works like `run`, but always fetches (http request) the route.\n */\n public fetch(\n config?: ClientRequestEntry<TConfig>,\n options?: ClientRequestOptions,\n ): Promise<FetchResponse<ClientRequestResponse<TConfig>>> {\n return this.httpClient.fetchAction({\n host: this.serverProvider.hostname, // that's the trick, we just use the server hostname\n action: this,\n config,\n options,\n });\n }\n}\n\nexport interface ActionPrimitiveFn<TConfig extends RequestConfigSchema>\n extends ActionPrimitive<TConfig> {\n (\n config?: ClientRequestEntry<TConfig>,\n options?: ClientRequestOptions,\n ): Promise<ClientRequestResponse<TConfig>>;\n}\n\n$action[KIND] = ActionPrimitive;\n\n// ----------------------------------------------------------------------------------------------------------\n\nexport type ClientRequestEntry<\n TConfig extends RequestConfigSchema,\n T = ClientRequestEntryContainer<TConfig>,\n> = {\n [K in keyof T as T[K] extends undefined ? never : K]: T[K];\n};\n\nexport type ClientRequestEntryContainer<TConfig extends RequestConfigSchema> = {\n body: TConfig[\"body\"] extends TObject ? Static<TConfig[\"body\"]> : undefined;\n\n params: TConfig[\"params\"] extends TObject\n ? Static<TConfig[\"params\"]>\n : undefined;\n\n headers?: TConfig[\"headers\"] extends TObject\n ? Static<TConfig[\"headers\"]>\n : undefined;\n\n query?: TConfig[\"query\"] extends TObject\n ? Partial<Static<TConfig[\"query\"]>>\n : undefined;\n};\n\nexport interface ClientRequestOptions extends FetchOptions {\n /**\n * Standard request fetch options.\n */\n request?: RequestInit;\n}\n\nexport type ClientRequestResponse<TConfig extends RequestConfigSchema> =\n TConfig[\"response\"] extends TSchema ? Static<TConfig[\"response\"]> : any;\n\n/**\n * Specific handler for server actions.\n */\nexport type ServerActionHandler<\n TConfig extends RequestConfigSchema = RequestConfigSchema,\n> = (\n request: ServerActionRequest<TConfig>,\n) => Async<ServerResponseBody<TConfig>>;\n\n/**\n * Server Action Request Interface\n *\n * Can be extended with module augmentation to add custom properties (like `user` in Server Security).\n *\n * This is NOT Server Request, but a specific type for actions.\n */\nexport interface ServerActionRequest<TConfig extends RequestConfigSchema>\n extends ServerRequest<TConfig> {}\n","import { $inject, createPrimitive, KIND, Primitive } from \"alepha\";\nimport type {\n RequestConfigSchema,\n ServerRoute,\n} from \"../interfaces/ServerRequest.ts\";\nimport { ServerRouterProvider } from \"../providers/ServerRouterProvider.ts\";\n\n/**\n * Create a basic endpoint.\n *\n * It's a low level primitive. You probably want to use `$action` instead.\n *\n * @see {@link $action}\n * @see {@link $page}\n */\nexport const $route = <TConfig extends RequestConfigSchema>(\n options: RoutePrimitiveOptions<TConfig>,\n): RoutePrimitive<TConfig> => {\n return createPrimitive(RoutePrimitive<TConfig>, options);\n};\n\n// ---------------------------------------------------------------------------------------------------------------------\n\nexport interface RoutePrimitiveOptions<\n TConfig extends RequestConfigSchema = RequestConfigSchema,\n> extends ServerRoute<TConfig> {}\n\n// ---------------------------------------------------------------------------------------------------------------------\n\nexport class RoutePrimitive<\n TConfig extends RequestConfigSchema,\n> extends Primitive<RoutePrimitiveOptions<TConfig>> {\n protected readonly serverRouterProvider = $inject(ServerRouterProvider);\n\n protected onInit() {\n this.serverRouterProvider.createRoute(this.options);\n }\n}\n\n$route[KIND] = RoutePrimitive;\n","import { $env, $hook, $inject, Alepha, type Static, t } from \"alepha\";\nimport { DateTimeProvider } from \"alepha/datetime\";\nimport { $logger } from \"alepha/logger\";\nimport { ServerProvider } from \"./ServerProvider.ts\";\nimport { ServerRouterProvider } from \"./ServerRouterProvider.ts\";\n\nconst envSchema = t.object({\n SERVER_PORT: t.integer({\n default: 3000,\n min: 0,\n max: 65535,\n description: \"Set 0 to listen on a random port.\",\n }),\n SERVER_HOST: t.text({\n default: \"localhost\",\n description: \"Set 0.0.0.0 to listen on all interfaces.\",\n }),\n});\n\ndeclare module \"alepha\" {\n interface Env extends Partial<Static<typeof envSchema>> {}\n}\n\n// Type declaration for Bun global (only when running in Bun runtime)\ndeclare const Bun: any;\n\nexport class BunHttpServerProvider extends ServerProvider {\n protected readonly alepha = $inject(Alepha);\n protected readonly dateTimeProvider = $inject(DateTimeProvider);\n protected readonly log = $logger();\n protected readonly env = $env(envSchema);\n protected readonly router = $inject(ServerRouterProvider);\n\n protected bunServer?: ReturnType<typeof Bun.serve>;\n\n public get hostname(): string {\n if (this.bunServer) {\n return `http://${this.bunServer.hostname}:${this.bunServer.port}`;\n }\n return `http://${this.env.SERVER_HOST}:${this.env.SERVER_PORT}`;\n }\n\n public readonly start = $hook({\n on: \"start\",\n handler: async () => {\n await this.listen();\n },\n });\n\n protected readonly stop = $hook({\n on: \"stop\",\n handler: async () => {\n if (this.alepha.isProduction()) {\n await this.close();\n return;\n }\n\n // do not await in development & test\n this.close().catch(() => {});\n },\n });\n\n protected async listen() {\n let port = this.env.SERVER_PORT;\n\n // for testing, use a random port if port is 3000 (default)\n if (this.alepha.isTest() && port === 3000) {\n port = 0;\n }\n\n try {\n this.bunServer = Bun.serve({\n port,\n hostname: this.env.SERVER_HOST,\n fetch: async (request: Request) => {\n this.log.trace(`Incoming Bun request -> ${request.url}`);\n\n // Create WebRequestEvent for handleWebRequest\n const webRequestEvent = {\n req: request,\n res: undefined as Response | undefined,\n };\n\n try {\n await this.handleWebRequest(webRequestEvent);\n\n if (!webRequestEvent.res) {\n // No response set, return 500\n return new Response(\"Internal Server Error\", {\n status: 500,\n headers: { \"content-type\": \"text/plain\" },\n });\n }\n\n return webRequestEvent.res;\n } catch (err) {\n this.log.error(\"Error handling request\", err);\n return new Response(\"Internal Server Error\", {\n status: 500,\n headers: { \"content-type\": \"text/plain\" },\n });\n }\n },\n error: (error: Error) => {\n this.log.error(\"Bun server error\", error);\n return new Response(\"Internal Server Error\", {\n status: 500,\n headers: { \"content-type\": \"text/plain\" },\n });\n },\n });\n\n this.log.info(`Server listening on ${this.hostname}`);\n } catch (err) {\n this.log.error(\"Failed to start Bun server\", err);\n throw err;\n }\n }\n\n protected async close() {\n if (!this.bunServer) {\n return;\n }\n\n try {\n // Bun's server.stop() returns a promise that resolves when all connections are closed\n const stopPromise = this.bunServer.stop();\n\n // Race between stop completion and timeout\n await Promise.race([this.dateTimeProvider.wait(10000), stopPromise]);\n\n this.bunServer = undefined;\n this.log.info(\"Server closed\");\n } catch (err) {\n this.log.error(\"Error closing Bun server\", err);\n throw err;\n }\n }\n}\n","import {\n createServer,\n type IncomingMessage,\n type Server,\n type ServerResponse,\n} from \"node:http\";\nimport { $env, $hook, $inject, Alepha, type Static, t } from \"alepha\";\nimport { DateTimeProvider } from \"alepha/datetime\";\nimport { $logger } from \"alepha/logger\";\nimport { ServerProvider } from \"./ServerProvider.ts\";\nimport { ServerRouterProvider } from \"./ServerRouterProvider.ts\";\n\nconst envSchema = t.object({\n SERVER_PORT: t.integer({\n default: 3000,\n min: 0,\n max: 65535,\n description: \"Set 0 to listen on a random port.\",\n }),\n SERVER_HOST: t.text({\n default: \"localhost\",\n description: \"Set 0.0.0.0 to listen on all interfaces.\",\n }),\n});\n\ndeclare module \"alepha\" {\n interface Env extends Partial<Static<typeof envSchema>> {}\n}\n\nexport class NodeHttpServerProvider extends ServerProvider {\n protected readonly alepha = $inject(Alepha);\n protected readonly dateTimeProvider = $inject(DateTimeProvider);\n protected readonly log = $logger();\n protected readonly env = $env(envSchema);\n protected readonly router = $inject(ServerRouterProvider);\n\n public get hostname(): string {\n if (this.server.listening) {\n const address = this.server.address();\n if (typeof address === \"object\" && address !== null) {\n return `http://${this.env.SERVER_HOST}:${address.port}`;\n }\n }\n return `http://${this.env.SERVER_HOST}:${this.env.SERVER_PORT}`;\n }\n\n public readonly server = this.createHttpServer((req, res) => {\n this.log.trace(`Incoming Node.js message -> ${req.url}`);\n this.handleNodeRequest({ req, res }).catch((err) => {\n this.log.error(\"Error handling request\", err);\n res.statusCode = 500;\n res.end(\"Internal Server Error\");\n });\n });\n\n public readonly start = $hook({\n on: \"start\",\n handler: async () => {\n await this.listen();\n this.alepha.store.set(\"alepha.node.server\", this.server);\n },\n });\n\n protected createHttpServer(\n func: (req: IncomingMessage, res: ServerResponse) => void,\n ): Server {\n return createServer(\n {\n // nov 25 - keep connections alive for better performance, cuz we http/1.1 by default\n keepAlive: this.alepha.isProduction(),\n },\n func,\n );\n }\n\n protected readonly stop = $hook({\n on: \"stop\",\n handler: async () => {\n if (this.alepha.isProduction()) {\n await this.close();\n return;\n }\n\n // do not await in development & test\n this.close().catch(() => {});\n },\n });\n\n protected async listen() {\n let port = this.env.SERVER_PORT;\n\n // for testing, use a random port if port is 3000 (default)\n if (this.alepha.isTest() && port === 3000) {\n port = 0;\n }\n\n await new Promise<void>((resolve, reject) => {\n this.server?.listen(port, this.env.SERVER_HOST, () => {\n this.log.info(`Server listening on ${this.hostname}`);\n resolve();\n });\n\n this.server?.on(\"error\", (err) => {\n reject(err);\n });\n });\n }\n\n protected async close() {\n const promise = new Promise<void>((resolve, reject) => {\n this.server?.close((err) => {\n if (err) {\n reject(err);\n } else {\n resolve();\n }\n });\n });\n\n await Promise.race([this.dateTimeProvider.wait(2000), promise]);\n\n this.log.info(\"Server closed\");\n }\n}\n","import { ReadableStream as WebStream } from \"node:stream/web\";\nimport { createBrotliDecompress, createGunzip, createInflate } from \"node:zlib\";\nimport type { TSchema } from \"alepha\";\nimport { $env, $hook, $inject, Alepha, t } from \"alepha\";\nimport { $logger } from \"alepha/logger\";\nimport { HttpError } from \"../errors/HttpError.ts\";\n\nconst envSchema = t.object({\n SERVER_BODY_PARSER_INFLATE: t.boolean({\n default: true,\n description: \"Enable decompression of request body.\",\n }),\n SERVER_BODY_PARSER_LIMIT: t.integer({\n default: 100_000, // 100KB\n min: 0,\n description: \"Maximum size of request body in bytes.\",\n }),\n});\n\nexport class ServerBodyParserProvider {\n protected readonly env = $env(envSchema);\n protected readonly alepha = $inject(Alepha);\n protected readonly log = $logger();\n\n public readonly onRequest = $hook({\n on: \"server:onRequest\",\n handler: async ({ route, request }) => {\n if (request.body) {\n return; // already parsed\n }\n\n let stream: ReadableStream | undefined;\n\n if (request.raw.web?.req.body) {\n stream = request.raw.web.req.body;\n } else if (request.raw.node?.req) {\n // convert Node.js IncomingMessage to Web ReadableStream\n // TODO: check performance impact, it's better to directly read from Node stream!\n stream = WebStream.from(request.raw.node.req) as ReadableStream;\n }\n\n if (!stream) {\n return;\n }\n\n if (route.schema?.body) {\n try {\n const body = await this.parse(\n stream,\n request.headers,\n route.schema.body,\n );\n if (body) {\n request.body = body;\n }\n } catch (error) {\n if (error instanceof HttpError) {\n throw error;\n }\n\n throw new HttpError(\n {\n status: 400,\n message: \"Failed to parse request body\",\n },\n error,\n );\n }\n }\n },\n });\n\n public async parse(\n stream: ReadableStream,\n headers: Record<string, string>,\n schema: TSchema,\n ): Promise<object | string | undefined> {\n const contentType = headers[\"content-type\"];\n const contentEncoding = headers[\"content-encoding\"];\n\n if (!contentType) return undefined;\n\n if (contentType.startsWith(\"text/plain\") || t.schema.isString(schema)) {\n return this.parseText(stream, contentEncoding);\n }\n\n if (contentType.startsWith(\"application/json\")) {\n return this.parseJson(stream, contentEncoding);\n }\n\n if (contentType.startsWith(\"application/x-www-form-urlencoded\")) {\n return this.parseUrlEncoded(stream, contentEncoding);\n }\n\n return undefined;\n }\n\n public async parseText(\n stream: ReadableStream,\n contentEncoding?: string,\n ): Promise<string> {\n const buffer = await this.streamToBuffer(stream);\n const bufferInflated = await this.maybeDecompress(buffer, contentEncoding);\n return bufferInflated.toString(\"utf-8\");\n }\n\n public async parseUrlEncoded(\n stream: ReadableStream,\n contentEncoding?: string,\n ): Promise<object> {\n const text = await this.parseText(stream, contentEncoding);\n const params = new URLSearchParams(text);\n const result: Record<string, string> = {};\n for (const [key, value] of params.entries()) {\n result[key] = value;\n }\n\n return result;\n }\n\n public async parseJson(\n stream: ReadableStream,\n contentEncoding?: string,\n ): Promise<object> {\n const text = await this.parseText(stream, contentEncoding);\n return JSON.parse(text);\n }\n\n protected async maybeDecompress(\n buffer: Buffer,\n encoding: string | undefined,\n ): Promise<Buffer> {\n if (!this.env.SERVER_BODY_PARSER_INFLATE && encoding) {\n throw new HttpError({\n status: 415,\n message: `Content-Encoding ${encoding} not allowed`,\n });\n }\n\n switch (encoding) {\n case \"gzip\":\n return new Promise((res, rej) =>\n createGunzip()\n .end(buffer, () => {})\n .on(\"data\", res)\n .on(\"error\", rej),\n );\n case \"deflate\":\n return new Promise((res, rej) =>\n createInflate()\n .end(buffer, () => {})\n .on(\"data\", res)\n .on(\"error\", rej),\n );\n case \"br\":\n return new Promise((res, rej) =>\n createBrotliDecompress()\n .end(buffer, () => {})\n .on(\"data\", res)\n .on(\"error\", rej),\n );\n case undefined:\n case \"identity\":\n return buffer;\n default:\n throw new Error(`Unsupported Content-Encoding: ${encoding}`);\n }\n }\n\n /**\n * Convert Web ReadableStream to Buffer, with a size limit.\n *\n * TODO: move to alepha/file FileUtils\n */\n protected async streamToBuffer(stream: ReadableStream): Promise<Buffer> {\n const chunks: Uint8Array[] = [];\n let totalLength = 0;\n\n const reader = stream.getReader();\n\n try {\n while (true) {\n const { done, value } = await reader.read();\n\n if (done) {\n break;\n }\n\n if (value) {\n totalLength += value.length;\n\n if (totalLength > this.env.SERVER_BODY_PARSER_LIMIT) {\n this.log.error(\n `Body size limit exceeded: ${totalLength} > ${this.env.SERVER_BODY_PARSER_LIMIT}`,\n );\n\n await reader.cancel(); // Cancel the stream\n\n throw new HttpError({\n status: 413,\n message: `Request body size limit exceeded`,\n });\n }\n\n chunks.push(value);\n }\n }\n\n // Combine all chunks into a single Buffer\n const combinedLength = chunks.reduce(\n (sum, chunk) => sum + chunk.length,\n 0,\n );\n const combined = new Uint8Array(combinedLength);\n let offset = 0;\n\n for (const chunk of chunks) {\n combined.set(chunk, offset);\n offset += chunk.length;\n }\n\n return Buffer.from(combined);\n } catch (error) {\n // Make sure to release the reader lock\n reader.releaseLock();\n throw error;\n }\n }\n}\n","import { $hook, $inject, Alepha } from \"alepha\";\nimport { $logger } from \"alepha/logger\";\n\nexport class ServerLoggerProvider {\n protected readonly log = $logger();\n protected readonly alepha = $inject(Alepha);\n\n public readonly onRequest = $hook({\n on: \"server:onRequest\",\n priority: \"first\",\n handler: ({ route, request }) => {\n if (!route.silent) {\n request.metadata.now = Date.now();\n\n const data: Record<string, string> = {\n method: request.method,\n path: request.url.pathname,\n };\n\n if (this.alepha.isProduction()) {\n data.agent = request.headers[\"user-agent\"];\n const ip = request.ip;\n if (ip) {\n data.ip = ip;\n }\n }\n\n this.log.info(\"Incoming request\", data);\n }\n },\n });\n\n public readonly onError = $hook({\n on: \"server:onError\",\n priority: \"last\",\n handler: ({ error }) => {\n this.log.error(\"Request has failed\", error);\n },\n });\n\n public readonly onResponse = $hook({\n on: \"server:onResponse\",\n priority: \"last\",\n handler: ({ route, request, response }) => {\n if (!route.silent) {\n const ms = Date.now() - request.metadata.now;\n this.log.info(\"Request completed\", { status: response.status, ms });\n }\n },\n });\n}\n","import { $hook, $inject, Alepha } from \"alepha\";\nimport { HttpError } from \"../errors/HttpError.ts\";\n\n/**\n * On every request, this provider checks if the server is ready.\n *\n * If the server is not ready, it responds with a 503 status code and a message indicating that the server is not ready yet.\n *\n * The response also includes a `Retry-After` header indicating that the client should retry after 5 seconds.\n */\nexport class ServerNotReadyProvider {\n protected readonly alepha = $inject(Alepha);\n\n public readonly onRequest = $hook({\n on: \"server:onRequest\",\n priority: \"first\",\n handler: ({ request: { reply } }) => {\n if (this.alepha.isReady()) {\n return;\n }\n\n reply.headers[\"Retry-After\"] = \"5\"; // Retry after 5 seconds\n\n throw new HttpError({\n status: 503,\n message: \"Server is not ready yet. Please try again later.\",\n });\n },\n });\n}\n","export const routeMethods = [\n // list of supported http methods\n \"GET\",\n \"POST\",\n \"PUT\",\n \"PATCH\",\n \"DELETE\",\n \"HEAD\",\n \"OPTIONS\",\n \"CONNECT\",\n \"TRACE\",\n] as const;\n\nexport type RouteMethod = (typeof routeMethods)[number];\n","import { HttpError } from \"./HttpError.ts\";\n\nexport class BadRequestError extends HttpError {\n constructor(message = \"Invalid request body\", cause?: unknown) {\n super(\n {\n message,\n status: 400,\n },\n cause,\n );\n }\n}\n","import { HttpError } from \"./HttpError.ts\";\n\nexport class ConflictError extends HttpError {\n constructor(message = \"Entity already exists\", cause?: unknown) {\n super(\n {\n message,\n status: 409,\n },\n cause,\n );\n }\n}\n","import { HttpError } from \"./HttpError.ts\";\n\nexport class ForbiddenError extends HttpError {\n constructor(\n message = \"No permission to access this resource\",\n cause?: unknown,\n ) {\n super(\n {\n message,\n status: 403,\n },\n cause,\n );\n }\n}\n","import { HttpError } from \"./HttpError.ts\";\n\nexport class NotFoundError extends HttpError {\n constructor(message = \"Resource not found\", cause?: unknown) {\n super(\n {\n message,\n status: 404,\n },\n cause,\n );\n }\n}\n","import { HttpError } from \"./HttpError.ts\";\n\nexport class UnauthorizedError extends HttpError {\n readonly name = \"UnauthorizedError\";\n\n constructor(\n message = \"Not allowed to access this resource\",\n cause?: unknown,\n ) {\n super(\n {\n message,\n status: 401,\n },\n cause,\n );\n }\n}\n","import type { Static } from \"alepha\";\nimport { t } from \"alepha\";\n\nexport const okSchema = t.object(\n {\n ok: t.boolean({ description: \"True when operation succeed\" }),\n id: t.optional(t.union([t.text(), t.integer()])),\n count: t.optional(\n t.number({ description: \"Number of resources affected\" }),\n ),\n },\n {\n title: \"Ok\",\n description: \"Generic response after a successful operation on a resource\",\n },\n);\n\nexport type Ok = Static<typeof okSchema>;\n","import type { Server } from \"node:http\";\nimport { $module, type Alepha, type PrimitiveFactoryLike } from \"alepha\";\nimport type { HttpError } from \"./errors/HttpError.ts\";\nimport type {\n NodeRequestEvent,\n RequestConfigSchema,\n ServerRequest,\n ServerRequestConfigEntry,\n ServerResponse,\n ServerRoute,\n WebRequestEvent,\n} from \"./interfaces/ServerRequest.ts\";\nimport {\n $action,\n type ActionPrimitive,\n type ClientRequestOptions,\n} from \"./primitives/$action.ts\";\nimport { $route } from \"./primitives/$route.ts\";\nimport { BunHttpServerProvider } from \"./providers/BunHttpServerProvider.ts\";\nimport { NodeHttpServerProvider } from \"./providers/NodeHttpServerProvider.ts\";\nimport { ServerBodyParserProvider } from \"./providers/ServerBodyParserProvider.ts\";\nimport { ServerLoggerProvider } from \"./providers/ServerLoggerProvider.ts\";\nimport { ServerNotReadyProvider } from \"./providers/ServerNotReadyProvider.ts\";\nimport { ServerProvider } from \"./providers/ServerProvider.ts\";\nimport { ServerRouterProvider } from \"./providers/ServerRouterProvider.ts\";\nimport { ServerTimingProvider } from \"./providers/ServerTimingProvider.ts\";\nimport type { FetchOptions, HttpAction } from \"./services/HttpClient.ts\";\nimport { HttpClient } from \"./services/HttpClient.ts\";\nimport { ServerRequestParser } from \"./services/ServerRequestParser.ts\";\nimport { UserAgentParser } from \"./services/UserAgentParser.ts\";\n\n// ---------------------------------------------------------------------------------------------------------------------\n\ndeclare module \"alepha\" {\n interface State {\n \"alepha.node.server\"?: Server;\n }\n interface Hooks {\n // -----------------------------------------------------------------------------------------------------------------\n // Local Actions hooks\n \"action:onRequest\": {\n action: ActionPrimitive<RequestConfigSchema>;\n request: ServerRequest;\n options: ClientRequestOptions;\n };\n \"action:onResponse\": {\n action: ActionPrimitive<RequestConfigSchema>;\n request: ServerRequest;\n options: ClientRequestOptions;\n response: any;\n };\n // -----------------------------------------------------------------------------------------------------------------\n // Server hooks\n \"server:onRequest\": {\n route: ServerRoute;\n request: ServerRequest;\n };\n \"server:onError\": {\n route: ServerRoute;\n request: ServerRequest;\n error: Error;\n };\n // last chance to modify the response -\n // TODO: probably not really needed, we can also update the response in the onResponse hook...\n \"server:onSend\": {\n route: ServerRoute;\n request: ServerRequest;\n };\n // response is ready\n \"server:onResponse\": {\n route: ServerRoute;\n request: ServerRequest;\n response: ServerResponse;\n };\n // -----------------------------------------------------------------------------------------------------------------\n // Http client hooks\n \"client:onRequest\": {\n route: HttpAction;\n config: ServerRequestConfigEntry;\n options: ClientRequestOptions;\n headers: Record<string, string>;\n request: RequestInit;\n };\n \"client:beforeFetch\": {\n url: string;\n options: FetchOptions;\n request: RequestInit;\n };\n \"client:onError\": {\n route?: HttpAction;\n error: HttpError;\n };\n // -----------------------------------------------------------------------------------------------------------------\n // Internal hooks\n \"node:request\": NodeRequestEvent;\n \"web:request\": WebRequestEvent;\n }\n}\n\n// ---------------------------------------------------------------------------------------------------------------------\n\nexport * from \"./index.shared.ts\";\nexport * from \"./primitives/$action.ts\";\nexport * from \"./primitives/$route.ts\";\nexport * from \"./providers/BunHttpServerProvider.ts\";\nexport * from \"./providers/NodeHttpServerProvider.ts\";\nexport * from \"./providers/ServerLoggerProvider.ts\";\nexport * from \"./providers/ServerNotReadyProvider.ts\";\nexport * from \"./providers/ServerProvider.ts\";\nexport * from \"./providers/ServerRouterProvider.ts\";\nexport * from \"./providers/ServerTimingProvider.ts\";\nexport * from \"./services/UserAgentParser.ts\";\n\n// ---------------------------------------------------------------------------------------------------------------------\n\n/**\n * Provides high-performance HTTP server capabilities with declarative routing and action primitives.\n *\n * The server module enables building REST APIs and web applications using `$route` and `$action` primitives\n * on class properties. It provides automatic request/response handling, schema validation, middleware support,\n * and seamless integration with other Alepha modules for a complete backend solution.\n *\n * @see {@link $route}\n * @see {@link $action}\n * @module alepha.server\n */\nexport const AlephaServer = $module({\n name: \"alepha.server\",\n primitives: [$route, $action as PrimitiveFactoryLike],\n services: [\n ServerProvider,\n BunHttpServerProvider,\n NodeHttpServerProvider,\n ServerBodyParserProvider,\n ServerLoggerProvider,\n ServerNotReadyProvider,\n ServerTimingProvider,\n HttpClient,\n UserAgentParser,\n ServerRequestParser,\n ServerRouterProvider,\n ],\n register: (alepha: Alepha) => {\n if (!alepha.isServerless() && !alepha.isViteDev()) {\n if (alepha.isBun()) {\n alepha.with({\n optional: true,\n provide: ServerProvider,\n use: BunHttpServerProvider,\n });\n } else {\n alepha.with({\n optional: true,\n provide: ServerProvider,\n use: NodeHttpServerProvider,\n });\n }\n } else {\n alepha.with(ServerProvider);\n }\n\n alepha.with(ServerBodyParserProvider);\n alepha.with(ServerLoggerProvider);\n alepha.with(ServerNotReadyProvider);\n\n if (!alepha.isProduction()) {\n alepha.with(ServerTimingProvider);\n }\n },\n});\n"],"mappings":"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"}
@@ -3,7 +3,7 @@ import { KIND, Primitive, Static } from "alepha";
3
3
  import * as alepha_logger0 from "alepha/logger";
4
4
  import { ServerRouterProvider } from "alepha/server";
5
5
 
6
- //#region ../../src/server-cors/primitives/$cors.d.ts
6
+ //#region ../../src/server/cors/primitives/$cors.d.ts
7
7
 
8
8
  /**
9
9
  * Declares CORS configuration for specific server routes.
@@ -41,7 +41,7 @@ declare class CorsPrimitive extends Primitive<CorsPrimitiveConfig> implements Ab
41
41
  protected onInit(): void;
42
42
  }
43
43
  //#endregion
44
- //#region ../../src/server-cors/providers/ServerCorsProvider.d.ts
44
+ //#region ../../src/server/cors/providers/ServerCorsProvider.d.ts
45
45
  /**
46
46
  * CORS configuration atom (global defaults)
47
47
  */
@@ -98,7 +98,7 @@ declare class ServerCorsProvider {
98
98
  }
99
99
  type ServerCorsProviderOptions = CorsOptions;
100
100
  //#endregion
101
- //#region ../../src/server-cors/index.d.ts
101
+ //#region ../../src/server/cors/index.d.ts
102
102
  declare module "alepha/server" {
103
103
  interface ServerRoute {
104
104
  /**