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
@@ -119,6 +119,18 @@ class MemoryCloudflareApi extends CloudflareApi {
119
119
  return this.secrets.get(scriptName) ?? [];
120
120
  }
121
121
 
122
+ public override async putSecret(
123
+ scriptName: string,
124
+ name: string,
125
+ _value: string,
126
+ ) {
127
+ const existing = this.secrets.get(scriptName) ?? [];
128
+ if (!existing.some((s) => s.name === name)) {
129
+ existing.push({ name, type: "secret_text" });
130
+ }
131
+ this.secrets.set(scriptName, existing);
132
+ }
133
+
122
134
  public override async listDeployments() {
123
135
  return [];
124
136
  }
@@ -379,10 +391,10 @@ describe("CloudflareAdapter", () => {
379
391
  });
380
392
 
381
393
  describe("secrets", () => {
382
- test("pushes non-binding env vars via wrangler secret bulk", async ({
394
+ test("pushes non-binding env vars via REST putSecret", async ({
383
395
  expect,
384
396
  }) => {
385
- const { adapter, fs, shell, naming } = createTestEnv();
397
+ const { adapter, fs, naming, api } = createTestEnv();
386
398
  const ctx = makeCtx(naming, {
387
399
  apps: [
388
400
  {
@@ -400,7 +412,6 @@ describe("CloudflareAdapter", () => {
400
412
  ],
401
413
  });
402
414
 
403
- // Write .env.production with a mix of secrets and excluded vars
404
415
  await fs.writeFile(
405
416
  "/project/.env.production",
406
417
  [
@@ -418,62 +429,13 @@ describe("CloudflareAdapter", () => {
418
429
  const run = createMockRun();
419
430
  await adapter.secrets(ctx, run);
420
431
 
421
- // Should call wrangler secret bulk with the worker name
422
- expect(
423
- shell.wasCalledMatching(
424
- /wrangler secret bulk.*--name=acme-portal-production/,
425
- ),
426
- ).toBe(true);
427
-
428
- // Verify the secrets JSON was written (only non-excluded vars)
429
- expect(
430
- fs.wasWrittenMatching(
431
- "/project/node_modules/.alepha/secrets.json",
432
- /GOOGLE_API_KEY/,
433
- ),
434
- ).toBe(true);
435
- expect(
436
- fs.wasWrittenMatching(
437
- "/project/node_modules/.alepha/secrets.json",
438
- /APP_SECRET/,
439
- ),
440
- ).toBe(true);
441
-
442
- // Excluded vars should NOT be in the secrets file
443
- expect(
444
- fs.wasWrittenMatching(
445
- "/project/node_modules/.alepha/secrets.json",
446
- /DATABASE_URL/,
447
- ),
448
- ).toBe(false);
449
- expect(
450
- fs.wasWrittenMatching(
451
- "/project/node_modules/.alepha/secrets.json",
452
- /R2_BUCKET_NAME/,
453
- ),
454
- ).toBe(false);
455
- expect(
456
- fs.wasWrittenMatching(
457
- "/project/node_modules/.alepha/secrets.json",
458
- /CLOUDFLARE_DOMAIN/,
459
- ),
460
- ).toBe(false);
461
- expect(
462
- fs.wasWrittenMatching(
463
- "/project/node_modules/.alepha/secrets.json",
464
- /VITE_PUBLIC_KEY/,
465
- ),
466
- ).toBe(false);
467
- expect(
468
- fs.wasWrittenMatching(
469
- "/project/node_modules/.alepha/secrets.json",
470
- /NODE_ENV/,
471
- ),
472
- ).toBe(false);
432
+ const pushed = api.secrets.get("acme-portal-production") ?? [];
433
+ const names = pushed.map((s) => s.name).sort();
434
+ expect(names).toEqual(["APP_SECRET", "GOOGLE_API_KEY"]);
473
435
  });
474
436
 
475
437
  test("skips when no env file exists", async ({ expect }) => {
476
- const { adapter, shell, naming } = createTestEnv();
438
+ const { adapter, naming, api } = createTestEnv();
477
439
  const ctx = makeCtx(naming, {
478
440
  apps: [
479
441
  {
@@ -494,11 +456,11 @@ describe("CloudflareAdapter", () => {
494
456
  const run = createMockRun();
495
457
  await adapter.secrets(ctx, run);
496
458
 
497
- expect(shell.wasCalledMatching(/wrangler secret/)).toBe(false);
459
+ expect(api.secrets.size).toBe(0);
498
460
  });
499
461
 
500
462
  test("skips comments and empty lines", async ({ expect }) => {
501
- const { adapter, fs, shell, naming } = createTestEnv();
463
+ const { adapter, fs, naming, api } = createTestEnv();
502
464
  const ctx = makeCtx(naming, {
503
465
  apps: [
504
466
  {
@@ -524,19 +486,8 @@ describe("CloudflareAdapter", () => {
524
486
  const run = createMockRun();
525
487
  await adapter.secrets(ctx, run);
526
488
 
527
- expect(shell.wasCalledMatching(/wrangler secret bulk/)).toBe(true);
528
- expect(
529
- fs.wasWrittenMatching(
530
- "/project/node_modules/.alepha/secrets.json",
531
- /ONLY_SECRET/,
532
- ),
533
- ).toBe(true);
534
- expect(
535
- fs.wasWrittenMatching(
536
- "/project/node_modules/.alepha/secrets.json",
537
- /comment/,
538
- ),
539
- ).toBe(false);
489
+ const pushed = api.secrets.get("acme-portal-production") ?? [];
490
+ expect(pushed.map((s) => s.name)).toEqual(["ONLY_SECRET"]);
540
491
  });
541
492
  });
542
493
 
@@ -252,8 +252,10 @@ describe("SecretsCommand", () => {
252
252
 
253
253
  const output = writes.join("");
254
254
  expect(output).toContain("env:");
255
+ // biome-ignore lint/suspicious/noTemplateCurlyInString: GitHub Actions `${{ ... }}` syntax in plain string
255
256
  expect(output).toContain("API_KEY: ${{ secrets.API_KEY }}");
256
257
  expect(output).toContain(
258
+ // biome-ignore lint/suspicious/noTemplateCurlyInString: GitHub Actions `${{ ... }}` syntax in plain string
257
259
  "GITHUB_CLIENT_ID: ${{ secrets.APP_GITHUB_CLIENT_ID }}",
258
260
  );
259
261
  });
@@ -1,5 +1,4 @@
1
1
  import { $inject, Alepha } from "alepha";
2
- import { AlephaCliUtils } from "alepha/cli";
3
2
  import { EnvUtils, Runner, type RunnerMethod } from "alepha/command";
4
3
  import { $logger } from "alepha/logger";
5
4
  import { FileSystemProvider, ShellProvider } from "alepha/system";
@@ -24,7 +23,6 @@ export class CloudflareAdapter extends PlatformAdapter {
24
23
  protected readonly log = $logger();
25
24
  protected readonly fs = $inject(FileSystemProvider);
26
25
  protected readonly shell = $inject(ShellProvider);
27
- protected readonly utils = $inject(AlephaCliUtils);
28
26
  protected readonly cache = $inject(PlatformCacheProvider);
29
27
  protected readonly alepha = $inject(Alepha);
30
28
  protected readonly envUtils = $inject(EnvUtils);
@@ -57,6 +55,7 @@ export class CloudflareAdapter extends PlatformAdapter {
57
55
  */
58
56
  protected configureApi(ctx: PlatformContext): void {
59
57
  this.api.setJurisdiction(ctx.envConfig.jurisdiction);
58
+ this.api.setAccountId(ctx.envConfig.accountId);
60
59
  }
61
60
 
62
61
  protected async runShell(
@@ -256,7 +255,9 @@ export class CloudflareAdapter extends PlatformAdapter {
256
255
  return;
257
256
  }
258
257
 
259
- // Push secrets to each worker
258
+ // Push secrets to each worker via the REST API (one PUT per secret).
259
+ // Historically we shelled out to `wrangler secret bulk`, but it has an
260
+ // open hang issue (workers-sdk#10555) and is redundant given putSecret.
260
261
  for (const app of ctx.apps) {
261
262
  const workerName = ctx.naming.worker(
262
263
  ctx.apps.length > 1 ? app.name : undefined,
@@ -265,13 +266,9 @@ export class CloudflareAdapter extends PlatformAdapter {
265
266
  await run({
266
267
  name: `push secrets to ${workerName}`,
267
268
  handler: async () => {
268
- const secretsPath = await this.utils.writeConfigFile(
269
- "secrets.json",
270
- JSON.stringify(secrets),
271
- ctx.root,
272
- );
273
-
274
- await this.wrangler.secretBulk(secretsPath, workerName);
269
+ for (const [name, value] of Object.entries(secrets)) {
270
+ await this.api.putSecret(workerName, name, value);
271
+ }
275
272
  },
276
273
  });
277
274
  }
@@ -882,7 +879,11 @@ export class CloudflareAdapter extends PlatformAdapter {
882
879
  > {
883
880
  const deployments = await this.api.listDeployments(workerName);
884
881
 
885
- const latest = deployments.at(-1);
882
+ // API ordering is not guaranteed across releases — sort explicitly.
883
+ const sorted = [...deployments].sort((a, b) =>
884
+ b.created_on.localeCompare(a.created_on),
885
+ );
886
+ const latest = sorted[0];
886
887
  if (!latest?.versions?.[0]) {
887
888
  return undefined;
888
889
  }
@@ -74,6 +74,14 @@ export const platformOptions = $atom({
74
74
  * Omit for the default (global) jurisdiction.
75
75
  */
76
76
  jurisdiction: t.optional(t.enum(["eu", "fedramp"])),
77
+ /**
78
+ * Cloudflare account ID to deploy into.
79
+ *
80
+ * Falls back to `CLOUDFLARE_ACCOUNT_ID` env var, then to the
81
+ * token's account when the token is scoped to exactly one.
82
+ * Required when the token has access to multiple accounts.
83
+ */
84
+ accountId: t.optional(t.text()),
77
85
  }),
78
86
  ),
79
87
  }),
@@ -93,4 +101,5 @@ export interface EnvironmentConfig {
93
101
  domain?: string;
94
102
  vars?: Record<string, string>;
95
103
  jurisdiction?: "eu" | "fedramp";
104
+ accountId?: string;
96
105
  }
@@ -40,7 +40,7 @@ export type CloudflareKV = Static<typeof cloudflareKVSchema>;
40
40
 
41
41
  export const cloudflareR2Schema = t.object({
42
42
  name: t.string(),
43
- creation_date: t.string(),
43
+ creation_date: t.optional(t.string()),
44
44
  });
45
45
 
46
46
  export type CloudflareR2 = Static<typeof cloudflareR2Schema>;
@@ -61,8 +61,9 @@ export const cloudflareQueueSchema = t.object({
61
61
  export type CloudflareQueue = Static<typeof cloudflareQueueSchema>;
62
62
 
63
63
  export const cloudflareQueueConsumerSchema = t.object({
64
+ consumer_id: t.string(),
64
65
  service: t.string(),
65
- environment: t.string(),
66
+ environment: t.optional(t.string()),
66
67
  });
67
68
 
68
69
  export type CloudflareQueueConsumer = Static<
@@ -22,9 +22,9 @@ import {
22
22
  cloudflareKVSchema,
23
23
  cloudflareQueueConsumerSchema,
24
24
  cloudflareQueueSchema,
25
- cloudflareR2ListSchema,
25
+ cloudflareR2Schema,
26
26
  cloudflareSecretSchema,
27
- cloudflareVersionListSchema,
27
+ cloudflareVersionSchema,
28
28
  cloudflareWorkerSchema,
29
29
  createD1BodySchema,
30
30
  createHyperdriveBodySchema,
@@ -81,6 +81,16 @@ export class CloudflareApi {
81
81
  this.jurisdiction = jurisdiction;
82
82
  }
83
83
 
84
+ /**
85
+ * Override the Cloudflare account ID (from platform config).
86
+ *
87
+ * When unset, `resolveAccountId` falls back to `CLOUDFLARE_ACCOUNT_ID` env
88
+ * var or the token's single account.
89
+ */
90
+ public setAccountId(accountId?: string): void {
91
+ this.accountId = accountId;
92
+ }
93
+
84
94
  // -------------------------------------------------------------------------
85
95
  // Auth
86
96
  // -------------------------------------------------------------------------
@@ -107,6 +117,12 @@ export class CloudflareApi {
107
117
  return this.accountId;
108
118
  }
109
119
 
120
+ const fromEnv = process.env.CLOUDFLARE_ACCOUNT_ID;
121
+ if (fromEnv) {
122
+ this.accountId = fromEnv;
123
+ return this.accountId;
124
+ }
125
+
110
126
  const res = await this.fetch<CloudflareAccount[]>("/accounts", {
111
127
  schema: t.array(cloudflareAccountSchema),
112
128
  });
@@ -115,6 +131,15 @@ export class CloudflareApi {
115
131
  throw new AlephaError("No Cloudflare accounts found for this token.");
116
132
  }
117
133
 
134
+ if (res.length > 1) {
135
+ const list = res.map((a) => ` - ${a.id} ${a.name}`).join("\n");
136
+ throw new AlephaError(
137
+ `Cloudflare token has access to ${res.length} accounts; set ` +
138
+ `\`CLOUDFLARE_ACCOUNT_ID\` or the \`accountId\` field in your ` +
139
+ `platform config to pick one:\n${list}`,
140
+ );
141
+ }
142
+
118
143
  this.accountId = res[0].id;
119
144
  return this.accountId;
120
145
  }
@@ -125,9 +150,9 @@ export class CloudflareApi {
125
150
 
126
151
  public async listD1(): Promise<CloudflareD1[]> {
127
152
  const accountId = await this.resolveAccountId();
128
- return await this.fetch<CloudflareD1[]>(
153
+ return await this.paginate<CloudflareD1>(
129
154
  `/accounts/${accountId}/d1/database`,
130
- { schema: t.array(cloudflareD1Schema) },
155
+ cloudflareD1Schema,
131
156
  );
132
157
  }
133
158
 
@@ -136,15 +161,19 @@ export class CloudflareApi {
136
161
  location = "weur", // TODO: move to config (or auto-resolve based on account info, or ask ?)
137
162
  ): Promise<CloudflareD1> {
138
163
  const accountId = await this.resolveAccountId();
164
+ // When jurisdiction is set, `primary_location_hint` is silently ignored
165
+ // by the API, so omit it to avoid confusion.
166
+ const body: Record<string, unknown> = { name };
167
+ if (this.jurisdiction) {
168
+ body.jurisdiction = this.jurisdiction;
169
+ } else {
170
+ body.primary_location_hint = location;
171
+ }
139
172
  return await this.fetch<CloudflareD1>(
140
173
  `/accounts/${accountId}/d1/database`,
141
174
  {
142
175
  method: "POST",
143
- body: {
144
- name,
145
- primary_location_hint: location,
146
- ...(this.jurisdiction ? { jurisdiction: this.jurisdiction } : {}),
147
- },
176
+ body,
148
177
  bodySchema: createD1BodySchema,
149
178
  schema: cloudflareD1Schema,
150
179
  },
@@ -164,9 +193,10 @@ export class CloudflareApi {
164
193
 
165
194
  public async listKV(): Promise<CloudflareKV[]> {
166
195
  const accountId = await this.resolveAccountId();
167
- return await this.fetch<CloudflareKV[]>(
196
+ return await this.paginate<CloudflareKV>(
168
197
  `/accounts/${accountId}/storage/kv/namespaces`,
169
- { schema: t.array(cloudflareKVSchema) },
198
+ cloudflareKVSchema,
199
+ 100, // KV list caps at 100 per page
170
200
  );
171
201
  }
172
202
 
@@ -197,11 +227,11 @@ export class CloudflareApi {
197
227
 
198
228
  public async listR2(): Promise<CloudflareR2[]> {
199
229
  const accountId = await this.resolveAccountId();
200
- const res = await this.fetch<{ buckets: CloudflareR2[] }>(
230
+ return await this.paginateCursor<CloudflareR2>(
201
231
  `/accounts/${accountId}/r2/buckets`,
202
- { schema: cloudflareR2ListSchema },
232
+ "buckets",
233
+ cloudflareR2Schema,
203
234
  );
204
- return res.buckets;
205
235
  }
206
236
 
207
237
  public async createR2(name: string): Promise<void> {
@@ -226,9 +256,9 @@ export class CloudflareApi {
226
256
 
227
257
  public async listQueues(): Promise<CloudflareQueue[]> {
228
258
  const accountId = await this.resolveAccountId();
229
- return await this.fetch<CloudflareQueue[]>(
259
+ return await this.paginate<CloudflareQueue>(
230
260
  `/accounts/${accountId}/queues`,
231
- { schema: t.array(cloudflareQueueSchema) },
261
+ cloudflareQueueSchema,
232
262
  );
233
263
  }
234
264
 
@@ -253,9 +283,9 @@ export class CloudflareApi {
253
283
  queueId: string,
254
284
  ): Promise<CloudflareQueueConsumer[]> {
255
285
  const accountId = await this.resolveAccountId();
256
- return await this.fetch<CloudflareQueueConsumer[]>(
286
+ return await this.paginate<CloudflareQueueConsumer>(
257
287
  `/accounts/${accountId}/queues/${queueId}/consumers`,
258
- { schema: t.array(cloudflareQueueConsumerSchema) },
288
+ cloudflareQueueConsumerSchema,
259
289
  );
260
290
  }
261
291
 
@@ -264,8 +294,13 @@ export class CloudflareApi {
264
294
  consumerService: string,
265
295
  ): Promise<void> {
266
296
  const accountId = await this.resolveAccountId();
297
+ const consumers = await this.listQueueConsumers(queueId);
298
+ const consumer = consumers.find((c) => c.service === consumerService);
299
+ if (!consumer) {
300
+ return;
301
+ }
267
302
  await this.fetch(
268
- `/accounts/${accountId}/queues/${queueId}/consumers/${consumerService}`,
303
+ `/accounts/${accountId}/queues/${queueId}/consumers/${consumer.consumer_id}`,
269
304
  { method: "DELETE" },
270
305
  );
271
306
  }
@@ -276,9 +311,9 @@ export class CloudflareApi {
276
311
 
277
312
  public async listHyperdrive(): Promise<CloudflareHyperdrive[]> {
278
313
  const accountId = await this.resolveAccountId();
279
- return await this.fetch<CloudflareHyperdrive[]>(
314
+ return await this.paginate<CloudflareHyperdrive>(
280
315
  `/accounts/${accountId}/hyperdrive/configs`,
281
- { schema: t.array(cloudflareHyperdriveSchema) },
316
+ cloudflareHyperdriveSchema,
282
317
  );
283
318
  }
284
319
 
@@ -338,20 +373,22 @@ export class CloudflareApi {
338
373
  scriptName: string,
339
374
  ): Promise<CloudflareDeployment[]> {
340
375
  const accountId = await this.resolveAccountId();
376
+ // Deployments list is wrapped in `{ deployments }` and returns newest
377
+ // first; for picking the active deployment we only need the top page.
341
378
  const res = await this.fetch<{ deployments: CloudflareDeployment[] }>(
342
379
  `/accounts/${accountId}/workers/scripts/${scriptName}/deployments`,
343
- { schema: cloudflareDeploymentListSchema },
380
+ { schema: cloudflareDeploymentListSchema, query: { per_page: "100" } },
344
381
  );
345
382
  return res.deployments;
346
383
  }
347
384
 
348
385
  public async listVersions(scriptName: string): Promise<CloudflareVersion[]> {
349
386
  const accountId = await this.resolveAccountId();
350
- const res = await this.fetch<{ items: CloudflareVersion[] }>(
387
+ return await this.paginateCursor<CloudflareVersion>(
351
388
  `/accounts/${accountId}/workers/scripts/${scriptName}/versions`,
352
- { schema: cloudflareVersionListSchema },
389
+ "items",
390
+ cloudflareVersionSchema,
353
391
  );
354
- return res.items;
355
392
  }
356
393
 
357
394
  // -------------------------------------------------------------------------
@@ -428,6 +465,13 @@ export class CloudflareApi {
428
465
  success: boolean;
429
466
  result: T;
430
467
  errors: CloudflareApiError[];
468
+ result_info?: {
469
+ page: number;
470
+ per_page: number;
471
+ total_pages?: number;
472
+ count?: number;
473
+ total_count?: number;
474
+ };
431
475
  };
432
476
 
433
477
  if (!json.success) {
@@ -444,6 +488,101 @@ export class CloudflareApi {
444
488
  return json.result;
445
489
  }
446
490
 
491
+ /**
492
+ * Paginate a page-based list endpoint (`result_info.total_pages`).
493
+ *
494
+ * Cloudflare defaults to `per_page=20`; we push it to 1000 (max on most
495
+ * list endpoints) and loop if more pages exist. Each page is validated
496
+ * against the item schema.
497
+ */
498
+ protected async paginate<T>(
499
+ path: string,
500
+ itemSchema: TSchema,
501
+ perPage = 1000,
502
+ ): Promise<T[]> {
503
+ const results: T[] = [];
504
+ let page = 1;
505
+
506
+ while (true) {
507
+ const token = await this.resolveToken();
508
+ const url = `${CloudflareApi.BASE}${path}?per_page=${perPage}&page=${page}`;
509
+
510
+ const headers: Record<string, string> = {
511
+ Authorization: `Bearer ${token}`,
512
+ };
513
+ if (this.jurisdiction && /\/r2\//.test(path)) {
514
+ headers["cf-r2-jurisdiction"] = this.jurisdiction;
515
+ }
516
+
517
+ const response = await globalThis.fetch(url, { method: "GET", headers });
518
+ const json = (await response.json()) as {
519
+ success: boolean;
520
+ result: T[];
521
+ errors: CloudflareApiError[];
522
+ result_info?: { page: number; total_pages?: number };
523
+ };
524
+
525
+ if (!json.success) {
526
+ const messages = json.errors.map((e) => e.message).join(", ");
527
+ throw new AlephaError(
528
+ `Cloudflare API error (GET ${path}): ${messages}`,
529
+ );
530
+ }
531
+
532
+ const validated = this.alepha.codec.validate(
533
+ t.array(itemSchema),
534
+ json.result,
535
+ ) as T[];
536
+ results.push(...validated);
537
+
538
+ const totalPages = json.result_info?.total_pages;
539
+ if (!totalPages || page >= totalPages || validated.length === 0) {
540
+ break;
541
+ }
542
+ page++;
543
+ }
544
+
545
+ return results;
546
+ }
547
+
548
+ /**
549
+ * Paginate a cursor-based list endpoint where `result` is an object
550
+ * containing both the items array and a `cursor` field (R2 buckets,
551
+ * Workers versions). Returns the flattened item array.
552
+ */
553
+ protected async paginateCursor<T>(
554
+ path: string,
555
+ itemsKey: string,
556
+ itemSchema: TSchema,
557
+ perPage = 1000,
558
+ ): Promise<T[]> {
559
+ const results: T[] = [];
560
+ let cursor: string | undefined;
561
+
562
+ while (true) {
563
+ const query: Record<string, string> = { per_page: String(perPage) };
564
+ if (cursor) {
565
+ query.cursor = cursor;
566
+ }
567
+
568
+ const res = await this.fetch<Record<string, unknown>>(path, { query });
569
+ const items = (res[itemsKey] as unknown[]) ?? [];
570
+ const validated = this.alepha.codec.validate(
571
+ t.array(itemSchema),
572
+ items,
573
+ ) as T[];
574
+ results.push(...validated);
575
+
576
+ const nextCursor = res.cursor as string | undefined;
577
+ if (!nextCursor || validated.length === 0) {
578
+ break;
579
+ }
580
+ cursor = nextCursor;
581
+ }
582
+
583
+ return results;
584
+ }
585
+
447
586
  // -------------------------------------------------------------------------
448
587
  // Helpers
449
588
  // -------------------------------------------------------------------------
@@ -124,21 +124,4 @@ export class WranglerApi {
124
124
  { resolve: true, env: { CI: "1" } },
125
125
  );
126
126
  }
127
-
128
- // -------------------------------------------------------------------------
129
- // Secrets
130
- // -------------------------------------------------------------------------
131
-
132
- /**
133
- * Push secrets in bulk to a worker.
134
- */
135
- public async secretBulk(
136
- secretsPath: string,
137
- workerName: string,
138
- ): Promise<void> {
139
- await this.runShell(
140
- `wrangler secret bulk ${secretsPath} --name=${workerName}`,
141
- { resolve: true },
142
- );
143
- }
144
127
  }
@@ -555,7 +555,7 @@ export class CliProvider {
555
555
  const parsed = this.parseFlags(argv, flagDefs);
556
556
 
557
557
  // Remove the mode flag from parsed result (it's handled separately)
558
- delete parsed.__mode__;
558
+ parsed.__mode__ = undefined;
559
559
 
560
560
  // apply manually defaults for optional properties that have defaults
561
561
  for (const [key, value] of Object.entries(schema.properties)) {
@@ -826,6 +826,15 @@ export class Alepha {
826
826
  return this;
827
827
  }
828
828
 
829
+ /**
830
+ * Alias for {@link Alepha#with}.
831
+ */
832
+ public register<T extends object>(
833
+ serviceEntry: ServiceEntry<T> | { default: ServiceEntry<T> },
834
+ ): this {
835
+ return this.with(serviceEntry);
836
+ }
837
+
829
838
  /**
830
839
  * Get an instance of the specified service from the container.
831
840
  *
@@ -8,7 +8,9 @@ export type Service<T extends object = any> =
8
8
  | AbstractClass<T>
9
9
  | RunFunction<T>;
10
10
 
11
- export type RunFunction<T extends object = any> = (...args: any[]) => T | void;
11
+ export type RunFunction<T extends object = any> = (
12
+ ...args: any[]
13
+ ) => T | undefined;
12
14
 
13
15
  export type InstantiableClass<T extends object = any> = new (
14
16
  ...args: any[]
@@ -447,7 +447,7 @@ export class TypeProvider {
447
447
  /**
448
448
  * Create a schema that maps all properties of an object schema to nullable.
449
449
  */
450
- public nullify = <T extends TSchema>(schema: T, options?: TObjectOptions) =>
450
+ public nullify = (schema: TSchema, options?: TObjectOptions): TSchema =>
451
451
  Type.Mapped(
452
452
  Type.Identifier("K"),
453
453
  Type.KeyOf(schema),
@@ -146,7 +146,7 @@ export class Logger implements LoggerInterface {
146
146
  }
147
147
 
148
148
  let _data: object | Error | undefined;
149
- if (typeof data === "object" && !!data) {
149
+ if (typeof data === "object" && data) {
150
150
  _data = data;
151
151
  } else if (typeof message === "object" && message) {
152
152
  _data = message;
@@ -364,7 +364,7 @@ describe("$resource primitive", () => {
364
364
  uri: "protected://resource",
365
365
  handler: async ({ context }) => {
366
366
  const authHeader = context?.headers?.authorization;
367
- if (!authHeader || !authHeader.toString().startsWith("Bearer ")) {
367
+ if (!authHeader?.toString().startsWith("Bearer ")) {
368
368
  throw new Error("Unauthorized");
369
369
  }
370
370
  return { text: "Secret content" };
@@ -379,7 +379,7 @@ describe("$tool primitive", () => {
379
379
  },
380
380
  handler: async ({ context }) => {
381
381
  const authHeader = context?.headers?.authorization;
382
- if (!authHeader || !authHeader.toString().startsWith("Bearer ")) {
382
+ if (!authHeader?.toString().startsWith("Bearer ")) {
383
383
  throw new Error("Unauthorized");
384
384
  }
385
385
  return "Access granted";
@@ -751,7 +751,7 @@ describe("McpServerProvider", () => {
751
751
  schema: { result: t.text() },
752
752
  handler: async ({ context }) => {
753
753
  const auth = context?.headers?.authorization;
754
- if (!auth || !auth.toString().startsWith("Bearer ")) {
754
+ if (!auth?.toString().startsWith("Bearer ")) {
755
755
  throw new Error("Unauthorized");
756
756
  }
757
757
  return "Access granted";