alepha 0.13.0 → 0.13.2

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 (461) hide show
  1. package/README.md +1 -1
  2. package/dist/api-files/index.d.ts +28 -91
  3. package/dist/api-files/index.js +10 -755
  4. package/dist/api-files/index.js.map +1 -1
  5. package/dist/api-jobs/index.d.ts +67 -67
  6. package/dist/api-jobs/index.js +13 -13
  7. package/dist/api-jobs/index.js.map +1 -1
  8. package/dist/api-notifications/index.d.ts +129 -146
  9. package/dist/api-notifications/index.js +17 -39
  10. package/dist/api-notifications/index.js.map +1 -1
  11. package/dist/api-parameters/index.d.ts +21 -22
  12. package/dist/api-parameters/index.js +22 -22
  13. package/dist/api-parameters/index.js.map +1 -1
  14. package/dist/api-users/index.d.ts +224 -2001
  15. package/dist/api-users/index.js +914 -4787
  16. package/dist/api-users/index.js.map +1 -1
  17. package/dist/api-verifications/index.d.ts +96 -96
  18. package/dist/batch/index.d.ts +13 -13
  19. package/dist/batch/index.js +8 -8
  20. package/dist/batch/index.js.map +1 -1
  21. package/dist/bucket/index.d.ts +14 -14
  22. package/dist/bucket/index.js +12 -12
  23. package/dist/bucket/index.js.map +1 -1
  24. package/dist/cache/index.d.ts +11 -11
  25. package/dist/cache/index.js +9 -9
  26. package/dist/cache/index.js.map +1 -1
  27. package/dist/cli/{dist-Sz2EXvQX.cjs → dist-Dl9Vl7Ur.js} +17 -13
  28. package/dist/cli/{dist-BBPjuQ56.js.map → dist-Dl9Vl7Ur.js.map} +1 -1
  29. package/dist/cli/index.d.ts +31 -37
  30. package/dist/cli/index.js +152 -83
  31. package/dist/cli/index.js.map +1 -1
  32. package/dist/command/index.d.ts +19 -19
  33. package/dist/command/index.js +25 -25
  34. package/dist/command/index.js.map +1 -1
  35. package/dist/core/index.browser.js +218 -218
  36. package/dist/core/index.browser.js.map +1 -1
  37. package/dist/core/index.d.ts +232 -232
  38. package/dist/core/index.js +218 -218
  39. package/dist/core/index.js.map +1 -1
  40. package/dist/core/{index.cjs → index.native.js} +304 -455
  41. package/dist/core/index.native.js.map +1 -0
  42. package/dist/datetime/index.d.ts +9 -9
  43. package/dist/datetime/index.js +7 -7
  44. package/dist/datetime/index.js.map +1 -1
  45. package/dist/email/index.d.ts +16 -16
  46. package/dist/email/index.js +80 -82
  47. package/dist/email/index.js.map +1 -1
  48. package/dist/file/index.js +1 -1
  49. package/dist/file/index.js.map +1 -1
  50. package/dist/lock/index.d.ts +9 -9
  51. package/dist/lock/index.js +8 -8
  52. package/dist/lock/index.js.map +1 -1
  53. package/dist/lock-redis/index.js +3 -66
  54. package/dist/lock-redis/index.js.map +1 -1
  55. package/dist/logger/index.d.ts +5 -5
  56. package/dist/logger/index.js +8 -8
  57. package/dist/logger/index.js.map +1 -1
  58. package/dist/orm/index.browser.js +114 -114
  59. package/dist/orm/index.browser.js.map +1 -1
  60. package/dist/orm/index.d.ts +219 -219
  61. package/dist/orm/index.js +46 -46
  62. package/dist/orm/index.js.map +1 -1
  63. package/dist/queue/index.d.ts +25 -25
  64. package/dist/queue/index.js +20 -20
  65. package/dist/queue/index.js.map +1 -1
  66. package/dist/queue-redis/index.d.ts +2 -2
  67. package/dist/redis/index.d.ts +10 -10
  68. package/dist/retry/index.d.ts +20 -20
  69. package/dist/retry/index.js +9 -9
  70. package/dist/retry/index.js.map +1 -1
  71. package/dist/scheduler/index.d.ts +12 -12
  72. package/dist/scheduler/index.js +9 -9
  73. package/dist/scheduler/index.js.map +1 -1
  74. package/dist/security/index.d.ts +53 -53
  75. package/dist/security/index.js +32 -32
  76. package/dist/security/index.js.map +1 -1
  77. package/dist/server/index.browser.js +1 -1
  78. package/dist/server/index.browser.js.map +1 -1
  79. package/dist/server/index.d.ts +101 -101
  80. package/dist/server/index.js +17 -17
  81. package/dist/server/index.js.map +1 -1
  82. package/dist/server-auth/index.browser.js +4 -982
  83. package/dist/server-auth/index.browser.js.map +1 -1
  84. package/dist/server-auth/index.d.ts +204 -785
  85. package/dist/server-auth/index.js +47 -1239
  86. package/dist/server-auth/index.js.map +1 -1
  87. package/dist/server-cache/index.d.ts +10 -10
  88. package/dist/server-cache/index.js +2 -2
  89. package/dist/server-cache/index.js.map +1 -1
  90. package/dist/server-compress/index.d.ts +4 -4
  91. package/dist/server-compress/index.js +1 -1
  92. package/dist/server-compress/index.js.map +1 -1
  93. package/dist/server-cookies/index.browser.js +8 -8
  94. package/dist/server-cookies/index.browser.js.map +1 -1
  95. package/dist/server-cookies/index.d.ts +17 -17
  96. package/dist/server-cookies/index.js +10 -10
  97. package/dist/server-cookies/index.js.map +1 -1
  98. package/dist/server-cors/index.d.ts +17 -17
  99. package/dist/server-cors/index.js +9 -9
  100. package/dist/server-cors/index.js.map +1 -1
  101. package/dist/server-health/index.d.ts +2 -2
  102. package/dist/server-helmet/index.d.ts +1 -1
  103. package/dist/server-links/index.browser.js +12 -12
  104. package/dist/server-links/index.browser.js.map +1 -1
  105. package/dist/server-links/index.d.ts +59 -251
  106. package/dist/server-links/index.js +23 -502
  107. package/dist/server-links/index.js.map +1 -1
  108. package/dist/server-metrics/index.d.ts +4 -4
  109. package/dist/server-metrics/index.js +170 -174
  110. package/dist/server-metrics/index.js.map +1 -1
  111. package/dist/server-multipart/index.d.ts +2 -2
  112. package/dist/server-proxy/index.d.ts +12 -12
  113. package/dist/server-proxy/index.js +10 -10
  114. package/dist/server-proxy/index.js.map +1 -1
  115. package/dist/server-rate-limit/index.d.ts +22 -22
  116. package/dist/server-rate-limit/index.js +12 -12
  117. package/dist/server-rate-limit/index.js.map +1 -1
  118. package/dist/server-security/index.d.ts +24 -24
  119. package/dist/server-security/index.js +15 -15
  120. package/dist/server-security/index.js.map +1 -1
  121. package/dist/server-static/index.d.ts +14 -14
  122. package/dist/server-static/index.js +8 -8
  123. package/dist/server-static/index.js.map +1 -1
  124. package/dist/server-swagger/index.d.ts +25 -184
  125. package/dist/server-swagger/index.js +21 -724
  126. package/dist/server-swagger/index.js.map +1 -1
  127. package/dist/sms/index.d.ts +14 -14
  128. package/dist/sms/index.js +9 -9
  129. package/dist/sms/index.js.map +1 -1
  130. package/dist/thread/index.d.ts +11 -11
  131. package/dist/thread/index.js +17 -17
  132. package/dist/thread/index.js.map +1 -1
  133. package/dist/topic/index.d.ts +26 -26
  134. package/dist/topic/index.js +16 -16
  135. package/dist/topic/index.js.map +1 -1
  136. package/dist/topic-redis/index.d.ts +1 -1
  137. package/dist/vite/index.d.ts +3 -3
  138. package/dist/vite/index.js +12 -13
  139. package/dist/vite/index.js.map +1 -1
  140. package/dist/websocket/index.browser.js +11 -11
  141. package/dist/websocket/index.browser.js.map +1 -1
  142. package/dist/websocket/index.d.ts +51 -51
  143. package/dist/websocket/index.js +13 -13
  144. package/dist/websocket/index.js.map +1 -1
  145. package/package.json +62 -52
  146. package/src/api-files/services/FileService.ts +5 -7
  147. package/src/api-jobs/index.ts +1 -1
  148. package/src/api-jobs/{descriptors → primitives}/$job.ts +8 -8
  149. package/src/api-jobs/providers/JobProvider.ts +9 -9
  150. package/src/api-jobs/services/JobService.ts +5 -5
  151. package/src/api-notifications/index.ts +5 -15
  152. package/src/api-notifications/{descriptors → primitives}/$notification.ts +10 -10
  153. package/src/api-notifications/services/NotificationSenderService.ts +3 -3
  154. package/src/api-parameters/index.ts +1 -1
  155. package/src/api-parameters/{descriptors → primitives}/$config.ts +7 -12
  156. package/src/api-users/index.ts +1 -1
  157. package/src/api-users/{descriptors → primitives}/$userRealm.ts +8 -8
  158. package/src/api-users/providers/UserRealmProvider.ts +1 -1
  159. package/src/batch/index.ts +3 -3
  160. package/src/batch/{descriptors → primitives}/$batch.ts +13 -16
  161. package/src/bucket/index.ts +8 -8
  162. package/src/bucket/{descriptors → primitives}/$bucket.ts +8 -8
  163. package/src/bucket/providers/LocalFileStorageProvider.ts +3 -3
  164. package/src/cache/index.ts +4 -4
  165. package/src/cache/{descriptors → primitives}/$cache.ts +15 -15
  166. package/src/cli/apps/AlephaPackageBuilderCli.ts +30 -3
  167. package/src/cli/assets/appRouterTs.ts +9 -0
  168. package/src/cli/assets/indexHtml.ts +2 -1
  169. package/src/cli/assets/mainBrowserTs.ts +10 -0
  170. package/src/cli/commands/CoreCommands.ts +6 -5
  171. package/src/cli/commands/DrizzleCommands.ts +69 -61
  172. package/src/cli/commands/VerifyCommands.ts +2 -2
  173. package/src/cli/commands/ViteCommands.ts +6 -1
  174. package/src/cli/services/ProjectUtils.ts +78 -41
  175. package/src/command/index.ts +5 -5
  176. package/src/command/{descriptors → primitives}/$command.ts +9 -12
  177. package/src/command/providers/CliProvider.ts +10 -10
  178. package/src/core/Alepha.ts +30 -33
  179. package/src/core/constants/KIND.ts +1 -1
  180. package/src/core/constants/OPTIONS.ts +1 -1
  181. package/src/core/helpers/{descriptor.ts → primitive.ts} +18 -18
  182. package/src/core/helpers/ref.ts +1 -1
  183. package/src/core/index.shared.ts +8 -8
  184. package/src/core/{descriptors → primitives}/$context.ts +5 -5
  185. package/src/core/{descriptors → primitives}/$hook.ts +4 -4
  186. package/src/core/{descriptors → primitives}/$inject.ts +2 -2
  187. package/src/core/{descriptors → primitives}/$module.ts +9 -9
  188. package/src/core/{descriptors → primitives}/$use.ts +2 -2
  189. package/src/core/providers/CodecManager.ts +1 -1
  190. package/src/core/providers/JsonSchemaCodec.ts +1 -1
  191. package/src/core/providers/StateManager.ts +2 -2
  192. package/src/datetime/index.ts +3 -3
  193. package/src/datetime/{descriptors → primitives}/$interval.ts +6 -6
  194. package/src/email/index.ts +4 -4
  195. package/src/email/{descriptors → primitives}/$email.ts +8 -8
  196. package/src/file/index.ts +1 -1
  197. package/src/lock/index.ts +3 -3
  198. package/src/lock/{descriptors → primitives}/$lock.ts +10 -10
  199. package/src/logger/index.ts +8 -8
  200. package/src/logger/{descriptors → primitives}/$logger.ts +2 -2
  201. package/src/logger/services/Logger.ts +1 -1
  202. package/src/orm/constants/PG_SYMBOLS.ts +2 -2
  203. package/src/orm/index.browser.ts +2 -2
  204. package/src/orm/index.ts +8 -8
  205. package/src/orm/{descriptors → primitives}/$entity.ts +11 -11
  206. package/src/orm/{descriptors → primitives}/$repository.ts +2 -2
  207. package/src/orm/{descriptors → primitives}/$sequence.ts +8 -8
  208. package/src/orm/{descriptors → primitives}/$transaction.ts +4 -4
  209. package/src/orm/providers/DrizzleKitProvider.ts +1 -1
  210. package/src/orm/providers/PostgresTypeProvider.ts +3 -3
  211. package/src/orm/providers/RepositoryProvider.ts +4 -4
  212. package/src/orm/providers/drivers/DatabaseProvider.ts +7 -7
  213. package/src/orm/services/ModelBuilder.ts +9 -9
  214. package/src/orm/services/PgRelationManager.ts +2 -2
  215. package/src/orm/services/PostgresModelBuilder.ts +5 -5
  216. package/src/orm/services/Repository.ts +7 -7
  217. package/src/orm/services/SqliteModelBuilder.ts +5 -5
  218. package/src/queue/index.ts +7 -7
  219. package/src/queue/{descriptors → primitives}/$consumer.ts +15 -15
  220. package/src/queue/{descriptors → primitives}/$queue.ts +12 -12
  221. package/src/queue/providers/WorkerProvider.ts +7 -7
  222. package/src/retry/index.ts +3 -3
  223. package/src/retry/{descriptors → primitives}/$retry.ts +19 -17
  224. package/src/scheduler/index.ts +3 -3
  225. package/src/scheduler/{descriptors → primitives}/$scheduler.ts +9 -9
  226. package/src/scheduler/providers/CronProvider.ts +1 -1
  227. package/src/security/index.ts +9 -9
  228. package/src/security/{descriptors → primitives}/$permission.ts +7 -7
  229. package/src/security/{descriptors → primitives}/$realm.ts +6 -12
  230. package/src/security/{descriptors → primitives}/$role.ts +12 -12
  231. package/src/security/{descriptors → primitives}/$serviceAccount.ts +8 -8
  232. package/src/server/index.browser.ts +1 -1
  233. package/src/server/index.ts +14 -14
  234. package/src/server/{descriptors → primitives}/$action.ts +13 -13
  235. package/src/server/{descriptors → primitives}/$route.ts +9 -9
  236. package/src/server/providers/NodeHttpServerProvider.ts +2 -2
  237. package/src/server/services/HttpClient.ts +1 -1
  238. package/src/server-auth/index.browser.ts +1 -1
  239. package/src/server-auth/index.ts +6 -6
  240. package/src/server-auth/{descriptors → primitives}/$auth.ts +10 -10
  241. package/src/server-auth/{descriptors → primitives}/$authCredentials.ts +4 -4
  242. package/src/server-auth/{descriptors → primitives}/$authGithub.ts +4 -4
  243. package/src/server-auth/{descriptors → primitives}/$authGoogle.ts +4 -4
  244. package/src/server-auth/providers/ServerAuthProvider.ts +4 -4
  245. package/src/server-cache/providers/ServerCacheProvider.ts +7 -7
  246. package/src/server-compress/providers/ServerCompressProvider.ts +3 -3
  247. package/src/server-cookies/index.browser.ts +2 -2
  248. package/src/server-cookies/index.ts +5 -5
  249. package/src/server-cookies/{descriptors → primitives}/$cookie.browser.ts +12 -12
  250. package/src/server-cookies/{descriptors → primitives}/$cookie.ts +13 -13
  251. package/src/server-cookies/providers/ServerCookiesProvider.ts +4 -4
  252. package/src/server-cookies/services/CookieParser.ts +1 -1
  253. package/src/server-cors/index.ts +3 -3
  254. package/src/server-cors/{descriptors → primitives}/$cors.ts +11 -13
  255. package/src/server-cors/providers/ServerCorsProvider.ts +5 -5
  256. package/src/server-links/index.browser.ts +5 -5
  257. package/src/server-links/index.ts +9 -9
  258. package/src/server-links/{descriptors → primitives}/$remote.ts +11 -11
  259. package/src/server-links/providers/LinkProvider.ts +7 -7
  260. package/src/server-links/providers/{RemoteDescriptorProvider.ts → RemotePrimitiveProvider.ts} +6 -6
  261. package/src/server-links/providers/ServerLinksProvider.ts +3 -3
  262. package/src/server-proxy/index.ts +3 -3
  263. package/src/server-proxy/{descriptors → primitives}/$proxy.ts +8 -8
  264. package/src/server-proxy/providers/ServerProxyProvider.ts +4 -4
  265. package/src/server-rate-limit/index.ts +6 -6
  266. package/src/server-rate-limit/{descriptors → primitives}/$rateLimit.ts +13 -13
  267. package/src/server-rate-limit/providers/ServerRateLimitProvider.ts +5 -5
  268. package/src/server-security/index.ts +3 -3
  269. package/src/server-security/{descriptors → primitives}/$basicAuth.ts +13 -13
  270. package/src/server-security/providers/ServerBasicAuthProvider.ts +5 -5
  271. package/src/server-security/providers/ServerSecurityProvider.ts +4 -4
  272. package/src/server-static/index.ts +3 -3
  273. package/src/server-static/{descriptors → primitives}/$serve.ts +8 -10
  274. package/src/server-static/providers/ServerStaticProvider.ts +6 -6
  275. package/src/server-swagger/index.ts +5 -5
  276. package/src/server-swagger/{descriptors → primitives}/$swagger.ts +9 -9
  277. package/src/server-swagger/providers/ServerSwaggerProvider.ts +11 -10
  278. package/src/sms/index.ts +4 -4
  279. package/src/sms/{descriptors → primitives}/$sms.ts +8 -8
  280. package/src/thread/index.ts +3 -3
  281. package/src/thread/{descriptors → primitives}/$thread.ts +13 -13
  282. package/src/thread/providers/ThreadProvider.ts +7 -9
  283. package/src/topic/index.ts +5 -5
  284. package/src/topic/{descriptors → primitives}/$subscriber.ts +14 -14
  285. package/src/topic/{descriptors → primitives}/$topic.ts +10 -10
  286. package/src/topic/providers/TopicProvider.ts +4 -4
  287. package/src/vite/helpers/boot.ts +3 -3
  288. package/src/vite/tasks/copyAssets.ts +1 -1
  289. package/src/vite/tasks/generateSitemap.ts +3 -3
  290. package/src/vite/tasks/prerenderPages.ts +2 -2
  291. package/src/vite/tasks/runAlepha.ts +2 -2
  292. package/src/websocket/index.browser.ts +3 -3
  293. package/src/websocket/index.shared.ts +2 -2
  294. package/src/websocket/index.ts +4 -4
  295. package/src/websocket/interfaces/WebSocketInterfaces.ts +3 -3
  296. package/src/websocket/{descriptors → primitives}/$channel.ts +10 -10
  297. package/src/websocket/{descriptors → primitives}/$websocket.ts +8 -8
  298. package/src/websocket/providers/NodeWebSocketServerProvider.ts +7 -7
  299. package/src/websocket/providers/WebSocketServerProvider.ts +3 -3
  300. package/src/websocket/services/WebSocketClient.ts +5 -5
  301. package/dist/api-files/index.cjs +0 -1293
  302. package/dist/api-files/index.cjs.map +0 -1
  303. package/dist/api-files/index.d.cts +0 -829
  304. package/dist/api-jobs/index.cjs +0 -274
  305. package/dist/api-jobs/index.cjs.map +0 -1
  306. package/dist/api-jobs/index.d.cts +0 -654
  307. package/dist/api-notifications/index.cjs +0 -380
  308. package/dist/api-notifications/index.cjs.map +0 -1
  309. package/dist/api-notifications/index.d.cts +0 -289
  310. package/dist/api-parameters/index.cjs +0 -66
  311. package/dist/api-parameters/index.cjs.map +0 -1
  312. package/dist/api-parameters/index.d.cts +0 -84
  313. package/dist/api-users/index.cjs +0 -6009
  314. package/dist/api-users/index.cjs.map +0 -1
  315. package/dist/api-users/index.d.cts +0 -4740
  316. package/dist/api-verifications/index.cjs +0 -407
  317. package/dist/api-verifications/index.cjs.map +0 -1
  318. package/dist/api-verifications/index.d.cts +0 -207
  319. package/dist/batch/index.cjs +0 -408
  320. package/dist/batch/index.cjs.map +0 -1
  321. package/dist/batch/index.d.cts +0 -330
  322. package/dist/bin/index.cjs +0 -17
  323. package/dist/bin/index.cjs.map +0 -1
  324. package/dist/bin/index.d.cts +0 -1
  325. package/dist/bucket/index.cjs +0 -303
  326. package/dist/bucket/index.cjs.map +0 -1
  327. package/dist/bucket/index.d.cts +0 -355
  328. package/dist/cache/index.cjs +0 -241
  329. package/dist/cache/index.cjs.map +0 -1
  330. package/dist/cache/index.d.cts +0 -202
  331. package/dist/cache-redis/index.cjs +0 -84
  332. package/dist/cache-redis/index.cjs.map +0 -1
  333. package/dist/cache-redis/index.d.cts +0 -40
  334. package/dist/cli/chunk-DSlc6foC.cjs +0 -43
  335. package/dist/cli/dist-BBPjuQ56.js +0 -2778
  336. package/dist/cli/dist-Sz2EXvQX.cjs.map +0 -1
  337. package/dist/cli/index.cjs +0 -1241
  338. package/dist/cli/index.cjs.map +0 -1
  339. package/dist/cli/index.d.cts +0 -422
  340. package/dist/command/index.cjs +0 -693
  341. package/dist/command/index.cjs.map +0 -1
  342. package/dist/command/index.d.cts +0 -340
  343. package/dist/core/index.cjs.map +0 -1
  344. package/dist/core/index.d.cts +0 -1927
  345. package/dist/datetime/index.cjs +0 -318
  346. package/dist/datetime/index.cjs.map +0 -1
  347. package/dist/datetime/index.d.cts +0 -145
  348. package/dist/email/index.cjs +0 -10874
  349. package/dist/email/index.cjs.map +0 -1
  350. package/dist/email/index.d.cts +0 -186
  351. package/dist/fake/index.cjs +0 -34641
  352. package/dist/fake/index.cjs.map +0 -1
  353. package/dist/fake/index.d.cts +0 -74
  354. package/dist/file/index.cjs +0 -1212
  355. package/dist/file/index.cjs.map +0 -1
  356. package/dist/file/index.d.cts +0 -698
  357. package/dist/lock/index.cjs +0 -226
  358. package/dist/lock/index.cjs.map +0 -1
  359. package/dist/lock/index.d.cts +0 -361
  360. package/dist/lock-redis/index.cjs +0 -113
  361. package/dist/lock-redis/index.cjs.map +0 -1
  362. package/dist/lock-redis/index.d.cts +0 -24
  363. package/dist/logger/index.cjs +0 -521
  364. package/dist/logger/index.cjs.map +0 -1
  365. package/dist/logger/index.d.cts +0 -281
  366. package/dist/orm/index.cjs +0 -2986
  367. package/dist/orm/index.cjs.map +0 -1
  368. package/dist/orm/index.d.cts +0 -2213
  369. package/dist/queue/index.cjs +0 -1044
  370. package/dist/queue/index.cjs.map +0 -1
  371. package/dist/queue/index.d.cts +0 -1265
  372. package/dist/queue-redis/index.cjs +0 -873
  373. package/dist/queue-redis/index.cjs.map +0 -1
  374. package/dist/queue-redis/index.d.cts +0 -82
  375. package/dist/redis/index.cjs +0 -153
  376. package/dist/redis/index.cjs.map +0 -1
  377. package/dist/redis/index.d.cts +0 -82
  378. package/dist/retry/index.cjs +0 -146
  379. package/dist/retry/index.cjs.map +0 -1
  380. package/dist/retry/index.d.cts +0 -172
  381. package/dist/router/index.cjs +0 -111
  382. package/dist/router/index.cjs.map +0 -1
  383. package/dist/router/index.d.cts +0 -46
  384. package/dist/scheduler/index.cjs +0 -576
  385. package/dist/scheduler/index.cjs.map +0 -1
  386. package/dist/scheduler/index.d.cts +0 -145
  387. package/dist/security/index.cjs +0 -2402
  388. package/dist/security/index.cjs.map +0 -1
  389. package/dist/security/index.d.cts +0 -598
  390. package/dist/server/index.cjs +0 -1680
  391. package/dist/server/index.cjs.map +0 -1
  392. package/dist/server/index.d.cts +0 -810
  393. package/dist/server-auth/index.cjs +0 -3146
  394. package/dist/server-auth/index.cjs.map +0 -1
  395. package/dist/server-auth/index.d.cts +0 -1164
  396. package/dist/server-cache/index.cjs +0 -252
  397. package/dist/server-cache/index.cjs.map +0 -1
  398. package/dist/server-cache/index.d.cts +0 -164
  399. package/dist/server-compress/index.cjs +0 -141
  400. package/dist/server-compress/index.cjs.map +0 -1
  401. package/dist/server-compress/index.d.cts +0 -38
  402. package/dist/server-cookies/index.cjs +0 -234
  403. package/dist/server-cookies/index.cjs.map +0 -1
  404. package/dist/server-cookies/index.d.cts +0 -144
  405. package/dist/server-cors/index.cjs +0 -201
  406. package/dist/server-cors/index.cjs.map +0 -1
  407. package/dist/server-cors/index.d.cts +0 -140
  408. package/dist/server-health/index.cjs +0 -62
  409. package/dist/server-health/index.cjs.map +0 -1
  410. package/dist/server-health/index.d.cts +0 -58
  411. package/dist/server-helmet/index.cjs +0 -131
  412. package/dist/server-helmet/index.cjs.map +0 -1
  413. package/dist/server-helmet/index.d.cts +0 -97
  414. package/dist/server-links/index.cjs +0 -992
  415. package/dist/server-links/index.cjs.map +0 -1
  416. package/dist/server-links/index.d.cts +0 -513
  417. package/dist/server-metrics/index.cjs +0 -4535
  418. package/dist/server-metrics/index.cjs.map +0 -1
  419. package/dist/server-metrics/index.d.cts +0 -35
  420. package/dist/server-multipart/index.cjs +0 -237
  421. package/dist/server-multipart/index.cjs.map +0 -1
  422. package/dist/server-multipart/index.d.cts +0 -50
  423. package/dist/server-proxy/index.cjs +0 -186
  424. package/dist/server-proxy/index.cjs.map +0 -1
  425. package/dist/server-proxy/index.d.cts +0 -234
  426. package/dist/server-rate-limit/index.cjs +0 -241
  427. package/dist/server-rate-limit/index.cjs.map +0 -1
  428. package/dist/server-rate-limit/index.d.cts +0 -183
  429. package/dist/server-security/index.cjs +0 -316
  430. package/dist/server-security/index.cjs.map +0 -1
  431. package/dist/server-security/index.d.cts +0 -173
  432. package/dist/server-static/index.cjs +0 -170
  433. package/dist/server-static/index.cjs.map +0 -1
  434. package/dist/server-static/index.d.cts +0 -121
  435. package/dist/server-swagger/index.cjs +0 -1021
  436. package/dist/server-swagger/index.cjs.map +0 -1
  437. package/dist/server-swagger/index.d.cts +0 -382
  438. package/dist/sms/index.cjs +0 -221
  439. package/dist/sms/index.cjs.map +0 -1
  440. package/dist/sms/index.d.cts +0 -130
  441. package/dist/thread/index.cjs +0 -350
  442. package/dist/thread/index.cjs.map +0 -1
  443. package/dist/thread/index.d.cts +0 -260
  444. package/dist/topic/index.cjs +0 -282
  445. package/dist/topic/index.cjs.map +0 -1
  446. package/dist/topic/index.d.cts +0 -523
  447. package/dist/topic-redis/index.cjs +0 -71
  448. package/dist/topic-redis/index.cjs.map +0 -1
  449. package/dist/topic-redis/index.d.cts +0 -42
  450. package/dist/vite/index.cjs +0 -1077
  451. package/dist/vite/index.cjs.map +0 -1
  452. package/dist/vite/index.d.cts +0 -542
  453. package/dist/websocket/index.cjs +0 -1117
  454. package/dist/websocket/index.cjs.map +0 -1
  455. package/dist/websocket/index.d.cts +0 -861
  456. package/src/api-notifications/providers/MemorySmsProvider.ts +0 -20
  457. package/src/api-notifications/providers/SmsProvider.ts +0 -8
  458. /package/src/core/{descriptors → primitives}/$atom.ts +0 -0
  459. /package/src/core/{descriptors → primitives}/$env.ts +0 -0
  460. /package/src/server-auth/{descriptors → primitives}/$authApple.ts +0 -0
  461. /package/src/server-links/{descriptors → primitives}/$client.ts +0 -0
@@ -1,35 +0,0 @@
1
- import * as alepha1 from "alepha";
2
- import { Alepha } from "alepha";
3
- import * as alepha_server0 from "alepha/server";
4
- import { Histogram, Registry } from "prom-client";
5
-
6
- //#region src/server-metrics/providers/ServerMetricsProvider.d.ts
7
- declare class ServerMetricsProvider {
8
- protected readonly register: Registry;
9
- protected readonly alepha: Alepha;
10
- protected httpRequestDuration?: Histogram<string>;
11
- readonly options: ServerMetricsProviderOptions;
12
- readonly metrics: alepha_server0.RouteDescriptor<alepha_server0.RequestConfigSchema>;
13
- protected readonly onStart: alepha1.HookDescriptor<"start">;
14
- protected readonly onRequest: alepha1.HookDescriptor<"server:onRequest">;
15
- protected readonly onResponse: alepha1.HookDescriptor<"server:onResponse">;
16
- }
17
- interface ServerMetricsProviderOptions {
18
- prefix?: string;
19
- gcDurationBuckets?: number[];
20
- eventLoopMonitoringPrecision?: number;
21
- labels?: object;
22
- }
23
- //#endregion
24
- //#region src/server-metrics/index.d.ts
25
- /**
26
- * This module provides prometheus metrics for the Alepha server.
27
- * Metrics are exposed at the `/metrics` endpoint.
28
- *
29
- * @see {@link ServerMetricsProvider}
30
- * @module alepha.server.metrics
31
- */
32
- declare const AlephaServerMetrics: alepha1.Service<alepha1.Module>;
33
- //#endregion
34
- export { AlephaServerMetrics, ServerMetricsProvider, ServerMetricsProviderOptions };
35
- //# sourceMappingURL=index.d.cts.map
@@ -1,237 +0,0 @@
1
- //#region rolldown:runtime
2
- var __create = Object.create;
3
- var __defProp = Object.defineProperty;
4
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
- var __getOwnPropNames = Object.getOwnPropertyNames;
6
- var __getProtoOf = Object.getPrototypeOf;
7
- var __hasOwnProp = Object.prototype.hasOwnProperty;
8
- var __copyProps = (to, from, except, desc) => {
9
- if (from && typeof from === "object" || typeof from === "function") {
10
- for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
11
- key = keys[i];
12
- if (!__hasOwnProp.call(to, key) && key !== except) {
13
- __defProp(to, key, {
14
- get: ((k) => from[k]).bind(null, key),
15
- enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
16
- });
17
- }
18
- }
19
- }
20
- return to;
21
- };
22
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
23
- value: mod,
24
- enumerable: true
25
- }) : target, mod));
26
-
27
- //#endregion
28
- let alepha = require("alepha");
29
- let alepha_server = require("alepha/server");
30
- let node_crypto = require("node:crypto");
31
- let node_fs = require("node:fs");
32
- let node_fs_promises = require("node:fs/promises");
33
- let node_os = require("node:os");
34
- node_os = __toESM(node_os);
35
- let node_stream_web = require("node:stream/web");
36
- let alepha_logger = require("alepha/logger");
37
-
38
- //#region src/server-multipart/providers/ServerMultipartProvider.ts
39
- const envSchema = alepha.t.object({
40
- SERVER_MULTIPART_LIMIT: alepha.t.integer({
41
- default: 1e7,
42
- min: 0,
43
- description: "Maximum total size of multipart request body in bytes."
44
- }),
45
- SERVER_MULTIPART_FILE_LIMIT: alepha.t.integer({
46
- default: 5e6,
47
- min: 0,
48
- description: "Maximum size of a single file in bytes."
49
- }),
50
- SERVER_MULTIPART_FILE_COUNT: alepha.t.integer({
51
- default: 10,
52
- min: 1,
53
- description: "Maximum number of files allowed in a single request."
54
- })
55
- });
56
- var ServerMultipartProvider = class {
57
- alepha = (0, alepha.$inject)(alepha.Alepha);
58
- env = (0, alepha.$env)(envSchema);
59
- log = (0, alepha_logger.$logger)();
60
- onRequest = (0, alepha.$hook)({
61
- on: "server:onRequest",
62
- handler: async ({ route, request }) => {
63
- if (request.body) return;
64
- if (!route.schema?.body) return;
65
- let webRequest;
66
- if (request.raw.web?.req) webRequest = request.raw.web.req;
67
- else if (request.raw.node?.req) webRequest = new Request(request.url, {
68
- method: request.method,
69
- headers: request.headers,
70
- body: node_stream_web.ReadableStream.from(request.raw.node.req),
71
- duplex: "half"
72
- });
73
- if (!webRequest) return;
74
- const contentType = request.headers["content-type"];
75
- const contentLength = request.headers["content-length"];
76
- if (contentLength) {
77
- const size = Number.parseInt(contentLength, 10);
78
- if (!Number.isNaN(size) && size > this.env.SERVER_MULTIPART_LIMIT) {
79
- this.log.error(`Multipart request size limit exceeded: ${size} > ${this.env.SERVER_MULTIPART_LIMIT}`);
80
- throw new alepha_server.HttpError({
81
- status: 413,
82
- message: `Request body size limit exceeded. Maximum allowed: ${this.env.SERVER_MULTIPART_LIMIT} bytes`
83
- });
84
- }
85
- }
86
- if (!contentType?.startsWith("multipart/form-data")) {
87
- if (!(0, alepha_server.isMultipart)(route)) return;
88
- throw new alepha_server.HttpError({
89
- status: 415,
90
- message: `Invalid content-type: ${contentType} - only "multipart/form-data" is accepted`
91
- });
92
- }
93
- const { body, cleanup } = await this.handleMultipartBodyFromWeb(route, webRequest);
94
- request.body = body;
95
- request.metadata.multipart = { cleanup };
96
- }
97
- });
98
- onResponse = (0, alepha.$hook)({
99
- on: "server:onResponse",
100
- handler: async ({ request }) => {
101
- const cleanup = request.metadata.multipart?.cleanup;
102
- if (typeof cleanup === "function") await cleanup();
103
- }
104
- });
105
- async handleMultipartBodyFromWeb(route, request) {
106
- let formData;
107
- try {
108
- formData = await request.formData();
109
- } catch (error) {
110
- throw new alepha_server.HttpError({
111
- status: 400,
112
- message: "Malformed multipart/form-data"
113
- }, error);
114
- }
115
- const body = {};
116
- const tempFiles = [];
117
- const cleanupOnError = async () => {
118
- for (const file of tempFiles) try {
119
- await file.cleanup();
120
- } catch {}
121
- };
122
- try {
123
- let fileCount = 0;
124
- let totalSize = 0;
125
- if (route.schema?.body && alepha.t.schema.isObject(route.schema.body)) {
126
- for (const [key, value] of Object.entries(route.schema.body.properties)) if (alepha.t.schema.isSchema(value)) if ((0, alepha.isTypeFile)(value)) {
127
- const file = formData.get(key);
128
- if (file && typeof file === "object" && "arrayBuffer" in file) {
129
- const blob = file;
130
- fileCount++;
131
- if (fileCount > this.env.SERVER_MULTIPART_FILE_COUNT) {
132
- this.log.error(`Too many files in multipart request: ${fileCount} > ${this.env.SERVER_MULTIPART_FILE_COUNT}`);
133
- throw new alepha_server.HttpError({
134
- status: 413,
135
- message: `Too many files. Maximum allowed: ${this.env.SERVER_MULTIPART_FILE_COUNT}`
136
- });
137
- }
138
- if (blob.size > this.env.SERVER_MULTIPART_FILE_LIMIT) {
139
- this.log.error(`File "${key}" exceeds size limit: ${blob.size} > ${this.env.SERVER_MULTIPART_FILE_LIMIT}`);
140
- throw new alepha_server.HttpError({
141
- status: 413,
142
- message: `File "${key}" exceeds size limit. Maximum allowed: ${this.env.SERVER_MULTIPART_FILE_LIMIT} bytes`
143
- });
144
- }
145
- totalSize += blob.size;
146
- if (totalSize > this.env.SERVER_MULTIPART_LIMIT) {
147
- this.log.error(`Total multipart size exceeds limit: ${totalSize} > ${this.env.SERVER_MULTIPART_LIMIT}`);
148
- throw new alepha_server.HttpError({
149
- status: 413,
150
- message: `Total request size exceeds limit. Maximum allowed: ${this.env.SERVER_MULTIPART_LIMIT} bytes`
151
- });
152
- }
153
- const hybridFile = await this.createHybridFile(blob, key);
154
- body[key] = hybridFile;
155
- tempFiles.push(hybridFile);
156
- }
157
- } else {
158
- const fieldValue = formData.get(key);
159
- if (fieldValue !== null) {
160
- const stringValue = typeof fieldValue === "string" ? fieldValue : "";
161
- body[key] = this.alepha.codec.decode(value, stringValue);
162
- }
163
- }
164
- }
165
- return {
166
- body,
167
- cleanup: async () => {
168
- for (const file of tempFiles) await file.cleanup();
169
- }
170
- };
171
- } catch (error) {
172
- await cleanupOnError();
173
- throw error;
174
- }
175
- }
176
- /**
177
- * This is a legacy code, previously we used "busboy" to parse multipart in Node.js environment.
178
- * Now we rely on Web Request's formData() method, which is supported in modern Node.js versions.
179
- * However, we still need to create temporary files for uploaded files to provide a consistent File-like interface.
180
- *
181
- * TODO: In future, we might want to refactor this to avoid using temporary files if not necessary?
182
- */
183
- async createHybridFile(file, fieldName) {
184
- const tmpPath = `${node_os.tmpdir()}/${(0, node_crypto.randomUUID)()}`;
185
- const arrayBuffer = await file.arrayBuffer();
186
- await (0, node_fs_promises.writeFile)(tmpPath, Buffer.from(arrayBuffer));
187
- const fileName = file.name || `${fieldName}_${Date.now()}`;
188
- return {
189
- _state: {
190
- cleanup: false,
191
- size: file.size,
192
- tmpPath
193
- },
194
- name: fileName,
195
- type: file.type || "application/octet-stream",
196
- lastModified: file.lastModified || Date.now(),
197
- filepath: tmpPath,
198
- get size() {
199
- return this._state.size;
200
- },
201
- stream() {
202
- return (0, node_fs.createReadStream)(tmpPath);
203
- },
204
- async arrayBuffer() {
205
- const content = await (0, node_fs_promises.readFile)(tmpPath);
206
- return content.buffer.slice(content.byteOffset, content.byteOffset + content.byteLength);
207
- },
208
- text: async () => {
209
- return await (0, node_fs_promises.readFile)(tmpPath, "utf-8");
210
- },
211
- async cleanup() {
212
- if (this._state.cleanup) return;
213
- await (0, node_fs_promises.unlink)(tmpPath);
214
- this._state.cleanup = true;
215
- }
216
- };
217
- }
218
- };
219
-
220
- //#endregion
221
- //#region src/server-multipart/index.ts
222
- /**
223
- * This module provides support for handling multipart/form-data requests.
224
- * It allows to parse body data containing t.file().
225
- *
226
- * @see {@link ServerMultipartProvider}
227
- * @module alepha.server.multipart
228
- */
229
- const AlephaServerMultipart = (0, alepha.$module)({
230
- name: "alepha.server.multipart",
231
- services: [alepha_server.AlephaServer, ServerMultipartProvider]
232
- });
233
-
234
- //#endregion
235
- exports.AlephaServerMultipart = AlephaServerMultipart;
236
- exports.ServerMultipartProvider = ServerMultipartProvider;
237
- //# sourceMappingURL=index.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.cjs","names":["t","Alepha","webRequest: Request | undefined","WebStream","HttpError","formData: FormData","body: Record<string, any>","tempFiles: HybridFile[]","os","AlephaServer"],"sources":["../../src/server-multipart/providers/ServerMultipartProvider.ts","../../src/server-multipart/index.ts"],"sourcesContent":["import { randomUUID } from \"node:crypto\";\nimport { createReadStream } from \"node:fs\";\nimport { readFile, unlink, writeFile } from \"node:fs/promises\";\nimport * as os from \"node:os\";\nimport { ReadableStream as WebStream } from \"node:stream/web\";\nimport {\n $env,\n $hook,\n $inject,\n Alepha,\n type FileLike,\n isTypeFile,\n t,\n} from \"alepha\";\nimport { $logger } from \"alepha/logger\";\nimport { HttpError, isMultipart, type ServerRoute } from \"alepha/server\";\n\nconst envSchema = t.object({\n SERVER_MULTIPART_LIMIT: t.integer({\n default: 10_000_000, // 10MB total\n min: 0,\n description: \"Maximum total size of multipart request body in bytes.\",\n }),\n SERVER_MULTIPART_FILE_LIMIT: t.integer({\n default: 5_000_000, // 5MB per file\n min: 0,\n description: \"Maximum size of a single file in bytes.\",\n }),\n SERVER_MULTIPART_FILE_COUNT: t.integer({\n default: 10,\n min: 1,\n description: \"Maximum number of files allowed in a single request.\",\n }),\n});\n\nexport class ServerMultipartProvider {\n protected readonly alepha = $inject(Alepha);\n protected readonly env = $env(envSchema);\n protected readonly log = $logger();\n\n public readonly onRequest = $hook({\n on: \"server:onRequest\",\n handler: async ({ route, request }) => {\n // already parsed (e.g. by body parser)\n if (request.body) {\n return;\n }\n\n // we do not parse body if no schema\n if (!route.schema?.body) {\n return;\n }\n\n let webRequest: Request | undefined;\n\n if (request.raw.web?.req) {\n webRequest = request.raw.web.req;\n } else if (request.raw.node?.req) {\n webRequest = new Request(request.url, {\n method: request.method,\n headers: request.headers,\n body: WebStream.from(request.raw.node.req) as ReadableStream,\n duplex: \"half\",\n } as RequestInit & { duplex: \"half\" });\n }\n\n if (!webRequest) {\n return;\n }\n\n const contentType = request.headers[\"content-type\"];\n\n // Check content-length before processing to fail fast on oversized requests\n const contentLength = request.headers[\"content-length\"];\n if (contentLength) {\n const size = Number.parseInt(contentLength, 10);\n if (!Number.isNaN(size) && size > this.env.SERVER_MULTIPART_LIMIT) {\n this.log.error(\n `Multipart request size limit exceeded: ${size} > ${this.env.SERVER_MULTIPART_LIMIT}`,\n );\n throw new HttpError({\n status: 413,\n message: `Request body size limit exceeded. Maximum allowed: ${this.env.SERVER_MULTIPART_LIMIT} bytes`,\n });\n }\n }\n\n if (!contentType?.startsWith(\"multipart/form-data\")) {\n if (!isMultipart(route)) {\n return;\n }\n\n // route expects multipart but content-type is not correct! reject with 415\n throw new HttpError({\n status: 415,\n message: `Invalid content-type: ${contentType} - only \"multipart/form-data\" is accepted`,\n });\n }\n\n const { body, cleanup } = await this.handleMultipartBodyFromWeb(\n route,\n webRequest,\n );\n\n request.body = body;\n request.metadata.multipart = { cleanup };\n },\n });\n\n public readonly onResponse = $hook({\n on: \"server:onResponse\",\n handler: async ({ request }) => {\n const cleanup = request.metadata.multipart?.cleanup;\n if (typeof cleanup === \"function\") {\n await cleanup();\n }\n },\n });\n\n public async handleMultipartBodyFromWeb(\n route: ServerRoute,\n request: Request,\n ): Promise<{\n body: Record<string, unknown>;\n cleanup: () => Promise<void>;\n }> {\n let formData: FormData;\n\n try {\n // Parse the FormData from the request\n formData = await request.formData();\n } catch (error) {\n throw new HttpError(\n {\n status: 400,\n message: \"Malformed multipart/form-data\",\n },\n error,\n );\n }\n\n const body: Record<string, any> = {};\n const tempFiles: HybridFile[] = [];\n\n // Helper to clean up temp files on error\n const cleanupOnError = async () => {\n for (const file of tempFiles) {\n try {\n await file.cleanup();\n } catch {\n // Ignore cleanup errors during error handling\n }\n }\n };\n\n try {\n let fileCount = 0;\n let totalSize = 0;\n\n if (route.schema?.body && t.schema.isObject(route.schema.body)) {\n for (const [key, value] of Object.entries(\n route.schema.body.properties,\n )) {\n if (t.schema.isSchema(value)) {\n if (isTypeFile(value)) {\n const file = formData.get(key);\n // Check if file is a Blob (File extends Blob in Web APIs)\n if (file && typeof file === \"object\" && \"arrayBuffer\" in file) {\n const blob = file as Blob;\n\n // Validate file count\n fileCount++;\n if (fileCount > this.env.SERVER_MULTIPART_FILE_COUNT) {\n this.log.error(\n `Too many files in multipart request: ${fileCount} > ${this.env.SERVER_MULTIPART_FILE_COUNT}`,\n );\n throw new HttpError({\n status: 413,\n message: `Too many files. Maximum allowed: ${this.env.SERVER_MULTIPART_FILE_COUNT}`,\n });\n }\n\n // Validate individual file size\n if (blob.size > this.env.SERVER_MULTIPART_FILE_LIMIT) {\n this.log.error(\n `File \"${key}\" exceeds size limit: ${blob.size} > ${this.env.SERVER_MULTIPART_FILE_LIMIT}`,\n );\n throw new HttpError({\n status: 413,\n message: `File \"${key}\" exceeds size limit. Maximum allowed: ${this.env.SERVER_MULTIPART_FILE_LIMIT} bytes`,\n });\n }\n\n // Validate total size\n totalSize += blob.size;\n if (totalSize > this.env.SERVER_MULTIPART_LIMIT) {\n this.log.error(\n `Total multipart size exceeds limit: ${totalSize} > ${this.env.SERVER_MULTIPART_LIMIT}`,\n );\n throw new HttpError({\n status: 413,\n message: `Total request size exceeds limit. Maximum allowed: ${this.env.SERVER_MULTIPART_LIMIT} bytes`,\n });\n }\n\n const hybridFile = await this.createHybridFile(blob, key);\n body[key] = hybridFile;\n tempFiles.push(hybridFile);\n }\n } else {\n const fieldValue = formData.get(key);\n if (fieldValue !== null) {\n // FormData values are either string or File/Blob\n const stringValue =\n typeof fieldValue === \"string\" ? fieldValue : \"\";\n body[key] = this.alepha.codec.decode(value, stringValue);\n }\n }\n }\n }\n }\n\n return {\n body,\n cleanup: async () => {\n for (const file of tempFiles) {\n await file.cleanup();\n }\n },\n };\n } catch (error) {\n // Clean up any temp files that were created before the error\n await cleanupOnError();\n throw error;\n }\n }\n\n /**\n * This is a legacy code, previously we used \"busboy\" to parse multipart in Node.js environment.\n * Now we rely on Web Request's formData() method, which is supported in modern Node.js versions.\n * However, we still need to create temporary files for uploaded files to provide a consistent File-like interface.\n *\n * TODO: In future, we might want to refactor this to avoid using temporary files if not necessary?\n */\n protected async createHybridFile(\n file: Blob,\n fieldName: string,\n ): Promise<HybridFile> {\n const tmpPath = `${os.tmpdir()}/${randomUUID()}`;\n\n // Get file data\n const arrayBuffer = await file.arrayBuffer();\n const buffer = Buffer.from(arrayBuffer);\n\n // Write to temp file\n await writeFile(tmpPath, buffer);\n\n // Get file name - check if it has name property (File type)\n const fileName = (file as any).name || `${fieldName}_${Date.now()}`;\n\n const hybridFile: HybridFile = {\n _state: {\n cleanup: false,\n size: file.size,\n tmpPath,\n },\n name: fileName,\n type: file.type || \"application/octet-stream\",\n lastModified: (file as any).lastModified || Date.now(),\n filepath: tmpPath,\n get size() {\n return this._state.size;\n },\n stream() {\n return createReadStream(tmpPath);\n },\n async arrayBuffer() {\n const content = await readFile(tmpPath);\n return content.buffer.slice(\n content.byteOffset,\n content.byteOffset + content.byteLength,\n ) as ArrayBuffer;\n },\n text: async () => {\n return await readFile(tmpPath, \"utf-8\");\n },\n async cleanup() {\n if (this._state.cleanup) {\n return;\n }\n\n await unlink(tmpPath); // clean up the temp file\n this._state.cleanup = true;\n },\n };\n\n return hybridFile;\n }\n}\n\ninterface HybridFile extends FileLike {\n cleanup(): Promise<void>;\n _state: {\n cleanup: boolean;\n size: number;\n tmpPath: string;\n };\n}\n","import { $module } from \"alepha\";\nimport { AlephaServer } from \"alepha/server\";\nimport { ServerMultipartProvider } from \"./providers/ServerMultipartProvider.ts\";\n\n// ---------------------------------------------------------------------------------------------------------------------\n\nexport * from \"./providers/ServerMultipartProvider.ts\";\n\n// ---------------------------------------------------------------------------------------------------------------------\n\n/**\n * This module provides support for handling multipart/form-data requests.\n * It allows to parse body data containing t.file().\n *\n * @see {@link ServerMultipartProvider}\n * @module alepha.server.multipart\n */\nexport const AlephaServerMultipart = $module({\n name: \"alepha.server.multipart\",\n services: [AlephaServer, ServerMultipartProvider],\n});\n"],"mappings":"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"}
@@ -1,50 +0,0 @@
1
- import * as alepha1 from "alepha";
2
- import { Alepha, FileLike } from "alepha";
3
- import * as alepha_logger0 from "alepha/logger";
4
- import { ServerRoute } from "alepha/server";
5
-
6
- //#region src/server-multipart/providers/ServerMultipartProvider.d.ts
7
- declare class ServerMultipartProvider {
8
- protected readonly alepha: Alepha;
9
- protected readonly env: {
10
- SERVER_MULTIPART_LIMIT: number;
11
- SERVER_MULTIPART_FILE_LIMIT: number;
12
- SERVER_MULTIPART_FILE_COUNT: number;
13
- };
14
- protected readonly log: alepha_logger0.Logger;
15
- readonly onRequest: alepha1.HookDescriptor<"server:onRequest">;
16
- readonly onResponse: alepha1.HookDescriptor<"server:onResponse">;
17
- handleMultipartBodyFromWeb(route: ServerRoute, request: Request): Promise<{
18
- body: Record<string, unknown>;
19
- cleanup: () => Promise<void>;
20
- }>;
21
- /**
22
- * This is a legacy code, previously we used "busboy" to parse multipart in Node.js environment.
23
- * Now we rely on Web Request's formData() method, which is supported in modern Node.js versions.
24
- * However, we still need to create temporary files for uploaded files to provide a consistent File-like interface.
25
- *
26
- * TODO: In future, we might want to refactor this to avoid using temporary files if not necessary?
27
- */
28
- protected createHybridFile(file: Blob, fieldName: string): Promise<HybridFile>;
29
- }
30
- interface HybridFile extends FileLike {
31
- cleanup(): Promise<void>;
32
- _state: {
33
- cleanup: boolean;
34
- size: number;
35
- tmpPath: string;
36
- };
37
- }
38
- //#endregion
39
- //#region src/server-multipart/index.d.ts
40
- /**
41
- * This module provides support for handling multipart/form-data requests.
42
- * It allows to parse body data containing t.file().
43
- *
44
- * @see {@link ServerMultipartProvider}
45
- * @module alepha.server.multipart
46
- */
47
- declare const AlephaServerMultipart: alepha1.Service<alepha1.Module>;
48
- //#endregion
49
- export { AlephaServerMultipart, ServerMultipartProvider };
50
- //# sourceMappingURL=index.d.cts.map
@@ -1,186 +0,0 @@
1
- let alepha = require("alepha");
2
- let alepha_server = require("alepha/server");
3
- let node_stream_web = require("node:stream/web");
4
- let alepha_logger = require("alepha/logger");
5
-
6
- //#region src/server-proxy/descriptors/$proxy.ts
7
- /**
8
- * Creates a proxy descriptor to forward requests to another server.
9
- *
10
- * This descriptor enables you to create reverse proxy functionality, allowing your Alepha server
11
- * to forward requests to other services while maintaining a unified API surface. It's particularly
12
- * useful for microservice architectures, API gateways, or when you need to aggregate multiple
13
- * services behind a single endpoint.
14
- *
15
- * **Key Features**
16
- *
17
- * - **Path-based routing**: Match specific paths or patterns to proxy
18
- * - **Dynamic targets**: Support both static and dynamic target resolution
19
- * - **Request/Response hooks**: Modify requests before forwarding and responses after receiving
20
- * - **URL rewriting**: Transform URLs before forwarding to the target
21
- * - **Conditional proxying**: Enable/disable proxies based on environment or conditions
22
- *
23
- * @example
24
- * **Basic proxy setup:**
25
- * ```ts
26
- * import { $proxy } from "alepha/server/proxy";
27
- *
28
- * class ApiGateway {
29
- * // Forward all /api/* requests to external service
30
- * api = $proxy({
31
- * path: "/api/*",
32
- * target: "https://api.example.com"
33
- * });
34
- * }
35
- * ```
36
- *
37
- * @example
38
- * **Dynamic target with environment-based routing:**
39
- * ```ts
40
- * class ApiGateway {
41
- * // Route to different environments based on configuration
42
- * api = $proxy({
43
- * path: "/api/*",
44
- * target: () => process.env.NODE_ENV === "production"
45
- * ? "https://api.prod.example.com"
46
- * : "https://api.dev.example.com"
47
- * });
48
- * }
49
- * ```
50
- *
51
- * @example
52
- * **Advanced proxy with request/response modification:**
53
- * ```ts
54
- * class SecureProxy {
55
- * secure = $proxy({
56
- * path: "/secure/*",
57
- * target: "https://secure-api.example.com",
58
- * beforeRequest: async (request, proxyRequest) => {
59
- * // Add authentication headers
60
- * proxyRequest.headers = {
61
- * ...proxyRequest.headers,
62
- * 'Authorization': `Bearer ${await getServiceToken()}`,
63
- * 'X-Forwarded-For': request.headers['x-forwarded-for'] || request.ip
64
- * };
65
- * },
66
- * afterResponse: async (request, proxyResponse) => {
67
- * // Log response for monitoring
68
- * console.log(`Proxied ${request.url} -> ${proxyResponse.status}`);
69
- * },
70
- * rewrite: (url) => {
71
- * // Remove /secure prefix when forwarding
72
- * url.pathname = url.pathname.replace('/secure', '');
73
- * }
74
- * });
75
- * }
76
- * ```
77
- *
78
- * @example
79
- * **Conditional proxy based on feature flags:**
80
- * ```ts
81
- * class FeatureProxy {
82
- * newApi = $proxy({
83
- * path: "/v2/*",
84
- * target: "https://new-api.example.com",
85
- * disabled: !process.env.ENABLE_V2_API // Disable if feature flag is off
86
- * });
87
- * }
88
- * ```
89
- */
90
- const $proxy = (options) => {
91
- return (0, alepha.createDescriptor)(ProxyDescriptor, options);
92
- };
93
- var ProxyDescriptor = class extends alepha.Descriptor {};
94
- $proxy[alepha.KIND] = ProxyDescriptor;
95
-
96
- //#endregion
97
- //#region src/server-proxy/providers/ServerProxyProvider.ts
98
- var ServerProxyProvider = class {
99
- log = (0, alepha_logger.$logger)();
100
- routerProvider = (0, alepha.$inject)(alepha_server.ServerRouterProvider);
101
- alepha = (0, alepha.$inject)(alepha.Alepha);
102
- configure = (0, alepha.$hook)({
103
- on: "configure",
104
- handler: () => {
105
- for (const proxy of this.alepha.descriptors($proxy)) this.createProxy(proxy.options);
106
- }
107
- });
108
- createProxy(options) {
109
- if (options.disabled) return;
110
- const path = options.path;
111
- const target = typeof options.target === "function" ? options.target() : options.target;
112
- if (!path.endsWith("/*")) throw new alepha.AlephaError("Proxy path should end with '/*'");
113
- const handler = this.createProxyHandler(target, options);
114
- for (const method of alepha_server.routeMethods) this.routerProvider.createRoute({
115
- method,
116
- path,
117
- handler
118
- });
119
- this.log.info("Proxying", {
120
- path,
121
- target
122
- });
123
- }
124
- createProxyHandler(target, options) {
125
- return async (request) => {
126
- const url = new URL(target + request.url.pathname);
127
- if (request.url.search) url.search = request.url.search;
128
- options.rewrite?.(url);
129
- const requestInit = {
130
- url: url.toString(),
131
- method: request.method,
132
- headers: {
133
- ...request.headers,
134
- "accept-encoding": "identity"
135
- },
136
- body: this.getRawRequestBody(request)
137
- };
138
- if (requestInit.body) requestInit.duplex = "half";
139
- if (options.beforeRequest) await options.beforeRequest(request, requestInit);
140
- this.log.debug("Proxying request", {
141
- url: url.toString(),
142
- method: request.method,
143
- headers: request.headers
144
- });
145
- const response = await fetch(requestInit.url, requestInit);
146
- request.reply.status = response.status;
147
- request.reply.headers = Object.fromEntries(response.headers.entries());
148
- request.reply.body = response.body;
149
- this.log.debug("Received response", {
150
- status: request.reply.status,
151
- headers: request.reply.headers
152
- });
153
- if (options.afterResponse) await options.afterResponse(request, response);
154
- };
155
- }
156
- getRawRequestBody(req) {
157
- const { method } = req;
158
- if (method === "GET" || method === "HEAD" || method === "OPTIONS") return;
159
- if (req.raw?.web?.req) return req.raw.web.req.body;
160
- if (req.raw?.node?.req) {
161
- const nodeReq = req.raw.node.req;
162
- return node_stream_web.ReadableStream.from(nodeReq);
163
- }
164
- }
165
- };
166
-
167
- //#endregion
168
- //#region src/server-proxy/index.ts
169
- /**
170
- * Plugin for Alepha that provides a proxy server functionality.
171
- *
172
- * @see {@link $proxy}
173
- * @module alepha.server.proxy
174
- */
175
- const AlephaServerProxy = (0, alepha.$module)({
176
- name: "alepha.server.proxy",
177
- descriptors: [$proxy],
178
- services: [alepha_server.AlephaServer, ServerProxyProvider]
179
- });
180
-
181
- //#endregion
182
- exports.$proxy = $proxy;
183
- exports.AlephaServerProxy = AlephaServerProxy;
184
- exports.ProxyDescriptor = ProxyDescriptor;
185
- exports.ServerProxyProvider = ServerProxyProvider;
186
- //# sourceMappingURL=index.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.cjs","names":["Descriptor","KIND","ServerRouterProvider","Alepha","AlephaError","routeMethods","WebStream","AlephaServer"],"sources":["../../src/server-proxy/descriptors/$proxy.ts","../../src/server-proxy/providers/ServerProxyProvider.ts","../../src/server-proxy/index.ts"],"sourcesContent":["import { type Async, createDescriptor, Descriptor, KIND } from \"alepha\";\nimport type { ServerRequest } from \"alepha/server\";\n\n/**\n * Creates a proxy descriptor to forward requests to another server.\n *\n * This descriptor enables you to create reverse proxy functionality, allowing your Alepha server\n * to forward requests to other services while maintaining a unified API surface. It's particularly\n * useful for microservice architectures, API gateways, or when you need to aggregate multiple\n * services behind a single endpoint.\n *\n * **Key Features**\n *\n * - **Path-based routing**: Match specific paths or patterns to proxy\n * - **Dynamic targets**: Support both static and dynamic target resolution\n * - **Request/Response hooks**: Modify requests before forwarding and responses after receiving\n * - **URL rewriting**: Transform URLs before forwarding to the target\n * - **Conditional proxying**: Enable/disable proxies based on environment or conditions\n *\n * @example\n * **Basic proxy setup:**\n * ```ts\n * import { $proxy } from \"alepha/server/proxy\";\n *\n * class ApiGateway {\n * // Forward all /api/* requests to external service\n * api = $proxy({\n * path: \"/api/*\",\n * target: \"https://api.example.com\"\n * });\n * }\n * ```\n *\n * @example\n * **Dynamic target with environment-based routing:**\n * ```ts\n * class ApiGateway {\n * // Route to different environments based on configuration\n * api = $proxy({\n * path: \"/api/*\",\n * target: () => process.env.NODE_ENV === \"production\"\n * ? \"https://api.prod.example.com\"\n * : \"https://api.dev.example.com\"\n * });\n * }\n * ```\n *\n * @example\n * **Advanced proxy with request/response modification:**\n * ```ts\n * class SecureProxy {\n * secure = $proxy({\n * path: \"/secure/*\",\n * target: \"https://secure-api.example.com\",\n * beforeRequest: async (request, proxyRequest) => {\n * // Add authentication headers\n * proxyRequest.headers = {\n * ...proxyRequest.headers,\n * 'Authorization': `Bearer ${await getServiceToken()}`,\n * 'X-Forwarded-For': request.headers['x-forwarded-for'] || request.ip\n * };\n * },\n * afterResponse: async (request, proxyResponse) => {\n * // Log response for monitoring\n * console.log(`Proxied ${request.url} -> ${proxyResponse.status}`);\n * },\n * rewrite: (url) => {\n * // Remove /secure prefix when forwarding\n * url.pathname = url.pathname.replace('/secure', '');\n * }\n * });\n * }\n * ```\n *\n * @example\n * **Conditional proxy based on feature flags:**\n * ```ts\n * class FeatureProxy {\n * newApi = $proxy({\n * path: \"/v2/*\",\n * target: \"https://new-api.example.com\",\n * disabled: !process.env.ENABLE_V2_API // Disable if feature flag is off\n * });\n * }\n * ```\n */\nexport const $proxy = (options: ProxyDescriptorOptions): ProxyDescriptor => {\n return createDescriptor(ProxyDescriptor, options);\n};\n\nexport type ProxyDescriptorOptions = {\n /**\n * Path pattern to match for proxying requests.\n *\n * Supports wildcards and path parameters:\n * - `/api/*` - Matches all paths starting with `/api/`\n * - `/api/v1/*` - Matches all paths starting with `/api/v1/`\n * - `/users/:id` - Matches `/users/123`, `/users/abc`, etc.\n *\n * @example \"/api/*\"\n * @example \"/secure/admin/*\"\n * @example \"/users/:id/posts\"\n */\n path: string;\n\n /**\n * Target URL to which matching requests should be forwarded.\n *\n * Can be either:\n * - **Static string**: A fixed URL like `\"https://api.example.com\"`\n * - **Dynamic function**: A function that returns the URL, enabling runtime target resolution\n *\n * The target URL will be combined with the remaining path from the original request.\n *\n * @example \"https://api.example.com\"\n * @example () => process.env.API_URL || \"http://localhost:3001\"\n */\n target: string | (() => string);\n\n /**\n * Whether this proxy is disabled.\n *\n * When `true`, requests matching the path will not be proxied and will be handled\n * by other routes or return 404. Useful for feature toggles or conditional proxying.\n *\n * @default false\n * @example !process.env.ENABLE_PROXY\n */\n disabled?: boolean;\n\n /**\n * Hook called before forwarding the request to the target server.\n *\n * Use this to:\n * - Add authentication headers\n * - Modify request headers or body\n * - Add request tracking/logging\n * - Transform the request before forwarding\n *\n * @param request - The original incoming server request\n * @param proxyRequest - The request that will be sent to the target (modifiable)\n *\n * @example\n * ```ts\n * beforeRequest: async (request, proxyRequest) => {\n * proxyRequest.headers = {\n * ...proxyRequest.headers,\n * 'Authorization': `Bearer ${await getToken()}`,\n * 'X-Request-ID': generateRequestId()\n * };\n * }\n * ```\n */\n beforeRequest?: (\n request: ServerRequest,\n proxyRequest: RequestInit,\n ) => Async<void>;\n\n /**\n * Hook called after receiving the response from the target server.\n *\n * Use this to:\n * - Log response details for monitoring\n * - Add custom headers to the response\n * - Transform response data\n * - Handle error responses\n *\n * @param request - The original incoming server request\n * @param proxyResponse - The response received from the target server\n *\n * @example\n * ```ts\n * afterResponse: async (request, proxyResponse) => {\n * console.log(`Proxy ${request.method} ${request.url} -> ${proxyResponse.status}`);\n *\n * if (!proxyResponse.ok) {\n * await logError(`Proxy error: ${proxyResponse.status}`, { request, response: proxyResponse });\n * }\n * }\n * ```\n */\n afterResponse?: (\n request: ServerRequest,\n proxyResponse: Response,\n ) => Async<void>;\n\n /**\n * Function to rewrite the URL before sending to the target server.\n *\n * Use this to:\n * - Remove or add path prefixes\n * - Transform path parameters\n * - Modify query parameters\n * - Change the URL structure entirely\n *\n * The function receives a mutable URL object and should modify it in-place.\n *\n * @param url - The URL object to modify (mutable)\n *\n * @example\n * ```ts\n * // Remove /api prefix when forwarding\n * rewrite: (url) => {\n * url.pathname = url.pathname.replace('/api', '');\n * }\n * ```\n *\n * @example\n * ```ts\n * // Add version prefix\n * rewrite: (url) => {\n * url.pathname = `/v2${url.pathname}`;\n * }\n * ```\n */\n rewrite?: (url: URL) => void;\n\n // TODO: Add retry functionality\n // retry?: RetryOptions;\n};\n\nexport class ProxyDescriptor extends Descriptor<ProxyDescriptorOptions> {}\n\n$proxy[KIND] = ProxyDescriptor;\n","import { ReadableStream as WebStream } from \"node:stream/web\";\nimport { $hook, $inject, Alepha, AlephaError } from \"alepha\";\nimport { $logger } from \"alepha/logger\";\nimport {\n routeMethods,\n type ServerHandler,\n type ServerRequest,\n ServerRouterProvider,\n} from \"alepha/server\";\nimport { $proxy, type ProxyDescriptorOptions } from \"../descriptors/$proxy.ts\";\n\nexport class ServerProxyProvider {\n protected readonly log = $logger();\n protected readonly routerProvider = $inject(ServerRouterProvider);\n protected readonly alepha = $inject(Alepha);\n\n protected readonly configure = $hook({\n on: \"configure\",\n handler: () => {\n for (const proxy of this.alepha.descriptors($proxy)) {\n this.createProxy(proxy.options);\n }\n },\n });\n\n public createProxy(options: ProxyDescriptorOptions): void {\n if (options.disabled) {\n return;\n }\n\n const path = options.path;\n const target =\n typeof options.target === \"function\" ? options.target() : options.target;\n\n if (!path.endsWith(\"/*\")) {\n throw new AlephaError(\"Proxy path should end with '/*'\");\n }\n\n // Extract base path without /*\n const handler = this.createProxyHandler(target, options);\n\n for (const method of routeMethods) {\n this.routerProvider.createRoute({\n method,\n path,\n handler,\n });\n }\n\n this.log.info(\"Proxying\", { path, target });\n }\n\n public createProxyHandler(\n target: string,\n options: Omit<ProxyDescriptorOptions, \"path\">,\n ): ServerHandler {\n return async (request) => {\n const url = new URL(target + request.url.pathname);\n if (request.url.search) {\n url.search = request.url.search;\n }\n\n options.rewrite?.(url);\n\n const requestInit = {\n url: url.toString(),\n method: request.method,\n headers: {\n ...request.headers,\n \"accept-encoding\": \"identity\", // ignore compression\n },\n body: this.getRawRequestBody(request),\n };\n\n if (requestInit.body) {\n (requestInit as any).duplex = \"half\";\n }\n\n if (options.beforeRequest) {\n await options.beforeRequest(request, requestInit);\n }\n\n this.log.debug(\"Proxying request\", {\n url: url.toString(),\n method: request.method,\n headers: request.headers,\n });\n\n const response = await fetch(requestInit.url, requestInit);\n\n request.reply.status = response.status;\n request.reply.headers = Object.fromEntries(response.headers.entries());\n request.reply.body = response.body;\n\n this.log.debug(\"Received response\", {\n status: request.reply.status,\n headers: request.reply.headers,\n });\n\n if (options.afterResponse) {\n await options.afterResponse(request, response);\n }\n };\n }\n\n private getRawRequestBody(req: ServerRequest): ReadableStream | undefined {\n const { method } = req;\n\n if (method === \"GET\" || method === \"HEAD\" || method === \"OPTIONS\") {\n return;\n }\n\n if (req.raw?.web?.req) {\n return req.raw.web.req.body as ReadableStream;\n }\n\n if (req.raw?.node?.req) {\n const nodeReq = req.raw.node.req;\n return WebStream.from(nodeReq) as ReadableStream;\n }\n }\n}\n","import { $module } from \"alepha\";\nimport { AlephaServer } from \"alepha/server\";\nimport { $proxy } from \"./descriptors/$proxy.ts\";\nimport { ServerProxyProvider } from \"./providers/ServerProxyProvider.ts\";\n\n// ---------------------------------------------------------------------------------------------------------------------\n\nexport * from \"./descriptors/$proxy.ts\";\nexport * from \"./providers/ServerProxyProvider.ts\";\n\n// ---------------------------------------------------------------------------------------------------------------------\n\n/**\n * Plugin for Alepha that provides a proxy server functionality.\n *\n * @see {@link $proxy}\n * @module alepha.server.proxy\n */\nexport const AlephaServerProxy = $module({\n name: \"alepha.server.proxy\",\n descriptors: [$proxy],\n services: [AlephaServer, ServerProxyProvider],\n});\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAsFA,MAAa,UAAU,YAAqD;AAC1E,qCAAwB,iBAAiB,QAAQ;;AAsInD,IAAa,kBAAb,cAAqCA,kBAAmC;AAExE,OAAOC,eAAQ;;;;ACpNf,IAAa,sBAAb,MAAiC;CAC/B,AAAmB,kCAAe;CAClC,AAAmB,qCAAyBC,mCAAqB;CACjE,AAAmB,6BAAiBC,cAAO;CAE3C,AAAmB,8BAAkB;EACnC,IAAI;EACJ,eAAe;AACb,QAAK,MAAM,SAAS,KAAK,OAAO,YAAY,OAAO,CACjD,MAAK,YAAY,MAAM,QAAQ;;EAGpC,CAAC;CAEF,AAAO,YAAY,SAAuC;AACxD,MAAI,QAAQ,SACV;EAGF,MAAM,OAAO,QAAQ;EACrB,MAAM,SACJ,OAAO,QAAQ,WAAW,aAAa,QAAQ,QAAQ,GAAG,QAAQ;AAEpE,MAAI,CAAC,KAAK,SAAS,KAAK,CACtB,OAAM,IAAIC,mBAAY,kCAAkC;EAI1D,MAAM,UAAU,KAAK,mBAAmB,QAAQ,QAAQ;AAExD,OAAK,MAAM,UAAUC,2BACnB,MAAK,eAAe,YAAY;GAC9B;GACA;GACA;GACD,CAAC;AAGJ,OAAK,IAAI,KAAK,YAAY;GAAE;GAAM;GAAQ,CAAC;;CAG7C,AAAO,mBACL,QACA,SACe;AACf,SAAO,OAAO,YAAY;GACxB,MAAM,MAAM,IAAI,IAAI,SAAS,QAAQ,IAAI,SAAS;AAClD,OAAI,QAAQ,IAAI,OACd,KAAI,SAAS,QAAQ,IAAI;AAG3B,WAAQ,UAAU,IAAI;GAEtB,MAAM,cAAc;IAClB,KAAK,IAAI,UAAU;IACnB,QAAQ,QAAQ;IAChB,SAAS;KACP,GAAG,QAAQ;KACX,mBAAmB;KACpB;IACD,MAAM,KAAK,kBAAkB,QAAQ;IACtC;AAED,OAAI,YAAY,KACd,CAAC,YAAoB,SAAS;AAGhC,OAAI,QAAQ,cACV,OAAM,QAAQ,cAAc,SAAS,YAAY;AAGnD,QAAK,IAAI,MAAM,oBAAoB;IACjC,KAAK,IAAI,UAAU;IACnB,QAAQ,QAAQ;IAChB,SAAS,QAAQ;IAClB,CAAC;GAEF,MAAM,WAAW,MAAM,MAAM,YAAY,KAAK,YAAY;AAE1D,WAAQ,MAAM,SAAS,SAAS;AAChC,WAAQ,MAAM,UAAU,OAAO,YAAY,SAAS,QAAQ,SAAS,CAAC;AACtE,WAAQ,MAAM,OAAO,SAAS;AAE9B,QAAK,IAAI,MAAM,qBAAqB;IAClC,QAAQ,QAAQ,MAAM;IACtB,SAAS,QAAQ,MAAM;IACxB,CAAC;AAEF,OAAI,QAAQ,cACV,OAAM,QAAQ,cAAc,SAAS,SAAS;;;CAKpD,AAAQ,kBAAkB,KAAgD;EACxE,MAAM,EAAE,WAAW;AAEnB,MAAI,WAAW,SAAS,WAAW,UAAU,WAAW,UACtD;AAGF,MAAI,IAAI,KAAK,KAAK,IAChB,QAAO,IAAI,IAAI,IAAI,IAAI;AAGzB,MAAI,IAAI,KAAK,MAAM,KAAK;GACtB,MAAM,UAAU,IAAI,IAAI,KAAK;AAC7B,UAAOC,+BAAU,KAAK,QAAQ;;;;;;;;;;;;;ACpGpC,MAAa,wCAA4B;CACvC,MAAM;CACN,aAAa,CAAC,OAAO;CACrB,UAAU,CAACC,4BAAc,oBAAoB;CAC9C,CAAC"}