alepha 0.22.0 → 0.24.0

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 (869) hide show
  1. package/assets/swagger-ui/swagger-ui-bundle.js +1 -1
  2. package/assets/swagger-ui/swagger-ui-standalone-preset.js +1 -1
  3. package/dist/api/audits/index.browser.js +49 -52
  4. package/dist/api/audits/index.browser.js.map +1 -1
  5. package/dist/api/audits/index.d.ts +629 -565
  6. package/dist/api/audits/index.d.ts.map +1 -1
  7. package/dist/api/audits/index.js +206 -98
  8. package/dist/api/audits/index.js.map +1 -1
  9. package/dist/api/files/index.browser.js +44 -44
  10. package/dist/api/files/index.browser.js.map +1 -1
  11. package/dist/api/files/index.d.ts +292 -293
  12. package/dist/api/files/index.d.ts.map +1 -1
  13. package/dist/api/files/index.js +61 -64
  14. package/dist/api/files/index.js.map +1 -1
  15. package/dist/api/jobs/index.browser.js +61 -59
  16. package/dist/api/jobs/index.browser.js.map +1 -1
  17. package/dist/api/jobs/index.d.ts +546 -347
  18. package/dist/api/jobs/index.d.ts.map +1 -1
  19. package/dist/api/jobs/index.js +165 -86
  20. package/dist/api/jobs/index.js.map +1 -1
  21. package/dist/api/keys/index.d.ts +242 -230
  22. package/dist/api/keys/index.d.ts.map +1 -1
  23. package/dist/api/keys/index.js +63 -66
  24. package/dist/api/keys/index.js.map +1 -1
  25. package/dist/api/notifications/index.browser.js +40 -38
  26. package/dist/api/notifications/index.browser.js.map +1 -1
  27. package/dist/api/notifications/index.d.ts +339 -209
  28. package/dist/api/notifications/index.d.ts.map +1 -1
  29. package/dist/api/notifications/index.js +108 -60
  30. package/dist/api/notifications/index.js.map +1 -1
  31. package/dist/api/oauth/index.d.ts +190 -78
  32. package/dist/api/oauth/index.d.ts.map +1 -1
  33. package/dist/api/oauth/index.js +290 -68
  34. package/dist/api/oauth/index.js.map +1 -1
  35. package/dist/api/organizations/index.browser.js +14 -14
  36. package/dist/api/organizations/index.browser.js.map +1 -1
  37. package/dist/api/organizations/index.d.ts +158 -134
  38. package/dist/api/organizations/index.d.ts.map +1 -1
  39. package/dist/api/organizations/index.js +18 -18
  40. package/dist/api/organizations/index.js.map +1 -1
  41. package/dist/api/parameters/index.browser.js +74 -53
  42. package/dist/api/parameters/index.browser.js.map +1 -1
  43. package/dist/api/parameters/index.d.ts +607 -513
  44. package/dist/api/parameters/index.d.ts.map +1 -1
  45. package/dist/api/parameters/index.js +205 -127
  46. package/dist/api/parameters/index.js.map +1 -1
  47. package/dist/api/payments/index.d.ts +652 -449
  48. package/dist/api/payments/index.d.ts.map +1 -1
  49. package/dist/api/payments/index.js +159 -93
  50. package/dist/api/payments/index.js.map +1 -1
  51. package/dist/api/subscriptions/index.d.ts +1032 -762
  52. package/dist/api/subscriptions/index.d.ts.map +1 -1
  53. package/dist/api/subscriptions/index.js +166 -185
  54. package/dist/api/subscriptions/index.js.map +1 -1
  55. package/dist/api/users/index.browser.js +48 -71
  56. package/dist/api/users/index.browser.js.map +1 -1
  57. package/dist/api/users/index.d.ts +1297 -1109
  58. package/dist/api/users/index.d.ts.map +1 -1
  59. package/dist/api/users/index.js +454 -369
  60. package/dist/api/users/index.js.map +1 -1
  61. package/dist/api/verifications/index.browser.js +17 -17
  62. package/dist/api/verifications/index.browser.js.map +1 -1
  63. package/dist/api/verifications/index.d.ts +169 -157
  64. package/dist/api/verifications/index.d.ts.map +1 -1
  65. package/dist/api/verifications/index.js +47 -95
  66. package/dist/api/verifications/index.js.map +1 -1
  67. package/dist/background/index.d.ts +0 -1
  68. package/dist/background/index.d.ts.map +1 -1
  69. package/dist/background/index.js.map +1 -1
  70. package/dist/background/index.workerd.js.map +1 -1
  71. package/dist/batch/index.d.ts +0 -1
  72. package/dist/batch/index.d.ts.map +1 -1
  73. package/dist/batch/index.js.map +1 -1
  74. package/dist/bin/index.js +1 -1
  75. package/dist/bin/index.js.map +1 -1
  76. package/dist/bucket/index.d.ts +27 -32
  77. package/dist/bucket/index.d.ts.map +1 -1
  78. package/dist/bucket/index.js +56 -26
  79. package/dist/bucket/index.js.map +1 -1
  80. package/dist/bucket/index.workerd.js +52 -24
  81. package/dist/bucket/index.workerd.js.map +1 -1
  82. package/dist/cache/core/index.d.ts +4 -6
  83. package/dist/cache/core/index.d.ts.map +1 -1
  84. package/dist/cache/core/index.js +4 -10
  85. package/dist/cache/core/index.js.map +1 -1
  86. package/dist/cache/core/index.workerd.js +4 -10
  87. package/dist/cache/core/index.workerd.js.map +1 -1
  88. package/dist/cache/database/index.d.ts +22 -23
  89. package/dist/cache/database/index.d.ts.map +1 -1
  90. package/dist/cache/database/index.js +11 -20
  91. package/dist/cache/database/index.js.map +1 -1
  92. package/dist/cache/redis/index.d.ts +3 -4
  93. package/dist/cache/redis/index.d.ts.map +1 -1
  94. package/dist/cache/redis/index.js +2 -2
  95. package/dist/cache/redis/index.js.map +1 -1
  96. package/dist/captcha/index.d.ts.map +1 -1
  97. package/dist/captcha/index.js +4 -4
  98. package/dist/captcha/index.js.map +1 -1
  99. package/dist/cli/config/index.d.ts +0 -1
  100. package/dist/cli/config/index.d.ts.map +1 -1
  101. package/dist/cli/core/index.d.ts +244 -475
  102. package/dist/cli/core/index.d.ts.map +1 -1
  103. package/dist/cli/core/index.js +308 -383
  104. package/dist/cli/core/index.js.map +1 -1
  105. package/dist/cli/devtools/index.d.ts +3 -9
  106. package/dist/cli/devtools/index.d.ts.map +1 -1
  107. package/dist/cli/devtools/index.js +3 -3
  108. package/dist/cli/devtools/index.js.map +1 -1
  109. package/dist/cli/i18n/index.d.ts +20 -39
  110. package/dist/cli/i18n/index.d.ts.map +1 -1
  111. package/dist/cli/i18n/index.js +51 -17
  112. package/dist/cli/i18n/index.js.map +1 -1
  113. package/dist/cli/platform/index.d.ts +89 -82
  114. package/dist/cli/platform/index.d.ts.map +1 -1
  115. package/dist/cli/platform/index.js +27 -33
  116. package/dist/cli/platform/index.js.map +1 -1
  117. package/dist/cli/platform-lib/index.d.ts +383 -410
  118. package/dist/cli/platform-lib/index.d.ts.map +1 -1
  119. package/dist/cli/platform-lib/index.js +300 -258
  120. package/dist/cli/platform-lib/index.js.map +1 -1
  121. package/dist/cli/vendor/index.d.ts +17 -41
  122. package/dist/cli/vendor/index.d.ts.map +1 -1
  123. package/dist/cli/vendor/index.js +10 -13
  124. package/dist/cli/vendor/index.js.map +1 -1
  125. package/dist/command/index.d.ts +82 -194
  126. package/dist/command/index.d.ts.map +1 -1
  127. package/dist/command/index.js +160 -563
  128. package/dist/command/index.js.map +1 -1
  129. package/dist/core/index.browser.js +845 -859
  130. package/dist/core/index.browser.js.map +1 -1
  131. package/dist/core/index.d.ts +787 -527
  132. package/dist/core/index.d.ts.map +1 -1
  133. package/dist/core/index.js +845 -859
  134. package/dist/core/index.js.map +1 -1
  135. package/dist/core/index.native.js +845 -859
  136. package/dist/core/index.native.js.map +1 -1
  137. package/dist/core/index.workerd.js +845 -859
  138. package/dist/core/index.workerd.js.map +1 -1
  139. package/dist/crypto/index.browser.js +1 -1
  140. package/dist/crypto/index.browser.js.map +1 -1
  141. package/dist/crypto/index.d.ts +3 -4
  142. package/dist/crypto/index.d.ts.map +1 -1
  143. package/dist/crypto/index.js +6 -3
  144. package/dist/crypto/index.js.map +1 -1
  145. package/dist/datetime/index.d.ts +12 -2
  146. package/dist/datetime/index.d.ts.map +1 -1
  147. package/dist/datetime/index.js +6 -1
  148. package/dist/datetime/index.js.map +1 -1
  149. package/dist/email/brevo/index.d.ts +0 -1
  150. package/dist/email/brevo/index.d.ts.map +1 -1
  151. package/dist/email/brevo/index.js +4 -4
  152. package/dist/email/brevo/index.js.map +1 -1
  153. package/dist/email/cloudflare/index.d.ts +0 -1
  154. package/dist/email/cloudflare/index.d.ts.map +1 -1
  155. package/dist/email/cloudflare/index.js +2 -2
  156. package/dist/email/cloudflare/index.js.map +1 -1
  157. package/dist/email/core/index.d.ts +15 -7
  158. package/dist/email/core/index.d.ts.map +1 -1
  159. package/dist/email/core/index.js +14 -5
  160. package/dist/email/core/index.js.map +1 -1
  161. package/dist/email/core/index.workerd.js +5 -1
  162. package/dist/email/core/index.workerd.js.map +1 -1
  163. package/dist/email/smtp/index.d.ts +8 -9
  164. package/dist/email/smtp/index.d.ts.map +1 -1
  165. package/dist/email/smtp/index.js +702 -479
  166. package/dist/email/smtp/index.js.map +1 -1
  167. package/dist/fake/index.d.ts +1580 -1238
  168. package/dist/fake/index.d.ts.map +1 -1
  169. package/dist/fake/index.js +11728 -32131
  170. package/dist/fake/index.js.map +1 -1
  171. package/dist/lock/core/index.d.ts +13 -9
  172. package/dist/lock/core/index.d.ts.map +1 -1
  173. package/dist/lock/core/index.js +5 -5
  174. package/dist/lock/core/index.js.map +1 -1
  175. package/dist/lock/redis/index.d.ts +0 -1
  176. package/dist/lock/redis/index.d.ts.map +1 -1
  177. package/dist/lock/redis/index.js.map +1 -1
  178. package/dist/logger/index.d.ts +81 -69
  179. package/dist/logger/index.d.ts.map +1 -1
  180. package/dist/logger/index.js +123 -56
  181. package/dist/logger/index.js.map +1 -1
  182. package/dist/mcp/index.d.ts +36 -90
  183. package/dist/mcp/index.d.ts.map +1 -1
  184. package/dist/mcp/index.js +65 -70
  185. package/dist/mcp/index.js.map +1 -1
  186. package/dist/orm/core/index.browser.js +54 -40
  187. package/dist/orm/core/index.browser.js.map +1 -1
  188. package/dist/orm/core/index.bun.js +140 -106
  189. package/dist/orm/core/index.bun.js.map +1 -1
  190. package/dist/orm/core/index.d.ts +145 -150
  191. package/dist/orm/core/index.d.ts.map +1 -1
  192. package/dist/orm/core/index.js +144 -109
  193. package/dist/orm/core/index.js.map +1 -1
  194. package/dist/orm/postgres/index.bun.js +64 -54
  195. package/dist/orm/postgres/index.bun.js.map +1 -1
  196. package/dist/orm/postgres/index.d.ts +36 -76
  197. package/dist/orm/postgres/index.d.ts.map +1 -1
  198. package/dist/orm/postgres/index.js +67 -57
  199. package/dist/orm/postgres/index.js.map +1 -1
  200. package/dist/queue/core/index.d.ts +62 -75
  201. package/dist/queue/core/index.d.ts.map +1 -1
  202. package/dist/queue/core/index.js +48 -71
  203. package/dist/queue/core/index.js.map +1 -1
  204. package/dist/queue/core/index.workerd.js +48 -71
  205. package/dist/queue/core/index.workerd.js.map +1 -1
  206. package/dist/queue/redis/index.d.ts +3 -4
  207. package/dist/queue/redis/index.d.ts.map +1 -1
  208. package/dist/queue/redis/index.js +2 -2
  209. package/dist/queue/redis/index.js.map +1 -1
  210. package/dist/react/auth/index.browser.js.map +1 -1
  211. package/dist/react/auth/index.d.ts +7 -4
  212. package/dist/react/auth/index.d.ts.map +1 -1
  213. package/dist/react/auth/index.js.map +1 -1
  214. package/dist/react/core/index.d.ts +87 -5
  215. package/dist/react/core/index.d.ts.map +1 -1
  216. package/dist/react/core/index.js +170 -23
  217. package/dist/react/core/index.js.map +1 -1
  218. package/dist/react/form/index.d.ts +4 -6
  219. package/dist/react/form/index.d.ts.map +1 -1
  220. package/dist/react/form/index.js +107 -71
  221. package/dist/react/form/index.js.map +1 -1
  222. package/dist/react/head/index.browser.js.map +1 -1
  223. package/dist/react/head/index.d.ts +0 -1
  224. package/dist/react/head/index.d.ts.map +1 -1
  225. package/dist/react/head/index.js.map +1 -1
  226. package/dist/react/i18n/index.d.ts +47 -5
  227. package/dist/react/i18n/index.d.ts.map +1 -1
  228. package/dist/react/i18n/index.js +116 -12
  229. package/dist/react/i18n/index.js.map +1 -1
  230. package/dist/react/intro/index.d.ts +1 -4
  231. package/dist/react/intro/index.d.ts.map +1 -1
  232. package/dist/react/intro/index.js.map +1 -1
  233. package/dist/react/router/index.browser.js +188 -29
  234. package/dist/react/router/index.browser.js.map +1 -1
  235. package/dist/react/router/index.d.ts +480 -372
  236. package/dist/react/router/index.d.ts.map +1 -1
  237. package/dist/react/router/index.js +261 -47
  238. package/dist/react/router/index.js.map +1 -1
  239. package/dist/react/sitemap/index.browser.js +35 -0
  240. package/dist/react/sitemap/index.browser.js.map +1 -0
  241. package/dist/react/sitemap/index.d.ts +91 -0
  242. package/dist/react/sitemap/index.d.ts.map +1 -0
  243. package/dist/react/sitemap/index.js +131 -0
  244. package/dist/react/sitemap/index.js.map +1 -0
  245. package/dist/react/testing/index.d.ts +4 -5
  246. package/dist/react/testing/index.d.ts.map +1 -1
  247. package/dist/react/testing/index.js +41 -15
  248. package/dist/react/testing/index.js.map +1 -1
  249. package/dist/react/testing/{chunk-BpyX8vjI.js → rolldown-runtime-Bl3dcgcQ.js} +1 -1
  250. package/dist/react/ui/index.d.ts +35 -34
  251. package/dist/react/ui/index.d.ts.map +1 -1
  252. package/dist/react/ui/index.js +12 -17
  253. package/dist/react/ui/index.js.map +1 -1
  254. package/dist/redis/index.bun.js +5 -5
  255. package/dist/redis/index.bun.js.map +1 -1
  256. package/dist/redis/index.d.ts +6 -7
  257. package/dist/redis/index.d.ts.map +1 -1
  258. package/dist/redis/index.js +6 -6
  259. package/dist/redis/index.js.map +1 -1
  260. package/dist/retry/index.d.ts +0 -1
  261. package/dist/retry/index.d.ts.map +1 -1
  262. package/dist/retry/index.js.map +1 -1
  263. package/dist/router/index.d.ts.map +1 -1
  264. package/dist/router/index.js.map +1 -1
  265. package/dist/scheduler/index.d.ts +4 -12
  266. package/dist/scheduler/index.d.ts.map +1 -1
  267. package/dist/scheduler/index.js +9 -4
  268. package/dist/scheduler/index.js.map +1 -1
  269. package/dist/scheduler/index.workerd.js +9 -4
  270. package/dist/scheduler/index.workerd.js.map +1 -1
  271. package/dist/security/index.browser.js +30 -28
  272. package/dist/security/index.browser.js.map +1 -1
  273. package/dist/security/index.d.ts +113 -44
  274. package/dist/security/index.d.ts.map +1 -1
  275. package/dist/security/index.js +452 -37
  276. package/dist/security/index.js.map +1 -1
  277. package/dist/server/auth/index.browser.js +19 -19
  278. package/dist/server/auth/index.browser.js.map +1 -1
  279. package/dist/server/auth/index.d.ts +215 -187
  280. package/dist/server/auth/index.d.ts.map +1 -1
  281. package/dist/server/auth/index.js +1145 -86
  282. package/dist/server/auth/index.js.map +1 -1
  283. package/dist/server/cookies/index.browser.js +103 -5
  284. package/dist/server/cookies/index.browser.js.map +1 -1
  285. package/dist/server/cookies/index.d.ts +86 -4
  286. package/dist/server/cookies/index.d.ts.map +1 -1
  287. package/dist/server/cookies/index.js +121 -8
  288. package/dist/server/cookies/index.js.map +1 -1
  289. package/dist/server/core/index.browser.js +22 -27
  290. package/dist/server/core/index.browser.js.map +1 -1
  291. package/dist/server/core/index.d.ts +134 -85
  292. package/dist/server/core/index.d.ts.map +1 -1
  293. package/dist/server/core/index.js +130 -118
  294. package/dist/server/core/index.js.map +1 -1
  295. package/dist/server/cors/index.d.ts +9 -10
  296. package/dist/server/cors/index.d.ts.map +1 -1
  297. package/dist/server/cors/index.js +14 -26
  298. package/dist/server/cors/index.js.map +1 -1
  299. package/dist/server/etag/index.d.ts +2 -3
  300. package/dist/server/etag/index.d.ts.map +1 -1
  301. package/dist/server/etag/index.js.map +1 -1
  302. package/dist/server/health/index.d.ts +18 -19
  303. package/dist/server/health/index.d.ts.map +1 -1
  304. package/dist/server/health/index.js +6 -6
  305. package/dist/server/health/index.js.map +1 -1
  306. package/dist/server/links/index.browser.js +15 -18
  307. package/dist/server/links/index.browser.js.map +1 -1
  308. package/dist/server/links/index.d.ts +66 -67
  309. package/dist/server/links/index.d.ts.map +1 -1
  310. package/dist/server/links/index.js +29 -32
  311. package/dist/server/links/index.js.map +1 -1
  312. package/dist/server/metrics/index.d.ts +0 -1
  313. package/dist/server/metrics/index.d.ts.map +1 -1
  314. package/dist/server/metrics/index.js +10 -3
  315. package/dist/server/metrics/index.js.map +1 -1
  316. package/dist/server/proxy/index.d.ts +0 -1
  317. package/dist/server/proxy/index.d.ts.map +1 -1
  318. package/dist/server/proxy/index.js.map +1 -1
  319. package/dist/server/rate-limit/index.d.ts +8 -9
  320. package/dist/server/rate-limit/index.d.ts.map +1 -1
  321. package/dist/server/rate-limit/index.js +6 -12
  322. package/dist/server/rate-limit/index.js.map +1 -1
  323. package/dist/server/static/index.d.ts +0 -1
  324. package/dist/server/static/index.d.ts.map +1 -1
  325. package/dist/server/static/index.js.map +1 -1
  326. package/dist/server/swagger/index.d.ts +4 -4
  327. package/dist/server/swagger/index.d.ts.map +1 -1
  328. package/dist/server/swagger/index.js +37 -25
  329. package/dist/server/swagger/index.js.map +1 -1
  330. package/dist/sms/index.d.ts +0 -1
  331. package/dist/sms/index.d.ts.map +1 -1
  332. package/dist/sms/index.js.map +1 -1
  333. package/dist/system/index.browser.js.map +1 -1
  334. package/dist/system/index.d.ts +0 -1
  335. package/dist/system/index.d.ts.map +1 -1
  336. package/dist/system/index.js +2 -1
  337. package/dist/system/index.js.map +1 -1
  338. package/dist/system/index.workerd.js.map +1 -1
  339. package/dist/topic/core/index.d.ts +19 -20
  340. package/dist/topic/core/index.d.ts.map +1 -1
  341. package/dist/topic/core/index.js +8 -8
  342. package/dist/topic/core/index.js.map +1 -1
  343. package/dist/topic/redis/index.d.ts +3 -4
  344. package/dist/topic/redis/index.d.ts.map +1 -1
  345. package/dist/topic/redis/index.js +2 -2
  346. package/dist/topic/redis/index.js.map +1 -1
  347. package/package.json +36 -36
  348. package/src/api/audits/__tests__/AuditJobs.spec.ts +83 -0
  349. package/src/api/audits/__tests__/AuditService.spec.ts +139 -1
  350. package/src/api/audits/controllers/AdminAuditController.ts +41 -41
  351. package/src/api/audits/entities/audits.ts +22 -22
  352. package/src/api/audits/index.ts +6 -1
  353. package/src/api/audits/jobs/AuditJobs.ts +29 -0
  354. package/src/api/audits/parameters/AuditParameters.ts +51 -0
  355. package/src/api/audits/primitives/$audit.ts +24 -0
  356. package/src/api/audits/schemas/auditQuerySchema.ts +13 -13
  357. package/src/api/audits/schemas/createAuditSchema.ts +18 -18
  358. package/src/api/audits/services/AuditService.ts +79 -7
  359. package/src/api/files/__tests__/FileController.spec.ts +5 -5
  360. package/src/api/files/__tests__/FileJobs.spec.ts +6 -0
  361. package/src/api/files/controllers/FileController.ts +25 -25
  362. package/src/api/files/entities/files.ts +15 -15
  363. package/src/api/files/schemas/fileCreatorSummarySchema.ts +7 -7
  364. package/src/api/files/schemas/fileQuerySchema.ts +9 -9
  365. package/src/api/files/schemas/fileResourceSchema.ts +7 -9
  366. package/src/api/files/schemas/storageStatsSchema.ts +13 -13
  367. package/src/api/jobs/__tests__/$job-hardening.spec.ts +289 -0
  368. package/src/api/jobs/__tests__/$job.spec.ts +18 -18
  369. package/src/api/jobs/controllers/AdminJobController.ts +8 -8
  370. package/src/api/jobs/entities/jobExecutionEntity.ts +29 -19
  371. package/src/api/jobs/providers/JobProvider.ts +128 -12
  372. package/src/api/jobs/providers/JobQueueProvider.ts +2 -2
  373. package/src/api/jobs/schemas/jobConfigAtom.ts +22 -22
  374. package/src/api/jobs/schemas/jobExecutionQuerySchema.ts +6 -6
  375. package/src/api/jobs/schemas/jobExecutionResourceSchema.ts +11 -15
  376. package/src/api/jobs/schemas/jobRegistrationSchema.ts +20 -19
  377. package/src/api/jobs/schemas/triggerJobSchema.ts +3 -3
  378. package/src/api/jobs/services/JobService.ts +6 -6
  379. package/src/api/keys/__tests__/ApiKeyService.spec.ts +2 -2
  380. package/src/api/keys/controllers/AdminApiKeyController.ts +10 -10
  381. package/src/api/keys/entities/apiKeyEntity.ts +15 -15
  382. package/src/api/keys/schemas/adminApiKeyQuerySchema.ts +4 -4
  383. package/src/api/keys/schemas/adminApiKeyResourceSchema.ts +15 -15
  384. package/src/api/keys/schemas/createApiKeyBodySchema.ts +5 -5
  385. package/src/api/keys/schemas/createApiKeyResponseSchema.ts +9 -9
  386. package/src/api/keys/schemas/listApiKeyResponseSchema.ts +13 -13
  387. package/src/api/keys/schemas/revokeApiKeyParamsSchema.ts +3 -3
  388. package/src/api/keys/schemas/revokeApiKeyResponseSchema.ts +3 -3
  389. package/src/api/notifications/__tests__/AlephaApiNotifications.spec.ts +2 -2
  390. package/src/api/notifications/controllers/AdminNotificationController.ts +38 -14
  391. package/src/api/notifications/jobs/NotificationJobs.ts +7 -6
  392. package/src/api/notifications/primitives/$notification.ts +43 -4
  393. package/src/api/notifications/schemas/notificationContactPreferencesSchema.ts +4 -4
  394. package/src/api/notifications/schemas/notificationContactSchema.ts +7 -7
  395. package/src/api/notifications/schemas/notificationDetailResourceSchema.ts +9 -11
  396. package/src/api/notifications/schemas/notificationPayloadSchema.ts +11 -9
  397. package/src/api/notifications/schemas/notificationQuerySchema.ts +6 -6
  398. package/src/api/notifications/schemas/notificationResourceSchema.ts +14 -14
  399. package/src/api/notifications/services/NotificationSenderService.ts +38 -2
  400. package/src/api/oauth/__tests__/OAuthClientService.spec.ts +42 -0
  401. package/src/api/oauth/__tests__/OAuthController.spec.ts +128 -0
  402. package/src/api/oauth/controllers/OAuthController.ts +132 -12
  403. package/src/api/oauth/entities/oauthClientEntity.ts +29 -12
  404. package/src/api/oauth/helpers/oauthMetadata.ts +1 -0
  405. package/src/api/oauth/helpers/oidcMetadata.ts +19 -0
  406. package/src/api/oauth/index.ts +1 -0
  407. package/src/api/oauth/schemas/authorizeDecisionBodySchema.ts +12 -11
  408. package/src/api/oauth/schemas/authorizeQuerySchema.ts +12 -10
  409. package/src/api/oauth/schemas/registerClientBodySchema.ts +10 -11
  410. package/src/api/oauth/schemas/tokenRequestBodySchema.ts +9 -8
  411. package/src/api/oauth/services/OAuthClientService.ts +228 -15
  412. package/src/api/organizations/controllers/AdminOrganizationController.ts +8 -8
  413. package/src/api/organizations/entities/organizations.ts +6 -6
  414. package/src/api/organizations/schemas/createOrganizationSchema.ts +5 -5
  415. package/src/api/organizations/schemas/organizationQuerySchema.ts +4 -4
  416. package/src/api/organizations/schemas/updateOrganizationSchema.ts +1 -2
  417. package/src/api/parameters/__tests__/$parameter.spec.ts +229 -50
  418. package/src/api/parameters/controllers/AdminParameterController.ts +9 -12
  419. package/src/api/parameters/entities/parameters.ts +29 -16
  420. package/src/api/parameters/primitives/$parameter.ts +3 -3
  421. package/src/api/parameters/schemas/activateParameterBodySchema.ts +4 -4
  422. package/src/api/parameters/schemas/createParameterVersionBodySchema.ts +15 -15
  423. package/src/api/parameters/schemas/parameterCreatorSummarySchema.ts +7 -7
  424. package/src/api/parameters/schemas/parameterCurrentResponseSchema.ts +7 -7
  425. package/src/api/parameters/schemas/parameterHistoryResponseSchema.ts +3 -3
  426. package/src/api/parameters/schemas/parameterNameParamSchema.ts +2 -3
  427. package/src/api/parameters/schemas/parameterNamesResponseSchema.ts +3 -3
  428. package/src/api/parameters/schemas/parameterResponseSchema.ts +3 -3
  429. package/src/api/parameters/schemas/parameterStatusSchema.ts +2 -2
  430. package/src/api/parameters/schemas/parameterTreeNodeSchema.ts +6 -6
  431. package/src/api/parameters/schemas/parameterVersionParamSchema.ts +5 -6
  432. package/src/api/parameters/schemas/parameterVersionResponseSchema.ts +3 -3
  433. package/src/api/parameters/schemas/rollbackParameterBodySchema.ts +6 -9
  434. package/src/api/parameters/services/ParameterProvider.ts +152 -65
  435. package/src/api/payments/controllers/AdminPaymentController.ts +7 -7
  436. package/src/api/payments/controllers/MockCheckoutController.ts +79 -28
  437. package/src/api/payments/controllers/PaymentController.ts +4 -4
  438. package/src/api/payments/entities/paymentIntents.ts +11 -11
  439. package/src/api/payments/entities/paymentMethods.ts +11 -11
  440. package/src/api/payments/entities/refunds.ts +9 -9
  441. package/src/api/payments/providers/PaymentProvider.ts +18 -0
  442. package/src/api/payments/schemas/intentSchemas.ts +25 -25
  443. package/src/api/payments/schemas/paymentMethodSchemas.ts +3 -3
  444. package/src/api/payments/services/PaymentService.ts +60 -3
  445. package/src/api/subscriptions/__tests__/SubscriptionService.spec.ts +14 -0
  446. package/src/api/subscriptions/controllers/AdminSubscriptionController.ts +11 -11
  447. package/src/api/subscriptions/controllers/SubscriptionController.ts +5 -4
  448. package/src/api/subscriptions/entities/subscriptionEvents.ts +15 -15
  449. package/src/api/subscriptions/entities/subscriptions.ts +22 -22
  450. package/src/api/subscriptions/notifications/SubscriptionNotifications.ts +22 -22
  451. package/src/api/subscriptions/schemas/cancelSubscriptionSchema.ts +4 -4
  452. package/src/api/subscriptions/schemas/changePlanSchema.ts +5 -5
  453. package/src/api/subscriptions/schemas/createSubscriptionSchema.ts +14 -7
  454. package/src/api/subscriptions/schemas/entitlementsSchema.ts +10 -10
  455. package/src/api/subscriptions/schemas/mrrSchema.ts +9 -9
  456. package/src/api/subscriptions/schemas/planDefinitionSchema.ts +21 -21
  457. package/src/api/subscriptions/schemas/planResourceSchema.ts +19 -19
  458. package/src/api/subscriptions/schemas/subscriptionQuerySchema.ts +8 -8
  459. package/src/api/subscriptions/schemas/subscriptionSettingsSchema.ts +7 -7
  460. package/src/api/subscriptions/schemas/subscriptionStatsSchema.ts +17 -17
  461. package/src/api/subscriptions/services/SubscriptionConfig.ts +2 -2
  462. package/src/api/users/__tests__/ApiKeys-integration.spec.ts +11 -11
  463. package/src/api/users/atoms/realmAuthSettingsAtom.ts +111 -119
  464. package/src/api/users/controllers/AdminIdentityController.ts +29 -19
  465. package/src/api/users/controllers/AdminSessionController.ts +37 -27
  466. package/src/api/users/controllers/AdminUserController.ts +75 -53
  467. package/src/api/users/controllers/MySessionController.ts +125 -0
  468. package/src/api/users/controllers/RealmController.ts +9 -9
  469. package/src/api/users/controllers/UserController.ts +55 -55
  470. package/src/api/users/entities/identities.ts +8 -8
  471. package/src/api/users/entities/sessions.ts +17 -17
  472. package/src/api/users/entities/users.ts +17 -17
  473. package/src/api/users/index.ts +3 -0
  474. package/src/api/users/notifications/UserNotifications.ts +76 -24
  475. package/src/api/users/primitives/$realm.ts +12 -0
  476. package/src/api/users/schemas/completePasswordResetRequestSchema.ts +8 -12
  477. package/src/api/users/schemas/completeRegistrationRequestSchema.ts +17 -20
  478. package/src/api/users/schemas/createUserSchema.ts +2 -2
  479. package/src/api/users/schemas/identityQuerySchema.ts +4 -4
  480. package/src/api/users/schemas/identityResourceSchema.ts +3 -2
  481. package/src/api/users/schemas/loginSchema.ts +4 -4
  482. package/src/api/users/schemas/passwordResetIntentResponseSchema.ts +6 -8
  483. package/src/api/users/schemas/realmConfigSchema.ts +10 -10
  484. package/src/api/users/schemas/registerQuerySchema.ts +6 -6
  485. package/src/api/users/schemas/registerRequestSchema.ts +21 -43
  486. package/src/api/users/schemas/registerResponseSchema.ts +2 -2
  487. package/src/api/users/schemas/registerSchema.ts +13 -31
  488. package/src/api/users/schemas/registrationIntentResponseSchema.ts +19 -23
  489. package/src/api/users/schemas/resetPasswordSchema.ts +10 -17
  490. package/src/api/users/schemas/sessionQuerySchema.ts +3 -3
  491. package/src/api/users/schemas/sessionResourceSchema.ts +25 -25
  492. package/src/api/users/schemas/updateUserSchema.ts +3 -4
  493. package/src/api/users/schemas/userQuerySchema.ts +7 -7
  494. package/src/api/users/services/RegistrationService.ts +25 -11
  495. package/src/api/users/services/UserService.ts +12 -6
  496. package/src/api/verifications/__tests__/CodeVerification.spec.ts +63 -101
  497. package/src/api/verifications/__tests__/LinkVerification.spec.ts +23 -92
  498. package/src/api/verifications/controllers/VerificationController.ts +13 -27
  499. package/src/api/verifications/entities/verifications.ts +13 -14
  500. package/src/api/verifications/schemas/requestVerificationCodeResponseSchema.ts +17 -14
  501. package/src/api/verifications/schemas/validateVerificationCodeResponseSchema.ts +9 -10
  502. package/src/api/verifications/schemas/verificationSettingsSchema.ts +65 -66
  503. package/src/api/verifications/schemas/verificationTypeEnumSchema.ts +2 -2
  504. package/src/api/verifications/services/VerificationService.ts +12 -0
  505. package/src/background/__tests__/BackgroundTaskProvider.spec.ts +36 -0
  506. package/src/batch/__tests__/$batch.spec.ts +22 -22
  507. package/src/batch/__tests__/startup-buffering.spec.ts +9 -9
  508. package/src/bin/index.ts +1 -1
  509. package/src/bucket/__tests__/TenantScopedBucket.spec.ts +60 -0
  510. package/src/bucket/providers/LocalFileStorageProvider.ts +14 -6
  511. package/src/bucket/providers/MemoryFileStorageProvider.ts +18 -7
  512. package/src/bucket/providers/R2FileStorageProvider.ts +14 -6
  513. package/src/bucket/providers/S3FileStorageProvider.ts +31 -15
  514. package/src/cache/core/primitives/$cache.ts +7 -10
  515. package/src/cache/database/entities/cacheEntries.ts +16 -27
  516. package/src/cache/database/providers/DatabaseCacheProvider.ts +15 -13
  517. package/src/cache/redis/providers/RedisCacheProvider.ts +6 -6
  518. package/src/captcha/providers/TurnstileCaptchaProvider.ts +4 -4
  519. package/src/cli/core/__tests__/BuildCloudflareTask.spec.ts +178 -0
  520. package/src/cli/core/__tests__/BuildDockerTask.spec.ts +0 -2
  521. package/src/cli/core/__tests__/DbCommand.spec.ts +108 -0
  522. package/src/cli/core/atoms/appEntryOptions.ts +5 -5
  523. package/src/cli/core/atoms/buildOptions.ts +76 -88
  524. package/src/cli/core/atoms/changelogOptions.ts +3 -3
  525. package/src/cli/core/atoms/devOptions.ts +3 -3
  526. package/src/cli/core/commands/build.ts +36 -49
  527. package/src/cli/core/commands/db.ts +171 -83
  528. package/src/cli/core/commands/dev.ts +8 -8
  529. package/src/cli/core/commands/gen/changelog.ts +12 -14
  530. package/src/cli/core/commands/gen/env.ts +6 -6
  531. package/src/cli/core/commands/gen/openapi.ts +6 -6
  532. package/src/cli/core/commands/init.ts +28 -33
  533. package/src/cli/core/commands/pack.ts +10 -10
  534. package/src/cli/core/commands/root.ts +7 -8
  535. package/src/cli/core/commands/test.ts +17 -20
  536. package/src/cli/core/index.ts +0 -3
  537. package/src/cli/core/tasks/BuildCloudflareTask.ts +138 -245
  538. package/src/cli/core/tasks/BuildPrerenderTask.ts +44 -7
  539. package/src/cli/core/templates/apiHelloResponseSchemaTs.ts +4 -4
  540. package/src/cli/devtools/atoms/devtoolsOptions.ts +6 -6
  541. package/src/cli/i18n/__tests__/I18nCheckService.spec.ts +48 -0
  542. package/src/cli/i18n/atoms/i18nOptions.ts +8 -8
  543. package/src/cli/i18n/services/I18nCheckService.ts +65 -11
  544. package/src/cli/platform/commands/SecretsCommand.ts +24 -25
  545. package/src/cli/platform/commands/platform.ts +40 -46
  546. package/src/cli/platform/index.ts +1 -1
  547. package/src/cli/platform-lib/__tests__/CloudflareAdapter.spec.ts +0 -4
  548. package/src/cli/platform-lib/__tests__/PlatformInspector.spec.ts +10 -3
  549. package/src/cli/platform-lib/__tests__/VercelAdapter.spec.ts +0 -2
  550. package/src/cli/platform-lib/adapters/CloudflareAdapter.ts +141 -50
  551. package/src/cli/platform-lib/adapters/VercelAdapter.ts +6 -11
  552. package/src/cli/platform-lib/atoms/platformOptions.ts +46 -25
  553. package/src/cli/platform-lib/schemas/cloudflare.ts +87 -87
  554. package/src/cli/platform-lib/schemas/platform.ts +51 -51
  555. package/src/cli/platform-lib/schemas/vercel.ts +28 -28
  556. package/src/cli/platform-lib/services/CloudflareApi.ts +5 -5
  557. package/src/cli/platform-lib/services/VercelApi.ts +4 -4
  558. package/src/cli/platform-lib/services/VercelCli.ts +6 -15
  559. package/src/cli/platform-lib/services/WranglerApi.ts +6 -15
  560. package/src/cli/vendor/atoms/vendorOptions.ts +9 -9
  561. package/src/cli/vendor/commands/VendorCommand.ts +11 -12
  562. package/src/command/__tests__/$command.spec.ts +82 -83
  563. package/src/command/__tests__/Asker.spec.ts +6 -13
  564. package/src/command/__tests__/CliProvider.spec.ts +136 -149
  565. package/src/command/__tests__/Runner.spec.ts +86 -110
  566. package/src/command/helpers/Asker.ts +23 -58
  567. package/src/command/helpers/Runner.ts +34 -110
  568. package/src/command/index.ts +4 -9
  569. package/src/command/primitives/$command.ts +10 -10
  570. package/src/command/providers/CliProvider.ts +183 -161
  571. package/src/core/Alepha.ts +62 -13
  572. package/src/core/__tests__/$atom.spec.ts +52 -3
  573. package/src/core/__tests__/$computed.spec.ts +129 -0
  574. package/src/core/__tests__/$env.spec.ts +13 -13
  575. package/src/core/__tests__/$inject.spec.ts +4 -4
  576. package/src/core/__tests__/$module.spec.ts +1 -1
  577. package/src/core/__tests__/Alepha-graph.spec.ts +1 -1
  578. package/src/core/__tests__/Alepha-parseEnv.spec.ts +32 -32
  579. package/src/core/__tests__/Alepha-start.spec.ts +3 -3
  580. package/src/core/__tests__/CodecManager.spec.ts +113 -94
  581. package/src/core/__tests__/KeylessJsonSchemaCodec.spec.ts +138 -138
  582. package/src/core/__tests__/SchemaValidator.spec.ts +43 -44
  583. package/src/core/__tests__/StateManager.persist.browser.spec.ts +87 -0
  584. package/src/core/__tests__/StateManager.spec.ts +423 -0
  585. package/src/core/__tests__/TypeBox-usecases.spec.ts +8 -8
  586. package/src/core/__tests__/TypeProvider.spec.ts +314 -309
  587. package/src/core/__tests__/dump.spec.ts +6 -6
  588. package/src/core/__tests__/pagination.spec.ts +4 -4
  589. package/src/core/__tests__/scoped-after-start.spec.ts +43 -0
  590. package/src/core/errors/TypeBoxError.ts +10 -4
  591. package/src/core/helpers/FileLike.ts +5 -5
  592. package/src/core/helpers/coerceStrings.ts +70 -0
  593. package/src/core/helpers/jsonSchemaToZod.ts +112 -0
  594. package/src/core/index.shared.ts +4 -1
  595. package/src/core/primitives/$atom.ts +95 -27
  596. package/src/core/primitives/$computed.ts +148 -0
  597. package/src/core/primitives/$env.ts +5 -5
  598. package/src/core/primitives/$state.ts +1 -1
  599. package/src/core/providers/AlsProvider.ts +26 -0
  600. package/src/core/providers/CodecManager.ts +1 -2
  601. package/src/core/providers/JsonSchemaCodec.ts +1 -2
  602. package/src/core/providers/KeylessJsonSchemaCodec.ts +82 -57
  603. package/src/core/providers/SchemaValidator.ts +48 -158
  604. package/src/core/providers/StateManager.ts +383 -9
  605. package/src/core/providers/TypeProvider.ts +80 -734
  606. package/src/core/providers/ZodProvider.ts +380 -0
  607. package/src/core/providers/zodAugment.ts +69 -0
  608. package/src/core/schemas/pageQuerySchema.ts +19 -21
  609. package/src/core/schemas/pageSchema.ts +47 -57
  610. package/src/crypto/__tests__/SecretProvider.spec.ts +31 -0
  611. package/src/crypto/providers/SecretProvider.ts +16 -10
  612. package/src/datetime/primitives/$throttle.ts +6 -1
  613. package/src/email/brevo/providers/BrevoEmailProvider.ts +4 -4
  614. package/src/email/cloudflare/providers/CloudflareEmailProvider.ts +6 -6
  615. package/src/email/core/index.ts +7 -2
  616. package/src/email/core/primitives/$email.ts +5 -1
  617. package/src/email/core/providers/LocalEmailProvider.ts +5 -5
  618. package/src/email/smtp/providers/NodemailerEmailProvider.ts +41 -52
  619. package/src/fake/__tests__/FakeProvider.spec.ts +110 -110
  620. package/src/fake/__tests__/keyName.example.ts +21 -21
  621. package/src/fake/__tests__/keyName.spec.ts +41 -41
  622. package/src/fake/__tests__/module.example.ts +8 -8
  623. package/src/fake/providers/FakeProvider.ts +122 -121
  624. package/src/lock/core/__tests__/lock-mutual-exclusion.spec.ts +44 -0
  625. package/src/lock/core/index.ts +1 -0
  626. package/src/lock/core/primitives/$lock.ts +13 -6
  627. package/src/logger/__tests__/CliFormatterProvider.spec.ts +76 -0
  628. package/src/logger/__tests__/Logger.spec.ts +49 -0
  629. package/src/logger/index.ts +25 -18
  630. package/src/logger/providers/CliFormatterProvider.ts +75 -0
  631. package/src/logger/schemas/logEntrySchema.ts +10 -10
  632. package/src/logger/services/Logger.ts +18 -0
  633. package/src/mcp/__tests__/$prompt.spec.ts +21 -23
  634. package/src/mcp/__tests__/$tool.spec.ts +22 -22
  635. package/src/mcp/__tests__/McpServerProvider.spec.ts +82 -11
  636. package/src/mcp/__tests__/StreamableHttpMcpTransport.spec.ts +2 -2
  637. package/src/mcp/__tests__/integration.spec.ts +33 -33
  638. package/src/mcp/primitives/$prompt.ts +11 -9
  639. package/src/mcp/primitives/$tool.ts +27 -86
  640. package/src/mcp/providers/McpServerProvider.ts +55 -0
  641. package/src/mcp/transports/StreamableHttpMcpTransport.ts +7 -7
  642. package/src/orm/__tests__/$repository-tests.ts +133 -27
  643. package/src/orm/__tests__/$repository.spec.ts +23 -0
  644. package/src/orm/__tests__/$transactional-tests.ts +4 -4
  645. package/src/orm/__tests__/ModelBuilder-tests.ts +28 -28
  646. package/src/orm/__tests__/ModelBuilder.spec.ts +124 -106
  647. package/src/orm/__tests__/QueryManager.spec.ts +5 -5
  648. package/src/orm/__tests__/delete-returning-tests.ts +11 -11
  649. package/src/orm/__tests__/deletedAt-tests.ts +3 -3
  650. package/src/orm/__tests__/enums.spec.ts +29 -25
  651. package/src/orm/__tests__/execute-tests.ts +8 -8
  652. package/src/orm/__tests__/fixtures/bigEntitySchema.ts +48 -48
  653. package/src/orm/__tests__/fixtures/userEntitySchema.ts +6 -6
  654. package/src/orm/__tests__/joins-tests.ts +30 -30
  655. package/src/orm/__tests__/organization-tests.ts +105 -3
  656. package/src/orm/__tests__/organization.spec.ts +46 -0
  657. package/src/orm/__tests__/orm-errors.spec.ts +10 -10
  658. package/src/orm/__tests__/orm-next-tests.ts +29 -29
  659. package/src/orm/__tests__/orm-showcase-tests.ts +9 -9
  660. package/src/orm/__tests__/primaryKey.spec.ts +4 -4
  661. package/src/orm/__tests__/query-date-encoding-tests.ts +17 -17
  662. package/src/orm/__tests__/ref-auto-onDelete.spec.ts +14 -14
  663. package/src/orm/__tests__/references.spec.ts +7 -7
  664. package/src/orm/__tests__/security.spec.ts +17 -17
  665. package/src/orm/__tests__/string-operators-tests.ts +5 -5
  666. package/src/orm/__tests__/timestamps-tests.ts +14 -14
  667. package/src/orm/__tests__/validation-tests.ts +5 -5
  668. package/src/orm/core/__tests__/BunSqliteProvider.bun.spec.ts +8 -8
  669. package/src/orm/core/constants/PG_SYMBOLS.ts +13 -1
  670. package/src/orm/core/entities/alephaSequences.ts +8 -8
  671. package/src/orm/core/helpers/pgAttr.ts +4 -4
  672. package/src/orm/core/primitives/$entity.ts +10 -6
  673. package/src/orm/core/providers/DatabaseTypeProvider.ts +46 -53
  674. package/src/orm/core/providers/drivers/BunSqliteProvider.ts +8 -8
  675. package/src/orm/core/providers/drivers/CloudflareD1Provider.ts +3 -5
  676. package/src/orm/core/providers/drivers/NodeSqliteProvider.ts +8 -8
  677. package/src/orm/core/schemas/databaseEnvSchema.ts +4 -4
  678. package/src/orm/core/schemas/insertSchema.ts +14 -18
  679. package/src/orm/core/schemas/legacyIdSchema.ts +2 -2
  680. package/src/orm/core/schemas/updateSchema.ts +10 -16
  681. package/src/orm/core/services/PgRelationManager.ts +2 -2
  682. package/src/orm/core/services/QueryManager.ts +13 -2
  683. package/src/orm/core/services/Repository.ts +88 -33
  684. package/src/orm/core/services/SqliteModelBuilder.ts +38 -45
  685. package/src/orm/postgres/__tests__/BunPostgresProvider.bun.spec.ts +4 -4
  686. package/src/orm/postgres/providers/CloudflareHyperdriveProvider.ts +4 -6
  687. package/src/orm/postgres/schemas/postgresEnvSchema.ts +6 -6
  688. package/src/orm/postgres/services/PostgresModelBuilder.ts +127 -114
  689. package/src/queue/core/__tests__/$consumer.spec.ts +4 -4
  690. package/src/queue/core/__tests__/WorkerProvider.spec.ts +4 -4
  691. package/src/queue/core/__tests__/shared.ts +6 -6
  692. package/src/queue/core/primitives/$consumer.ts +5 -5
  693. package/src/queue/core/primitives/$queue.ts +44 -61
  694. package/src/queue/core/providers/CloudflareQueueProvider.ts +6 -0
  695. package/src/queue/core/providers/WorkerProvider.ts +17 -14
  696. package/src/queue/redis/providers/RedisQueueProvider.ts +3 -3
  697. package/src/react/core/__tests__/ErrorBoundary.browser.spec.tsx +92 -0
  698. package/src/react/core/__tests__/Router.spec.tsx +4 -4
  699. package/src/react/core/__tests__/useComputed.browser.spec.tsx +192 -0
  700. package/src/react/core/__tests__/useQuery.browser.spec.tsx +48 -0
  701. package/src/react/core/__tests__/useSelector.browser.spec.tsx +105 -0
  702. package/src/react/core/__tests__/useStore.browser.spec.tsx +113 -0
  703. package/src/react/core/components/ErrorBoundary.tsx +42 -0
  704. package/src/react/core/hooks/useAction.ts +56 -19
  705. package/src/react/core/hooks/useComputed.ts +91 -0
  706. package/src/react/core/hooks/useSelector.ts +67 -0
  707. package/src/react/core/hooks/useStore.ts +36 -17
  708. package/src/react/core/index.ts +3 -0
  709. package/src/react/core/utils/shallowEqual.ts +36 -0
  710. package/src/react/form/__tests__/FormModel-submit-loading.spec.ts +71 -0
  711. package/src/react/form/__tests__/form-submitting-reactive.browser.spec.tsx +96 -0
  712. package/src/react/form/__tests__/useForm.browser.spec.tsx +54 -54
  713. package/src/react/form/errors/FormValidationError.ts +0 -2
  714. package/src/react/form/hooks/useForm.ts +19 -4
  715. package/src/react/form/hooks/useFormQuerySync.ts +0 -0
  716. package/src/react/form/services/FormModel.ts +124 -86
  717. package/src/react/form/services/parseField.ts +66 -27
  718. package/src/react/i18n/__tests__/I18nProvider.spec.ts +89 -0
  719. package/src/react/i18n/__tests__/Localize.spec.tsx +1 -1
  720. package/src/react/i18n/__tests__/locale-routing.spec.ts +107 -0
  721. package/src/react/i18n/providers/I18nProvider.ts +173 -14
  722. package/src/react/router/__tests__/$page.browser.spec.tsx +19 -19
  723. package/src/react/router/__tests__/$page.spec.tsx +21 -21
  724. package/src/react/router/__tests__/ReactBrowserProvider.browser.spec.ts +87 -1
  725. package/src/react/router/__tests__/RouterLocaleProvider.spec.ts +127 -0
  726. package/src/react/router/atoms/ssrManifestAtom.ts +16 -16
  727. package/src/react/router/components/NestedView.tsx +11 -3
  728. package/src/react/router/hooks/useQueryParams.ts +1 -1
  729. package/src/react/router/index.browser.ts +4 -0
  730. package/src/react/router/index.shared.ts +1 -0
  731. package/src/react/router/index.ts +9 -0
  732. package/src/react/router/primitives/$page.ts +2 -2
  733. package/src/react/router/providers/ReactBrowserProvider.ts +64 -13
  734. package/src/react/router/providers/ReactBrowserRouterProvider.ts +15 -1
  735. package/src/react/router/providers/ReactPageProvider.ts +38 -13
  736. package/src/react/router/providers/ReactServerProvider.ts +105 -16
  737. package/src/react/router/providers/RootComponentsProvider.ts +13 -0
  738. package/src/react/router/providers/RouterLocaleProvider.ts +125 -0
  739. package/src/react/router/providers/__tests__/RootComponentsProvider.spec.ts +15 -0
  740. package/src/react/router/providers/__tests__/rootComponents.ssr.browser.spec.tsx +67 -0
  741. package/src/react/sitemap/__tests__/$sitemap.spec.ts +131 -0
  742. package/src/react/sitemap/index.browser.ts +21 -0
  743. package/src/react/sitemap/index.ts +25 -0
  744. package/src/react/sitemap/primitives/$sitemap.browser.ts +26 -0
  745. package/src/react/sitemap/primitives/$sitemap.ts +196 -0
  746. package/src/react/ui/atoms/uiAtom.ts +6 -6
  747. package/src/react/ui/atoms/uiThemeListAtom.ts +7 -7
  748. package/src/react/ui/hooks/useColorMode.ts +11 -4
  749. package/src/react/ui/services/SchemaControl.ts +4 -4
  750. package/src/redis/providers/BunRedisProvider.ts +19 -11
  751. package/src/redis/providers/NodeRedisProvider.ts +3 -3
  752. package/src/scheduler/primitives/$scheduler.ts +21 -8
  753. package/src/security/__tests__/assertRealmScope.spec.ts +29 -0
  754. package/src/security/atoms/currentTenantAtom.ts +6 -6
  755. package/src/security/atoms/currentUserAtom.ts +2 -2
  756. package/src/security/primitives/$issuer.ts +24 -2
  757. package/src/security/providers/JwtProvider.ts +100 -0
  758. package/src/security/providers/SecurityProvider.ts +43 -2
  759. package/src/security/schemas/permissionSchema.ts +19 -19
  760. package/src/security/schemas/roleSchema.ts +22 -28
  761. package/src/security/schemas/userAccountInfoSchema.ts +47 -37
  762. package/src/server/auth/__tests__/appleClientSecret.spec.ts +34 -0
  763. package/src/server/auth/__tests__/federationRedirectReplay.spec.ts +44 -0
  764. package/src/server/auth/helpers/appleClientSecret.ts +24 -0
  765. package/src/server/auth/helpers/jtiReplayGuard.ts +41 -0
  766. package/src/server/auth/helpers/safeRedirectPath.ts +19 -0
  767. package/src/server/auth/index.ts +1 -0
  768. package/src/server/auth/primitives/$auth.ts +6 -6
  769. package/src/server/auth/primitives/$authApple.ts +10 -10
  770. package/src/server/auth/primitives/$authFacebook.ts +10 -10
  771. package/src/server/auth/primitives/$authFranceConnect.ts +10 -10
  772. package/src/server/auth/primitives/$authGithub.ts +10 -10
  773. package/src/server/auth/primitives/$authGoogle.ts +10 -10
  774. package/src/server/auth/primitives/$authMicrosoft.ts +14 -14
  775. package/src/server/auth/providers/ServerAuthProvider.ts +67 -52
  776. package/src/server/auth/schemas/authenticationProviderSchema.ts +9 -12
  777. package/src/server/auth/schemas/tokenResponseSchema.ts +2 -2
  778. package/src/server/auth/schemas/tokensSchema.ts +16 -16
  779. package/src/server/auth/schemas/userinfoResponseSchema.ts +3 -3
  780. package/src/server/cookies/__tests__/AtomCookieBinding.spec.ts +80 -0
  781. package/src/server/cookies/__tests__/AtomCookiePersistence.browser.spec.ts +169 -0
  782. package/src/server/cookies/__tests__/AtomCookiePersistence.spec.ts +294 -0
  783. package/src/server/cookies/__tests__/ServerCookiesProvider.spec.ts +82 -12
  784. package/src/server/cookies/index.browser.ts +4 -1
  785. package/src/server/cookies/index.ts +8 -1
  786. package/src/server/cookies/primitives/$cookie.browser.ts +1 -1
  787. package/src/server/cookies/primitives/$cookie.ts +16 -0
  788. package/src/server/cookies/providers/AtomCookiePersistence.browser.ts +133 -0
  789. package/src/server/cookies/providers/AtomCookiePersistence.ts +148 -0
  790. package/src/server/cookies/providers/ServerCookiesProvider.ts +32 -4
  791. package/src/server/cookies/services/CookieParser.ts +6 -1
  792. package/src/server/core/__tests__/$action.spec.ts +13 -13
  793. package/src/server/core/__tests__/$middleware.spec.ts +10 -10
  794. package/src/server/core/__tests__/$route.spec.ts +9 -9
  795. package/src/server/core/__tests__/$sse.spec.ts +26 -26
  796. package/src/server/core/__tests__/BunHttpServerProvider.bun.spec.ts +6 -6
  797. package/src/server/core/__tests__/HttpClient.spec.ts +2 -2
  798. package/src/server/core/__tests__/NodeHttpServerProvider.spec.ts +15 -3
  799. package/src/server/core/__tests__/ServerBodyParserProvider.spec.ts +14 -14
  800. package/src/server/core/__tests__/ServerMultipartProvider.spec.ts +33 -33
  801. package/src/server/core/__tests__/ServerRouterProvider-errorHandler.spec.ts +5 -1
  802. package/src/server/core/__tests__/ServerRouterProvider-getRoutes.spec.ts +25 -25
  803. package/src/server/core/__tests__/ServerRouterProvider-serializationError.spec.ts +9 -5
  804. package/src/server/core/__tests__/ServerRouterProvider-validationError.spec.ts +56 -24
  805. package/src/server/core/errors/ValidationError.ts +6 -3
  806. package/src/server/core/helpers/isMultipart.ts +2 -1
  807. package/src/server/core/index.ts +5 -2
  808. package/src/server/core/interfaces/ServerRequest.ts +14 -14
  809. package/src/server/core/primitives/$action.ts +26 -36
  810. package/src/server/core/primitives/$route.ts +27 -0
  811. package/src/server/core/primitives/$sse.ts +3 -3
  812. package/src/server/core/providers/BunHttpServerProvider.ts +8 -9
  813. package/src/server/core/providers/NodeHttpServerProvider.ts +8 -9
  814. package/src/server/core/providers/ServerBodyParserProvider.ts +20 -12
  815. package/src/server/core/providers/ServerCompressProvider.ts +9 -10
  816. package/src/server/core/providers/ServerHelmetProvider.ts +26 -27
  817. package/src/server/core/providers/ServerMultipartProvider.ts +19 -19
  818. package/src/server/core/providers/ServerRouterProvider.ts +44 -15
  819. package/src/server/core/schemas/errorSchema.ts +20 -25
  820. package/src/server/core/schemas/okSchema.ts +9 -14
  821. package/src/server/core/services/HttpClient.ts +13 -1
  822. package/src/server/core/services/ServerRequestParser.ts +6 -6
  823. package/src/server/cors/providers/ServerCorsProvider.ts +26 -28
  824. package/src/server/health/schemas/healthSchema.ts +6 -6
  825. package/src/server/links/__tests__/$remote.spec.ts +3 -3
  826. package/src/server/links/__tests__/BatchEndpoint.spec.ts +9 -9
  827. package/src/server/links/__tests__/LinkProvider.spec.ts +9 -9
  828. package/src/server/links/__tests__/ServerLinksProvider.spec.ts +23 -23
  829. package/src/server/links/__tests__/fixtures/CrudApp.ts +21 -21
  830. package/src/server/links/atoms/apiLinksAtom.ts +2 -2
  831. package/src/server/links/atoms/linkOptionsAtom.ts +6 -6
  832. package/src/server/links/primitives/$remote.ts +3 -3
  833. package/src/server/links/providers/LinkProvider.ts +3 -3
  834. package/src/server/links/providers/ServerLinksProvider.ts +20 -20
  835. package/src/server/links/schemas/apiLinksResponseSchema.ts +23 -23
  836. package/src/server/proxy/__tests__/$proxy.spec.ts +9 -9
  837. package/src/server/proxy/providers/ServerProxyProvider.ts +5 -0
  838. package/src/server/rate-limit/providers/ServerRateLimitProvider.ts +18 -20
  839. package/src/server/swagger/__tests__/$swagger.spec.ts +91 -94
  840. package/src/server/swagger/__tests__/ui.spec.ts +3 -3
  841. package/src/server/swagger/providers/ServerSwaggerProvider.ts +66 -43
  842. package/src/system/__tests__/NodeShellProvider.spec.ts +46 -0
  843. package/src/system/providers/NodeShellProvider.ts +4 -1
  844. package/src/topic/core/__tests__/$subscriber.spec.ts +4 -4
  845. package/src/topic/core/__tests__/shared.ts +8 -8
  846. package/src/topic/core/primitives/$subscriber.ts +5 -5
  847. package/src/topic/core/primitives/$topic.ts +14 -14
  848. package/src/topic/redis/providers/RedisTopicProvider.ts +3 -3
  849. package/dist/container/core/index.d.ts +0 -236
  850. package/dist/container/core/index.d.ts.map +0 -1
  851. package/dist/container/core/index.js +0 -231
  852. package/dist/container/core/index.js.map +0 -1
  853. package/dist/container/core/index.workerd.js +0 -192
  854. package/dist/container/core/index.workerd.js.map +0 -1
  855. package/src/cli/core/tasks/BuildSitemapTask.ts +0 -130
  856. package/src/command/helpers/PrettyAsker.ts +0 -256
  857. package/src/command/helpers/PrettyPrint.ts +0 -332
  858. package/src/container/core/__tests__/$container.spec.ts +0 -83
  859. package/src/container/core/index.ts +0 -50
  860. package/src/container/core/index.workerd.ts +0 -53
  861. package/src/container/core/interfaces/ContainerOptions.ts +0 -69
  862. package/src/container/core/primitives/$container.ts +0 -100
  863. package/src/container/core/providers/CloudflareContainerProvider.ts +0 -70
  864. package/src/container/core/providers/ContainerProvider.ts +0 -92
  865. package/src/container/core/providers/MockContainerProvider.ts +0 -62
  866. package/src/container/core/providers/NodeContainerProvider.ts +0 -53
  867. package/src/core/__tests__/jsonSchemaToTypeBox.spec.ts +0 -771
  868. package/src/core/helpers/jsonSchemaToTypeBox.ts +0 -359
  869. /package/dist/orm/core/{chunk-B4FMCO8f.js → rolldown-runtime-B4FMCO8f.js} +0 -0
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","names":[],"sources":["../../../src/api/notifications/schemas/notificationPayloadSchema.ts","../../../src/api/notifications/services/NotificationSenderService.ts","../../../src/api/notifications/jobs/NotificationJobs.ts","../../../src/api/notifications/controllers/AdminNotificationController.ts","../../../src/api/notifications/primitives/$notification.ts","../../../src/api/notifications/schemas/notificationContactPreferencesSchema.ts","../../../src/api/notifications/schemas/notificationContactSchema.ts","../../../src/api/notifications/schemas/notificationDetailResourceSchema.ts","../../../src/api/notifications/schemas/notificationQuerySchema.ts","../../../src/api/notifications/schemas/notificationResourceSchema.ts","../../../src/api/notifications/index.ts"],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","names":[],"sources":["../../../src/api/notifications/schemas/notificationPayloadSchema.ts","../../../src/api/notifications/services/NotificationSenderService.ts","../../../src/api/notifications/jobs/NotificationJobs.ts","../../../src/api/notifications/controllers/AdminNotificationController.ts","../../../src/api/notifications/primitives/$notification.ts","../../../src/api/notifications/schemas/notificationContactPreferencesSchema.ts","../../../src/api/notifications/schemas/notificationContactSchema.ts","../../../src/api/notifications/schemas/notificationDetailResourceSchema.ts","../../../src/api/notifications/schemas/notificationQuerySchema.ts","../../../src/api/notifications/schemas/notificationResourceSchema.ts","../../../src/api/notifications/index.ts"],"mappings":";;;;;cAEa,yCAAyB;;;;;;;;;;;;;KAY1B,sBAAsB,cAAc;;;KCP3C;EACH;EACA,iBAAiB;;KAEd;EACH,oBAAoB;;cAGT;qBACQ,QAAM;qBACN,6BAAG;qBACH,eAAa;qBACb,aAAW;EAEjB,KAAK,SAAS,sBAAmB;;;;;;;;;;;;;EAqCvC,UAAU,SAAS;;;;EAoBnB,YAAY,SAAS;;;;;;;;;;;YA2BlB,YACR;IACE,eAAe;MAEX;MAAiB;;KAGvB;IAEI,QAAQ;IAA0B,MAAM;;YASpC,KAAK,SAAS;cAAA;;;;;;;;;;;;;;;;;;;;;;;;cCjGb;qBACQ,6BAAG;qBACH,IAAE;qBACF,2BAAyB;qBAGzB,iCAAU,yBAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;WAGb,0CAAQ,iCAAA;;;WAgBR,4CAAgB,2BAAA;;;;;;;;;;;;;WAgBhB,iDAAqB,8BAAA;;;;cCzD1B;qBACQ;qBACA;qBACA,QAAM;qBACN,kBAAgB;qBAChB,iCAAU,yBAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;gBAEf;;;;;;;gBAUA;;YAKJ,WAAW;IAAQ;;WAKb,2CAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;WA4BjB,yCAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;WAmBf,4CAAkB;;;;;;;;;;WAsBlB,6CAAmB;;;;;;;;YA4BzB,WAAW,MAAM;IAGvB;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;;YAIM,iBAAiB,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cChHtB;GAAiB,UAAU,SAAO,SACpC,6BAA6B,KAAE,sBAAA;;;UAKzB,6BAA6B,UAAU,iBAC9C,oBAAoB;EAC5B;EACA;EACA;EACA;EACA;EACA;KAEG,eAAe,oBAAoB;;EAEtC,QAAQ;;cAKG,sBAAsB,UAAU,iBAAiB,UAC5D,6BAA6B;qBAEV,kBAAgB;MAExB;;;;;;;YAUD,YAAY;EAYT,KAAK,SAAS,wBAAwB,KAAE;EA+C9C,UAAU,SAAS,QAAQ,6BAA6B;;UAShD,wBAAwB,UAAU;EACjD,WAAW,aAAa;EACxB;;EAEA;;;;;;;EAOA;;UAGe,oBAAoB,UAAU;EAC7C;IACE;IACA,iBAAiB,WAAW,OAAO;;EAErC;IACE,oBAAoB,WAAW,OAAO;;;;;cCnK7B,oDAAoC;;;;KAKrC,iCAAiC,cACpC;;;cCNI,yCAAyB;;;;;;;KAQ1B,sBAAsB,cAAc;;;cCNnC,gDAAgC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAWjC,6BAA6B,cAChC;;;cCbI,uCAAuB;;;;;;;;;;;;;;KAcxB,oBAAoB,cAAc;;;cCfjC,0CAA0B;;;;;;;;;;;;;;KAe3B,uBAAuB,cAAc;;;;;;;;;;;;;;;;;;;;;;;;cC2BpC,yCAAsB,yBAAA"}
@@ -1,22 +1,24 @@
1
- import { $inject, $module, Alepha, AlephaError, KIND, Primitive, createPrimitive, t } from "alepha";
1
+ import { $inject, $module, Alepha, AlephaError, KIND, Primitive, createPrimitive, z } from "alepha";
2
2
  import { $job, AlephaApiJobs, jobExecutionEntity } from "alepha/api/jobs";
3
3
  import { $parameter, AlephaApiParameters } from "alepha/api/parameters";
4
4
  import { $repository, pageQuerySchema } from "alepha/orm";
5
- import { $secure } from "alepha/security";
5
+ import { $secure, currentTenantAtom } from "alepha/security";
6
6
  import { $action, NotFoundError, okSchema } from "alepha/server";
7
7
  import { DateTimeProvider } from "alepha/datetime";
8
8
  import { $logger, logEntrySchema } from "alepha/logger";
9
9
  import { EmailProvider } from "alepha/email";
10
10
  import { SmsProvider } from "alepha/sms";
11
11
  //#region ../../src/api/notifications/schemas/notificationPayloadSchema.ts
12
- const notificationPayloadSchema = t.object({
13
- type: t.enum(["email", "sms"]),
14
- template: t.text(),
15
- contact: t.text(),
16
- variables: t.optional(t.record(t.text(), t.any())),
17
- category: t.optional(t.text()),
18
- critical: t.optional(t.boolean()),
19
- sensitive: t.optional(t.boolean())
12
+ const notificationPayloadSchema = z.object({
13
+ type: z.enum(["email", "sms"]),
14
+ template: z.text(),
15
+ contact: z.text(),
16
+ variables: z.record(z.text(), z.any()).optional(),
17
+ category: z.text().optional(),
18
+ critical: z.boolean().optional(),
19
+ sensitive: z.boolean().optional(),
20
+ /** Recipient language (e.g. "fr" or "fr-FR") used to pick `translations`. */
21
+ lang: z.text().optional()
20
22
  });
21
23
  //#endregion
22
24
  //#region ../../src/api/notifications/primitives/$notification.ts
@@ -32,7 +34,7 @@ const notificationPayloadSchema = t.object({
32
34
  * welcomeEmail = $notification({
33
35
  * name: "welcome-email",
34
36
  * category: "onboarding",
35
- * schema: t.object({ username: t.text(), activationLink: t.text() }),
37
+ * schema: z.object({ username: z.text(), activationLink: z.text() }),
36
38
  * email: {
37
39
  * subject: "Welcome to our platform!",
38
40
  * body: (vars) => `Hello ${vars.username}, click: ${vars.activationLink}`
@@ -54,8 +56,26 @@ var NotificationPrimitive = class extends Primitive {
54
56
  get name() {
55
57
  return this.options.name ?? `${this.config.propertyKey}`;
56
58
  }
59
+ /**
60
+ * Recipient language for `translations` resolution. Explicit `lang` wins;
61
+ * otherwise the language is captured FROM THE CURRENT REQUEST at push time
62
+ * (the i18n `lang` cookie, then `Accept-Language`) — the send job may run
63
+ * out of request context, so this must be resolved here, not in the sender.
64
+ */
65
+ resolveLang(explicit) {
66
+ if (explicit) return explicit;
67
+ const request = this.alepha.store.get("alepha.http.request");
68
+ const fromCookie = (request?.headers?.cookie)?.match(/(?:^|;\s*)lang=([a-zA-Z-]+)/)?.[1];
69
+ if (fromCookie) return fromCookie;
70
+ return (request?.headers?.["accept-language"])?.split(",")[0]?.trim().split(";")[0] || void 0;
71
+ }
57
72
  async push(options) {
58
- const pushOpts = this.options.critical ? { priority: "critical" } : void 0;
73
+ const lang = this.resolveLang(options.lang);
74
+ const organizationId = options.organizationId ?? this.alepha.store.get(currentTenantAtom)?.id;
75
+ const pushOpts = {
76
+ ...this.options.critical ? { priority: "critical" } : {},
77
+ organizationId
78
+ };
59
79
  if (this.options.email) await this.notificationJobs.sendNotification.push({
60
80
  type: "email",
61
81
  template: this.name,
@@ -63,7 +83,8 @@ var NotificationPrimitive = class extends Primitive {
63
83
  variables: options.variables,
64
84
  category: this.options.category,
65
85
  critical: this.options.critical,
66
- sensitive: this.options.sensitive
86
+ sensitive: this.options.sensitive,
87
+ lang
67
88
  }, pushOpts);
68
89
  if (this.options.sms) await this.notificationJobs.sendNotification.push({
69
90
  type: "sms",
@@ -72,7 +93,8 @@ var NotificationPrimitive = class extends Primitive {
72
93
  variables: options.variables,
73
94
  category: this.options.category,
74
95
  critical: this.options.critical,
75
- sensitive: this.options.sensitive
96
+ sensitive: this.options.sensitive,
97
+ lang
76
98
  }, pushOpts);
77
99
  }
78
100
  configure(options) {
@@ -123,7 +145,7 @@ var NotificationSenderService = class {
123
145
  }
124
146
  renderSms(payload) {
125
147
  const { variables, contact, template } = this.load(payload);
126
- const sms = template.options.sms;
148
+ const sms = this.translation(template.options, payload.lang)?.sms ?? template.options.sms;
127
149
  if (!sms) throw new AlephaError(`Notification template ${payload.template} has no sms defined`);
128
150
  return {
129
151
  to: contact,
@@ -132,7 +154,7 @@ var NotificationSenderService = class {
132
154
  }
133
155
  renderEmail(payload) {
134
156
  const { variables, contact, template } = this.load(payload);
135
- const email = template.options.email;
157
+ const email = this.translation(template.options, payload.lang)?.email ?? template.options.email;
136
158
  if (!email) throw new AlephaError(`Notification template ${payload.template} has no email defined`);
137
159
  return {
138
160
  to: contact,
@@ -140,6 +162,19 @@ var NotificationSenderService = class {
140
162
  body: typeof email.body === "function" ? email.body(variables) : email.body
141
163
  };
142
164
  }
165
+ /**
166
+ * Pick the template's `translations` entry for the payload language:
167
+ * exact match ("fr-FR") first, then the base language ("fr"). Returns
168
+ * undefined when there is no match — callers fall back to the default
169
+ * (template-level) message.
170
+ */
171
+ translation(options, lang) {
172
+ if (!lang || !options.translations) return void 0;
173
+ const exact = options.translations[lang];
174
+ if (exact) return exact;
175
+ const base = lang.split("-")[0]?.toLowerCase();
176
+ return base ? options.translations[base] : void 0;
177
+ }
143
178
  load(payload) {
144
179
  const variables = payload.variables || {};
145
180
  const contact = payload.contact;
@@ -180,10 +215,7 @@ var NotificationJobs = class {
180
215
  settings = $parameter({
181
216
  name: "alepha.api.notifications",
182
217
  description: "Notification delivery & retention settings.",
183
- schema: t.object({ retentionDays: t.integer({
184
- description: "Days to keep notification execution rows before the purge sweep removes them.",
185
- minimum: 1
186
- }) }),
218
+ schema: z.object({ retentionDays: z.integer().min(1).describe("Days to keep notification execution rows before the purge sweep removes them.") }),
187
219
  default: { retentionDays: 7 }
188
220
  });
189
221
  sendNotification = $job({
@@ -236,33 +268,33 @@ var NotificationJobs = class {
236
268
  };
237
269
  //#endregion
238
270
  //#region ../../src/api/notifications/schemas/notificationResourceSchema.ts
239
- const notificationResourceSchema = t.object({
240
- id: t.uuid(),
241
- createdAt: t.datetime(),
242
- status: t.text(),
243
- template: t.optional(t.text()),
244
- type: t.optional(t.text()),
245
- contact: t.optional(t.text()),
246
- category: t.optional(t.text()),
247
- critical: t.optional(t.boolean()),
248
- sensitive: t.optional(t.boolean()),
249
- startedAt: t.optional(t.datetime()),
250
- completedAt: t.optional(t.datetime()),
251
- error: t.optional(t.text())
271
+ const notificationResourceSchema = z.object({
272
+ id: z.uuid(),
273
+ createdAt: z.datetime(),
274
+ status: z.text(),
275
+ template: z.text().optional(),
276
+ type: z.text().optional(),
277
+ contact: z.text().optional(),
278
+ category: z.text().optional(),
279
+ critical: z.boolean().optional(),
280
+ sensitive: z.boolean().optional(),
281
+ startedAt: z.datetime().optional(),
282
+ completedAt: z.datetime().optional(),
283
+ error: z.text().optional()
252
284
  });
253
285
  //#endregion
254
286
  //#region ../../src/api/notifications/schemas/notificationDetailResourceSchema.ts
255
- const notificationDetailResourceSchema = t.extend(notificationResourceSchema, {
256
- variables: t.optional(t.record(t.text(), t.any())),
257
- rendered: t.optional(t.record(t.text(), t.any())),
258
- logs: t.optional(t.array(logEntrySchema))
259
- }, {
287
+ const notificationDetailResourceSchema = notificationResourceSchema.extend({
288
+ variables: z.record(z.text(), z.any()).optional(),
289
+ rendered: z.record(z.text(), z.any()).optional(),
290
+ logs: z.array(logEntrySchema).optional()
291
+ }).meta({
260
292
  title: "NotificationDetailResource",
261
293
  description: "A notification resource with rendered content and logs."
262
294
  });
263
295
  //#endregion
264
296
  //#region ../../src/api/notifications/schemas/notificationQuerySchema.ts
265
- const notificationQuerySchema = t.extend(pageQuerySchema, { status: t.optional(t.enum([
297
+ const notificationQuerySchema = pageQuerySchema.extend({ status: z.enum([
266
298
  "pending",
267
299
  "scheduled",
268
300
  "retrying",
@@ -270,29 +302,46 @@ const notificationQuerySchema = t.extend(pageQuerySchema, { status: t.optional(t
270
302
  "completed",
271
303
  "dead",
272
304
  "cancelled"
273
- ])) });
305
+ ]).optional() });
274
306
  //#endregion
275
307
  //#region ../../src/api/notifications/controllers/AdminNotificationController.ts
276
308
  var AdminNotificationController = class {
277
309
  url = "/notifications";
278
310
  group = "admin:notifications";
311
+ alepha = $inject(Alepha);
279
312
  notificationJobs = $inject(NotificationJobs);
280
313
  executions = $repository(jobExecutionEntity);
281
314
  get jobName() {
282
315
  return this.notificationJobs.sendNotification.name;
283
316
  }
317
+ /**
318
+ * The tenant this request is acting in, when multi-tenant. The notification
319
+ * outbox (`job_executions`) is shared across tenants in a pooled worker, so
320
+ * every read/delete here is scoped to this org to prevent cross-tenant access.
321
+ * Undefined in single-tenant apps → no extra filter (all rows are this app's).
322
+ */
323
+ get organizationId() {
324
+ return this.alepha.store.get(currentTenantAtom)?.id;
325
+ }
326
+ /** True when `exec` belongs to the acting tenant (or the app is single-tenant). */
327
+ sameTenant(exec) {
328
+ const org = this.organizationId;
329
+ return !org || exec.organizationId === org;
330
+ }
284
331
  findNotifications = $action({
285
332
  path: this.url,
286
333
  group: this.group,
287
334
  use: [$secure({ permissions: ["admin:notification:read"] })],
288
335
  schema: {
289
336
  query: notificationQuerySchema,
290
- response: t.page(notificationResourceSchema)
337
+ response: z.page(notificationResourceSchema)
291
338
  },
292
339
  handler: async ({ query }) => {
293
340
  query.sort ??= "-createdAt";
294
341
  const where = this.executions.createQueryWhere();
295
342
  where.jobName = { eq: this.jobName };
343
+ const org = this.organizationId;
344
+ if (org) where.organizationId = { eq: org };
296
345
  const page = await this.executions.paginate(query, { where }, { count: true });
297
346
  return {
298
347
  ...page,
@@ -305,12 +354,12 @@ var AdminNotificationController = class {
305
354
  group: this.group,
306
355
  use: [$secure({ permissions: ["admin:notification:read"] })],
307
356
  schema: {
308
- params: t.object({ id: t.uuid() }),
357
+ params: z.object({ id: z.uuid() }),
309
358
  response: notificationDetailResourceSchema
310
359
  },
311
360
  handler: async ({ params }) => {
312
361
  const exec = await this.executions.findById(params.id);
313
- if (!exec || exec.jobName !== this.jobName) throw new NotFoundError(`Notification not found: ${params.id}`);
362
+ if (!exec || exec.jobName !== this.jobName || !this.sameTenant(exec)) throw new NotFoundError(`Notification not found: ${params.id}`);
314
363
  return this.toDetailResource(exec);
315
364
  }
316
365
  });
@@ -321,12 +370,12 @@ var AdminNotificationController = class {
321
370
  use: [$secure({ permissions: ["admin:notification:delete"] })],
322
371
  description: "Delete a notification record",
323
372
  schema: {
324
- params: t.object({ id: t.uuid() }),
373
+ params: z.object({ id: z.uuid() }),
325
374
  response: okSchema
326
375
  },
327
376
  handler: async ({ params }) => {
328
377
  const exec = await this.executions.findById(params.id);
329
- if (!exec || exec.jobName !== this.jobName) throw new NotFoundError(`Notification not found: ${params.id}`);
378
+ if (!exec || exec.jobName !== this.jobName || !this.sameTenant(exec)) throw new NotFoundError(`Notification not found: ${params.id}`);
330
379
  await this.executions.deleteById(params.id);
331
380
  return {
332
381
  ok: true,
@@ -341,16 +390,15 @@ var AdminNotificationController = class {
341
390
  use: [$secure({ permissions: ["admin:notification:delete"] })],
342
391
  description: "Delete many notification records in one call",
343
392
  schema: {
344
- body: t.object({ ids: t.array(t.uuid(), {
345
- minItems: 1,
346
- maxItems: 1e3
347
- }) }),
348
- response: t.object({ deleted: t.array(t.uuid()) })
393
+ body: z.object({ ids: z.array(z.uuid()).min(1).max(1e3) }),
394
+ response: z.object({ deleted: z.array(z.uuid()) })
349
395
  },
350
396
  handler: async ({ body }) => {
397
+ const org = this.organizationId;
351
398
  return { deleted: (await this.executions.deleteMany({
352
399
  id: { inArray: body.ids },
353
- jobName: { eq: this.jobName }
400
+ jobName: { eq: this.jobName },
401
+ ...org ? { organizationId: { eq: org } } : {}
354
402
  })).map(String) };
355
403
  }
356
404
  });
@@ -382,18 +430,18 @@ var AdminNotificationController = class {
382
430
  };
383
431
  //#endregion
384
432
  //#region ../../src/api/notifications/schemas/notificationContactPreferencesSchema.ts
385
- const notificationContactPreferencesSchema = t.object({
386
- language: t.optional(t.text()),
387
- exclude: t.array(t.text())
433
+ const notificationContactPreferencesSchema = z.object({
434
+ language: z.text().optional(),
435
+ exclude: z.array(z.text())
388
436
  });
389
437
  //#endregion
390
438
  //#region ../../src/api/notifications/schemas/notificationContactSchema.ts
391
- const notificationContactSchema = t.object({
392
- email: t.optional(t.email()),
393
- phoneNumber: t.optional(t.e164()),
394
- firstName: t.optional(t.shortText()),
395
- lastName: t.optional(t.text({ size: "short" })),
396
- language: t.optional(t.bcp47())
439
+ const notificationContactSchema = z.object({
440
+ email: z.email().optional(),
441
+ phoneNumber: z.e164().optional(),
442
+ firstName: z.shortText().optional(),
443
+ lastName: z.text({ size: "short" }).optional(),
444
+ language: z.bcp47().optional()
397
445
  });
398
446
  //#endregion
399
447
  //#region ../../src/api/notifications/index.ts
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../../src/api/notifications/schemas/notificationPayloadSchema.ts","../../../src/api/notifications/primitives/$notification.ts","../../../src/api/notifications/services/NotificationSenderService.ts","../../../src/api/notifications/jobs/NotificationJobs.ts","../../../src/api/notifications/schemas/notificationResourceSchema.ts","../../../src/api/notifications/schemas/notificationDetailResourceSchema.ts","../../../src/api/notifications/schemas/notificationQuerySchema.ts","../../../src/api/notifications/controllers/AdminNotificationController.ts","../../../src/api/notifications/schemas/notificationContactPreferencesSchema.ts","../../../src/api/notifications/schemas/notificationContactSchema.ts","../../../src/api/notifications/index.ts"],"sourcesContent":["import { type Static, t } from \"alepha\";\n\nexport const notificationPayloadSchema = t.object({\n type: t.enum([\"email\", \"sms\"]),\n template: t.text(),\n contact: t.text(),\n variables: t.optional(t.record(t.text(), t.any())),\n category: t.optional(t.text()),\n critical: t.optional(t.boolean()),\n sensitive: t.optional(t.boolean()),\n});\n\nexport type NotificationPayload = Static<typeof notificationPayloadSchema>;\n","import {\n $inject,\n createPrimitive,\n KIND,\n Primitive,\n type Static,\n type StaticEncode,\n type TObject,\n} from \"alepha\";\nimport { NotificationJobs } from \"../jobs/NotificationJobs.ts\";\n\n/**\n * Creates a notification primitive for managing email/SMS notification templates.\n *\n * Provides type-safe, reusable notification templates with multi-language support,\n * variable substitution, and categorization for different notification channels.\n *\n * @example\n * ```ts\n * class NotificationTemplates {\n * welcomeEmail = $notification({\n * name: \"welcome-email\",\n * category: \"onboarding\",\n * schema: t.object({ username: t.text(), activationLink: t.text() }),\n * email: {\n * subject: \"Welcome to our platform!\",\n * body: (vars) => `Hello ${vars.username}, click: ${vars.activationLink}`\n * }\n * });\n *\n * async sendWelcome(user: User) {\n * await this.welcomeEmail.push({\n * variables: { username: user.name, activationLink: generateLink() },\n * contact: user.email\n * });\n * }\n * }\n * ```\n */\nexport const $notification = <T extends TObject>(\n options: NotificationPrimitiveOptions<T>,\n) => createPrimitive(NotificationPrimitive<T>, options);\n\n// ---------------------------------------------------------------------------------------------------------------------\n\nexport interface NotificationPrimitiveOptions<T extends TObject>\n extends NotificationMessage<T> {\n name?: string;\n description?: string;\n category?: string;\n critical?: boolean;\n sensitive?: boolean;\n translations?: {\n // e.g., \"en\", \"fr\", even \"en-US\"\n [lang: string]: NotificationMessage<T>;\n };\n schema: T;\n}\n\n// ---------------------------------------------------------------------------------------------------------------------\n\nexport class NotificationPrimitive<T extends TObject> extends Primitive<\n NotificationPrimitiveOptions<T>\n> {\n protected readonly notificationJobs = $inject(NotificationJobs);\n\n public get name() {\n return this.options.name ?? `${this.config.propertyKey}`;\n }\n\n public async push(options: NotificationPushOptions<T>) {\n const pushOpts = this.options.critical\n ? ({ priority: \"critical\" } as const)\n : undefined;\n\n if (this.options.email) {\n await this.notificationJobs.sendNotification.push(\n {\n type: \"email\",\n template: this.name,\n contact: options.contact,\n variables: options.variables as Record<string, unknown>,\n category: this.options.category,\n critical: this.options.critical,\n sensitive: this.options.sensitive,\n },\n pushOpts,\n );\n }\n\n if (this.options.sms) {\n await this.notificationJobs.sendNotification.push(\n {\n type: \"sms\",\n template: this.name,\n contact: options.contact,\n variables: options.variables as Record<string, unknown>,\n category: this.options.category,\n critical: this.options.critical,\n sensitive: this.options.sensitive,\n },\n pushOpts,\n );\n }\n }\n\n public configure(options: Partial<NotificationPrimitiveOptions<T>>) {\n Object.assign(this.options, options);\n }\n}\n\n$notification[KIND] = NotificationPrimitive;\n\n// ---------------------------------------------------------------------------------------------------------------------\n\nexport interface NotificationPushOptions<T extends TObject> {\n variables: StaticEncode<T>;\n contact: string;\n}\n\nexport interface NotificationMessage<T extends TObject> {\n email?: {\n subject: string;\n body: string | ((variables: Static<T>) => string);\n };\n sms?: {\n message: string | ((variables: Static<T>) => string);\n };\n}\n","import { $inject, Alepha, AlephaError } from \"alepha\";\nimport { EmailProvider } from \"alepha/email\";\nimport { $logger } from \"alepha/logger\";\nimport { SmsProvider } from \"alepha/sms\";\nimport { $notification } from \"../primitives/$notification.ts\";\nimport type { NotificationPayload } from \"../schemas/notificationPayloadSchema.ts\";\n\nexport class NotificationSenderService {\n protected readonly alepha = $inject(Alepha);\n protected readonly log = $logger();\n protected readonly emailProvider = $inject(EmailProvider);\n protected readonly smsProvider = $inject(SmsProvider);\n\n public async send(payload: NotificationPayload) {\n this.log.debug(\"Processing notification\", {\n type: payload.type,\n template: payload.template,\n contact: payload.contact,\n });\n\n if (payload.type === \"email\") {\n const rendered = this.renderEmail(payload);\n await this.emailProvider.send(rendered);\n this.log.info(\"Email notification sent\", {\n template: payload.template,\n contact: payload.contact,\n });\n return {\n type: \"email\" as const,\n to: rendered.to,\n subject: rendered.subject,\n body: rendered.body,\n };\n }\n\n if (payload.type === \"sms\") {\n const rendered = this.renderSms(payload);\n await this.smsProvider.send(rendered);\n this.log.info(\"SMS notification sent\", {\n template: payload.template,\n contact: payload.contact,\n });\n return {\n type: \"sms\" as const,\n to: rendered.to,\n message: rendered.message,\n };\n }\n }\n\n public renderSms(payload: NotificationPayload) {\n const { variables, contact, template } = this.load(payload);\n\n const sms = template.options.sms;\n if (!sms) {\n throw new AlephaError(\n `Notification template ${payload.template} has no sms defined`,\n );\n }\n\n const message =\n typeof sms.message === \"function\"\n ? sms.message(variables as any)\n : sms.message;\n\n return { to: contact, message };\n }\n\n public renderEmail(payload: NotificationPayload) {\n const { variables, contact, template } = this.load(payload);\n\n const email = template.options.email;\n if (!email) {\n throw new AlephaError(\n `Notification template ${payload.template} has no email defined`,\n );\n }\n\n const subject = email.subject;\n const body =\n typeof email.body === \"function\"\n ? email.body(variables as any)\n : email.body;\n\n return { to: contact, subject, body };\n }\n\n protected load(payload: NotificationPayload) {\n const variables = payload.variables || {};\n const contact = payload.contact;\n const template = this.alepha\n .primitives($notification)\n .find((it) => it.name === payload.template);\n\n if (!template) {\n throw new AlephaError(\n `No notification template found for ${payload.template}`,\n );\n }\n\n return { template, variables, contact };\n }\n}\n","import { $inject, t } from \"alepha\";\nimport { $job, jobExecutionEntity } from \"alepha/api/jobs\";\nimport { $parameter } from \"alepha/api/parameters\";\nimport { DateTimeProvider } from \"alepha/datetime\";\nimport { $logger } from \"alepha/logger\";\nimport { $repository } from \"alepha/orm\";\nimport { notificationPayloadSchema } from \"../schemas/notificationPayloadSchema.ts\";\nimport { NotificationSenderService } from \"../services/NotificationSenderService.ts\";\n\n/**\n * Notification jobs + runtime-editable retention.\n *\n * - `settings` — a `$parameter` exposing `retentionDays` that admins can\n * update at runtime. Changes propagate across instances via the parameter\n * pub/sub; the next purge run picks up the new value with no restart.\n * - `sendNotification` — queue-mode, audit-oriented. Every execution is kept\n * (`record: \"all\"`, `keep: { ok: 0, error: 0 }` disables the ring-buffer\n * trim) so the audit trail survives even under heavy volume.\n * - `purgeOldNotifications` — cron sweep that deletes notification execution\n * rows whose `completedAt` is older than the current `retentionDays`.\n *\n * Cron expression note: the purge cron is declared statically (`0 3 * * *`)\n * because some runtimes (Cloudflare Workers) freeze cron triggers at deploy\n * time. The *retention window* is fully runtime-editable — that's the knob\n * that actually matters for operators.\n */\nexport class NotificationJobs {\n protected readonly log = $logger();\n protected readonly dt = $inject(DateTimeProvider);\n protected readonly notificationSenderService = $inject(\n NotificationSenderService,\n );\n protected readonly executions = $repository(jobExecutionEntity);\n\n /** Runtime-editable config. Admins can change retentionDays without deploy. */\n public readonly settings = $parameter({\n name: \"alepha.api.notifications\",\n description: \"Notification delivery & retention settings.\",\n schema: t.object({\n retentionDays: t.integer({\n description:\n \"Days to keep notification execution rows before the purge sweep removes them.\",\n minimum: 1,\n }),\n }),\n default: {\n retentionDays: 7,\n },\n });\n\n public readonly sendNotification = $job({\n name: \"api:notifications:sendNotification\",\n description:\n \"Sends a notification (email/SMS) and keeps every execution for audit.\",\n schema: notificationPayloadSchema,\n retry: {\n retries: 3,\n },\n timeout: [30, \"seconds\"],\n record: \"all\",\n keep: { ok: 0, error: 0 },\n handler: async ({ payload }) => {\n await this.notificationSenderService.send(payload);\n },\n });\n\n public readonly purgeOldNotifications = $job({\n name: \"api:notifications:purgeOldNotifications\",\n description:\n \"Hourly sweep that deletes notification execution rows older than the configured retention window.\",\n cron: \"0 * * * *\",\n handler: async ({ now }) => {\n const { retentionDays } = this.settings.cachedCurrentContent;\n const cutoff = now.subtract(retentionDays, \"day\").toISOString();\n const jobName = this.sendNotification.name;\n\n const expired = await this.executions.findMany({\n where: {\n jobName: { eq: jobName },\n status: { inArray: [\"ok\", \"error\", \"cancelled\"] },\n completedAt: { lt: cutoff },\n },\n columns: [\"id\"] as any,\n limit: 5_000,\n });\n\n if (expired.length === 0) {\n this.log.debug(\"Notification purge: nothing to delete\", {\n cutoff,\n retentionDays,\n });\n return;\n }\n\n await this.executions.deleteMany({\n id: { inArray: expired.map((r) => r.id) },\n });\n this.log.info(\n `Notification purge: deleted ${expired.length} row(s) older than ${retentionDays} days`,\n { cutoff },\n );\n },\n });\n}\n","import { type Static, t } from \"alepha\";\n\nexport const notificationResourceSchema = t.object({\n id: t.uuid(),\n createdAt: t.datetime(),\n status: t.text(),\n template: t.optional(t.text()),\n type: t.optional(t.text()),\n contact: t.optional(t.text()),\n category: t.optional(t.text()),\n critical: t.optional(t.boolean()),\n sensitive: t.optional(t.boolean()),\n startedAt: t.optional(t.datetime()),\n completedAt: t.optional(t.datetime()),\n error: t.optional(t.text()),\n});\n\nexport type NotificationResource = Static<typeof notificationResourceSchema>;\n","import { type Static, t } from \"alepha\";\nimport { logEntrySchema } from \"alepha/logger\";\nimport { notificationResourceSchema } from \"./notificationResourceSchema.ts\";\n\nexport const notificationDetailResourceSchema = t.extend(\n notificationResourceSchema,\n {\n variables: t.optional(t.record(t.text(), t.any())),\n rendered: t.optional(t.record(t.text(), t.any())),\n logs: t.optional(t.array(logEntrySchema)),\n },\n {\n title: \"NotificationDetailResource\",\n description: \"A notification resource with rendered content and logs.\",\n },\n);\n\nexport type NotificationDetailResource = Static<\n typeof notificationDetailResourceSchema\n>;\n","import { type Static, t } from \"alepha\";\nimport { pageQuerySchema } from \"alepha/orm\";\n\nexport const notificationQuerySchema = t.extend(pageQuerySchema, {\n status: t.optional(\n t.enum([\n \"pending\",\n \"scheduled\",\n \"retrying\",\n \"running\",\n \"completed\",\n \"dead\",\n \"cancelled\",\n ]),\n ),\n});\n\nexport type NotificationQuery = Static<typeof notificationQuerySchema>;\n","import { $inject, t } from \"alepha\";\nimport { jobExecutionEntity } from \"alepha/api/jobs\";\nimport { $repository } from \"alepha/orm\";\nimport { $secure } from \"alepha/security\";\nimport { $action, NotFoundError, okSchema } from \"alepha/server\";\nimport { NotificationJobs } from \"../jobs/NotificationJobs.ts\";\nimport { notificationDetailResourceSchema } from \"../schemas/notificationDetailResourceSchema.ts\";\nimport { notificationQuerySchema } from \"../schemas/notificationQuerySchema.ts\";\nimport { notificationResourceSchema } from \"../schemas/notificationResourceSchema.ts\";\n\nexport class AdminNotificationController {\n protected readonly url: string = \"/notifications\";\n protected readonly group: string = \"admin:notifications\";\n protected readonly notificationJobs = $inject(NotificationJobs);\n protected readonly executions = $repository(jobExecutionEntity);\n\n protected get jobName(): string {\n return this.notificationJobs.sendNotification.name;\n }\n\n public readonly findNotifications = $action({\n path: this.url,\n group: this.group,\n use: [$secure({ permissions: [\"admin:notification:read\"] })],\n schema: {\n query: notificationQuerySchema,\n response: t.page(notificationResourceSchema),\n },\n handler: async ({ query }) => {\n query.sort ??= \"-createdAt\";\n const where = this.executions.createQueryWhere();\n where.jobName = { eq: this.jobName };\n const page = await this.executions.paginate(\n query,\n { where },\n { count: true },\n );\n return {\n ...page,\n content: page.content.map((exec) => this.toResource(exec)),\n } as any;\n },\n });\n\n public readonly getNotification = $action({\n path: `${this.url}/:id`,\n group: this.group,\n use: [$secure({ permissions: [\"admin:notification:read\"] })],\n schema: {\n params: t.object({\n id: t.uuid(),\n }),\n response: notificationDetailResourceSchema,\n },\n handler: async ({ params }) => {\n const exec = await this.executions.findById(params.id);\n if (!exec || exec.jobName !== this.jobName) {\n throw new NotFoundError(`Notification not found: ${params.id}`);\n }\n return this.toDetailResource(exec) as any;\n },\n });\n\n public readonly deleteNotification = $action({\n method: \"DELETE\",\n path: `${this.url}/:id`,\n group: this.group,\n use: [$secure({ permissions: [\"admin:notification:delete\"] })],\n description: \"Delete a notification record\",\n schema: {\n params: t.object({\n id: t.uuid(),\n }),\n response: okSchema,\n },\n handler: async ({ params }) => {\n const exec = await this.executions.findById(params.id);\n if (!exec || exec.jobName !== this.jobName) {\n throw new NotFoundError(`Notification not found: ${params.id}`);\n }\n await this.executions.deleteById(params.id);\n return { ok: true, id: params.id };\n },\n });\n\n public readonly deleteNotifications = $action({\n method: \"POST\",\n path: `${this.url}/delete`,\n group: this.group,\n use: [$secure({ permissions: [\"admin:notification:delete\"] })],\n description: \"Delete many notification records in one call\",\n schema: {\n body: t.object({\n ids: t.array(t.uuid(), { minItems: 1, maxItems: 1000 }),\n }),\n response: t.object({\n deleted: t.array(t.uuid()),\n }),\n },\n handler: async ({ body }) => {\n // Constrain to this job's executions so an admin can't delete arbitrary\n // job rows through this endpoint.\n const deleted = await this.executions.deleteMany({\n id: { inArray: body.ids },\n jobName: { eq: this.jobName },\n });\n return { deleted: deleted.map(String) };\n },\n });\n\n protected toResource(exec: Record<string, unknown>) {\n const payload = (exec.payload ?? {}) as Record<string, unknown>;\n return {\n id: exec.id,\n createdAt: exec.createdAt,\n status: exec.status,\n template: payload.template,\n type: payload.type,\n contact: payload.contact,\n category: payload.category,\n critical: payload.critical,\n sensitive: payload.sensitive,\n startedAt: exec.startedAt,\n completedAt: exec.completedAt,\n error: exec.error,\n };\n }\n\n protected toDetailResource(exec: Record<string, unknown>) {\n const payload = (exec.payload ?? {}) as Record<string, unknown>;\n return {\n ...this.toResource(exec),\n variables: payload.variables,\n logs: exec.logs,\n };\n }\n}\n","import { type Static, t } from \"alepha\";\n\nexport const notificationContactPreferencesSchema = t.object({\n language: t.optional(t.text()),\n exclude: t.array(t.text()),\n});\n\nexport type NotificationContactPreferences = Static<\n typeof notificationContactPreferencesSchema\n>;\n","import { type Static, t } from \"alepha\";\n\nexport const notificationContactSchema = t.object({\n email: t.optional(t.email()),\n phoneNumber: t.optional(t.e164()),\n firstName: t.optional(t.shortText()),\n lastName: t.optional(t.text({ size: \"short\" })),\n language: t.optional(t.bcp47()),\n});\n\nexport type NotificationContact = Static<typeof notificationContactSchema>;\n","import { $module } from \"alepha\";\nimport { AlephaApiJobs } from \"alepha/api/jobs\";\nimport { AlephaApiParameters } from \"alepha/api/parameters\";\nimport { AdminNotificationController } from \"./controllers/AdminNotificationController.ts\";\nimport { NotificationJobs } from \"./jobs/NotificationJobs.ts\";\nimport { $notification } from \"./primitives/$notification.ts\";\nimport { NotificationSenderService } from \"./services/NotificationSenderService.ts\";\n\n// ---------------------------------------------------------------------------------------------------------------------\n\nexport * from \"./controllers/AdminNotificationController.ts\";\nexport * from \"./jobs/NotificationJobs.ts\";\nexport * from \"./primitives/$notification.ts\";\nexport * from \"./schemas/notificationContactPreferencesSchema.ts\";\nexport * from \"./schemas/notificationContactSchema.ts\";\nexport * from \"./schemas/notificationDetailResourceSchema.ts\";\nexport * from \"./schemas/notificationPayloadSchema.ts\";\nexport * from \"./schemas/notificationQuerySchema.ts\";\nexport * from \"./schemas/notificationResourceSchema.ts\";\nexport * from \"./services/NotificationSenderService.ts\";\n\n// ---------------------------------------------------------------------------------------------------------------------\n\n/**\n * User notification management.\n *\n * **Features:**\n * - Notification definitions (email/SMS templates)\n * - Delivery via `$job` with retry and audit trail (`record: \"all\"` + no ring buffer trim)\n * - Runtime-editable retention window via `$parameter` — purge cron respects it live\n * - Admin API for inspecting sent notifications\n *\n * **Delivery mode** is decided at runtime by the `$job` system:\n * - If your app loads `AlephaApiJobsQueue` (and thus `AlephaQueue`), notifications\n * go through the queue (best for high-volume systems).\n * - Otherwise, notifications run in **direct** mode: pushed to the outbox table\n * and processed in the same process right after the HTTP response is returned.\n * The reconciliation sweep is the safety net for crashes / retries.\n *\n * Direct mode is the recommended default for small / cheap deployments\n * (Cloudflare Workers, single-instance Node) — no queue infrastructure required.\n *\n * @module alepha.api.notifications\n */\nexport const AlephaApiNotifications = $module({\n name: \"alepha.api.notifications\",\n imports: [AlephaApiJobs, AlephaApiParameters],\n primitives: [$notification],\n services: [\n NotificationSenderService,\n NotificationJobs,\n AdminNotificationController,\n ],\n});\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../../src/api/notifications/schemas/notificationPayloadSchema.ts","../../../src/api/notifications/primitives/$notification.ts","../../../src/api/notifications/services/NotificationSenderService.ts","../../../src/api/notifications/jobs/NotificationJobs.ts","../../../src/api/notifications/schemas/notificationResourceSchema.ts","../../../src/api/notifications/schemas/notificationDetailResourceSchema.ts","../../../src/api/notifications/schemas/notificationQuerySchema.ts","../../../src/api/notifications/controllers/AdminNotificationController.ts","../../../src/api/notifications/schemas/notificationContactPreferencesSchema.ts","../../../src/api/notifications/schemas/notificationContactSchema.ts","../../../src/api/notifications/index.ts"],"sourcesContent":["import { type Static, z } from \"alepha\";\n\nexport const notificationPayloadSchema = z.object({\n type: z.enum([\"email\", \"sms\"]),\n template: z.text(),\n contact: z.text(),\n variables: z.record(z.text(), z.any()).optional(),\n category: z.text().optional(),\n critical: z.boolean().optional(),\n sensitive: z.boolean().optional(),\n /** Recipient language (e.g. \"fr\" or \"fr-FR\") used to pick `translations`. */\n lang: z.text().optional(),\n});\n\nexport type NotificationPayload = Static<typeof notificationPayloadSchema>;\n","import {\n $inject,\n createPrimitive,\n KIND,\n Primitive,\n type Static,\n type StaticEncode,\n type TObject,\n} from \"alepha\";\nimport { currentTenantAtom } from \"alepha/security\";\nimport { NotificationJobs } from \"../jobs/NotificationJobs.ts\";\n\n/**\n * Creates a notification primitive for managing email/SMS notification templates.\n *\n * Provides type-safe, reusable notification templates with multi-language support,\n * variable substitution, and categorization for different notification channels.\n *\n * @example\n * ```ts\n * class NotificationTemplates {\n * welcomeEmail = $notification({\n * name: \"welcome-email\",\n * category: \"onboarding\",\n * schema: z.object({ username: z.text(), activationLink: z.text() }),\n * email: {\n * subject: \"Welcome to our platform!\",\n * body: (vars) => `Hello ${vars.username}, click: ${vars.activationLink}`\n * }\n * });\n *\n * async sendWelcome(user: User) {\n * await this.welcomeEmail.push({\n * variables: { username: user.name, activationLink: generateLink() },\n * contact: user.email\n * });\n * }\n * }\n * ```\n */\nexport const $notification = <T extends TObject>(\n options: NotificationPrimitiveOptions<T>,\n) => createPrimitive(NotificationPrimitive<T>, options);\n\n// ---------------------------------------------------------------------------------------------------------------------\n\nexport interface NotificationPrimitiveOptions<T extends TObject>\n extends NotificationMessage<T> {\n name?: string;\n description?: string;\n category?: string;\n critical?: boolean;\n sensitive?: boolean;\n translations?: {\n // e.g., \"en\", \"fr\", even \"en-US\"\n [lang: string]: NotificationMessage<T>;\n };\n schema: T;\n}\n\n// ---------------------------------------------------------------------------------------------------------------------\n\nexport class NotificationPrimitive<T extends TObject> extends Primitive<\n NotificationPrimitiveOptions<T>\n> {\n protected readonly notificationJobs = $inject(NotificationJobs);\n\n public get name() {\n return this.options.name ?? `${this.config.propertyKey}`;\n }\n\n /**\n * Recipient language for `translations` resolution. Explicit `lang` wins;\n * otherwise the language is captured FROM THE CURRENT REQUEST at push time\n * (the i18n `lang` cookie, then `Accept-Language`) — the send job may run\n * out of request context, so this must be resolved here, not in the sender.\n */\n protected resolveLang(explicit?: string): string | undefined {\n if (explicit) return explicit;\n const request = this.alepha.store.get(\"alepha.http.request\") as\n | { headers?: Record<string, string | undefined> }\n | undefined;\n const cookie = request?.headers?.cookie;\n const fromCookie = cookie?.match(/(?:^|;\\s*)lang=([a-zA-Z-]+)/)?.[1];\n if (fromCookie) return fromCookie;\n const accept = request?.headers?.[\"accept-language\"];\n return accept?.split(\",\")[0]?.trim().split(\";\")[0] || undefined;\n }\n\n public async push(options: NotificationPushOptions<T>) {\n const lang = this.resolveLang(options.lang);\n // Tag the outbox row with the owning tenant so the notification admin list\n // stays org-scoped (the outbox is shared by every tenant in a pooled\n // worker). Explicit `organizationId` wins (cron sweeps run out of request\n // context and pass the subject's org); otherwise fall back to the tenant\n // resolved for the current request.\n const organizationId =\n options.organizationId ?? this.alepha.store.get(currentTenantAtom)?.id;\n const pushOpts = {\n ...(this.options.critical ? ({ priority: \"critical\" } as const) : {}),\n organizationId,\n };\n\n if (this.options.email) {\n await this.notificationJobs.sendNotification.push(\n {\n type: \"email\",\n template: this.name,\n contact: options.contact,\n variables: options.variables as Record<string, unknown>,\n category: this.options.category,\n critical: this.options.critical,\n sensitive: this.options.sensitive,\n lang,\n },\n pushOpts,\n );\n }\n\n if (this.options.sms) {\n await this.notificationJobs.sendNotification.push(\n {\n type: \"sms\",\n template: this.name,\n contact: options.contact,\n variables: options.variables as Record<string, unknown>,\n category: this.options.category,\n critical: this.options.critical,\n sensitive: this.options.sensitive,\n lang,\n },\n pushOpts,\n );\n }\n }\n\n public configure(options: Partial<NotificationPrimitiveOptions<T>>) {\n Object.assign(this.options, options);\n }\n}\n\n$notification[KIND] = NotificationPrimitive;\n\n// ---------------------------------------------------------------------------------------------------------------------\n\nexport interface NotificationPushOptions<T extends TObject> {\n variables: StaticEncode<T>;\n contact: string;\n /** Recipient language (e.g. \"fr\"); defaults to the current request's. */\n lang?: string;\n /**\n * Owning tenant for this notification. Defaults to the tenant resolved for\n * the current request. Pass it explicitly when sending from a context with no\n * request tenant — e.g. a cron sweep that fans out across clubs (use the\n * subject entity's `organizationId`) — so the row stays correctly org-scoped.\n */\n organizationId?: string;\n}\n\nexport interface NotificationMessage<T extends TObject> {\n email?: {\n subject: string;\n body: string | ((variables: Static<T>) => string);\n };\n sms?: {\n message: string | ((variables: Static<T>) => string);\n };\n}\n","import { $inject, Alepha, AlephaError } from \"alepha\";\nimport { EmailProvider } from \"alepha/email\";\nimport { $logger } from \"alepha/logger\";\nimport { SmsProvider } from \"alepha/sms\";\nimport { $notification } from \"../primitives/$notification.ts\";\nimport type { NotificationPayload } from \"../schemas/notificationPayloadSchema.ts\";\n\ntype NotificationMessageEmail = {\n subject: string;\n body: string | ((variables: any) => string);\n};\ntype NotificationMessageSms = {\n message: string | ((variables: any) => string);\n};\n\nexport class NotificationSenderService {\n protected readonly alepha = $inject(Alepha);\n protected readonly log = $logger();\n protected readonly emailProvider = $inject(EmailProvider);\n protected readonly smsProvider = $inject(SmsProvider);\n\n public async send(payload: NotificationPayload) {\n this.log.debug(\"Processing notification\", {\n type: payload.type,\n template: payload.template,\n contact: payload.contact,\n });\n\n if (payload.type === \"email\") {\n const rendered = this.renderEmail(payload);\n await this.emailProvider.send(rendered);\n this.log.info(\"Email notification sent\", {\n template: payload.template,\n contact: payload.contact,\n });\n return {\n type: \"email\" as const,\n to: rendered.to,\n subject: rendered.subject,\n body: rendered.body,\n };\n }\n\n if (payload.type === \"sms\") {\n const rendered = this.renderSms(payload);\n await this.smsProvider.send(rendered);\n this.log.info(\"SMS notification sent\", {\n template: payload.template,\n contact: payload.contact,\n });\n return {\n type: \"sms\" as const,\n to: rendered.to,\n message: rendered.message,\n };\n }\n }\n\n public renderSms(payload: NotificationPayload) {\n const { variables, contact, template } = this.load(payload);\n\n const sms =\n this.translation(template.options, payload.lang)?.sms ??\n template.options.sms;\n if (!sms) {\n throw new AlephaError(\n `Notification template ${payload.template} has no sms defined`,\n );\n }\n\n const message =\n typeof sms.message === \"function\"\n ? sms.message(variables as any)\n : sms.message;\n\n return { to: contact, message };\n }\n\n public renderEmail(payload: NotificationPayload) {\n const { variables, contact, template } = this.load(payload);\n\n const email =\n this.translation(template.options, payload.lang)?.email ??\n template.options.email;\n if (!email) {\n throw new AlephaError(\n `Notification template ${payload.template} has no email defined`,\n );\n }\n\n const subject = email.subject;\n const body =\n typeof email.body === \"function\"\n ? email.body(variables as any)\n : email.body;\n\n return { to: contact, subject, body };\n }\n\n /**\n * Pick the template's `translations` entry for the payload language:\n * exact match (\"fr-FR\") first, then the base language (\"fr\"). Returns\n * undefined when there is no match — callers fall back to the default\n * (template-level) message.\n */\n protected translation(\n options: {\n translations?: Record<\n string,\n { email?: unknown; sms?: unknown } | undefined\n >;\n },\n lang?: string,\n ):\n | { email?: NotificationMessageEmail; sms?: NotificationMessageSms }\n | undefined {\n if (!lang || !options.translations) return undefined;\n const exact = options.translations[lang];\n if (exact) return exact as any;\n const base = lang.split(\"-\")[0]?.toLowerCase();\n return base ? (options.translations[base] as any) : undefined;\n }\n\n protected load(payload: NotificationPayload) {\n const variables = payload.variables || {};\n const contact = payload.contact;\n const template = this.alepha\n .primitives($notification)\n .find((it) => it.name === payload.template);\n\n if (!template) {\n throw new AlephaError(\n `No notification template found for ${payload.template}`,\n );\n }\n\n return { template, variables, contact };\n }\n}\n","import { $inject, z } from \"alepha\";\nimport { $job, jobExecutionEntity } from \"alepha/api/jobs\";\nimport { $parameter } from \"alepha/api/parameters\";\nimport { DateTimeProvider } from \"alepha/datetime\";\nimport { $logger } from \"alepha/logger\";\nimport { $repository } from \"alepha/orm\";\nimport { notificationPayloadSchema } from \"../schemas/notificationPayloadSchema.ts\";\nimport { NotificationSenderService } from \"../services/NotificationSenderService.ts\";\n\n/**\n * Notification jobs + runtime-editable retention.\n *\n * - `settings` — a `$parameter` exposing `retentionDays` that admins can\n * update at runtime. Changes propagate across instances via the parameter\n * pub/sub; the next purge run picks up the new value with no restart.\n * - `sendNotification` — queue-mode, audit-oriented. Every execution is kept\n * (`record: \"all\"`, `keep: { ok: 0, error: 0 }` disables the ring-buffer\n * trim) so the audit trail survives even under heavy volume.\n * - `purgeOldNotifications` — cron sweep that deletes notification execution\n * rows whose `completedAt` is older than the current `retentionDays`.\n *\n * Cron expression note: the purge cron is declared statically (`0 3 * * *`)\n * because some runtimes (Cloudflare Workers) freeze cron triggers at deploy\n * time. The *retention window* is fully runtime-editable — that's the knob\n * that actually matters for operators.\n */\nexport class NotificationJobs {\n protected readonly log = $logger();\n protected readonly dt = $inject(DateTimeProvider);\n protected readonly notificationSenderService = $inject(\n NotificationSenderService,\n );\n protected readonly executions = $repository(jobExecutionEntity);\n\n /** Runtime-editable config. Admins can change retentionDays without deploy. */\n public readonly settings = $parameter({\n name: \"alepha.api.notifications\",\n description: \"Notification delivery & retention settings.\",\n schema: z.object({\n retentionDays: z\n .integer()\n .min(1)\n .describe(\n \"Days to keep notification execution rows before the purge sweep removes them.\",\n ),\n }),\n default: {\n retentionDays: 7,\n },\n });\n\n public readonly sendNotification = $job({\n name: \"api:notifications:sendNotification\",\n description:\n \"Sends a notification (email/SMS) and keeps every execution for audit.\",\n schema: notificationPayloadSchema,\n retry: {\n retries: 3,\n },\n timeout: [30, \"seconds\"],\n record: \"all\",\n keep: { ok: 0, error: 0 },\n handler: async ({ payload }) => {\n await this.notificationSenderService.send(payload);\n },\n });\n\n public readonly purgeOldNotifications = $job({\n name: \"api:notifications:purgeOldNotifications\",\n description:\n \"Hourly sweep that deletes notification execution rows older than the configured retention window.\",\n cron: \"0 * * * *\",\n handler: async ({ now }) => {\n const { retentionDays } = this.settings.cachedCurrentContent;\n const cutoff = now.subtract(retentionDays, \"day\").toISOString();\n const jobName = this.sendNotification.name;\n\n const expired = await this.executions.findMany({\n where: {\n jobName: { eq: jobName },\n status: { inArray: [\"ok\", \"error\", \"cancelled\"] },\n completedAt: { lt: cutoff },\n },\n columns: [\"id\"] as any,\n limit: 5_000,\n });\n\n if (expired.length === 0) {\n this.log.debug(\"Notification purge: nothing to delete\", {\n cutoff,\n retentionDays,\n });\n return;\n }\n\n await this.executions.deleteMany({\n id: { inArray: expired.map((r) => r.id) },\n });\n this.log.info(\n `Notification purge: deleted ${expired.length} row(s) older than ${retentionDays} days`,\n { cutoff },\n );\n },\n });\n}\n","import { type Static, z } from \"alepha\";\n\nexport const notificationResourceSchema = z.object({\n id: z.uuid(),\n createdAt: z.datetime(),\n status: z.text(),\n template: z.text().optional(),\n type: z.text().optional(),\n contact: z.text().optional(),\n category: z.text().optional(),\n critical: z.boolean().optional(),\n sensitive: z.boolean().optional(),\n startedAt: z.datetime().optional(),\n completedAt: z.datetime().optional(),\n error: z.text().optional(),\n});\n\nexport type NotificationResource = Static<typeof notificationResourceSchema>;\n","import { type Static, z } from \"alepha\";\nimport { logEntrySchema } from \"alepha/logger\";\nimport { notificationResourceSchema } from \"./notificationResourceSchema.ts\";\n\nexport const notificationDetailResourceSchema = notificationResourceSchema\n .extend({\n variables: z.record(z.text(), z.any()).optional(),\n rendered: z.record(z.text(), z.any()).optional(),\n logs: z.array(logEntrySchema).optional(),\n })\n .meta({\n title: \"NotificationDetailResource\",\n description: \"A notification resource with rendered content and logs.\",\n });\n\nexport type NotificationDetailResource = Static<\n typeof notificationDetailResourceSchema\n>;\n","import { type Static, z } from \"alepha\";\nimport { pageQuerySchema } from \"alepha/orm\";\n\nexport const notificationQuerySchema = pageQuerySchema.extend({\n status: z\n .enum([\n \"pending\",\n \"scheduled\",\n \"retrying\",\n \"running\",\n \"completed\",\n \"dead\",\n \"cancelled\",\n ])\n .optional(),\n});\n\nexport type NotificationQuery = Static<typeof notificationQuerySchema>;\n","import { $inject, Alepha, z } from \"alepha\";\nimport { jobExecutionEntity } from \"alepha/api/jobs\";\nimport { $repository } from \"alepha/orm\";\nimport { $secure, currentTenantAtom } from \"alepha/security\";\nimport { $action, NotFoundError, okSchema } from \"alepha/server\";\nimport { NotificationJobs } from \"../jobs/NotificationJobs.ts\";\nimport { notificationDetailResourceSchema } from \"../schemas/notificationDetailResourceSchema.ts\";\nimport { notificationQuerySchema } from \"../schemas/notificationQuerySchema.ts\";\nimport { notificationResourceSchema } from \"../schemas/notificationResourceSchema.ts\";\n\nexport class AdminNotificationController {\n protected readonly url: string = \"/notifications\";\n protected readonly group: string = \"admin:notifications\";\n protected readonly alepha = $inject(Alepha);\n protected readonly notificationJobs = $inject(NotificationJobs);\n protected readonly executions = $repository(jobExecutionEntity);\n\n protected get jobName(): string {\n return this.notificationJobs.sendNotification.name;\n }\n\n /**\n * The tenant this request is acting in, when multi-tenant. The notification\n * outbox (`job_executions`) is shared across tenants in a pooled worker, so\n * every read/delete here is scoped to this org to prevent cross-tenant access.\n * Undefined in single-tenant apps → no extra filter (all rows are this app's).\n */\n protected get organizationId(): string | undefined {\n return this.alepha.store.get(currentTenantAtom)?.id;\n }\n\n /** True when `exec` belongs to the acting tenant (or the app is single-tenant). */\n protected sameTenant(exec: { organizationId?: string | null }): boolean {\n const org = this.organizationId;\n return !org || exec.organizationId === org;\n }\n\n public readonly findNotifications = $action({\n path: this.url,\n group: this.group,\n use: [$secure({ permissions: [\"admin:notification:read\"] })],\n schema: {\n query: notificationQuerySchema,\n response: z.page(notificationResourceSchema),\n },\n handler: async ({ query }) => {\n query.sort ??= \"-createdAt\";\n const where = this.executions.createQueryWhere();\n where.jobName = { eq: this.jobName };\n const org = this.organizationId;\n if (org) {\n where.organizationId = { eq: org };\n }\n const page = await this.executions.paginate(\n query,\n { where },\n { count: true },\n );\n return {\n ...page,\n content: page.content.map((exec) => this.toResource(exec)),\n } as any;\n },\n });\n\n public readonly getNotification = $action({\n path: `${this.url}/:id`,\n group: this.group,\n use: [$secure({ permissions: [\"admin:notification:read\"] })],\n schema: {\n params: z.object({\n id: z.uuid(),\n }),\n response: notificationDetailResourceSchema,\n },\n handler: async ({ params }) => {\n const exec = await this.executions.findById(params.id);\n if (!exec || exec.jobName !== this.jobName || !this.sameTenant(exec)) {\n throw new NotFoundError(`Notification not found: ${params.id}`);\n }\n return this.toDetailResource(exec) as any;\n },\n });\n\n public readonly deleteNotification = $action({\n method: \"DELETE\",\n path: `${this.url}/:id`,\n group: this.group,\n use: [$secure({ permissions: [\"admin:notification:delete\"] })],\n description: \"Delete a notification record\",\n schema: {\n params: z.object({\n id: z.uuid(),\n }),\n response: okSchema,\n },\n handler: async ({ params }) => {\n const exec = await this.executions.findById(params.id);\n if (!exec || exec.jobName !== this.jobName || !this.sameTenant(exec)) {\n throw new NotFoundError(`Notification not found: ${params.id}`);\n }\n await this.executions.deleteById(params.id);\n return { ok: true, id: params.id };\n },\n });\n\n public readonly deleteNotifications = $action({\n method: \"POST\",\n path: `${this.url}/delete`,\n group: this.group,\n use: [$secure({ permissions: [\"admin:notification:delete\"] })],\n description: \"Delete many notification records in one call\",\n schema: {\n body: z.object({\n ids: z.array(z.uuid()).min(1).max(1000),\n }),\n response: z.object({\n deleted: z.array(z.uuid()),\n }),\n },\n handler: async ({ body }) => {\n // Constrain to this job's executions so an admin can't delete arbitrary\n // job rows through this endpoint — and, when multi-tenant, to this org so\n // one club can't delete another club's notification records.\n const org = this.organizationId;\n const deleted = await this.executions.deleteMany({\n id: { inArray: body.ids },\n jobName: { eq: this.jobName },\n ...(org ? { organizationId: { eq: org } } : {}),\n });\n return { deleted: deleted.map(String) };\n },\n });\n\n protected toResource(exec: Record<string, unknown>) {\n const payload = (exec.payload ?? {}) as Record<string, unknown>;\n return {\n id: exec.id,\n createdAt: exec.createdAt,\n status: exec.status,\n template: payload.template,\n type: payload.type,\n contact: payload.contact,\n category: payload.category,\n critical: payload.critical,\n sensitive: payload.sensitive,\n startedAt: exec.startedAt,\n completedAt: exec.completedAt,\n error: exec.error,\n };\n }\n\n protected toDetailResource(exec: Record<string, unknown>) {\n const payload = (exec.payload ?? {}) as Record<string, unknown>;\n return {\n ...this.toResource(exec),\n variables: payload.variables,\n logs: exec.logs,\n };\n }\n}\n","import { type Static, z } from \"alepha\";\n\nexport const notificationContactPreferencesSchema = z.object({\n language: z.text().optional(),\n exclude: z.array(z.text()),\n});\n\nexport type NotificationContactPreferences = Static<\n typeof notificationContactPreferencesSchema\n>;\n","import { type Static, z } from \"alepha\";\n\nexport const notificationContactSchema = z.object({\n email: z.email().optional(),\n phoneNumber: z.e164().optional(),\n firstName: z.shortText().optional(),\n lastName: z.text({ size: \"short\" }).optional(),\n language: z.bcp47().optional(),\n});\n\nexport type NotificationContact = Static<typeof notificationContactSchema>;\n","import { $module } from \"alepha\";\nimport { AlephaApiJobs } from \"alepha/api/jobs\";\nimport { AlephaApiParameters } from \"alepha/api/parameters\";\nimport { AdminNotificationController } from \"./controllers/AdminNotificationController.ts\";\nimport { NotificationJobs } from \"./jobs/NotificationJobs.ts\";\nimport { $notification } from \"./primitives/$notification.ts\";\nimport { NotificationSenderService } from \"./services/NotificationSenderService.ts\";\n\n// ---------------------------------------------------------------------------------------------------------------------\n\nexport * from \"./controllers/AdminNotificationController.ts\";\nexport * from \"./jobs/NotificationJobs.ts\";\nexport * from \"./primitives/$notification.ts\";\nexport * from \"./schemas/notificationContactPreferencesSchema.ts\";\nexport * from \"./schemas/notificationContactSchema.ts\";\nexport * from \"./schemas/notificationDetailResourceSchema.ts\";\nexport * from \"./schemas/notificationPayloadSchema.ts\";\nexport * from \"./schemas/notificationQuerySchema.ts\";\nexport * from \"./schemas/notificationResourceSchema.ts\";\nexport * from \"./services/NotificationSenderService.ts\";\n\n// ---------------------------------------------------------------------------------------------------------------------\n\n/**\n * User notification management.\n *\n * **Features:**\n * - Notification definitions (email/SMS templates)\n * - Delivery via `$job` with retry and audit trail (`record: \"all\"` + no ring buffer trim)\n * - Runtime-editable retention window via `$parameter` — purge cron respects it live\n * - Admin API for inspecting sent notifications\n *\n * **Delivery mode** is decided at runtime by the `$job` system:\n * - If your app loads `AlephaApiJobsQueue` (and thus `AlephaQueue`), notifications\n * go through the queue (best for high-volume systems).\n * - Otherwise, notifications run in **direct** mode: pushed to the outbox table\n * and processed in the same process right after the HTTP response is returned.\n * The reconciliation sweep is the safety net for crashes / retries.\n *\n * Direct mode is the recommended default for small / cheap deployments\n * (Cloudflare Workers, single-instance Node) — no queue infrastructure required.\n *\n * @module alepha.api.notifications\n */\nexport const AlephaApiNotifications = $module({\n name: \"alepha.api.notifications\",\n imports: [AlephaApiJobs, AlephaApiParameters],\n primitives: [$notification],\n services: [\n NotificationSenderService,\n NotificationJobs,\n AdminNotificationController,\n ],\n});\n"],"mappings":"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"}