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,10 +1,6 @@
1
- import { $env, $hook, $inject, $module, Alepha, AlephaError, Descriptor, KIND, createDescriptor, t } from "alepha";
2
- import { $permission, $realm, $role, AlephaSecurity, JwtProvider, SecurityProvider, userAccountInfoSchema } from "alepha/security";
3
- import { $action, $route, AlephaServer, ForbiddenError, HttpClient, HttpError, ServerReply, ServerRouterProvider, ServerTimingProvider, UnauthorizedError, routeMethods } from "alepha/server";
4
- import { randomUUID, timingSafeEqual } from "node:crypto";
5
- import { $logger } from "alepha/logger";
6
- import { $retry } from "alepha/retry";
7
- import { ReadableStream } from "node:stream/web";
1
+ import { $module, t } from "alepha";
2
+ import { userAccountInfoSchema } from "alepha/security";
3
+ import { apiLinksResponseSchema } from "alepha/server/links";
8
4
 
9
5
  //#region src/server-auth/constants/routes.ts
10
6
  const alephaServerAuthRoutes = {
@@ -27,980 +23,6 @@ const authenticationProviderSchema = t.object({
27
23
  ], { description: "Type of the authentication provider." })
28
24
  }, { title: "AuthenticationProvider" });
29
25
 
30
- //#endregion
31
- //#region src/server-security/providers/ServerBasicAuthProvider.ts
32
- var ServerBasicAuthProvider = class {
33
- alepha = $inject(Alepha);
34
- log = $logger();
35
- routerProvider = $inject(ServerRouterProvider);
36
- realm = "Secure Area";
37
- /**
38
- * Registered basic auth descriptors with their configurations
39
- */
40
- registeredAuths = [];
41
- /**
42
- * Register a basic auth configuration (called by descriptors)
43
- */
44
- registerAuth(config) {
45
- this.registeredAuths.push(config);
46
- }
47
- onStart = $hook({
48
- on: "start",
49
- handler: async () => {
50
- for (const auth of this.registeredAuths) if (auth.paths) for (const pattern of auth.paths) {
51
- const matchedRoutes = this.routerProvider.getRoutes(pattern);
52
- for (const route of matchedRoutes) route.secure = { basic: {
53
- username: auth.username,
54
- password: auth.password
55
- } };
56
- }
57
- if (this.registeredAuths.length > 0) this.log.info(`Initialized with ${this.registeredAuths.length} registered basic-auth configurations.`);
58
- }
59
- });
60
- /**
61
- * Hook into server:onRequest to check basic auth
62
- */
63
- onRequest = $hook({
64
- on: "server:onRequest",
65
- handler: async ({ route, request }) => {
66
- const routeAuth = route.secure;
67
- if (typeof routeAuth === "object" && "basic" in routeAuth && routeAuth.basic) this.checkAuth(request, routeAuth.basic);
68
- }
69
- });
70
- /**
71
- * Hook into action:onRequest to check basic auth for actions
72
- */
73
- onActionRequest = $hook({
74
- on: "action:onRequest",
75
- handler: async ({ action, request }) => {
76
- const routeAuth = action.route.secure;
77
- if (isBasicAuth(routeAuth)) this.checkAuth(request, routeAuth.basic);
78
- }
79
- });
80
- /**
81
- * Check basic authentication
82
- */
83
- checkAuth(request, options) {
84
- const authHeader = request.headers?.authorization;
85
- if (!authHeader || !authHeader.startsWith("Basic ")) {
86
- this.sendAuthRequired(request);
87
- throw new HttpError({
88
- status: 401,
89
- message: "Authentication required"
90
- });
91
- }
92
- const base64Credentials = authHeader.slice(6);
93
- const credentials = Buffer.from(base64Credentials, "base64").toString("utf-8");
94
- const colonIndex = credentials.indexOf(":");
95
- const username = colonIndex !== -1 ? credentials.slice(0, colonIndex) : credentials;
96
- const password = colonIndex !== -1 ? credentials.slice(colonIndex + 1) : "";
97
- if (!this.timingSafeCredentialCheck(username, password, options.username, options.password)) {
98
- this.sendAuthRequired(request);
99
- this.log.warn(`Failed basic auth attempt for user`, { username });
100
- throw new HttpError({
101
- status: 401,
102
- message: "Invalid credentials"
103
- });
104
- }
105
- }
106
- /**
107
- * Performs a timing-safe comparison of credentials to prevent timing attacks.
108
- * Always compares both username and password to avoid leaking which one is wrong.
109
- */
110
- timingSafeCredentialCheck(inputUsername, inputPassword, expectedUsername, expectedPassword) {
111
- const inputUserBuf = Buffer.from(inputUsername, "utf-8");
112
- const expectedUserBuf = Buffer.from(expectedUsername, "utf-8");
113
- const inputPassBuf = Buffer.from(inputPassword, "utf-8");
114
- const expectedPassBuf = Buffer.from(expectedPassword, "utf-8");
115
- return (this.safeCompare(inputUserBuf, expectedUserBuf) & this.safeCompare(inputPassBuf, expectedPassBuf)) === 1;
116
- }
117
- /**
118
- * Compares two buffers in constant time, handling different lengths safely.
119
- * Returns 1 if equal, 0 if not equal.
120
- */
121
- safeCompare(input, expected) {
122
- if (input.length !== expected.length) {
123
- timingSafeEqual(input, input);
124
- return 0;
125
- }
126
- return timingSafeEqual(input, expected) ? 1 : 0;
127
- }
128
- /**
129
- * Send WWW-Authenticate header
130
- */
131
- sendAuthRequired(request) {
132
- request.reply.setHeader("WWW-Authenticate", `Basic realm="${this.realm}"`);
133
- }
134
- };
135
- const isBasicAuth = (value) => {
136
- return typeof value === "object" && !!value && "basic" in value && !!value.basic;
137
- };
138
-
139
- //#endregion
140
- //#region src/server-security/descriptors/$basicAuth.ts
141
- /**
142
- * Declares HTTP Basic Authentication for server routes.
143
- * This descriptor provides methods to protect routes with username/password authentication.
144
- */
145
- const $basicAuth = (options) => {
146
- return createDescriptor(BasicAuthDescriptor, options);
147
- };
148
- var BasicAuthDescriptor = class extends Descriptor {
149
- serverBasicAuthProvider = $inject(ServerBasicAuthProvider);
150
- get name() {
151
- return this.options.name ?? `${this.config.propertyKey}`;
152
- }
153
- onInit() {
154
- this.serverBasicAuthProvider.registerAuth(this.options);
155
- }
156
- /**
157
- * Checks basic auth for the given request using this descriptor's configuration.
158
- */
159
- check(request, options) {
160
- const mergedOptions = {
161
- ...this.options,
162
- ...options
163
- };
164
- this.serverBasicAuthProvider.checkAuth(request, mergedOptions);
165
- }
166
- };
167
- $basicAuth[KIND] = BasicAuthDescriptor;
168
-
169
- //#endregion
170
- //#region src/server-security/providers/ServerSecurityProvider.ts
171
- var ServerSecurityProvider = class {
172
- log = $logger();
173
- securityProvider = $inject(SecurityProvider);
174
- jwtProvider = $inject(JwtProvider);
175
- alepha = $inject(Alepha);
176
- onConfigure = $hook({
177
- on: "configure",
178
- handler: async () => {
179
- for (const action of this.alepha.descriptors($action)) {
180
- if (action.options.disabled || action.options.secure === false || this.securityProvider.getRealms().length === 0) continue;
181
- if (typeof action.options.secure !== "object") this.securityProvider.createPermission({
182
- name: action.name,
183
- group: action.group,
184
- method: action.route.method,
185
- path: action.route.path
186
- });
187
- }
188
- }
189
- });
190
- onActionRequest = $hook({
191
- on: "action:onRequest",
192
- handler: async ({ action, request, options }) => {
193
- if (action.options.secure === false && !options.user) {
194
- this.log.trace("Skipping security check for route");
195
- return;
196
- }
197
- if (isBasicAuth(action.route.secure)) return;
198
- const permission = this.securityProvider.getPermissions().find((it) => it.path === action.route.path && it.method === action.route.method);
199
- try {
200
- request.user = this.createUserFromLocalFunctionContext(options, permission);
201
- const route = action.route;
202
- if (typeof route.secure === "object") this.check(request.user, route.secure);
203
- this.alepha.state.set("alepha.server.request.user", this.alepha.codec.decode(userAccountInfoSchema, request.user));
204
- } catch (error) {
205
- if (action.options.secure || permission) throw error;
206
- this.log.trace("Skipping security check for action");
207
- }
208
- }
209
- });
210
- onRequest = $hook({
211
- on: "server:onRequest",
212
- priority: "last",
213
- handler: async ({ request, route }) => {
214
- if (route.secure === false) {
215
- this.log.trace("Skipping security check for route - explicitly disabled");
216
- return;
217
- }
218
- if (isBasicAuth(route.secure)) return;
219
- const permission = this.securityProvider.getPermissions().find((it) => it.path === route.path && it.method === route.method);
220
- if (!request.headers.authorization && !route.secure && !permission) {
221
- this.log.trace("Skipping security check for route - no authorization header and not secure");
222
- return;
223
- }
224
- try {
225
- request.user = await this.securityProvider.createUserFromToken(request.headers.authorization, { permission });
226
- if (typeof route.secure === "object") this.check(request.user, route.secure);
227
- this.alepha.state.set("alepha.server.request.user", this.alepha.codec.decode(userAccountInfoSchema, request.user));
228
- this.log.trace("User set from request token", {
229
- user: request.user,
230
- permission
231
- });
232
- } catch (error) {
233
- if (route.secure || permission) throw error;
234
- this.log.trace("Skipping security check for route - error occurred", error);
235
- }
236
- }
237
- });
238
- check(user, secure) {
239
- if (secure.realm) {
240
- if (user.realm !== secure.realm) throw new ForbiddenError(`User must belong to realm '${secure.realm}' to access this route`);
241
- }
242
- }
243
- /**
244
- * Get the user account token for a local action call.
245
- * There are three possible sources for the user:
246
- * - `options.user`: the user passed in the options
247
- * - `"system"`: the system user from the state (you MUST set state `server.security.system.user`)
248
- * - `"context"`: the user from the request context (you MUST be in an HTTP request context)
249
- *
250
- * Priority order: `options.user` > `"system"` > `"context"`.
251
- *
252
- * In testing environment, if no user is provided, a test user is created based on the SecurityProvider's roles.
253
- */
254
- createUserFromLocalFunctionContext(options, permission) {
255
- const fromOptions = typeof options.user === "object" ? options.user : void 0;
256
- const type = typeof options.user === "string" ? options.user : void 0;
257
- let user;
258
- const fromContext = this.alepha.context.get("request")?.user;
259
- const fromSystem = this.alepha.state.get("alepha.server.security.system.user");
260
- if (type === "system") user = fromSystem;
261
- else if (type === "context") user = fromContext;
262
- else user = fromOptions ?? fromContext ?? fromSystem;
263
- if (!user) {
264
- if (this.alepha.isTest() && !("user" in options)) return this.createTestUser();
265
- throw new UnauthorizedError("User is required for calling this action");
266
- }
267
- const roles = user.roles ?? (this.alepha.isTest() ? this.securityProvider.getRoles().map((role) => role.name) : []);
268
- let ownership;
269
- if (permission) {
270
- const result = this.securityProvider.checkPermission(permission, ...roles);
271
- if (!result.isAuthorized) throw new ForbiddenError(`Permission '${this.securityProvider.permissionToString(permission)}' is required for this route`);
272
- ownership = result.ownership;
273
- }
274
- return {
275
- ...user,
276
- ownership
277
- };
278
- }
279
- createTestUser() {
280
- return {
281
- id: randomUUID(),
282
- name: "Test",
283
- roles: this.securityProvider.getRoles().map((role) => role.name)
284
- };
285
- }
286
- onClientRequest = $hook({
287
- on: "client:onRequest",
288
- handler: async ({ request, options }) => {
289
- if (!this.alepha.isTest()) return;
290
- if ("user" in options && options.user === void 0) return;
291
- request.headers = new Headers(request.headers);
292
- if (!request.headers.has("authorization")) {
293
- const test = this.createTestUser();
294
- const user = typeof options?.user === "object" ? options.user : void 0;
295
- const sub = user?.id ?? test.id;
296
- const roles = user?.roles ?? test.roles;
297
- const token = await this.jwtProvider.create({
298
- sub,
299
- roles
300
- }, user?.realm ?? this.securityProvider.getRealms()[0]?.name);
301
- request.headers.set("authorization", `Bearer ${token}`);
302
- }
303
- }
304
- });
305
- };
306
-
307
- //#endregion
308
- //#region src/server-security/index.ts
309
- /**
310
- * Plugin for Alepha Server that provides security features. Based on the Alepha Security module.
311
- *
312
- * By default, all $action will be guarded by a permission check.
313
- *
314
- * @see {@link ServerSecurityProvider}
315
- * @module alepha.server.security
316
- */
317
- const AlephaServerSecurity = $module({
318
- name: "alepha.server.security",
319
- descriptors: [
320
- $realm,
321
- $role,
322
- $permission,
323
- $basicAuth
324
- ],
325
- services: [
326
- AlephaServer,
327
- AlephaSecurity,
328
- ServerSecurityProvider,
329
- ServerBasicAuthProvider
330
- ]
331
- });
332
-
333
- //#endregion
334
- //#region src/server-links/schemas/apiLinksResponseSchema.ts
335
- const apiLinkSchema = t.object({
336
- name: t.text({ description: "Name of the API link, used for identification." }),
337
- group: t.optional(t.text({ description: "Group to which the API link belongs, used for categorization." })),
338
- path: t.text({ description: "Pathname used to access the API link." }),
339
- method: t.optional(t.text({ description: "HTTP method used for the API link, e.g., GET, POST, etc. If not specified, defaults to GET." })),
340
- requestBodyType: t.optional(t.text({ description: "Type of the request body for the API link. Default is application/json for POST/PUT/PATCH, null for others." })),
341
- service: t.optional(t.text({ description: "Service name associated with the API link, used for service discovery." }))
342
- });
343
- const apiLinksResponseSchema = t.object({
344
- prefix: t.optional(t.text()),
345
- links: t.array(apiLinkSchema)
346
- });
347
-
348
- //#endregion
349
- //#region src/server-links/providers/LinkProvider.ts
350
- /**
351
- * Browser, SSR friendly, service to handle links.
352
- */
353
- var LinkProvider = class LinkProvider {
354
- static path = {
355
- apiLinks: "/api/_links",
356
- apiSchema: "/api/_links/:name/schema"
357
- };
358
- log = $logger();
359
- alepha = $inject(Alepha);
360
- httpClient = $inject(HttpClient);
361
- serverLinks = [];
362
- /**
363
- * Get applicative links registered on the server.
364
- * This does not include lazy-loaded remote links.
365
- */
366
- getServerLinks() {
367
- if (this.alepha.isBrowser()) {
368
- this.log.warn("Getting server links in the browser is not supported. Use `fetchLinks` to get links from the server.");
369
- return [];
370
- }
371
- return this.serverLinks;
372
- }
373
- /**
374
- * Register a new link for the application.
375
- */
376
- registerLink(link) {
377
- if (this.alepha.isBrowser()) {
378
- this.log.warn("Registering links in the browser is not supported. Use `fetchLinks` to get links from the server.");
379
- return;
380
- }
381
- if (!link.handler && !link.host) throw new AlephaError("Can't create link - 'handler' or 'host' is required");
382
- if (this.serverLinks.some((l) => l.name === link.name)) this.serverLinks = this.serverLinks.filter((l) => l.name !== link.name);
383
- this.serverLinks.push(link);
384
- }
385
- get links() {
386
- const apiLinks = this.alepha.state.get("alepha.server.request.apiLinks")?.links;
387
- if (apiLinks) {
388
- if (this.alepha.isBrowser()) return apiLinks;
389
- const links = [];
390
- for (const link of apiLinks) {
391
- const originalLink = this.serverLinks.find((l) => l.name === link.name);
392
- if (originalLink) links.push(originalLink);
393
- }
394
- return links;
395
- }
396
- return this.serverLinks ?? [];
397
- }
398
- /**
399
- * Force browser to refresh links from the server.
400
- */
401
- async fetchLinks() {
402
- const { data } = await this.httpClient.fetch(`${LinkProvider.path.apiLinks}`, {
403
- method: "GET",
404
- schema: { response: apiLinksResponseSchema }
405
- });
406
- this.alepha.state.set("alepha.server.request.apiLinks", data);
407
- return data.links;
408
- }
409
- /**
410
- * Create a virtual client that can be used to call actions.
411
- *
412
- * Use js Proxy under the hood.
413
- */
414
- client(scope = {}) {
415
- return new Proxy({}, { get: (_, prop) => {
416
- if (typeof prop !== "string") return;
417
- return this.createVirtualAction(prop, scope);
418
- } });
419
- }
420
- /**
421
- * Check if a link with the given name exists.
422
- * @param name
423
- */
424
- can(name) {
425
- return this.links.some((link) => link.name === name);
426
- }
427
- /**
428
- * Resolve a link by its name and call it.
429
- * - If link is local, it will call the local handler.
430
- * - If link is remote, it will make a fetch request to the remote server.
431
- */
432
- async follow(name, config = {}, options = {}) {
433
- this.log.trace("Following link", {
434
- name,
435
- config,
436
- options
437
- });
438
- const link = await this.getLinkByName(name, options);
439
- if (link.handler && !options.request) {
440
- this.log.trace("Local link found", { name });
441
- return link.handler({
442
- method: link.method,
443
- url: new URL(`http://localhost${link.path}`),
444
- query: config.query ?? {},
445
- body: config.body ?? {},
446
- params: config.params ?? {},
447
- headers: config.headers ?? {},
448
- metadata: {},
449
- reply: new ServerReply()
450
- }, options);
451
- }
452
- this.log.trace("Remote link found", {
453
- name,
454
- host: link.host,
455
- service: link.service
456
- });
457
- return this.followRemote(link, config, options).then((response) => response.data);
458
- }
459
- createVirtualAction(name, scope = {}) {
460
- const $ = async (config = {}, options = {}) => {
461
- return this.follow(name, config, {
462
- ...scope,
463
- ...options
464
- });
465
- };
466
- Object.defineProperty($, "name", {
467
- value: name,
468
- writable: false
469
- });
470
- $.run = async (config = {}, options = {}) => {
471
- return this.follow(name, config, {
472
- ...scope,
473
- ...options
474
- });
475
- };
476
- $.fetch = async (config = {}, options = {}) => {
477
- const link = await this.getLinkByName(name, scope);
478
- return this.followRemote(link, config, options);
479
- };
480
- $.can = () => {
481
- return this.can(name);
482
- };
483
- return $;
484
- }
485
- async followRemote(link, config = {}, options = {}) {
486
- options.request ??= {};
487
- options.request.headers = new Headers(options.request.headers);
488
- const als = this.alepha.context.get("request");
489
- if (als?.headers.authorization) options.request.headers.set("authorization", als.headers.authorization);
490
- const context = this.alepha.context.get("context");
491
- if (typeof context === "string") options.request.headers.set("x-request-id", context);
492
- const action = {
493
- ...link,
494
- schema: {
495
- body: t.any(),
496
- response: t.any()
497
- }
498
- };
499
- if (!link.host && link.service) action.path = `/${link.service}${action.path}`;
500
- action.path = `${action.prefix ?? "/api"}${action.path}`;
501
- action.prefix = void 0;
502
- return this.httpClient.fetchAction({
503
- host: link.host,
504
- config,
505
- options,
506
- action
507
- });
508
- }
509
- async getLinkByName(name, options = {}) {
510
- if (this.alepha.isBrowser() && !this.alepha.state.get("alepha.server.request.apiLinks")) await this.fetchLinks();
511
- const link = this.links.find((a) => a.name === name && (!options.group || a.group === options.group) && (!options.service || options.service === a.service));
512
- if (!link) {
513
- const error = new UnauthorizedError(`Action ${name} not found.`);
514
- await this.alepha.events.emit("client:onError", {
515
- route: link,
516
- error
517
- });
518
- throw error;
519
- }
520
- if (options.hostname) return {
521
- ...link,
522
- host: options.hostname
523
- };
524
- return link;
525
- }
526
- };
527
-
528
- //#endregion
529
- //#region src/server-links/descriptors/$client.ts
530
- /**
531
- * Create a new client.
532
- */
533
- const $client = (scope) => {
534
- return $inject(LinkProvider).client(scope);
535
- };
536
- $client[KIND] = "$client";
537
-
538
- //#endregion
539
- //#region src/server-links/descriptors/$remote.ts
540
- /**
541
- * $remote is a descriptor that allows you to define remote service access.
542
- *
543
- * Use it only when you have 2 or more services that need to communicate with each other.
544
- *
545
- * All remote services can be exposed as actions, ... or not.
546
- *
547
- * You can add a service account if you want to use a security layer.
548
- */
549
- const $remote = (options) => {
550
- return createDescriptor(RemoteDescriptor, options);
551
- };
552
- var RemoteDescriptor = class extends Descriptor {
553
- get name() {
554
- return this.options.name ?? this.config.propertyKey;
555
- }
556
- };
557
- $remote[KIND] = RemoteDescriptor;
558
-
559
- //#endregion
560
- //#region src/server-proxy/descriptors/$proxy.ts
561
- /**
562
- * Creates a proxy descriptor to forward requests to another server.
563
- *
564
- * This descriptor enables you to create reverse proxy functionality, allowing your Alepha server
565
- * to forward requests to other services while maintaining a unified API surface. It's particularly
566
- * useful for microservice architectures, API gateways, or when you need to aggregate multiple
567
- * services behind a single endpoint.
568
- *
569
- * **Key Features**
570
- *
571
- * - **Path-based routing**: Match specific paths or patterns to proxy
572
- * - **Dynamic targets**: Support both static and dynamic target resolution
573
- * - **Request/Response hooks**: Modify requests before forwarding and responses after receiving
574
- * - **URL rewriting**: Transform URLs before forwarding to the target
575
- * - **Conditional proxying**: Enable/disable proxies based on environment or conditions
576
- *
577
- * @example
578
- * **Basic proxy setup:**
579
- * ```ts
580
- * import { $proxy } from "alepha/server/proxy";
581
- *
582
- * class ApiGateway {
583
- * // Forward all /api/* requests to external service
584
- * api = $proxy({
585
- * path: "/api/*",
586
- * target: "https://api.example.com"
587
- * });
588
- * }
589
- * ```
590
- *
591
- * @example
592
- * **Dynamic target with environment-based routing:**
593
- * ```ts
594
- * class ApiGateway {
595
- * // Route to different environments based on configuration
596
- * api = $proxy({
597
- * path: "/api/*",
598
- * target: () => process.env.NODE_ENV === "production"
599
- * ? "https://api.prod.example.com"
600
- * : "https://api.dev.example.com"
601
- * });
602
- * }
603
- * ```
604
- *
605
- * @example
606
- * **Advanced proxy with request/response modification:**
607
- * ```ts
608
- * class SecureProxy {
609
- * secure = $proxy({
610
- * path: "/secure/*",
611
- * target: "https://secure-api.example.com",
612
- * beforeRequest: async (request, proxyRequest) => {
613
- * // Add authentication headers
614
- * proxyRequest.headers = {
615
- * ...proxyRequest.headers,
616
- * 'Authorization': `Bearer ${await getServiceToken()}`,
617
- * 'X-Forwarded-For': request.headers['x-forwarded-for'] || request.ip
618
- * };
619
- * },
620
- * afterResponse: async (request, proxyResponse) => {
621
- * // Log response for monitoring
622
- * console.log(`Proxied ${request.url} -> ${proxyResponse.status}`);
623
- * },
624
- * rewrite: (url) => {
625
- * // Remove /secure prefix when forwarding
626
- * url.pathname = url.pathname.replace('/secure', '');
627
- * }
628
- * });
629
- * }
630
- * ```
631
- *
632
- * @example
633
- * **Conditional proxy based on feature flags:**
634
- * ```ts
635
- * class FeatureProxy {
636
- * newApi = $proxy({
637
- * path: "/v2/*",
638
- * target: "https://new-api.example.com",
639
- * disabled: !process.env.ENABLE_V2_API // Disable if feature flag is off
640
- * });
641
- * }
642
- * ```
643
- */
644
- const $proxy = (options) => {
645
- return createDescriptor(ProxyDescriptor, options);
646
- };
647
- var ProxyDescriptor = class extends Descriptor {};
648
- $proxy[KIND] = ProxyDescriptor;
649
-
650
- //#endregion
651
- //#region src/server-proxy/providers/ServerProxyProvider.ts
652
- var ServerProxyProvider = class {
653
- log = $logger();
654
- routerProvider = $inject(ServerRouterProvider);
655
- alepha = $inject(Alepha);
656
- configure = $hook({
657
- on: "configure",
658
- handler: () => {
659
- for (const proxy of this.alepha.descriptors($proxy)) this.createProxy(proxy.options);
660
- }
661
- });
662
- createProxy(options) {
663
- if (options.disabled) return;
664
- const path = options.path;
665
- const target = typeof options.target === "function" ? options.target() : options.target;
666
- if (!path.endsWith("/*")) throw new AlephaError("Proxy path should end with '/*'");
667
- const handler = this.createProxyHandler(target, options);
668
- for (const method of routeMethods) this.routerProvider.createRoute({
669
- method,
670
- path,
671
- handler
672
- });
673
- this.log.info("Proxying", {
674
- path,
675
- target
676
- });
677
- }
678
- createProxyHandler(target, options) {
679
- return async (request) => {
680
- const url = new URL(target + request.url.pathname);
681
- if (request.url.search) url.search = request.url.search;
682
- options.rewrite?.(url);
683
- const requestInit = {
684
- url: url.toString(),
685
- method: request.method,
686
- headers: {
687
- ...request.headers,
688
- "accept-encoding": "identity"
689
- },
690
- body: this.getRawRequestBody(request)
691
- };
692
- if (requestInit.body) requestInit.duplex = "half";
693
- if (options.beforeRequest) await options.beforeRequest(request, requestInit);
694
- this.log.debug("Proxying request", {
695
- url: url.toString(),
696
- method: request.method,
697
- headers: request.headers
698
- });
699
- const response = await fetch(requestInit.url, requestInit);
700
- request.reply.status = response.status;
701
- request.reply.headers = Object.fromEntries(response.headers.entries());
702
- request.reply.body = response.body;
703
- this.log.debug("Received response", {
704
- status: request.reply.status,
705
- headers: request.reply.headers
706
- });
707
- if (options.afterResponse) await options.afterResponse(request, response);
708
- };
709
- }
710
- getRawRequestBody(req) {
711
- const { method } = req;
712
- if (method === "GET" || method === "HEAD" || method === "OPTIONS") return;
713
- if (req.raw?.web?.req) return req.raw.web.req.body;
714
- if (req.raw?.node?.req) {
715
- const nodeReq = req.raw.node.req;
716
- return ReadableStream.from(nodeReq);
717
- }
718
- }
719
- };
720
-
721
- //#endregion
722
- //#region src/server-proxy/index.ts
723
- /**
724
- * Plugin for Alepha that provides a proxy server functionality.
725
- *
726
- * @see {@link $proxy}
727
- * @module alepha.server.proxy
728
- */
729
- const AlephaServerProxy = $module({
730
- name: "alepha.server.proxy",
731
- descriptors: [$proxy],
732
- services: [AlephaServer, ServerProxyProvider]
733
- });
734
-
735
- //#endregion
736
- //#region src/server-links/providers/RemoteDescriptorProvider.ts
737
- const envSchema$1 = t.object({ SERVER_API_PREFIX: t.text({
738
- description: "Prefix for all API routes (e.g. $action).",
739
- default: "/api"
740
- }) });
741
- var RemoteDescriptorProvider = class {
742
- env = $env(envSchema$1);
743
- alepha = $inject(Alepha);
744
- proxyProvider = $inject(ServerProxyProvider);
745
- linkProvider = $inject(LinkProvider);
746
- remotes = [];
747
- log = $logger();
748
- getRemotes() {
749
- return this.remotes;
750
- }
751
- configure = $hook({
752
- on: "configure",
753
- handler: async () => {
754
- const remotes = this.alepha.descriptors($remote);
755
- for (const remote of remotes) await this.registerRemote(remote);
756
- }
757
- });
758
- start = $hook({
759
- on: "start",
760
- handler: async () => {
761
- for (const remote of this.remotes) {
762
- const token = typeof remote.serviceAccount?.token === "function" ? await remote.serviceAccount.token() : void 0;
763
- if (!remote.internal) continue;
764
- const { links } = await remote.links({ authorization: token });
765
- for (const link of links) {
766
- let path = link.path.replace(remote.prefix, "");
767
- if (link.service) path = `/${link.service}${path}`;
768
- this.linkProvider.registerLink({
769
- ...link,
770
- prefix: remote.prefix,
771
- path,
772
- method: link.method ?? "GET",
773
- host: remote.url,
774
- service: remote.name
775
- });
776
- }
777
- this.log.info(`Remote '${remote.name}' OK`, {
778
- links: remote.links.length,
779
- prefix: remote.prefix
780
- });
781
- }
782
- }
783
- });
784
- async registerRemote(value) {
785
- const options = value.options;
786
- const url = typeof options.url === "string" ? options.url : options.url();
787
- const linkPath = LinkProvider.path.apiLinks;
788
- const name = value.name;
789
- const proxy = typeof options.proxy === "object" ? options.proxy : {};
790
- const remote = {
791
- url,
792
- name,
793
- prefix: "/api",
794
- serviceAccount: options.serviceAccount,
795
- proxy: !!options.proxy,
796
- internal: !proxy.noInternal,
797
- schema: async (opts) => {
798
- const { authorization, name: name$1 } = opts;
799
- return await fetch(`${url}${linkPath}/${name$1}/schema`, { headers: new Headers(authorization ? { authorization } : {}) }).then((it) => it.json());
800
- },
801
- links: async (opts) => {
802
- const { authorization } = opts;
803
- const remoteApi = await this.fetchLinks.run({
804
- service: name,
805
- url: `${url}${linkPath}`,
806
- authorization
807
- });
808
- if (remoteApi.prefix != null) remote.prefix = remoteApi.prefix;
809
- return remoteApi;
810
- }
811
- };
812
- this.remotes.push(remote);
813
- if (options.proxy) this.proxyProvider.createProxy({
814
- path: `${this.env.SERVER_API_PREFIX}/${name}/*`,
815
- target: url,
816
- rewrite: (url$1) => {
817
- url$1.pathname = url$1.pathname.replace(`${this.env.SERVER_API_PREFIX}/${name}`, remote.prefix);
818
- },
819
- ...proxy
820
- });
821
- }
822
- fetchLinks = $retry({
823
- max: 10,
824
- backoff: { initial: 1e3 },
825
- onError: (_, attempt, { service, url }) => {
826
- this.log.warn(`Failed to fetch links, retry (${attempt})...`, {
827
- service,
828
- url
829
- });
830
- },
831
- handler: async (opts) => {
832
- const { url, authorization } = opts;
833
- const response = await fetch(url, { headers: new Headers(authorization ? { authorization } : {}) });
834
- if (!response.ok) throw new Error(`Failed to fetch links from ${url}`);
835
- return this.alepha.codec.decode(apiLinksResponseSchema, await response.json());
836
- }
837
- });
838
- };
839
-
840
- //#endregion
841
- //#region src/server-links/providers/ServerLinksProvider.ts
842
- const envSchema = t.object({ SERVER_API_PREFIX: t.text({
843
- description: "Prefix for all API routes (e.g. $action).",
844
- default: "/api"
845
- }) });
846
- var ServerLinksProvider = class {
847
- env = $env(envSchema);
848
- alepha = $inject(Alepha);
849
- linkProvider = $inject(LinkProvider);
850
- remoteProvider = $inject(RemoteDescriptorProvider);
851
- serverTimingProvider = $inject(ServerTimingProvider);
852
- get prefix() {
853
- return this.env.SERVER_API_PREFIX;
854
- }
855
- onRoute = $hook({
856
- on: "configure",
857
- handler: () => {
858
- for (const action of this.alepha.descriptors($action)) this.linkProvider.registerLink({
859
- name: action.name,
860
- group: action.group,
861
- schema: action.options.schema,
862
- requestBodyType: action.getBodyContentType(),
863
- secured: action.options.secure ?? true,
864
- method: action.method === "GET" ? void 0 : action.method,
865
- prefix: action.prefix,
866
- path: action.path,
867
- handler: (config, options = {}) => action.run(config, options)
868
- });
869
- }
870
- });
871
- /**
872
- * First API - Get all API links for the user.
873
- *
874
- * This is based on the user's permissions.
875
- */
876
- links = $route({
877
- path: LinkProvider.path.apiLinks,
878
- schema: { response: apiLinksResponseSchema },
879
- handler: ({ user, headers }) => {
880
- return this.getUserApiLinks({
881
- user,
882
- authorization: headers.authorization
883
- });
884
- }
885
- });
886
- /**
887
- * Second API - Get schema for a specific API link.
888
- *
889
- * Note: Body/Response schema are not included in `links` API because it's TOO BIG.
890
- * I mean for 150+ links, you got 50ms of serialization time.
891
- */
892
- schema = $route({
893
- path: LinkProvider.path.apiSchema,
894
- schema: {
895
- params: t.object({ name: t.text() }),
896
- response: t.json()
897
- },
898
- handler: ({ params, user, headers }) => {
899
- return this.getSchemaByName(params.name, {
900
- user,
901
- authorization: headers.authorization
902
- });
903
- }
904
- });
905
- async getSchemaByName(name, options = {}) {
906
- const authorization = options.authorization;
907
- const api = await this.getUserApiLinks({
908
- user: options.user,
909
- authorization
910
- });
911
- for (const link of api.links) if (link.name === name) {
912
- if (link.service) return this.remoteProvider.getRemotes().find((it) => it.name === link.service)?.schema({
913
- name,
914
- authorization
915
- });
916
- return this.linkProvider.getServerLinks().find((it) => it.name === name)?.schema ?? {};
917
- }
918
- return {};
919
- }
920
- /**
921
- * Retrieves API links for the user based on their permissions.
922
- * Will check on local links and remote links.
923
- */
924
- async getUserApiLinks(options) {
925
- const { user } = options;
926
- let permissions;
927
- let permissionMap;
928
- const hasSecurity = this.alepha.has(SecurityProvider);
929
- if (hasSecurity && user) {
930
- permissions = this.alepha.inject(SecurityProvider).getPermissions(user);
931
- permissionMap = new Map(permissions.map((it) => [`${it.group}:${it.name}`, it]));
932
- }
933
- const userLinks = [];
934
- for (const permission of permissions ?? []) if (!permission.path && !permission.method && permission.name && permission.group) userLinks.push({
935
- path: "",
936
- name: permission.name,
937
- group: permission.group
938
- });
939
- for (const link of this.linkProvider.getServerLinks()) {
940
- if (link.host) continue;
941
- if (hasSecurity && link.secured) {
942
- if (!user) continue;
943
- if (typeof link.secured === "object" && link.secured.realm) {
944
- if (user.realm !== link.secured.realm) continue;
945
- } else if (permissionMap) {
946
- if (!permissionMap.has(`${link.group}:${link.name}`)) continue;
947
- }
948
- }
949
- userLinks.push({
950
- name: link.name,
951
- group: link.group,
952
- requestBodyType: link.requestBodyType,
953
- method: link.method,
954
- path: link.path
955
- });
956
- }
957
- this.serverTimingProvider.beginTiming("fetchRemoteLinks");
958
- const promises = this.remoteProvider.getRemotes().filter((it) => it.proxy).map(async (remote) => {
959
- const { links, prefix } = await remote.links(options);
960
- return links.map((link) => {
961
- let path = link.path.replace(prefix ?? "/api", "");
962
- if (link.service) path = `/${link.service}${path}`;
963
- return {
964
- ...link,
965
- path,
966
- proxy: true,
967
- service: remote.name
968
- };
969
- });
970
- });
971
- userLinks.push(...(await Promise.all(promises)).flat());
972
- this.serverTimingProvider.endTiming("fetchRemoteLinks");
973
- return {
974
- prefix: this.env.SERVER_API_PREFIX,
975
- links: userLinks
976
- };
977
- }
978
- };
979
-
980
- //#endregion
981
- //#region src/server-links/index.ts
982
- /**
983
- * Provides server-side link management and remote capabilities for client-server interactions.
984
- *
985
- * The server-links module enables declarative link definitions using `$remote` and `$client` descriptors,
986
- * facilitating seamless API endpoint management and client-server communication. It integrates with server
987
- * security features to ensure safe and controlled access to resources.
988
- *
989
- * @see {@link $remote}
990
- * @see {@link $client}
991
- * @module alepha.server.links
992
- */
993
- const AlephaServerLinks = $module({
994
- name: "alepha.server.links",
995
- descriptors: [$remote, $client],
996
- services: [
997
- AlephaServer,
998
- ServerLinksProvider,
999
- RemoteDescriptorProvider,
1000
- LinkProvider
1001
- ]
1002
- });
1003
-
1004
26
  //#endregion
1005
27
  //#region src/server-auth/schemas/tokensSchema.ts
1006
28
  const tokensSchema = t.object({
@@ -1033,7 +55,7 @@ const userinfoResponseSchema = t.object({
1033
55
  //#region src/server-auth/index.browser.ts
1034
56
  const AlephaServerAuth = $module({
1035
57
  name: "alepha.server.auth",
1036
- descriptors: [],
58
+ primitives: [],
1037
59
  services: []
1038
60
  });
1039
61