alepha 0.19.1 → 0.19.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 (531) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +6 -9
  3. package/dist/api/audits/index.d.ts +378 -346
  4. package/dist/api/audits/index.d.ts.map +1 -1
  5. package/dist/api/files/index.d.ts +216 -184
  6. package/dist/api/files/index.d.ts.map +1 -1
  7. package/dist/api/jobs/index.d.ts +534 -502
  8. package/dist/api/jobs/index.d.ts.map +1 -1
  9. package/dist/api/jobs/index.js +13 -7
  10. package/dist/api/jobs/index.js.map +1 -1
  11. package/dist/api/keys/index.d.ts +202 -202
  12. package/dist/api/keys/index.d.ts.map +1 -1
  13. package/dist/api/notifications/index.d.ts +152 -152
  14. package/dist/api/notifications/index.d.ts.map +1 -1
  15. package/dist/api/organizations/index.browser.js +48 -0
  16. package/dist/api/organizations/index.browser.js.map +1 -0
  17. package/dist/api/organizations/index.d.ts +516 -0
  18. package/dist/api/organizations/index.d.ts.map +1 -0
  19. package/dist/api/organizations/index.js +202 -0
  20. package/dist/api/organizations/index.js.map +1 -0
  21. package/dist/api/parameters/index.d.ts +391 -358
  22. package/dist/api/parameters/index.d.ts.map +1 -1
  23. package/dist/api/parameters/index.js +5 -1
  24. package/dist/api/parameters/index.js.map +1 -1
  25. package/dist/api/users/index.browser.js +7 -5
  26. package/dist/api/users/index.browser.js.map +1 -1
  27. package/dist/api/users/index.d.ts +986 -931
  28. package/dist/api/users/index.d.ts.map +1 -1
  29. package/dist/api/users/index.js +160 -112
  30. package/dist/api/users/index.js.map +1 -1
  31. package/dist/api/verifications/index.d.ts +137 -137
  32. package/dist/api/verifications/index.d.ts.map +1 -1
  33. package/dist/api/verifications/index.js +2 -2
  34. package/dist/api/verifications/index.js.map +1 -1
  35. package/dist/batch/index.d.ts +6 -6
  36. package/dist/batch/index.d.ts.map +1 -1
  37. package/dist/billing/index.d.ts +1048 -0
  38. package/dist/billing/index.d.ts.map +1 -0
  39. package/dist/billing/index.js +713 -0
  40. package/dist/billing/index.js.map +1 -0
  41. package/dist/bin/index.js +0 -2
  42. package/dist/bin/index.js.map +1 -1
  43. package/dist/bucket/index.d.ts +10 -10
  44. package/dist/bucket/index.d.ts.map +1 -1
  45. package/dist/bucket/index.js +2 -2
  46. package/dist/bucket/index.js.map +1 -1
  47. package/dist/cache/core/index.d.ts +9 -9
  48. package/dist/cache/core/index.d.ts.map +1 -1
  49. package/dist/cache/core/index.js +2 -2
  50. package/dist/cache/core/index.js.map +1 -1
  51. package/dist/cache/core/index.workerd.js +2 -2
  52. package/dist/cache/core/index.workerd.js.map +1 -1
  53. package/dist/cache/redis/index.d.ts +6 -6
  54. package/dist/cache/redis/index.d.ts.map +1 -1
  55. package/dist/cache/redis/index.js +2 -2
  56. package/dist/cache/redis/index.js.map +1 -1
  57. package/dist/cli/config/index.d.ts +6 -18
  58. package/dist/cli/config/index.d.ts.map +1 -1
  59. package/dist/cli/config/index.js +5 -6
  60. package/dist/cli/config/index.js.map +1 -1
  61. package/dist/cli/core/index.d.ts +11811 -323
  62. package/dist/cli/core/index.d.ts.map +1 -1
  63. package/dist/cli/core/index.js +324 -98
  64. package/dist/cli/core/index.js.map +1 -1
  65. package/dist/cli/devtools/index.d.ts +50 -0
  66. package/dist/cli/devtools/index.d.ts.map +1 -0
  67. package/dist/cli/devtools/index.js +174 -0
  68. package/dist/cli/devtools/index.js.map +1 -0
  69. package/dist/cli/platform/index.d.ts +438 -542
  70. package/dist/cli/platform/index.d.ts.map +1 -1
  71. package/dist/cli/platform/index.js +46 -511
  72. package/dist/cli/platform/index.js.map +1 -1
  73. package/dist/cli/vendor/index.d.ts +201 -0
  74. package/dist/cli/vendor/index.d.ts.map +1 -0
  75. package/dist/cli/vendor/index.js +388 -0
  76. package/dist/cli/vendor/index.js.map +1 -0
  77. package/dist/command/index.d.ts +18 -18
  78. package/dist/command/index.d.ts.map +1 -1
  79. package/dist/command/index.js +2 -2
  80. package/dist/command/index.js.map +1 -1
  81. package/dist/core/index.browser.js +4 -4
  82. package/dist/core/index.browser.js.map +1 -1
  83. package/dist/core/index.d.ts +10 -10
  84. package/dist/core/index.d.ts.map +1 -1
  85. package/dist/core/index.js +8 -4
  86. package/dist/core/index.js.map +1 -1
  87. package/dist/core/index.native.js +8 -4
  88. package/dist/core/index.native.js.map +1 -1
  89. package/dist/core/index.workerd.js +8 -4
  90. package/dist/core/index.workerd.js.map +1 -1
  91. package/dist/crypto/index.d.ts +7 -7
  92. package/dist/crypto/index.d.ts.map +1 -1
  93. package/dist/datetime/index.d.ts +4 -4
  94. package/dist/datetime/index.d.ts.map +1 -1
  95. package/dist/email/brevo/index.d.ts +4 -4
  96. package/dist/email/brevo/index.d.ts.map +1 -1
  97. package/dist/email/core/index.d.ts +15 -11
  98. package/dist/email/core/index.d.ts.map +1 -1
  99. package/dist/email/core/index.js +12 -35
  100. package/dist/email/core/index.js.map +1 -1
  101. package/dist/email/smtp/index.d.ts +12 -12
  102. package/dist/email/smtp/index.d.ts.map +1 -1
  103. package/dist/email/smtp/index.js +7 -4
  104. package/dist/email/smtp/index.js.map +1 -1
  105. package/dist/fake/index.d.ts +4 -8
  106. package/dist/fake/index.d.ts.map +1 -1
  107. package/dist/fake/index.js +55 -889
  108. package/dist/fake/index.js.map +1 -1
  109. package/dist/lock/core/index.d.ts +13 -13
  110. package/dist/lock/core/index.d.ts.map +1 -1
  111. package/dist/lock/core/index.js +2 -2
  112. package/dist/lock/core/index.js.map +1 -1
  113. package/dist/lock/redis/index.d.ts +4 -4
  114. package/dist/lock/redis/index.d.ts.map +1 -1
  115. package/dist/logger/index.d.ts +16 -15
  116. package/dist/logger/index.d.ts.map +1 -1
  117. package/dist/logger/index.js +6 -3
  118. package/dist/logger/index.js.map +1 -1
  119. package/dist/mcp/index.d.ts +11 -11
  120. package/dist/mcp/index.d.ts.map +1 -1
  121. package/dist/mcp/index.js +2 -2
  122. package/dist/mcp/index.js.map +1 -1
  123. package/dist/orm/core/index.browser.js +11 -1
  124. package/dist/orm/core/index.browser.js.map +1 -1
  125. package/dist/orm/core/index.bun.js +78 -72
  126. package/dist/orm/core/index.bun.js.map +1 -1
  127. package/dist/orm/core/index.d.ts +103 -69
  128. package/dist/orm/core/index.d.ts.map +1 -1
  129. package/dist/orm/core/index.js +80 -70
  130. package/dist/orm/core/index.js.map +1 -1
  131. package/dist/orm/postgres/index.d.ts +19 -17
  132. package/dist/orm/postgres/index.d.ts.map +1 -1
  133. package/dist/queue/core/index.d.ts +14 -14
  134. package/dist/queue/core/index.d.ts.map +1 -1
  135. package/dist/queue/core/index.js +2 -2
  136. package/dist/queue/core/index.js.map +1 -1
  137. package/dist/queue/core/index.workerd.js +2 -2
  138. package/dist/queue/core/index.workerd.js.map +1 -1
  139. package/dist/queue/redis/index.d.ts +4 -4
  140. package/dist/queue/redis/index.d.ts.map +1 -1
  141. package/dist/queue/redis/index.js +2 -2
  142. package/dist/queue/redis/index.js.map +1 -1
  143. package/dist/react/auth/index.d.ts +9 -9
  144. package/dist/react/auth/index.d.ts.map +1 -1
  145. package/dist/react/core/index.d.ts +6 -6
  146. package/dist/react/core/index.d.ts.map +1 -1
  147. package/dist/react/core/index.js +5 -4
  148. package/dist/react/core/index.js.map +1 -1
  149. package/dist/react/form/index.d.ts +4 -4
  150. package/dist/react/form/index.d.ts.map +1 -1
  151. package/dist/react/head/index.d.ts +4 -4
  152. package/dist/react/head/index.d.ts.map +1 -1
  153. package/dist/react/i18n/index.d.ts +9 -9
  154. package/dist/react/i18n/index.d.ts.map +1 -1
  155. package/dist/react/intro/index.d.ts +2 -2
  156. package/dist/react/intro/index.d.ts.map +1 -1
  157. package/dist/react/intro/index.js +1 -1
  158. package/dist/react/intro/index.js.map +1 -1
  159. package/dist/react/router/index.browser.js +4 -5
  160. package/dist/react/router/index.browser.js.map +1 -1
  161. package/dist/react/router/index.d.ts +215 -215
  162. package/dist/react/router/index.d.ts.map +1 -1
  163. package/dist/react/router/index.js +6 -7
  164. package/dist/react/router/index.js.map +1 -1
  165. package/dist/react/testing/index.d.ts +2 -2
  166. package/dist/react/testing/index.d.ts.map +1 -1
  167. package/dist/react/testing/index.js +2 -4
  168. package/dist/react/testing/index.js.map +1 -1
  169. package/dist/redis/index.d.ts +19 -19
  170. package/dist/redis/index.d.ts.map +1 -1
  171. package/dist/retry/index.d.ts +4 -4
  172. package/dist/retry/index.d.ts.map +1 -1
  173. package/dist/scheduler/index.d.ts +13 -13
  174. package/dist/scheduler/index.d.ts.map +1 -1
  175. package/dist/scheduler/index.js +2 -2
  176. package/dist/scheduler/index.js.map +1 -1
  177. package/dist/scheduler/index.workerd.js +2 -2
  178. package/dist/scheduler/index.workerd.js.map +1 -1
  179. package/dist/security/index.browser.js +1 -1
  180. package/dist/security/index.browser.js.map +1 -1
  181. package/dist/security/index.d.ts +47 -47
  182. package/dist/security/index.d.ts.map +1 -1
  183. package/dist/security/index.js +9 -12
  184. package/dist/security/index.js.map +1 -1
  185. package/dist/server/auth/index.d.ts +170 -169
  186. package/dist/server/auth/index.d.ts.map +1 -1
  187. package/dist/server/auth/index.js +16 -2
  188. package/dist/server/auth/index.js.map +1 -1
  189. package/dist/server/cookies/index.d.ts +7 -7
  190. package/dist/server/cookies/index.d.ts.map +1 -1
  191. package/dist/server/core/index.d.ts +76 -76
  192. package/dist/server/core/index.d.ts.map +1 -1
  193. package/dist/server/core/index.js +23 -17
  194. package/dist/server/core/index.js.map +1 -1
  195. package/dist/server/cors/index.d.ts +13 -13
  196. package/dist/server/cors/index.d.ts.map +1 -1
  197. package/dist/server/cors/index.js +2 -2
  198. package/dist/server/cors/index.js.map +1 -1
  199. package/dist/server/etag/index.d.ts +9 -9
  200. package/dist/server/etag/index.d.ts.map +1 -1
  201. package/dist/server/health/index.d.ts +20 -20
  202. package/dist/server/health/index.d.ts.map +1 -1
  203. package/dist/server/links/index.browser.js +2 -2
  204. package/dist/server/links/index.browser.js.map +1 -1
  205. package/dist/server/links/index.d.ts +66 -66
  206. package/dist/server/links/index.d.ts.map +1 -1
  207. package/dist/server/links/index.js +4 -4
  208. package/dist/server/links/index.js.map +1 -1
  209. package/dist/server/metrics/index.d.ts +7 -7
  210. package/dist/server/metrics/index.d.ts.map +1 -1
  211. package/dist/server/proxy/index.d.ts +5 -5
  212. package/dist/server/proxy/index.d.ts.map +1 -1
  213. package/dist/server/rate-limit/index.d.ts +12 -12
  214. package/dist/server/rate-limit/index.d.ts.map +1 -1
  215. package/dist/server/rate-limit/index.js +2 -2
  216. package/dist/server/rate-limit/index.js.map +1 -1
  217. package/dist/server/static/index.d.ts +5 -5
  218. package/dist/server/static/index.d.ts.map +1 -1
  219. package/dist/server/swagger/index.d.ts +7 -7
  220. package/dist/server/swagger/index.d.ts.map +1 -1
  221. package/dist/server/swagger/index.js +2 -2
  222. package/dist/server/swagger/index.js.map +1 -1
  223. package/dist/sms/index.d.ts +11 -7
  224. package/dist/sms/index.d.ts.map +1 -1
  225. package/dist/sms/index.js +9 -15
  226. package/dist/sms/index.js.map +1 -1
  227. package/dist/system/index.d.ts +4 -4
  228. package/dist/system/index.d.ts.map +1 -1
  229. package/dist/topic/core/index.d.ts +6 -6
  230. package/dist/topic/core/index.d.ts.map +1 -1
  231. package/dist/topic/redis/index.d.ts +7 -7
  232. package/dist/topic/redis/index.d.ts.map +1 -1
  233. package/dist/topic/redis/index.js +2 -2
  234. package/dist/topic/redis/index.js.map +1 -1
  235. package/dist/websocket/index.d.ts +36 -36
  236. package/dist/websocket/index.d.ts.map +1 -1
  237. package/dist/websocket/index.js +2 -2
  238. package/dist/websocket/index.js.map +1 -1
  239. package/package.json +37 -15
  240. package/src/api/jobs/{services → __tests__}/JobService.spec.ts +1 -1
  241. package/src/api/jobs/providers/JobProvider.ts +13 -9
  242. package/src/api/keys/{services → __tests__}/ApiKeyService.spec.ts +1 -1
  243. package/src/api/organizations/__tests__/OrganizationService.spec.ts +193 -0
  244. package/src/api/organizations/controllers/AdminOrganizationController.ts +103 -0
  245. package/src/api/organizations/entities/organizations.ts +20 -0
  246. package/src/api/organizations/index.browser.ts +10 -0
  247. package/src/api/organizations/index.ts +31 -0
  248. package/src/api/organizations/schemas/createOrganizationSchema.ts +10 -0
  249. package/src/api/organizations/schemas/organizationQuerySchema.ts +10 -0
  250. package/src/api/organizations/schemas/organizationResourceSchema.ts +6 -0
  251. package/src/api/organizations/schemas/updateOrganizationSchema.ts +7 -0
  252. package/src/api/organizations/services/OrganizationService.ts +75 -0
  253. package/src/api/parameters/services/ParameterProvider.ts +6 -1
  254. package/src/api/users/{services → __tests__}/SessionService.spec.ts +67 -0
  255. package/src/api/users/{jobs → __tests__}/UserJobs.spec.ts +1 -1
  256. package/src/api/users/entities/users.ts +9 -3
  257. package/src/api/users/index.ts +23 -4
  258. package/src/api/users/primitives/$realm.ts +6 -4
  259. package/src/api/users/providers/RealmProvider.ts +1 -1
  260. package/src/api/users/services/RegistrationService.ts +1 -1
  261. package/src/api/users/services/SessionService.ts +92 -5
  262. package/src/api/users/services/UserService.ts +1 -1
  263. package/src/api/verifications/{jobs → __tests__}/VerificationJobs.spec.ts +4 -2
  264. package/src/api/verifications/parameters/VerificationParameters.ts +2 -2
  265. package/src/billing/__tests__/BillingService.spec.ts +136 -0
  266. package/src/billing/__tests__/PaymentMethodService.spec.ts +78 -0
  267. package/src/billing/controllers/AdminBillingController.ts +149 -0
  268. package/src/billing/controllers/BillingController.ts +108 -0
  269. package/src/billing/entities/paymentIntents.ts +34 -0
  270. package/src/billing/entities/paymentMethods.ts +24 -0
  271. package/src/billing/entities/refunds.ts +22 -0
  272. package/src/billing/errors/BillingError.ts +5 -0
  273. package/src/billing/index.ts +76 -0
  274. package/src/billing/providers/BillingProvider.ts +79 -0
  275. package/src/billing/providers/MemoryBillingProvider.ts +139 -0
  276. package/src/billing/schemas/intentSchemas.ts +60 -0
  277. package/src/billing/schemas/paymentMethodSchemas.ts +13 -0
  278. package/src/billing/schemas/refundSchemas.ts +6 -0
  279. package/src/billing/services/BillingService.ts +325 -0
  280. package/src/billing/services/PaymentMethodService.ts +82 -0
  281. package/src/bin/index.ts +0 -2
  282. package/src/bucket/providers/LocalFileStorageProvider.ts +2 -2
  283. package/src/cache/core/{primitives → __tests__}/$cache.middleware.spec.ts +1 -1
  284. package/src/cache/core/{providers → __tests__}/MemoryCacheProvider.spec.ts +1 -1
  285. package/src/cache/core/primitives/$cache.ts +2 -2
  286. package/src/cache/redis/providers/RedisCacheProvider.ts +2 -2
  287. package/src/cli/config/defineConfig.ts +17 -26
  288. package/src/cli/core/{services → __tests__}/ProjectScaffolder.spec.ts +1 -1
  289. package/src/cli/core/{commands/gen → __tests__}/changelog.spec.ts +1 -1
  290. package/src/cli/core/{commands → __tests__}/init.spec.ts +2 -8
  291. package/src/cli/core/atoms/devOptions.ts +0 -5
  292. package/src/cli/core/commands/build.ts +2 -2
  293. package/src/cli/core/commands/dev.ts +165 -30
  294. package/src/cli/core/commands/gen/changelog.ts +2 -2
  295. package/src/cli/core/commands/init.ts +2 -7
  296. package/src/cli/core/commands/verify.ts +0 -1
  297. package/src/cli/core/providers/AppEntryProvider.ts +2 -2
  298. package/src/cli/core/providers/ViteDevServerProvider.ts +99 -69
  299. package/src/cli/core/services/PackageManagerUtils.ts +8 -1
  300. package/src/cli/core/services/ProjectScaffolder.ts +23 -23
  301. package/src/cli/core/tasks/BuildClientTask.ts +8 -0
  302. package/src/cli/core/tasks/BuildServerTask.ts +17 -4
  303. package/src/cli/core/templates/agentMd.ts +14 -5
  304. package/src/cli/core/templates/alephaConfigTs.ts +0 -6
  305. package/src/cli/core/templates/webAdminDashboardTsx.ts +17 -0
  306. package/src/cli/core/templates/webAppRouterTs.ts +85 -2
  307. package/src/cli/devtools/atoms/devtoolsOptions.ts +26 -0
  308. package/src/cli/devtools/index.ts +214 -0
  309. package/src/cli/platform/{adapters → __tests__}/CloudflareAdapter.spec.ts +2 -2
  310. package/src/cli/platform/{providers → __tests__}/GitHubSecretStore.spec.ts +1 -1
  311. package/src/cli/platform/{services → __tests__}/NamingService.spec.ts +1 -1
  312. package/src/cli/platform/{providers → __tests__}/PlatformCacheProvider.spec.ts +1 -1
  313. package/src/cli/platform/{services → __tests__}/PlatformInspector.spec.ts +1 -1
  314. package/src/cli/platform/{services → __tests__}/PlatformOrchestrator.spec.ts +3 -3
  315. package/src/cli/platform/{services → __tests__}/SecretFilterService.spec.ts +1 -1
  316. package/src/cli/platform/{commands → __tests__}/SecretsCommand.spec.ts +1 -1
  317. package/src/cli/platform/{adapters → __tests__}/VercelAdapter.spec.ts +2 -2
  318. package/src/cli/platform/atoms/platformOptions.ts +2 -10
  319. package/src/cli/platform/commands/SecretsCommand.ts +2 -2
  320. package/src/cli/platform/commands/platform.ts +2 -11
  321. package/src/cli/platform/index.ts +55 -11
  322. package/src/cli/platform/services/PlatformInspector.ts +2 -2
  323. package/src/cli/platform/services/PlatformOrchestrator.ts +0 -9
  324. package/src/cli/vendor/__tests__/VendorService.spec.ts +407 -0
  325. package/src/cli/vendor/atoms/vendorOptions.ts +41 -0
  326. package/src/cli/vendor/commands/VendorCommand.ts +204 -0
  327. package/src/cli/vendor/index.ts +60 -0
  328. package/src/cli/vendor/services/VendorService.ts +338 -0
  329. package/src/command/{providers → __tests__}/CliProvider.spec.ts +1 -1
  330. package/src/command/{helpers → __tests__}/EnvUtils.spec.ts +1 -1
  331. package/src/command/providers/CliProvider.ts +2 -2
  332. package/src/core/Alepha.ts +10 -0
  333. package/src/core/{primitives → __tests__}/$atom.spec.ts +2 -2
  334. package/src/core/{primitives → __tests__}/$memoize.spec.ts +1 -1
  335. package/src/core/{primitives → __tests__}/$mode.spec.ts +1 -1
  336. package/src/core/{primitives → __tests__}/$pipeline.spec.ts +1 -1
  337. package/src/core/{primitives → __tests__}/$scope.spec.ts +2 -2
  338. package/src/core/{providers → __tests__}/KeylessJsonSchemaCodec.spec.ts +1 -1
  339. package/src/core/{providers → __tests__}/SchemaValidator.spec.ts +1 -1
  340. package/src/core/{helpers → __tests__}/jsonSchemaToTypeBox.spec.ts +1 -1
  341. package/src/core/index.shared.ts +1 -1
  342. package/src/core/primitives/{$use.ts → $state.ts} +4 -4
  343. package/src/crypto/{providers → __tests__}/BrowserCryptoProvider.browser.spec.ts +1 -1
  344. package/src/crypto/{providers → __tests__}/CryptoProvider.spec.ts +1 -1
  345. package/src/datetime/{primitives → __tests__}/$debounce.spec.ts +1 -1
  346. package/src/datetime/{primitives → __tests__}/$throttle.spec.ts +1 -1
  347. package/src/datetime/{primitives → __tests__}/$timeout.spec.ts +1 -1
  348. package/src/email/brevo/{providers → __tests__}/BrevoEmailProvider.spec.ts +1 -1
  349. package/src/email/core/{providers → __tests__}/LocalEmailProvider.spec.ts +39 -150
  350. package/src/email/core/providers/LocalEmailProvider.ts +13 -51
  351. package/src/email/smtp/providers/NodemailerEmailProvider.ts +2 -2
  352. package/src/lock/core/{primitives → __tests__}/$lock.middleware.spec.ts +1 -1
  353. package/src/lock/core/primitives/$lock.ts +2 -2
  354. package/src/logger/index.ts +16 -5
  355. package/src/mcp/transports/SseMcpTransport.ts +2 -2
  356. package/src/orm/__tests__/ModelBuilder-tests.ts +53 -0
  357. package/src/orm/__tests__/ModelBuilder.spec.ts +80 -0
  358. package/src/orm/__tests__/organization-tests.ts +200 -0
  359. package/src/orm/__tests__/organization.spec.ts +103 -0
  360. package/src/orm/core/{providers/drivers → __tests__}/BunSqliteProvider.bun.spec.ts +5 -2
  361. package/src/orm/core/constants/PG_SYMBOLS.ts +2 -0
  362. package/src/orm/core/index.shared.ts +1 -0
  363. package/src/orm/core/primitives/$entity.ts +31 -0
  364. package/src/orm/core/providers/DatabaseTypeProvider.ts +11 -0
  365. package/src/orm/core/providers/DrizzleKitProvider.ts +57 -106
  366. package/src/orm/core/providers/drivers/BunSqliteProvider.ts +2 -2
  367. package/src/orm/core/providers/drivers/NodeSqliteProvider.ts +3 -3
  368. package/src/orm/core/services/ModelBuilder.ts +11 -0
  369. package/src/orm/core/services/QueryManager.ts +16 -2
  370. package/src/orm/core/services/Repository.ts +70 -10
  371. package/src/orm/postgres/{providers → __tests__}/BunPostgresProvider.bun.spec.ts +1 -1
  372. package/src/queue/core/providers/WorkerProvider.ts +2 -2
  373. package/src/queue/redis/providers/RedisQueueProvider.ts +2 -2
  374. package/src/react/core/{hooks → __tests__}/useAction.browser.spec.tsx +1 -1
  375. package/src/react/core/hooks/useAction.ts +7 -6
  376. package/src/react/head/{providers → __tests__}/BrowserHeadProvider.browser.spec.ts +1 -1
  377. package/src/react/head/{helpers → __tests__}/SeoExpander.spec.ts +1 -1
  378. package/src/react/i18n/{providers → __tests__}/I18nProvider.spec.ts +1 -1
  379. package/src/react/i18n/{hooks → __tests__}/useI18n.browser.spec.tsx +1 -1
  380. package/src/react/intro/components/GettingStartedDevtoolsSlide.tsx +1 -1
  381. package/src/react/router/{providers → __tests__}/ReactBrowserProvider.browser.spec.ts +1 -1
  382. package/src/react/router/providers/ReactBrowserProvider.ts +2 -2
  383. package/src/react/router/providers/ReactPageProvider.ts +2 -2
  384. package/src/react/router/providers/ReactServerProvider.ts +3 -3
  385. package/src/redis/{providers → __tests__}/BunRedisProvider.bun.spec.ts +4 -4
  386. package/src/retry/{primitives → __tests__}/$retry.middleware.spec.ts +1 -1
  387. package/src/router/{TemplatedPathParser.spec.ts → __tests__/TemplatedPathParser.spec.ts} +1 -1
  388. package/src/scheduler/primitives/$scheduler.ts +2 -2
  389. package/src/security/{primitives → __tests__}/$secure-browser.spec.ts +1 -1
  390. package/src/security/{primitives → __tests__}/$secure.spec.ts +1 -1
  391. package/src/security/primitives/$issuer.ts +1 -1
  392. package/src/security/providers/JwtProvider.ts +6 -10
  393. package/src/security/providers/SecurityProvider.ts +6 -11
  394. package/src/security/schemas/userAccountInfoSchema.ts +3 -3
  395. package/src/server/auth/providers/ServerAuthProvider.ts +24 -2
  396. package/src/server/cookies/{services → __tests__}/CookieParser.spec.ts +1 -1
  397. package/src/server/core/{primitives → __tests__}/$circuit.spec.ts +1 -1
  398. package/src/server/core/{providers → __tests__}/NodeHttpServerProvider.spec.ts +1 -1
  399. package/src/server/core/{providers → __tests__}/ServerBodyParserProvider.spec.ts +31 -1
  400. package/src/server/core/{providers → __tests__}/ServerCompressProvider.spec.ts +1 -1
  401. package/src/server/core/{providers → __tests__}/ServerHelmetProvider.spec.ts +4 -1
  402. package/src/server/core/{providers → __tests__}/ServerMultipartProvider.spec.ts +1 -1
  403. package/src/server/core/{services → __tests__}/ServerRequestParser.spec.ts +1 -1
  404. package/src/server/core/primitives/$action.ts +2 -2
  405. package/src/server/core/primitives/$sse.ts +2 -2
  406. package/src/server/core/providers/ServerBodyParserProvider.ts +21 -12
  407. package/src/server/core/providers/ServerCompressProvider.ts +2 -2
  408. package/src/server/core/providers/ServerHelmetProvider.ts +2 -2
  409. package/src/server/core/providers/ServerMultipartProvider.ts +2 -2
  410. package/src/server/core/providers/ServerRouterProvider.ts +1 -5
  411. package/src/server/cors/{primitives → __tests__}/$cors.spec.ts +1 -1
  412. package/src/server/cors/providers/ServerCorsProvider.ts +2 -2
  413. package/src/server/links/{services → __tests__}/BatchCollector.spec.ts +1 -1
  414. package/src/server/links/providers/LinkProvider.ts +2 -2
  415. package/src/server/links/providers/RemotePrimitiveProvider.ts +2 -2
  416. package/src/server/links/providers/ServerLinksProvider.ts +2 -2
  417. package/src/server/rate-limit/{primitives → __tests__}/$rateLimit.spec.ts +1 -1
  418. package/src/server/rate-limit/providers/ServerRateLimitProvider.ts +2 -2
  419. package/src/server/swagger/providers/ServerSwaggerProvider.ts +2 -2
  420. package/src/sms/{providers → __tests__}/LocalSmsProvider.spec.ts +35 -29
  421. package/src/sms/providers/LocalSmsProvider.ts +13 -24
  422. package/src/system/{providers → __tests__}/MemoryFileSystemProvider.spec.ts +1 -1
  423. package/src/system/{providers → __tests__}/MemoryShellProvider.spec.ts +1 -1
  424. package/src/topic/redis/providers/RedisTopicProvider.ts +2 -2
  425. package/src/websocket/{services → __tests__}/RoomManager.spec.ts +1 -1
  426. package/src/websocket/providers/NodeWebSocketServerProvider.ts +2 -2
  427. package/src/cli/platform/adapters/DockerAdapter.spec.ts +0 -378
  428. package/src/cli/platform/adapters/DockerAdapter.ts +0 -417
  429. package/src/cli/platform/services/DockerComposeGenerator.spec.ts +0 -490
  430. package/src/cli/platform/services/DockerComposeGenerator.ts +0 -353
  431. package/src/cli/platform/services/DockerSshService.spec.ts +0 -47
  432. package/src/cli/platform/services/DockerSshService.ts +0 -61
  433. /package/src/api/audits/{primitives → __tests__}/$audit.spec.ts +0 -0
  434. /package/src/api/audits/{services → __tests__}/AuditService.spec.ts +0 -0
  435. /package/src/api/files/{controllers → __tests__}/AdminFileStatsController.spec.ts +0 -0
  436. /package/src/api/files/{controllers → __tests__}/FileController.spec.ts +0 -0
  437. /package/src/api/files/{jobs → __tests__}/FileJobs.spec.ts +0 -0
  438. /package/src/api/files/{services → __tests__}/FileService.spec.ts +0 -0
  439. /package/src/api/jobs/{primitives → __tests__}/$job-middleware.spec.ts +0 -0
  440. /package/src/api/parameters/{primitives → __tests__}/$parameter.spec.ts +0 -0
  441. /package/src/api/users/{primitives → __tests__}/$realm.spec.ts +0 -0
  442. /package/src/api/users/{controllers → __tests__}/AdminIdentityController.spec.ts +0 -0
  443. /package/src/api/users/{controllers → __tests__}/AdminSessionController.spec.ts +0 -0
  444. /package/src/api/users/{controllers → __tests__}/AdminUserController.spec.ts +0 -0
  445. /package/src/api/users/{services → __tests__}/CredentialService.spec.ts +0 -0
  446. /package/src/api/users/{providers → __tests__}/RealmProvider.spec.ts +0 -0
  447. /package/src/api/users/{services → __tests__}/RegistrationService.spec.ts +0 -0
  448. /package/src/batch/{primitives → __tests__}/$batch.spec.ts +0 -0
  449. /package/src/batch/{providers → __tests__}/BatchProvider.spec.ts +0 -0
  450. /package/src/bucket/{primitives → __tests__}/$bucket.spec.ts +0 -0
  451. /package/src/bucket/{providers → __tests__}/FileStorageProvider.spec.ts +0 -0
  452. /package/src/bucket/{providers → __tests__}/LocalFileStorageProvider.spec.ts +0 -0
  453. /package/src/bucket/{providers → __tests__}/MemoryFileStorageProvider.spec.ts +0 -0
  454. /package/src/cache/core/{primitives → __tests__}/$cache.spec.ts +0 -0
  455. /package/src/cache/redis/{providers → __tests__}/RedisCacheProvider.spec.ts +0 -0
  456. /package/src/command/{primitives → __tests__}/$command.spec.ts +0 -0
  457. /package/src/command/{helpers → __tests__}/Asker.spec.ts +0 -0
  458. /package/src/command/{helpers → __tests__}/Runner.spec.ts +0 -0
  459. /package/src/core/{primitives → __tests__}/$context.spec.ts +0 -0
  460. /package/src/core/{primitives → __tests__}/$env.spec.ts +0 -0
  461. /package/src/core/{primitives → __tests__}/$hook.spec.ts +0 -0
  462. /package/src/core/{primitives → __tests__}/$inject.spec.ts +0 -0
  463. /package/src/core/{primitives → __tests__}/$module.spec.ts +0 -0
  464. /package/src/core/{providers → __tests__}/CodecManager.spec.ts +0 -0
  465. /package/src/core/{providers → __tests__}/EventManager.spec.ts +0 -0
  466. /package/src/core/{providers → __tests__}/StateManager.spec.ts +0 -0
  467. /package/src/core/{providers → __tests__}/TypeProvider.spec.ts +0 -0
  468. /package/src/datetime/{primitives → __tests__}/$interval.spec.ts +0 -0
  469. /package/src/datetime/{providers → __tests__}/DateTimeProvider.spec.ts +0 -0
  470. /package/src/email/core/{primitives → __tests__}/$email.spec.ts +0 -0
  471. /package/src/fake/{providers → __tests__}/FakeProvider.spec.ts +0 -0
  472. /package/src/lock/core/{providers → __tests__}/MemoryLockProvider.spec.ts +0 -0
  473. /package/src/lock/redis/{providers → __tests__}/RedisLockProvider.spec.ts +0 -0
  474. /package/src/logger/{primitives → __tests__}/$logger.spec.ts +0 -0
  475. /package/src/logger/{services → __tests__}/Logger.spec.ts +0 -0
  476. /package/src/mcp/{primitives → __tests__}/$prompt.spec.ts +0 -0
  477. /package/src/mcp/{primitives → __tests__}/$resource.spec.ts +0 -0
  478. /package/src/mcp/{primitives → __tests__}/$tool.spec.ts +0 -0
  479. /package/src/mcp/{providers → __tests__}/McpServerProvider.spec.ts +0 -0
  480. /package/src/mcp/{helpers → __tests__}/jsonrpc.spec.ts +0 -0
  481. /package/src/orm/core/{helpers → __tests__}/parseQueryString.spec.ts +0 -0
  482. /package/src/queue/core/{primitives → __tests__}/$consumer.spec.ts +0 -0
  483. /package/src/queue/core/{providers → __tests__}/MemoryQueueProvider.spec.ts +0 -0
  484. /package/src/queue/core/{providers → __tests__}/WorkerProvider.spec.ts +0 -0
  485. /package/src/queue/redis/{providers → __tests__}/RedisQueueProvider.spec.ts +0 -0
  486. /package/src/react/form/{hooks → __tests__}/useForm.browser.spec.tsx +0 -0
  487. /package/src/react/head/{hooks → __tests__}/useHead.spec.tsx +0 -0
  488. /package/src/react/i18n/{components → __tests__}/Localize.spec.tsx +0 -0
  489. /package/src/react/router/{primitives → __tests__}/$page.browser.spec.tsx +0 -0
  490. /package/src/react/router/{primitives → __tests__}/$page.middleware.spec.tsx +0 -0
  491. /package/src/react/router/{primitives → __tests__}/$page.spec.tsx +0 -0
  492. /package/src/react/router/{providers → __tests__}/ReactPreloadProvider.spec.ts +0 -0
  493. /package/src/react/router/{providers → __tests__}/ReactServerProvider.spec.tsx +0 -0
  494. /package/src/react/router/{providers → __tests__}/ReactServerTemplateProvider.spec.ts +0 -0
  495. /package/src/retry/{primitives → __tests__}/$retry.spec.ts +0 -0
  496. /package/src/retry/{providers → __tests__}/RetryProvider.spec.ts +0 -0
  497. /package/src/router/{providers → __tests__}/RouterProvider.spec.ts +0 -0
  498. /package/src/security/{primitives → __tests__}/$issuer.spec.ts +0 -0
  499. /package/src/security/{primitives → __tests__}/$permission.spec.ts +0 -0
  500. /package/src/security/{primitives → __tests__}/$role.spec.ts +0 -0
  501. /package/src/security/{primitives → __tests__}/$serviceAccount.spec.ts +0 -0
  502. /package/src/security/{providers → __tests__}/SecurityProvider.spec.ts +0 -0
  503. /package/src/server/cookies/{providers → __tests__}/ServerCookiesProvider.spec.ts +0 -0
  504. /package/src/server/core/{primitives → __tests__}/$action.spec.ts +0 -0
  505. /package/src/server/core/{primitives → __tests__}/$middleware.spec.ts +0 -0
  506. /package/src/server/core/{primitives → __tests__}/$route.spec.ts +0 -0
  507. /package/src/server/core/{primitives → __tests__}/$sse.spec.ts +0 -0
  508. /package/src/server/core/{providers → __tests__}/BunHttpServerProvider.bun.spec.ts +0 -0
  509. /package/src/server/core/{services → __tests__}/HttpClient.spec.ts +0 -0
  510. /package/src/server/core/{providers → __tests__}/ServerLoggerProvider.spec.ts +0 -0
  511. /package/src/server/core/{services → __tests__}/UserAgentParser.spec.ts +0 -0
  512. /package/src/server/cors/{providers → __tests__}/ServerCorsProvider.spec.ts +0 -0
  513. /package/src/server/etag/{providers → __tests__}/ServerEtagProvider.spec.ts +0 -0
  514. /package/src/server/health/{providers → __tests__}/ServerHealthProvider.spec.ts +0 -0
  515. /package/src/server/links/{primitives → __tests__}/$remote.spec.ts +0 -0
  516. /package/src/server/links/{services → __tests__}/BatchEndpoint.spec.ts +0 -0
  517. /package/src/server/links/{providers → __tests__}/LinkProvider.spec.ts +0 -0
  518. /package/src/server/links/{providers → __tests__}/ServerLinksProvider.spec.ts +0 -0
  519. /package/src/server/metrics/{providers → __tests__}/ServerMetricsProvider.spec.ts +0 -0
  520. /package/src/server/proxy/{primitives → __tests__}/$proxy.spec.ts +0 -0
  521. /package/src/server/rate-limit/{providers → __tests__}/ServerRateLimitProvider.spec.ts +0 -0
  522. /package/src/server/static/{primitives → __tests__}/$serve.spec.ts +0 -0
  523. /package/src/server/swagger/{primitives → __tests__}/$swagger.spec.ts +0 -0
  524. /package/src/sms/{primitives → __tests__}/$sms.spec.ts +0 -0
  525. /package/src/sms/{providers → __tests__}/MemorySmsProvider.spec.ts +0 -0
  526. /package/src/system/{services → __tests__}/FileDetector.spec.ts +0 -0
  527. /package/src/system/{providers → __tests__}/NodeFileSystemProvider.spec.ts +0 -0
  528. /package/src/topic/core/{primitives → __tests__}/$subscriber.spec.ts +0 -0
  529. /package/src/topic/core/{providers → __tests__}/MemoryTopicProvider.spec.ts +0 -0
  530. /package/src/topic/redis/{providers → __tests__}/RedisTopicProvider.spec.ts +0 -0
  531. /package/src/websocket/{primitives → __tests__}/$channel.spec.ts +0 -0
@@ -0,0 +1,325 @@
1
+ import { $inject, Alepha } from "alepha";
2
+ import { $job } from "alepha/api/jobs";
3
+ import { DateTimeProvider } from "alepha/datetime";
4
+ import { $logger } from "alepha/logger";
5
+ import { $repository } from "alepha/orm";
6
+ import {
7
+ type PaymentIntentEntity,
8
+ paymentIntents,
9
+ } from "../entities/paymentIntents.ts";
10
+ import { type RefundEntity, refunds } from "../entities/refunds.ts";
11
+ import { BillingError } from "../errors/BillingError.ts";
12
+ import { BillingProvider } from "../providers/BillingProvider.ts";
13
+
14
+ export class BillingService {
15
+ protected readonly alepha = $inject(Alepha);
16
+ protected readonly log = $logger();
17
+ protected readonly dateTime = $inject(DateTimeProvider);
18
+ protected readonly provider = $inject(BillingProvider);
19
+ protected readonly intentRepo = $repository(paymentIntents);
20
+ protected readonly refundRepo = $repository(refunds);
21
+
22
+ /**
23
+ * Expires stale payment intents that have been in "processing" status
24
+ * for more than 30 minutes. Runs every 15 minutes.
25
+ */
26
+ protected readonly expireStaleIntents = $job({
27
+ cron: "*/15 * * * *",
28
+ handler: async () => {
29
+ const cutoff = this.dateTime.now().subtract(30, "minutes").toISOString();
30
+
31
+ const stale = await this.intentRepo.findMany({
32
+ where: { status: { eq: "processing" }, createdAt: { lt: cutoff } },
33
+ });
34
+
35
+ for (const intent of stale) {
36
+ if (intent.providerRef) {
37
+ try {
38
+ await this.provider.expireSession(intent.providerRef);
39
+ } catch (error) {
40
+ this.log.warn(
41
+ `Failed to expire session for intent ${intent.id}`,
42
+ error,
43
+ );
44
+ }
45
+ }
46
+ await this.intentRepo.updateById(intent.id, { status: "expired" });
47
+ this.log.info(`Expired stale intent ${intent.id}`);
48
+ }
49
+ },
50
+ });
51
+
52
+ /**
53
+ * Create a new payment intent in "created" status.
54
+ */
55
+ public async createIntent(
56
+ amount: number,
57
+ currency: string,
58
+ metadata?: unknown,
59
+ options?: { paymentMethodId?: string; userId?: string },
60
+ ): Promise<PaymentIntentEntity> {
61
+ return await this.intentRepo.create({
62
+ amount,
63
+ currency,
64
+ status: "created",
65
+ metadata: metadata as any,
66
+ paymentMethodId: options?.paymentMethodId,
67
+ userId: options?.userId,
68
+ });
69
+ }
70
+
71
+ /**
72
+ * Create a checkout session with the payment provider and
73
+ * transition the intent to "processing".
74
+ */
75
+ public async createSession(
76
+ intentId: string,
77
+ returnUrl: string,
78
+ authorize?: boolean,
79
+ ): Promise<{ url: string; intentId: string }> {
80
+ const intent = await this.getIntent(intentId);
81
+ this.assertStatus(intent, "created", "createSession");
82
+
83
+ const result = await this.provider.createSession(intent, {
84
+ returnUrl,
85
+ authorize,
86
+ });
87
+
88
+ await this.intentRepo.updateById(intent.id, {
89
+ status: "processing",
90
+ providerRef: result.providerRef,
91
+ });
92
+
93
+ return { url: result.url, intentId: intent.id };
94
+ }
95
+
96
+ /**
97
+ * Handle an incoming webhook from the payment provider.
98
+ */
99
+ public async handleWebhook(request: Request): Promise<void> {
100
+ const event = await this.provider.parseWebhook(request);
101
+ const intents = await this.intentRepo.findMany({
102
+ where: { providerRef: { eq: event.providerRef } },
103
+ limit: 1,
104
+ });
105
+
106
+ if (intents.length === 0) {
107
+ this.log.warn(`Webhook for unknown providerRef: ${event.providerRef}`);
108
+ return;
109
+ }
110
+
111
+ const intent = intents[0];
112
+ await this.handleWebhookEvent(intent.id, event.status, event.raw);
113
+ }
114
+
115
+ /**
116
+ * Process a webhook event by updating the intent status and emitting
117
+ * the corresponding billing event.
118
+ */
119
+ public async handleWebhookEvent(
120
+ intentId: string,
121
+ status: string,
122
+ raw?: unknown,
123
+ ): Promise<void> {
124
+ const intent = await this.getIntent(intentId);
125
+
126
+ const eventMap = {
127
+ authorized: "billing:authorized",
128
+ captured: "billing:captured",
129
+ failed: "billing:failed",
130
+ } as const;
131
+
132
+ type WebhookStatus = keyof typeof eventMap;
133
+ if (!(status in eventMap)) {
134
+ this.log.warn(`Unknown webhook status: ${status}`);
135
+ return;
136
+ }
137
+
138
+ const webhookStatus = status as WebhookStatus;
139
+
140
+ await this.intentRepo.updateById(intent.id, {
141
+ status: webhookStatus,
142
+ providerRaw: raw as any,
143
+ });
144
+
145
+ await this.alepha.events.emit(eventMap[webhookStatus], {
146
+ intentId: intent.id,
147
+ amount: intent.amount,
148
+ currency: intent.currency,
149
+ metadata: intent.metadata,
150
+ });
151
+ }
152
+
153
+ /**
154
+ * Capture a previously authorized payment. Optionally specify a different
155
+ * amount for partial capture.
156
+ */
157
+ public async capture(
158
+ intentId: string,
159
+ finalAmount?: number,
160
+ ): Promise<PaymentIntentEntity> {
161
+ const intent = await this.getIntent(intentId);
162
+ this.assertStatus(intent, "authorized", "capture");
163
+
164
+ const amount = finalAmount ?? intent.amount;
165
+ if (intent.providerRef) {
166
+ await this.provider.capturePayment(intent.providerRef, amount);
167
+ }
168
+
169
+ const updated = await this.intentRepo.updateById(intent.id, {
170
+ status: "captured",
171
+ amount,
172
+ });
173
+
174
+ await this.alepha.events.emit("billing:captured", {
175
+ intentId: intent.id,
176
+ amount,
177
+ currency: intent.currency,
178
+ metadata: intent.metadata,
179
+ });
180
+
181
+ return updated;
182
+ }
183
+
184
+ /**
185
+ * Void a previously authorized payment before capture.
186
+ */
187
+ public async void(intentId: string): Promise<PaymentIntentEntity> {
188
+ const intent = await this.getIntent(intentId);
189
+ this.assertStatus(intent, "authorized", "void");
190
+
191
+ if (intent.providerRef) {
192
+ await this.provider.voidPayment(intent.providerRef);
193
+ }
194
+
195
+ const updated = await this.intentRepo.updateById(intent.id, {
196
+ status: "voided",
197
+ });
198
+
199
+ await this.alepha.events.emit("billing:voided", {
200
+ intentId: intent.id,
201
+ amount: intent.amount,
202
+ currency: intent.currency,
203
+ metadata: intent.metadata,
204
+ });
205
+
206
+ return updated;
207
+ }
208
+
209
+ /**
210
+ * Refund a captured payment (partial or full).
211
+ */
212
+ public async refund(
213
+ intentId: string,
214
+ amount: number,
215
+ reason?: string,
216
+ ): Promise<RefundEntity> {
217
+ const intent = await this.getIntent(intentId);
218
+ this.assertStatus(intent, "captured", "refund");
219
+
220
+ let refundProviderRef: string | undefined;
221
+ if (intent.providerRef) {
222
+ const result = await this.provider.refundPayment(
223
+ intent.providerRef,
224
+ amount,
225
+ );
226
+ refundProviderRef = result.providerRef;
227
+ }
228
+
229
+ const refund = await this.refundRepo.create({
230
+ intentId: intent.id,
231
+ organizationId: intent.organizationId,
232
+ amount,
233
+ currency: intent.currency,
234
+ status: "completed",
235
+ reason,
236
+ providerRef: refundProviderRef,
237
+ });
238
+
239
+ await this.intentRepo.updateById(intent.id, { status: "refunded" });
240
+
241
+ await this.alepha.events.emit("billing:refunded", {
242
+ intentId: intent.id,
243
+ refundId: refund.id,
244
+ amount,
245
+ currency: intent.currency,
246
+ metadata: intent.metadata,
247
+ });
248
+
249
+ return refund;
250
+ }
251
+
252
+ /**
253
+ * Record a cash or offline payment directly as captured,
254
+ * bypassing the checkout flow.
255
+ */
256
+ public async recordCashPayment(
257
+ amount: number,
258
+ currency: string,
259
+ metadata?: unknown,
260
+ ): Promise<PaymentIntentEntity> {
261
+ const intent = await this.intentRepo.create({
262
+ amount,
263
+ currency,
264
+ status: "captured",
265
+ metadata: metadata as any,
266
+ });
267
+
268
+ await this.alepha.events.emit("billing:captured", {
269
+ intentId: intent.id,
270
+ amount,
271
+ currency,
272
+ metadata,
273
+ });
274
+
275
+ return intent;
276
+ }
277
+
278
+ /**
279
+ * Cancel a payment intent that has not yet entered processing.
280
+ */
281
+ public async cancel(intentId: string): Promise<PaymentIntentEntity> {
282
+ const intent = await this.getIntent(intentId);
283
+ this.assertStatus(intent, "created", "cancel");
284
+
285
+ return await this.intentRepo.updateById(intent.id, {
286
+ status: "cancelled",
287
+ });
288
+ }
289
+
290
+ /**
291
+ * Get a payment intent by ID. Throws NotFoundError if not found.
292
+ */
293
+ public async getIntent(intentId: string): Promise<PaymentIntentEntity> {
294
+ return await this.intentRepo.getById(intentId);
295
+ }
296
+
297
+ /**
298
+ * Find payment intents with optional filters and pagination.
299
+ */
300
+ public async findIntents(query: {
301
+ status?: string;
302
+ userId?: string;
303
+ sort?: string;
304
+ size?: number;
305
+ page?: number;
306
+ }) {
307
+ const where = this.intentRepo.createQueryWhere();
308
+ if (query.status)
309
+ where.status = { eq: query.status as PaymentIntentEntity["status"] };
310
+ if (query.userId) where.userId = { eq: query.userId };
311
+ return await this.intentRepo.paginate(query, { where }, { count: true });
312
+ }
313
+
314
+ protected assertStatus(
315
+ intent: PaymentIntentEntity,
316
+ expected: PaymentIntentEntity["status"],
317
+ operation: string,
318
+ ): void {
319
+ if (intent.status !== expected) {
320
+ throw new BillingError(
321
+ `Cannot ${operation}: intent ${intent.id} is '${intent.status}', expected '${expected}'`,
322
+ );
323
+ }
324
+ }
325
+ }
@@ -0,0 +1,82 @@
1
+ import { $inject } from "alepha";
2
+ import { $logger } from "alepha/logger";
3
+ import { $repository } from "alepha/orm";
4
+ import {
5
+ type PaymentMethodEntity,
6
+ paymentMethods,
7
+ } from "../entities/paymentMethods.ts";
8
+ import { BillingError } from "../errors/BillingError.ts";
9
+ import { BillingProvider } from "../providers/BillingProvider.ts";
10
+
11
+ export class PaymentMethodService {
12
+ protected readonly log = $logger();
13
+ protected readonly provider = $inject(BillingProvider);
14
+ protected readonly methodRepo = $repository(paymentMethods);
15
+
16
+ public async addPaymentMethod(
17
+ userId: string,
18
+ organizationId: string,
19
+ token: string,
20
+ ): Promise<PaymentMethodEntity> {
21
+ const result = await this.provider.createPaymentMethod(userId, token);
22
+
23
+ const existing = await this.methodRepo.findMany({
24
+ where: { userId: { eq: userId } },
25
+ });
26
+
27
+ return await this.methodRepo.create({
28
+ userId,
29
+ organizationId,
30
+ type: result.type,
31
+ brand: result.brand,
32
+ last4: result.last4,
33
+ expMonth: result.expMonth,
34
+ expYear: result.expYear,
35
+ isDefault: existing.length === 0,
36
+ providerRef: result.providerRef,
37
+ });
38
+ }
39
+
40
+ public async listPaymentMethods(
41
+ userId: string,
42
+ ): Promise<PaymentMethodEntity[]> {
43
+ return await this.methodRepo.findMany({
44
+ where: { userId: { eq: userId } },
45
+ });
46
+ }
47
+
48
+ public async removePaymentMethod(
49
+ methodId: string,
50
+ userId: string,
51
+ ): Promise<void> {
52
+ const method = await this.methodRepo.getById(methodId);
53
+ if (method.userId !== userId) {
54
+ throw new BillingError("Cannot remove another user's payment method");
55
+ }
56
+
57
+ await this.provider.deletePaymentMethod(method.providerRef);
58
+ await this.methodRepo.deleteById(method.id);
59
+ }
60
+
61
+ public async setDefault(
62
+ methodId: string,
63
+ userId: string,
64
+ ): Promise<PaymentMethodEntity> {
65
+ const method = await this.methodRepo.getById(methodId);
66
+ if (method.userId !== userId) {
67
+ throw new BillingError("Cannot modify another user's payment method");
68
+ }
69
+
70
+ const userMethods = await this.methodRepo.findMany({
71
+ where: { userId: { eq: userId } },
72
+ });
73
+
74
+ for (const m of userMethods) {
75
+ if (m.isDefault) {
76
+ await this.methodRepo.updateById(m.id, { isDefault: false });
77
+ }
78
+ }
79
+
80
+ return await this.methodRepo.updateById(method.id, { isDefault: true });
81
+ }
82
+ }
package/src/bin/index.ts CHANGED
@@ -1,7 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  import { Alepha, run } from "alepha";
3
3
  import { AlephaCli, version } from "alepha/cli";
4
- import { AlephaCliPlatform } from "alepha/cli/platform";
5
4
 
6
5
  const alepha = Alepha.create({
7
6
  env: {
@@ -14,6 +13,5 @@ const alepha = Alepha.create({
14
13
  });
15
14
 
16
15
  alepha.with(AlephaCli);
17
- alepha.with(AlephaCliPlatform);
18
16
 
19
17
  run(alepha);
@@ -8,7 +8,7 @@ import {
8
8
  $atom,
9
9
  $hook,
10
10
  $inject,
11
- $use,
11
+ $state,
12
12
  Alepha,
13
13
  AlephaError,
14
14
  type FileLike,
@@ -55,7 +55,7 @@ export class LocalFileStorageProvider implements FileStorageProvider {
55
55
  protected readonly log = $logger();
56
56
  protected readonly fileDetector = $inject(FileDetector);
57
57
  protected readonly fileSystemProvider = $inject(FileSystemProvider);
58
- protected readonly options = $use(localFileStorageOptions);
58
+ protected readonly options = $state(localFileStorageOptions);
59
59
 
60
60
  protected get storagePath(): string {
61
61
  return this.options.storagePath;
@@ -1,7 +1,7 @@
1
1
  import { $pipeline, Alepha } from "alepha";
2
2
  import { describe, test } from "vitest";
3
3
  import { AlephaCache } from "../index.ts";
4
- import { $cache } from "./$cache.ts";
4
+ import { $cache } from "../primitives/$cache.ts";
5
5
 
6
6
  describe("$cache middleware", () => {
7
7
  test("caches handler result", async ({ expect }) => {
@@ -1,7 +1,7 @@
1
1
  import { Alepha } from "alepha";
2
2
  import { DateTimeProvider } from "alepha/datetime";
3
3
  import { beforeEach, describe, expect, it } from "vitest";
4
- import { MemoryCacheProvider } from "./MemoryCacheProvider.ts";
4
+ import { MemoryCacheProvider } from "../providers/MemoryCacheProvider.ts";
5
5
 
6
6
  describe("MemoryCacheProvider", () => {
7
7
  let alepha: Alepha;
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  $atom,
3
3
  $inject,
4
- $use,
4
+ $state,
5
5
  AlephaError,
6
6
  createPrimitive,
7
7
  type InstantiableClass,
@@ -173,7 +173,7 @@ export class CachePrimitive<
173
173
  TReturn = any,
174
174
  TParameter extends any[] = any[],
175
175
  > extends Primitive<CachePrimitiveOptions<TReturn, TParameter>> {
176
- protected readonly settings = $use(cacheOptions);
176
+ protected readonly settings = $state(cacheOptions);
177
177
  protected readonly dateTimeProvider = $inject(DateTimeProvider);
178
178
  public readonly provider = this.$provider();
179
179
 
@@ -1,4 +1,4 @@
1
- import { $atom, $inject, $use, Alepha, type Static, t } from "alepha";
1
+ import { $atom, $inject, $state, Alepha, type Static, t } from "alepha";
2
2
  import { CacheProvider } from "alepha/cache";
3
3
  import { $logger } from "alepha/logger";
4
4
  import { RedisProvider } from "alepha/redis";
@@ -34,7 +34,7 @@ declare module "alepha" {
34
34
  export class RedisCacheProvider extends CacheProvider {
35
35
  protected readonly log = $logger();
36
36
  protected readonly redisProvider = $inject(RedisProvider);
37
- protected readonly options = $use(redisCacheOptions);
37
+ protected readonly options = $state(redisCacheOptions);
38
38
  protected readonly alepha = $inject(Alepha);
39
39
 
40
40
  public async get(name: string, key: string): Promise<Uint8Array | undefined> {
@@ -7,18 +7,23 @@ import {
7
7
  type DevOptions,
8
8
  devOptions,
9
9
  } from "alepha/cli";
10
- import { type PlatformOptions, platformOptions } from "alepha/cli/platform";
11
- import type { CommandPrimitive } from "alepha/command";
10
+
11
+ // ---------------------------------------------------------------------------------------------------------------------
12
+
13
+ export type AlephaCliConfigPlugin = (
14
+ config: AlephaCliConfig,
15
+ alepha: Alepha,
16
+ ) => void;
17
+
18
+ export const cliConfigPlugins: AlephaCliConfigPlugin[] = [];
19
+
20
+ // ---------------------------------------------------------------------------------------------------------------------
12
21
 
13
22
  export interface AlephaCliConfig {
14
- entry?: AppEntryOptions;
15
23
  /**
16
- * Add custom commands to the Alepha CLI.
17
- *
18
- * You can override 'deploy', 'build', 'dev', 'start' commands this way.
19
- * But you can also add your own commands and run them via `alepha <command>`.
24
+ * Override entry paths.
20
25
  */
21
- commands?: Record<string, CommandPrimitive>;
26
+ entry?: AppEntryOptions;
22
27
 
23
28
  /**
24
29
  * Register more services to the Alepha CLI (enhancements, commands, etc.).
@@ -41,24 +46,12 @@ export interface AlephaCliConfig {
41
46
  * Always use .env files by default, this is only for dynamic values.
42
47
  */
43
48
  env?: Record<string, unknown>;
44
-
45
- /**
46
- * Platform deployment configuration.
47
- */
48
- platform?: PlatformOptions;
49
49
  }
50
50
 
51
- export type AlephaCliConfigFn = (alepha: Alepha) => AlephaCliConfig;
52
-
53
51
  // ---------------------------------------------------------------------------------------------------------------------
54
52
 
55
- export const defineConfig = (
56
- runConfig: AlephaCliConfig | AlephaCliConfigFn,
57
- ) => {
53
+ export const defineConfig = (config: AlephaCliConfig) => {
58
54
  return (alepha: Alepha) => {
59
- const config =
60
- typeof runConfig === "function" ? runConfig(alepha) : runConfig;
61
-
62
55
  if (config.services) {
63
56
  for (const it of config.services) {
64
57
  alepha.with(it);
@@ -83,12 +76,10 @@ export const defineConfig = (
83
76
  alepha.set(appEntryOptions, config.entry);
84
77
  }
85
78
 
86
- if (config.platform) {
87
- alepha.set(platformOptions, config.platform);
79
+ for (const plugin of cliConfigPlugins) {
80
+ plugin(config, alepha);
88
81
  }
89
82
 
90
- return {
91
- ...config.commands,
92
- };
83
+ return {};
93
84
  };
94
85
  };
@@ -6,7 +6,7 @@ import {
6
6
  ShellProvider,
7
7
  } from "alepha/system";
8
8
  import { describe, expect, it } from "vitest";
9
- import { ProjectScaffolder } from "./ProjectScaffolder.ts";
9
+ import { ProjectScaffolder } from "../services/ProjectScaffolder.ts";
10
10
 
11
11
  describe("ProjectScaffolder", () => {
12
12
  const createTestEnv = () => {
@@ -10,7 +10,7 @@ import {
10
10
  changelogOptions,
11
11
  GitMessageParser,
12
12
  GitProvider,
13
- } from "./changelog.ts";
13
+ } from "../commands/gen/changelog.ts";
14
14
 
15
15
  // =============================================================================
16
16
  // MOCK GIT PROVIDER
@@ -7,7 +7,7 @@ import {
7
7
  ShellProvider,
8
8
  } from "alepha/system";
9
9
  import { describe, expect, it } from "vitest";
10
- import { InitCommand } from "./init.ts";
10
+ import { InitCommand } from "../commands/init.ts";
11
11
 
12
12
  describe("alepha init", () => {
13
13
  const createTestEnv = () => {
@@ -542,13 +542,7 @@ describe("alepha init", () => {
542
542
  });
543
543
 
544
544
  it("should check each codegen flag independently", async () => {
545
- for (const flag of [
546
- "--react",
547
- "--ui",
548
- "--auth",
549
- "--admin",
550
- "--tailwind",
551
- ]) {
545
+ for (const flag of ["--react", "--ui", "--saas", "--tailwind"]) {
552
546
  const { fs, cli, cmd, json } = createTestEnv();
553
547
  await setupProject(fs, json);
554
548
  await fs.writeFile("/project/src/existing.ts", "export {}");
@@ -10,11 +10,6 @@ export const devOptions = $atom({
10
10
  name: "alepha.cli.dev.options",
11
11
  description: "Dev configuration options",
12
12
  schema: t.object({
13
- /**
14
- * Disable devtools.
15
- */
16
- noDevtools: t.optional(t.boolean({ default: false })),
17
-
18
13
  /**
19
14
  * Disable Vite React plugin.
20
15
  */
@@ -1,4 +1,4 @@
1
- import { $inject, $use, Alepha, AlephaError, t } from "alepha";
1
+ import { $inject, $state, Alepha, AlephaError, t } from "alepha";
2
2
  import { $command } from "alepha/command";
3
3
  import { $logger } from "alepha/logger";
4
4
  import {
@@ -31,7 +31,7 @@ export class BuildCommand {
31
31
  protected readonly scaffolder = $inject(ProjectScaffolder);
32
32
  protected readonly boot = $inject(AppEntryProvider);
33
33
  protected readonly viteBuildProvider = $inject(ViteBuildProvider);
34
- protected readonly options = $use(buildOptions);
34
+ protected readonly options = $state(buildOptions);
35
35
 
36
36
  /**
37
37
  * Build pipeline: tasks run sequentially in this order.