alepha 0.20.1 → 0.20.3

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 (393) hide show
  1. package/README.md +0 -1
  2. package/assets/swagger-ui/swagger-ui-bundle.js +1 -1
  3. package/assets/swagger-ui/swagger-ui.css +1 -1
  4. package/dist/api/audits/index.browser.js +49 -0
  5. package/dist/api/audits/index.browser.js.map +1 -1
  6. package/dist/api/audits/index.d.ts.map +1 -1
  7. package/dist/api/audits/index.js +49 -0
  8. package/dist/api/audits/index.js.map +1 -1
  9. package/dist/api/files/index.d.ts.map +1 -1
  10. package/dist/api/files/index.js +2 -1
  11. package/dist/api/files/index.js.map +1 -1
  12. package/dist/api/jobs/index.browser.js +64 -148
  13. package/dist/api/jobs/index.browser.js.map +1 -1
  14. package/dist/api/jobs/index.d.ts +339 -600
  15. package/dist/api/jobs/index.d.ts.map +1 -1
  16. package/dist/api/jobs/index.js +605 -1012
  17. package/dist/api/jobs/index.js.map +1 -1
  18. package/dist/api/keys/index.js.map +1 -1
  19. package/dist/api/notifications/index.d.ts +79 -27
  20. package/dist/api/notifications/index.d.ts.map +1 -1
  21. package/dist/api/notifications/index.js +90 -23
  22. package/dist/api/notifications/index.js.map +1 -1
  23. package/dist/api/organizations/index.d.ts.map +1 -1
  24. package/dist/api/parameters/index.browser.js +37 -0
  25. package/dist/api/parameters/index.browser.js.map +1 -1
  26. package/dist/api/parameters/index.d.ts +4 -65
  27. package/dist/api/parameters/index.d.ts.map +1 -1
  28. package/dist/api/parameters/index.js +37 -0
  29. package/dist/api/parameters/index.js.map +1 -1
  30. package/dist/api/payments/index.d.ts +2 -1
  31. package/dist/api/payments/index.d.ts.map +1 -1
  32. package/dist/api/payments/index.js +4 -2
  33. package/dist/api/payments/index.js.map +1 -1
  34. package/dist/api/users/index.d.ts +225 -5199
  35. package/dist/api/users/index.d.ts.map +1 -1
  36. package/dist/api/users/index.js +15 -11
  37. package/dist/api/users/index.js.map +1 -1
  38. package/dist/api/verifications/index.d.ts.map +1 -1
  39. package/dist/api/verifications/index.js +4 -2
  40. package/dist/api/verifications/index.js.map +1 -1
  41. package/dist/bucket/index.js +5 -1
  42. package/dist/bucket/index.js.map +1 -1
  43. package/dist/bucket/index.workerd.js +5 -1
  44. package/dist/bucket/index.workerd.js.map +1 -1
  45. package/dist/cache/core/index.js.map +1 -1
  46. package/dist/cache/core/index.workerd.js.map +1 -1
  47. package/dist/captcha/index.js.map +1 -1
  48. package/dist/cli/core/index.d.ts +225 -11681
  49. package/dist/cli/core/index.d.ts.map +1 -1
  50. package/dist/cli/core/index.js +732 -257
  51. package/dist/cli/core/index.js.map +1 -1
  52. package/dist/cli/devtools/index.js +7 -1
  53. package/dist/cli/devtools/index.js.map +1 -1
  54. package/dist/cli/platform/index.d.ts +65 -63
  55. package/dist/cli/platform/index.d.ts.map +1 -1
  56. package/dist/cli/platform/index.js +140 -27
  57. package/dist/cli/platform/index.js.map +1 -1
  58. package/dist/cli/vendor/index.js +15 -0
  59. package/dist/cli/vendor/index.js.map +1 -1
  60. package/dist/command/index.d.ts +1 -1
  61. package/dist/command/index.js +1 -1
  62. package/dist/command/index.js.map +1 -1
  63. package/dist/core/index.browser.js +6 -0
  64. package/dist/core/index.browser.js.map +1 -1
  65. package/dist/core/index.d.ts +8 -8
  66. package/dist/core/index.d.ts.map +1 -1
  67. package/dist/core/index.js +6 -0
  68. package/dist/core/index.js.map +1 -1
  69. package/dist/core/index.native.js +6 -0
  70. package/dist/core/index.native.js.map +1 -1
  71. package/dist/core/index.workerd.js +6 -0
  72. package/dist/core/index.workerd.js.map +1 -1
  73. package/dist/crypto/index.js.map +1 -1
  74. package/dist/datetime/index.js.map +1 -1
  75. package/dist/email/core/index.js.map +1 -1
  76. package/dist/email/smtp/index.js +2 -10522
  77. package/dist/email/smtp/index.js.map +1 -1
  78. package/dist/fake/index.d.ts +4 -8085
  79. package/dist/fake/index.d.ts.map +1 -1
  80. package/dist/fake/index.js +3 -33554
  81. package/dist/fake/index.js.map +1 -1
  82. package/dist/lock/core/index.js.map +1 -1
  83. package/dist/lock/redis/index.js.map +1 -1
  84. package/dist/logger/index.js +32 -1
  85. package/dist/logger/index.js.map +1 -1
  86. package/dist/mcp/index.js +5 -1
  87. package/dist/mcp/index.js.map +1 -1
  88. package/dist/orm/core/index.browser.js +1 -361
  89. package/dist/orm/core/index.browser.js.map +1 -1
  90. package/dist/orm/core/index.bun.js +14 -406
  91. package/dist/orm/core/index.bun.js.map +1 -1
  92. package/dist/orm/core/index.d.ts +96 -5117
  93. package/dist/orm/core/index.d.ts.map +1 -1
  94. package/dist/orm/core/index.js +23 -419
  95. package/dist/orm/core/index.js.map +1 -1
  96. package/dist/orm/postgres/index.bun.js +17 -20
  97. package/dist/orm/postgres/index.bun.js.map +1 -1
  98. package/dist/orm/postgres/index.d.ts +2 -613
  99. package/dist/orm/postgres/index.d.ts.map +1 -1
  100. package/dist/orm/postgres/index.js +17 -20
  101. package/dist/orm/postgres/index.js.map +1 -1
  102. package/dist/react/core/index.js.map +1 -1
  103. package/dist/react/form/index.d.ts +60 -1
  104. package/dist/react/form/index.d.ts.map +1 -1
  105. package/dist/react/form/index.js +86 -1
  106. package/dist/react/form/index.js.map +1 -1
  107. package/dist/react/head/index.browser.js +16 -1
  108. package/dist/react/head/index.browser.js.map +1 -1
  109. package/dist/react/head/index.d.ts +6 -0
  110. package/dist/react/head/index.d.ts.map +1 -1
  111. package/dist/react/head/index.js +16 -1
  112. package/dist/react/head/index.js.map +1 -1
  113. package/dist/react/i18n/index.js.map +1 -1
  114. package/dist/react/intro/index.js +22 -17
  115. package/dist/react/intro/index.js.map +1 -1
  116. package/dist/react/router/index.browser.js +78 -12
  117. package/dist/react/router/index.browser.js.map +1 -1
  118. package/dist/react/router/index.d.ts +57 -13
  119. package/dist/react/router/index.d.ts.map +1 -1
  120. package/dist/react/router/index.js +102 -14
  121. package/dist/react/router/index.js.map +1 -1
  122. package/dist/react/testing/index.d.ts +1 -411
  123. package/dist/react/testing/index.d.ts.map +1 -1
  124. package/dist/react/testing/index.js +13 -12293
  125. package/dist/react/testing/index.js.map +1 -1
  126. package/dist/react/ui/index.d.ts +124 -0
  127. package/dist/react/ui/index.d.ts.map +1 -0
  128. package/dist/react/ui/index.js +209 -0
  129. package/dist/react/ui/index.js.map +1 -0
  130. package/dist/react/websocket/index.js.map +1 -1
  131. package/dist/redis/index.js.map +1 -1
  132. package/dist/router/index.d.ts +13 -13
  133. package/dist/router/index.d.ts.map +1 -1
  134. package/dist/router/index.js +45 -32
  135. package/dist/router/index.js.map +1 -1
  136. package/dist/scheduler/index.d.ts +1 -83
  137. package/dist/scheduler/index.d.ts.map +1 -1
  138. package/dist/scheduler/index.js +2 -391
  139. package/dist/scheduler/index.js.map +1 -1
  140. package/dist/scheduler/index.workerd.js +2 -391
  141. package/dist/scheduler/index.workerd.js.map +1 -1
  142. package/dist/security/index.browser.js.map +1 -1
  143. package/dist/security/index.d.ts +2 -325
  144. package/dist/security/index.d.ts.map +1 -1
  145. package/dist/security/index.js +3 -1362
  146. package/dist/security/index.js.map +1 -1
  147. package/dist/server/auth/index.d.ts +1 -1054
  148. package/dist/server/auth/index.d.ts.map +1 -1
  149. package/dist/server/auth/index.js +16 -1224
  150. package/dist/server/auth/index.js.map +1 -1
  151. package/dist/server/cookies/index.js.map +1 -1
  152. package/dist/server/core/index.browser.js.map +1 -1
  153. package/dist/server/core/index.d.ts +1 -4
  154. package/dist/server/core/index.d.ts.map +1 -1
  155. package/dist/server/core/index.js +19 -4
  156. package/dist/server/core/index.js.map +1 -1
  157. package/dist/server/links/index.browser.js.map +1 -1
  158. package/dist/server/links/index.js.map +1 -1
  159. package/dist/server/metrics/index.d.ts +1 -514
  160. package/dist/server/metrics/index.d.ts.map +1 -1
  161. package/dist/server/metrics/index.js +4 -4356
  162. package/dist/server/metrics/index.js.map +1 -1
  163. package/dist/server/rate-limit/index.js.map +1 -1
  164. package/dist/server/static/index.js.map +1 -1
  165. package/dist/server/swagger/index.js +1 -1
  166. package/dist/server/swagger/index.js.map +1 -1
  167. package/dist/sms/index.js.map +1 -1
  168. package/dist/system/index.browser.js.map +1 -1
  169. package/dist/system/index.d.ts.map +1 -1
  170. package/dist/system/index.js +1 -0
  171. package/dist/system/index.js.map +1 -1
  172. package/dist/system/index.workerd.js.map +1 -1
  173. package/dist/topic/core/index.js +1 -1
  174. package/dist/topic/core/index.js.map +1 -1
  175. package/dist/websocket/index.browser.js +21 -0
  176. package/dist/websocket/index.browser.js.map +1 -1
  177. package/dist/websocket/index.js +21 -0
  178. package/dist/websocket/index.js.map +1 -1
  179. package/package.json +23 -37
  180. package/src/api/files/__tests__/FileController.spec.ts +1 -1
  181. package/src/api/files/jobs/FileJobs.ts +2 -1
  182. package/src/api/jobs/__tests__/$job.spec.ts +320 -2867
  183. package/src/api/jobs/controllers/AdminJobController.ts +29 -138
  184. package/src/api/jobs/entities/jobExecutionEntity.ts +27 -19
  185. package/src/api/jobs/index.browser.ts +5 -7
  186. package/src/api/jobs/index.ts +23 -51
  187. package/src/api/jobs/primitives/$job.ts +66 -58
  188. package/src/api/jobs/providers/JobProvider.ts +561 -566
  189. package/src/api/jobs/providers/JobQueueProvider.ts +18 -19
  190. package/src/api/jobs/schemas/jobConfigAtom.ts +20 -23
  191. package/src/api/jobs/schemas/jobExecutionQuerySchema.ts +3 -27
  192. package/src/api/jobs/schemas/jobExecutionResourceSchema.ts +5 -7
  193. package/src/api/jobs/schemas/jobRegistrationSchema.ts +7 -4
  194. package/src/api/jobs/schemas/triggerJobSchema.ts +0 -1
  195. package/src/api/jobs/services/JobService.ts +90 -483
  196. package/src/api/notifications/controllers/AdminNotificationController.ts +19 -12
  197. package/src/api/notifications/index.ts +7 -4
  198. package/src/api/notifications/jobs/NotificationJobs.ts +83 -12
  199. package/src/api/payments/services/PaymentService.ts +4 -2
  200. package/src/api/users/__tests__/UserJobs.spec.ts +10 -49
  201. package/src/api/users/audits/UserAudits.ts +3 -1
  202. package/src/api/users/buckets/UserBuckets.ts +2 -1
  203. package/src/api/users/index.ts +1 -4
  204. package/src/api/users/jobs/UserJobs.ts +5 -4
  205. package/src/api/users/schemas/userQuerySchema.ts +0 -1
  206. package/src/api/users/services/UserService.ts +1 -5
  207. package/src/api/verifications/__tests__/CodeVerification.spec.ts +14 -0
  208. package/src/api/verifications/__tests__/LinkVerification.spec.ts +14 -0
  209. package/src/api/verifications/jobs/VerificationJobs.ts +2 -1
  210. package/src/api/verifications/services/VerificationService.ts +1 -0
  211. package/src/cli/core/__tests__/init.spec.ts +209 -1
  212. package/src/cli/core/commands/init.ts +9 -9
  213. package/src/cli/core/services/PackageManagerUtils.ts +22 -12
  214. package/src/cli/core/services/ProjectScaffolder.ts +300 -70
  215. package/src/cli/core/tasks/BuildDockerTask.ts +9 -10
  216. package/src/cli/core/tasks/BuildServerTask.ts +8 -0
  217. package/src/cli/core/templates/agentMd.ts +2 -8
  218. package/src/cli/core/templates/apiIndexTs.ts +22 -14
  219. package/src/cli/core/templates/componentsJsonTs.ts +39 -0
  220. package/src/cli/core/templates/mainCss.ts +2 -36
  221. package/src/cli/core/templates/saasAdminLayoutTsx.ts +77 -0
  222. package/src/cli/core/templates/saasAdminPagesTsx.ts +26 -0
  223. package/src/cli/core/templates/saasAuthLayoutTsx.ts +20 -0
  224. package/src/cli/core/templates/saasAuthPagesTsx.ts +62 -0
  225. package/src/cli/core/templates/saasRealmProviderTs.ts +46 -0
  226. package/src/cli/core/templates/vitestConfigTs.ts +17 -0
  227. package/src/cli/core/templates/webAppRouterTs.ts +102 -82
  228. package/src/cli/core/templates/webIndexTs.ts +23 -1
  229. package/src/cli/platform/__tests__/CloudflareAdapter.spec.ts +22 -71
  230. package/src/cli/platform/__tests__/SecretsCommand.spec.ts +2 -0
  231. package/src/cli/platform/adapters/CloudflareAdapter.ts +12 -11
  232. package/src/cli/platform/atoms/platformOptions.ts +9 -0
  233. package/src/cli/platform/schemas/cloudflare.ts +3 -2
  234. package/src/cli/platform/services/CloudflareApi.ts +164 -25
  235. package/src/cli/platform/services/WranglerApi.ts +0 -17
  236. package/src/command/providers/CliProvider.ts +1 -1
  237. package/src/core/Alepha.ts +9 -0
  238. package/src/core/interfaces/Service.ts +3 -1
  239. package/src/core/providers/TypeProvider.ts +1 -1
  240. package/src/logger/services/Logger.ts +1 -1
  241. package/src/mcp/__tests__/$resource.spec.ts +1 -1
  242. package/src/mcp/__tests__/$tool.spec.ts +1 -1
  243. package/src/mcp/__tests__/McpServerProvider.spec.ts +1 -1
  244. package/src/orm/__tests__/$repository-tests.ts +1 -0
  245. package/src/orm/__tests__/orm-next-tests.ts +2 -67
  246. package/src/orm/__tests__/orm-next.spec.ts +0 -21
  247. package/src/orm/core/index.shared.ts +0 -2
  248. package/src/orm/core/index.ts +1 -2
  249. package/src/orm/core/primitives/$repository.ts +3 -6
  250. package/src/orm/core/providers/drivers/DatabaseProvider.ts +0 -5
  251. package/src/orm/core/providers/drivers/NodeSqliteProvider.ts +11 -13
  252. package/src/orm/core/services/ModelBuilder.ts +1 -13
  253. package/src/orm/core/services/Repository.ts +1 -42
  254. package/src/orm/core/services/SqliteModelBuilder.ts +2 -33
  255. package/src/orm/postgres/services/PostgresModelBuilder.ts +10 -45
  256. package/src/react/form/index.ts +2 -0
  257. package/src/react/form/services/parseField.ts +163 -0
  258. package/src/react/form/services/prettyName.ts +19 -0
  259. package/src/react/head/providers/BrowserHeadProvider.ts +31 -10
  260. package/src/react/intro/components/GettingStartedAuthSlide.tsx +11 -4
  261. package/src/react/router/__tests__/ReactBrowserProvider.browser.spec.ts +213 -2
  262. package/src/react/router/primitives/$page.ts +35 -12
  263. package/src/react/router/providers/ReactBrowserProvider.ts +73 -0
  264. package/src/react/router/providers/ReactBrowserRouterProvider.ts +1 -1
  265. package/src/react/router/providers/ReactPreloadProvider.ts +1 -1
  266. package/src/react/router/providers/ReactServerProvider.ts +1 -0
  267. package/src/react/ui/atoms/uiAtom.ts +28 -0
  268. package/src/react/ui/components/ColorScheme.tsx +36 -0
  269. package/src/react/ui/hooks/useColorMode.ts +49 -0
  270. package/src/react/ui/hooks/useSidebarState.ts +26 -0
  271. package/src/react/ui/hooks/useTheme.ts +22 -0
  272. package/src/react/ui/index.ts +35 -0
  273. package/src/react/ui/services/UiPersistence.ts +41 -0
  274. package/src/router/TemplatedPathParser.ts +50 -51
  275. package/src/router/__tests__/RouterProvider.spec.ts +62 -0
  276. package/src/router/__tests__/TemplatedPathParser.spec.ts +18 -0
  277. package/src/router/providers/RouterProvider.ts +10 -5
  278. package/src/scheduler/providers/CronProvider.ts +1 -1
  279. package/src/security/primitives/$basicAuth.ts +1 -1
  280. package/src/server/auth/providers/ServerAuthProvider.ts +5 -1
  281. package/src/server/core/interfaces/ServerRequest.ts +1 -0
  282. package/src/server/core/providers/ServerProvider.ts +1 -1
  283. package/src/server/core/providers/ServerRouterProvider.ts +2 -2
  284. package/src/server/core/services/HttpClient.ts +1 -1
  285. package/src/server/swagger/providers/ServerSwaggerProvider.ts +1 -1
  286. package/src/system/providers/NodeShellProvider.ts +1 -0
  287. package/src/topic/core/providers/TopicProvider.ts +1 -1
  288. package/dist/api/invitations/index.d.ts +0 -790
  289. package/dist/api/invitations/index.d.ts.map +0 -1
  290. package/dist/api/invitations/index.js +0 -662
  291. package/dist/api/invitations/index.js.map +0 -1
  292. package/dist/api/issues/index.d.ts +0 -810
  293. package/dist/api/issues/index.d.ts.map +0 -1
  294. package/dist/api/issues/index.js +0 -444
  295. package/dist/api/issues/index.js.map +0 -1
  296. package/dist/api/subscriptions/index.d.ts +0 -1692
  297. package/dist/api/subscriptions/index.d.ts.map +0 -1
  298. package/dist/api/subscriptions/index.js +0 -1867
  299. package/dist/api/subscriptions/index.js.map +0 -1
  300. package/dist/api/workflows/index.browser.js +0 -246
  301. package/dist/api/workflows/index.browser.js.map +0 -1
  302. package/dist/api/workflows/index.d.ts +0 -1618
  303. package/dist/api/workflows/index.d.ts.map +0 -1
  304. package/dist/api/workflows/index.js +0 -1495
  305. package/dist/api/workflows/index.js.map +0 -1
  306. package/dist/react/testing/chunk-DBEY4PJZ.js +0 -16
  307. package/src/api/invitations/__tests__/InvitationService.spec.ts +0 -439
  308. package/src/api/invitations/controllers/AdminInvitationController.ts +0 -86
  309. package/src/api/invitations/controllers/InvitationController.ts +0 -84
  310. package/src/api/invitations/entities/invitations.ts +0 -33
  311. package/src/api/invitations/index.ts +0 -58
  312. package/src/api/invitations/jobs/InvitationJobs.ts +0 -37
  313. package/src/api/invitations/providers/InvitationProvider.ts +0 -45
  314. package/src/api/invitations/schemas/createInvitationSchema.ts +0 -12
  315. package/src/api/invitations/schemas/invitationConfigAtom.ts +0 -20
  316. package/src/api/invitations/schemas/invitationQuerySchema.ts +0 -15
  317. package/src/api/invitations/schemas/invitationResourceSchema.ts +0 -6
  318. package/src/api/invitations/schemas/invitationWithResourceInfoSchema.ts +0 -22
  319. package/src/api/invitations/schemas/myInvitationsQuerySchema.ts +0 -10
  320. package/src/api/invitations/services/InvitationService.ts +0 -556
  321. package/src/api/issues/__tests__/IssueService.spec.ts +0 -263
  322. package/src/api/issues/controllers/AdminIssueController.ts +0 -149
  323. package/src/api/issues/controllers/IssueController.ts +0 -44
  324. package/src/api/issues/entities/issues.ts +0 -49
  325. package/src/api/issues/index.ts +0 -50
  326. package/src/api/issues/schemas/createIssueSchema.ts +0 -13
  327. package/src/api/issues/schemas/issueConfigAtom.ts +0 -13
  328. package/src/api/issues/schemas/issueQuerySchema.ts +0 -18
  329. package/src/api/issues/schemas/issueResourceSchema.ts +0 -6
  330. package/src/api/issues/schemas/myIssueQuerySchema.ts +0 -10
  331. package/src/api/issues/schemas/updateIssueSchema.ts +0 -13
  332. package/src/api/issues/services/IssueService.ts +0 -264
  333. package/src/api/jobs/__tests__/$job-middleware.spec.ts +0 -126
  334. package/src/api/jobs/__tests__/JobService.spec.ts +0 -31
  335. package/src/api/jobs/entities/jobExecutionLogEntity.ts +0 -13
  336. package/src/api/jobs/schemas/jobActivitySchema.ts +0 -15
  337. package/src/api/jobs/schemas/jobCronInfoSchema.ts +0 -22
  338. package/src/api/jobs/schemas/jobExecutionDetailResourceSchema.ts +0 -20
  339. package/src/api/jobs/schemas/jobFailureSchema.ts +0 -9
  340. package/src/api/jobs/schemas/jobQueueDepthSchema.ts +0 -14
  341. package/src/api/jobs/schemas/jobStatsSchema.ts +0 -14
  342. package/src/api/jobs/services/JobService-tests.ts +0 -157
  343. package/src/api/subscriptions/__tests__/BillingService.spec.ts +0 -218
  344. package/src/api/subscriptions/__tests__/SubscriptionService.spec.ts +0 -278
  345. package/src/api/subscriptions/controllers/AdminSubscriptionController.ts +0 -212
  346. package/src/api/subscriptions/controllers/SubscriptionController.ts +0 -189
  347. package/src/api/subscriptions/entities/subscriptionEvents.ts +0 -54
  348. package/src/api/subscriptions/entities/subscriptions.ts +0 -68
  349. package/src/api/subscriptions/index.ts +0 -133
  350. package/src/api/subscriptions/jobs/SubscriptionJobs.ts +0 -382
  351. package/src/api/subscriptions/middleware/$requireLimit.ts +0 -50
  352. package/src/api/subscriptions/middleware/$requirePlan.ts +0 -49
  353. package/src/api/subscriptions/notifications/SubscriptionNotifications.ts +0 -110
  354. package/src/api/subscriptions/schemas/cancelSubscriptionSchema.ts +0 -8
  355. package/src/api/subscriptions/schemas/changePlanSchema.ts +0 -9
  356. package/src/api/subscriptions/schemas/createSubscriptionSchema.ts +0 -11
  357. package/src/api/subscriptions/schemas/entitlementsSchema.ts +0 -21
  358. package/src/api/subscriptions/schemas/mrrSchema.ts +0 -13
  359. package/src/api/subscriptions/schemas/planDefinitionSchema.ts +0 -71
  360. package/src/api/subscriptions/schemas/planResourceSchema.ts +0 -25
  361. package/src/api/subscriptions/schemas/subscriptionEventResourceSchema.ts +0 -8
  362. package/src/api/subscriptions/schemas/subscriptionQuerySchema.ts +0 -19
  363. package/src/api/subscriptions/schemas/subscriptionResourceSchema.ts +0 -6
  364. package/src/api/subscriptions/schemas/subscriptionSettingsSchema.ts +0 -32
  365. package/src/api/subscriptions/schemas/subscriptionStatsSchema.ts +0 -23
  366. package/src/api/subscriptions/services/BillingService.ts +0 -437
  367. package/src/api/subscriptions/services/SubscriptionConfig.ts +0 -56
  368. package/src/api/subscriptions/services/SubscriptionService.ts +0 -867
  369. package/src/api/subscriptions/services/UsageService.ts +0 -118
  370. package/src/api/workflows/__tests__/$workflow.spec.ts +0 -616
  371. package/src/api/workflows/controllers/AdminWorkflowController.ts +0 -191
  372. package/src/api/workflows/entities/workflowExecutions.ts +0 -74
  373. package/src/api/workflows/entities/workflowStepExecutions.ts +0 -74
  374. package/src/api/workflows/entities/workflowStepLogs.ts +0 -13
  375. package/src/api/workflows/index.browser.ts +0 -22
  376. package/src/api/workflows/index.ts +0 -115
  377. package/src/api/workflows/jobs/WorkflowJobs.ts +0 -77
  378. package/src/api/workflows/primitives/$workflow.ts +0 -202
  379. package/src/api/workflows/providers/WorkflowProvider.ts +0 -1284
  380. package/src/api/workflows/schemas/workflowActivitySchema.ts +0 -15
  381. package/src/api/workflows/schemas/workflowConfigAtom.ts +0 -51
  382. package/src/api/workflows/schemas/workflowExecutionDetailSchema.ts +0 -18
  383. package/src/api/workflows/schemas/workflowExecutionQuerySchema.ts +0 -26
  384. package/src/api/workflows/schemas/workflowExecutionResourceSchema.ts +0 -30
  385. package/src/api/workflows/schemas/workflowRegistrationSchema.ts +0 -26
  386. package/src/api/workflows/schemas/workflowStatsSchema.ts +0 -16
  387. package/src/api/workflows/schemas/workflowStepExecutionResourceSchema.ts +0 -15
  388. package/src/api/workflows/services/WorkflowService.ts +0 -382
  389. package/src/cli/core/templates/apiAppSecurityTs.ts +0 -43
  390. package/src/cli/core/templates/webAdminDashboardTsx.ts +0 -17
  391. package/src/orm/core/__tests__/parseQueryString.spec.ts +0 -196
  392. package/src/orm/core/helpers/parseQueryString.ts +0 -502
  393. package/src/orm/core/primitives/$view.ts +0 -88
@@ -1,7 +1,8 @@
1
1
  import { $inject, t } from "alepha";
2
- import { JobService } from "alepha/api/jobs";
2
+ import { jobExecutionEntity } from "alepha/api/jobs";
3
+ import { $repository } from "alepha/orm";
3
4
  import { $secure } from "alepha/security";
4
- import { $action } from "alepha/server";
5
+ import { $action, NotFoundError } from "alepha/server";
5
6
  import { NotificationJobs } from "../jobs/NotificationJobs.ts";
6
7
  import { notificationDetailResourceSchema } from "../schemas/notificationDetailResourceSchema.ts";
7
8
  import { notificationQuerySchema } from "../schemas/notificationQuerySchema.ts";
@@ -10,8 +11,8 @@ import { notificationResourceSchema } from "../schemas/notificationResourceSchem
10
11
  export class AdminNotificationController {
11
12
  protected readonly url: string = "/notifications";
12
13
  protected readonly group: string = "admin:notifications";
13
- protected readonly jobService = $inject(JobService);
14
14
  protected readonly notificationJobs = $inject(NotificationJobs);
15
+ protected readonly executions = $repository(jobExecutionEntity);
15
16
 
16
17
  protected get jobName(): string {
17
18
  return this.notificationJobs.sendNotification.name;
@@ -26,13 +27,17 @@ export class AdminNotificationController {
26
27
  response: t.page(notificationResourceSchema),
27
28
  },
28
29
  handler: async ({ query }) => {
29
- const result = await this.jobService.findExecutions({
30
- ...query,
31
- job: this.jobName,
32
- });
30
+ query.sort ??= "-createdAt";
31
+ const where = this.executions.createQueryWhere();
32
+ where.jobName = { eq: this.jobName };
33
+ const page = await this.executions.paginate(
34
+ query,
35
+ { where },
36
+ { count: true },
37
+ );
33
38
  return {
34
- ...result,
35
- content: result.content.map((exec) => this.toResource(exec)),
39
+ ...page,
40
+ content: page.content.map((exec) => this.toResource(exec)),
36
41
  } as any;
37
42
  },
38
43
  });
@@ -48,8 +53,11 @@ export class AdminNotificationController {
48
53
  response: notificationDetailResourceSchema,
49
54
  },
50
55
  handler: async ({ params }) => {
51
- const detail = await this.jobService.getExecution(params.id);
52
- return this.toDetailResource(detail) as any;
56
+ const exec = await this.executions.findById(params.id);
57
+ if (!exec || exec.jobName !== this.jobName) {
58
+ throw new NotFoundError(`Notification not found: ${params.id}`);
59
+ }
60
+ return this.toDetailResource(exec) as any;
53
61
  },
54
62
  });
55
63
 
@@ -76,7 +84,6 @@ export class AdminNotificationController {
76
84
  return {
77
85
  ...this.toResource(exec),
78
86
  variables: payload.variables,
79
- rendered: exec.result,
80
87
  logs: exec.logs,
81
88
  };
82
89
  }
@@ -1,4 +1,6 @@
1
1
  import { $module } from "alepha";
2
+ import { AlephaApiJobsQueue } from "alepha/api/jobs";
3
+ import { AlephaApiParameters } from "alepha/api/parameters";
2
4
  import { AdminNotificationController } from "./controllers/AdminNotificationController.ts";
3
5
  import { NotificationJobs } from "./jobs/NotificationJobs.ts";
4
6
  import { $notification } from "./primitives/$notification.ts";
@@ -23,15 +25,16 @@ export * from "./services/NotificationSenderService.ts";
23
25
  * User notification management.
24
26
  *
25
27
  * **Features:**
26
- * - Notification definitions
27
- * - Email/SMS notification sending
28
- * - Job-based delivery with retry and tracking
29
- * - User preferences
28
+ * - Notification definitions (email/SMS templates)
29
+ * - Queue-based delivery with retry and audit trail (`record: "all"` + no ring buffer trim)
30
+ * - Runtime-editable retention window via `$parameter` — purge cron respects it live
31
+ * - Admin API for inspecting sent notifications
30
32
  *
31
33
  * @module alepha.api.notifications
32
34
  */
33
35
  export const AlephaApiNotifications = $module({
34
36
  name: "alepha.api.notifications",
37
+ imports: [AlephaApiJobsQueue, AlephaApiParameters],
35
38
  primitives: [$notification],
36
39
  services: [
37
40
  NotificationSenderService,
@@ -1,16 +1,57 @@
1
- import { $inject } from "alepha";
1
+ import { $inject, t } from "alepha";
2
2
  import { $job, jobExecutionEntity } from "alepha/api/jobs";
3
+ import { $parameter } from "alepha/api/parameters";
4
+ import { DateTimeProvider } from "alepha/datetime";
5
+ import { $logger } from "alepha/logger";
3
6
  import { $repository } from "alepha/orm";
4
7
  import { notificationPayloadSchema } from "../schemas/notificationPayloadSchema.ts";
5
8
  import { NotificationSenderService } from "../services/NotificationSenderService.ts";
6
9
 
10
+ /**
11
+ * Notification jobs + runtime-editable retention.
12
+ *
13
+ * - `settings` — a `$parameter` exposing `retentionDays` that admins can
14
+ * update at runtime. Changes propagate across instances via the parameter
15
+ * pub/sub; the next purge run picks up the new value with no restart.
16
+ * - `sendNotification` — queue-mode, audit-oriented. Every execution is kept
17
+ * (`record: "all"`, `keep: { ok: 0, error: 0 }` disables the ring-buffer
18
+ * trim) so the audit trail survives even under heavy volume.
19
+ * - `purgeOldNotifications` — cron sweep that deletes notification execution
20
+ * rows whose `completedAt` is older than the current `retentionDays`.
21
+ *
22
+ * Cron expression note: the purge cron is declared statically (`0 3 * * *`)
23
+ * because some runtimes (Cloudflare Workers) freeze cron triggers at deploy
24
+ * time. The *retention window* is fully runtime-editable — that's the knob
25
+ * that actually matters for operators.
26
+ */
7
27
  export class NotificationJobs {
28
+ protected readonly log = $logger();
29
+ protected readonly dt = $inject(DateTimeProvider);
8
30
  protected readonly notificationSenderService = $inject(
9
31
  NotificationSenderService,
10
32
  );
11
33
  protected readonly executions = $repository(jobExecutionEntity);
12
34
 
35
+ /** Runtime-editable config. Admins can change retentionDays without deploy. */
36
+ public readonly settings = $parameter({
37
+ name: "alepha.api.notifications",
38
+ description: "Notification delivery & retention settings.",
39
+ schema: t.object({
40
+ retentionDays: t.integer({
41
+ description:
42
+ "Days to keep notification execution rows before the purge sweep removes them.",
43
+ minimum: 1,
44
+ }),
45
+ }),
46
+ default: {
47
+ retentionDays: 7,
48
+ },
49
+ });
50
+
13
51
  public readonly sendNotification = $job({
52
+ name: "api:notifications:sendNotification",
53
+ description:
54
+ "Sends a notification (email/SMS) and keeps every execution for audit.",
14
55
  schema: notificationPayloadSchema,
15
56
  retry: {
16
57
  retries: 3,
@@ -22,18 +63,48 @@ export class NotificationJobs {
22
63
  },
23
64
  },
24
65
  timeout: [30, "seconds"],
25
- concurrency: 5,
26
- handler: async ({ items }) => {
27
- for (const item of items) {
28
- const rendered = await this.notificationSenderService.send(
29
- item.payload,
30
- );
31
- if (rendered) {
32
- await this.executions.updateById(item.id, {
33
- result: rendered as Record<string, unknown>,
34
- });
35
- }
66
+ record: "all",
67
+ keep: { ok: 0, error: 0 },
68
+ handler: async ({ payload }) => {
69
+ await this.notificationSenderService.send(payload);
70
+ },
71
+ });
72
+
73
+ public readonly purgeOldNotifications = $job({
74
+ name: "api:notifications:purgeOldNotifications",
75
+ description:
76
+ "Hourly sweep that deletes notification execution rows older than the configured retention window.",
77
+ cron: "0 * * * *",
78
+ handler: async ({ now }) => {
79
+ const { retentionDays } = this.settings.cachedCurrentContent;
80
+ const cutoff = now.subtract(retentionDays, "day").toISOString();
81
+ const jobName = this.sendNotification.name;
82
+
83
+ const expired = await this.executions.findMany({
84
+ where: {
85
+ jobName: { eq: jobName },
86
+ status: { inArray: ["ok", "error", "cancelled"] },
87
+ completedAt: { lt: cutoff },
88
+ },
89
+ columns: ["id"] as any,
90
+ limit: 5_000,
91
+ });
92
+
93
+ if (expired.length === 0) {
94
+ this.log.debug("Notification purge: nothing to delete", {
95
+ cutoff,
96
+ retentionDays,
97
+ });
98
+ return;
36
99
  }
100
+
101
+ await this.executions.deleteMany({
102
+ id: { inArray: expired.map((r) => r.id) },
103
+ });
104
+ this.log.info(
105
+ `Notification purge: deleted ${expired.length} row(s) older than ${retentionDays} days`,
106
+ { cutoff },
107
+ );
37
108
  },
38
109
  });
39
110
  }
@@ -21,10 +21,12 @@ export class PaymentService {
21
21
 
22
22
  /**
23
23
  * Expires stale payment intents that have been in "processing" status
24
- * for more than 30 minutes. Runs every 15 minutes.
24
+ * for more than 30 minutes. Runs every 5 minutes — shares the CF wrangler
25
+ * trigger with the jobs sweep so no extra binding is consumed.
25
26
  */
26
27
  protected readonly expireStaleIntents = $job({
27
- cron: "*/15 * * * *",
28
+ name: "api:payments:expireStaleIntents",
29
+ cron: "*/5 * * * *",
28
30
  handler: async () => {
29
31
  const cutoff = this.dateTime.now().subtract(30, "minutes").toISOString();
30
32
 
@@ -1,15 +1,15 @@
1
1
  import { Alepha } from "alepha";
2
- import { AlephaApiJobs, jobExecutionEntity } from "alepha/api/jobs";
2
+ import { AlephaApiJobs } from "alepha/api/jobs";
3
3
  import { $repository } from "alepha/orm";
4
4
  import { AlephaOrmPostgres } from "alepha/orm/postgres";
5
- import { describe, test, vi } from "vitest";
5
+ import { describe, test } from "vitest";
6
6
  import { sessions } from "../entities/sessions.ts";
7
7
  import { users } from "../entities/users.ts";
8
8
  import { UserJobs } from "../jobs/UserJobs.ts";
9
9
 
10
10
  describe("UserJobs", () => {
11
11
  describe("purgeExpiredSessions", () => {
12
- test("should delete expired sessions", async ({ expect }) => {
12
+ test("deletes expired sessions", async ({ expect }) => {
13
13
  const alepha = Alepha.create()
14
14
  .with(AlephaOrmPostgres)
15
15
  .with(AlephaApiJobs);
@@ -17,20 +17,17 @@ describe("UserJobs", () => {
17
17
  class TestRepositories {
18
18
  userRepository = $repository(users);
19
19
  sessionRepository = $repository(sessions);
20
- executions = $repository(jobExecutionEntity);
21
20
  }
22
21
 
23
22
  const userJobs = alepha.inject(UserJobs);
24
23
  const repos = alepha.inject(TestRepositories);
25
24
  await alepha.start();
26
25
 
27
- // Create a test user
28
26
  const user = await repos.userRepository.create({
29
27
  email: "test@example.com",
30
28
  });
31
29
 
32
- // Create expired sessions (expiresAt in the past)
33
- const pastDate = new Date(Date.now() - 24 * 60 * 60 * 1000).toISOString(); // 1 day ago
30
+ const pastDate = new Date(Date.now() - 24 * 60 * 60 * 1000).toISOString();
34
31
  await repos.sessionRepository.create({
35
32
  userId: user.id,
36
33
  refreshToken: crypto.randomUUID(),
@@ -42,35 +39,20 @@ describe("UserJobs", () => {
42
39
  expiresAt: pastDate,
43
40
  });
44
41
 
45
- // Create a valid session (expiresAt in the future)
46
42
  const futureDate = new Date(
47
43
  Date.now() + 24 * 60 * 60 * 1000,
48
- ).toISOString(); // 1 day from now
44
+ ).toISOString();
49
45
  await repos.sessionRepository.create({
50
46
  userId: user.id,
51
47
  refreshToken: crypto.randomUUID(),
52
48
  expiresAt: futureDate,
53
49
  });
54
50
 
55
- // Verify we have 3 sessions
56
- const sessionsBefore = await repos.sessionRepository.findMany();
57
- expect(sessionsBefore).toHaveLength(3);
51
+ expect(await repos.sessionRepository.findMany()).toHaveLength(3);
58
52
 
59
- // Trigger the job
53
+ // Cron jobs run inline — trigger awaits the handler synchronously.
60
54
  await userJobs.purgeExpiredSessions.trigger();
61
55
 
62
- // Wait for async job processing to complete
63
- await vi.waitFor(async () => {
64
- const executions = await repos.executions.findMany({
65
- where: {
66
- jobName: "UserJobs.purgeExpiredSessions",
67
- status: "completed",
68
- },
69
- });
70
- expect(executions).toHaveLength(1);
71
- });
72
-
73
- // Verify only the valid session remains
74
56
  const sessionsAfter = await repos.sessionRepository.findMany();
75
57
  expect(sessionsAfter).toHaveLength(1);
76
58
  expect(new Date(sessionsAfter[0].expiresAt).getTime()).toBeGreaterThan(
@@ -78,9 +60,7 @@ describe("UserJobs", () => {
78
60
  );
79
61
  });
80
62
 
81
- test("should handle case when no expired sessions exist", async ({
82
- expect,
83
- }) => {
63
+ test("no-op when no expired sessions exist", async ({ expect }) => {
84
64
  const alepha = Alepha.create()
85
65
  .with(AlephaOrmPostgres)
86
66
  .with(AlephaApiJobs);
@@ -88,19 +68,16 @@ describe("UserJobs", () => {
88
68
  class TestRepositories {
89
69
  userRepository = $repository(users);
90
70
  sessionRepository = $repository(sessions);
91
- executions = $repository(jobExecutionEntity);
92
71
  }
93
72
 
94
73
  const userJobs = alepha.inject(UserJobs);
95
74
  const repos = alepha.inject(TestRepositories);
96
75
  await alepha.start();
97
76
 
98
- // Create a test user
99
77
  const user = await repos.userRepository.create({
100
78
  email: "test2@example.com",
101
79
  });
102
80
 
103
- // Create only valid sessions
104
81
  const futureDate = new Date(
105
82
  Date.now() + 24 * 60 * 60 * 1000,
106
83
  ).toISOString();
@@ -110,27 +87,11 @@ describe("UserJobs", () => {
110
87
  expiresAt: futureDate,
111
88
  });
112
89
 
113
- // Verify we have 1 session
114
- const sessionsBefore = await repos.sessionRepository.findMany();
115
- expect(sessionsBefore).toHaveLength(1);
90
+ expect(await repos.sessionRepository.findMany()).toHaveLength(1);
116
91
 
117
- // Trigger the job - should not throw
118
92
  await userJobs.purgeExpiredSessions.trigger();
119
93
 
120
- // Wait for async job processing to complete
121
- await vi.waitFor(async () => {
122
- const executions = await repos.executions.findMany({
123
- where: {
124
- jobName: "UserJobs.purgeExpiredSessions",
125
- status: "completed",
126
- },
127
- });
128
- expect(executions).toHaveLength(1);
129
- });
130
-
131
- // Session should still exist
132
- const sessionsAfter = await repos.sessionRepository.findMany();
133
- expect(sessionsAfter).toHaveLength(1);
94
+ expect(await repos.sessionRepository.findMany()).toHaveLength(1);
134
95
  });
135
96
  });
136
97
  });
@@ -7,7 +7,9 @@ type AuditContext = Omit<CreateAudit, "type" | "action">;
7
7
  * User-specific audit wrapper service.
8
8
  *
9
9
  * This service wraps the core AuditService to provide user-related audit logging.
10
- * It is lazy-loaded when the `audits` feature is enabled in the realm.
10
+ *
11
+ * Declared as a module variant — not auto-injected. It is instantiated
12
+ * lazily the first time something calls `alepha.inject(UserAudits)`.
11
13
  */
12
14
  export class UserAudits {
13
15
  protected readonly auditService = $inject(AuditService);
@@ -6,7 +6,8 @@ import { $bucket } from "alepha/bucket";
6
6
  * This service provides file storage for user-related files such as:
7
7
  * - User avatars/profile pictures
8
8
  *
9
- * It is lazy-loaded when the `avatars` feature is enabled in the realm.
9
+ * Declared as a module variant not auto-injected. It is instantiated
10
+ * lazily the first time something calls `alepha.inject(UserBuckets)`.
10
11
  */
11
12
  export class UserBuckets {
12
13
  /**
@@ -88,9 +88,6 @@ export const AlephaApiUsers = $module({
88
88
  AdminSessionController,
89
89
  AdminIdentityController,
90
90
  RealmController,
91
- UserJobs,
92
- UserNotifications,
93
- UserAudits,
94
- UserBuckets,
95
91
  ],
92
+ variants: [UserJobs, UserNotifications, UserAudits, UserBuckets],
96
93
  });
@@ -13,7 +13,8 @@ import { sessions } from "../entities/sessions.ts";
13
13
  * - Verification code cleanup
14
14
  * - Inactive user notifications
15
15
  *
16
- * It is lazy-loaded when the `sessionPurge` feature is enabled in the realm.
16
+ * Declared as a module variant not auto-injected. It is instantiated
17
+ * lazily the first time something calls `alepha.inject(UserJobs)`.
17
18
  */
18
19
  export class UserJobs {
19
20
  protected readonly log = $logger();
@@ -23,11 +24,11 @@ export class UserJobs {
23
24
  /**
24
25
  * Purge expired sessions from the database.
25
26
  *
26
- * This job runs daily at 3:00 AM and removes all sessions
27
- * where the `expiresAt` timestamp has passed.
27
+ * Runs hourly (at :00) and deletes sessions whose `expiresAt` has passed.
28
28
  */
29
29
  public readonly purgeExpiredSessions = $job({
30
- cron: "0 0 * * *", // Daily at 3:00 AM
30
+ name: "api:users:purgeExpiredSessions",
31
+ cron: "0 * * * *", // Hourly at minute 0
31
32
  handler: async () => {
32
33
  const now = this.dateTimeProvider.nowISOString();
33
34
 
@@ -7,7 +7,6 @@ export const userQuerySchema = t.extend(pageQuerySchema, {
7
7
  enabled: t.optional(t.boolean()),
8
8
  emailVerified: t.optional(t.boolean()),
9
9
  roles: t.optional(t.array(t.string())),
10
- query: t.optional(t.text()),
11
10
  });
12
11
 
13
12
  export type UserQuery = Static<typeof userQuerySchema>;
@@ -1,7 +1,7 @@
1
1
  import { $inject, Alepha } from "alepha";
2
2
  import type { VerificationController } from "alepha/api/verifications";
3
3
  import { $logger } from "alepha/logger";
4
- import { type Page, parseQueryString } from "alepha/orm";
4
+ import type { Page } from "alepha/orm";
5
5
  import { BadRequestError } from "alepha/server";
6
6
  import { $client } from "alepha/server/links";
7
7
  import { UserAudits } from "../audits/UserAudits.ts";
@@ -229,10 +229,6 @@ export class UserService {
229
229
  where.roles = { arrayContains: q.roles };
230
230
  }
231
231
 
232
- if (q.query) {
233
- Object.assign(where, parseQueryString(q.query));
234
- }
235
-
236
232
  const result = await this.users(userRealmName).paginate(
237
233
  q,
238
234
  { where },
@@ -198,6 +198,20 @@ describe("Code Verification", () => {
198
198
  const { parameters, controller, dateTimeProvider, target } =
199
199
  await createTest();
200
200
 
201
+ // Anchor test time at noon to keep all `limitPerDay` inserts inside the
202
+ // same calendar day — running near midnight (real wall-clock) used to
203
+ // make the cooldown travel cross day boundaries and reset the window.
204
+ const now = dateTimeProvider.now();
205
+ const noon = now.startOf("day").add(12, "hours");
206
+ if (noon.diff(now) > 0) {
207
+ await dateTimeProvider.travel(noon.diff(now), "milliseconds");
208
+ } else {
209
+ await dateTimeProvider.travel(
210
+ noon.add(1, "day").diff(now),
211
+ "milliseconds",
212
+ );
213
+ }
214
+
201
215
  for (let i = 0; i < parameters.limitPerDay; i++) {
202
216
  await controller.requestVerificationCode({
203
217
  params: {
@@ -198,6 +198,20 @@ describe("Link Verification", () => {
198
198
  const { parameters, controller, dateTimeProvider, target } =
199
199
  await createTest();
200
200
 
201
+ // Anchor test time at noon to keep all `limitPerDay` inserts inside the
202
+ // same calendar day — running near midnight (real wall-clock) used to
203
+ // make the cooldown travel cross day boundaries and reset the window.
204
+ const now = dateTimeProvider.now();
205
+ const noon = now.startOf("day").add(12, "hours");
206
+ if (noon.diff(now) > 0) {
207
+ await dateTimeProvider.travel(noon.diff(now), "milliseconds");
208
+ } else {
209
+ await dateTimeProvider.travel(
210
+ noon.add(1, "day").diff(now),
211
+ "milliseconds",
212
+ );
213
+ }
214
+
201
215
  for (let i = 0; i < parameters.limitPerDay; i++) {
202
216
  await controller.requestVerificationCode({
203
217
  params: {
@@ -11,7 +11,8 @@ export class VerificationJobs {
11
11
  protected readonly dateTimeProvider = $inject(DateTimeProvider);
12
12
 
13
13
  public readonly cleanExpired = $scheduler({
14
- cron: "0 0 * * *", // Every day at midnight
14
+ name: "api:verifications:cleanExpired",
15
+ cron: "0 * * * *", // Hourly at minute 0
15
16
  description: "Clean expired verifications",
16
17
  handler: async () => {
17
18
  const purgeDays = this.verificationParameters.get("purgeDays");
@@ -134,6 +134,7 @@ export class VerificationService {
134
134
  type: entry.type,
135
135
  target: entry.target,
136
136
  code: this.hashCode(token),
137
+ createdAt: this.dateTimeProvider.nowISOString(),
137
138
  });
138
139
 
139
140
  this.log.info("Verification created", {