alepha 0.21.2 → 0.23.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (519) hide show
  1. package/README.md +0 -1
  2. package/dist/api/audits/index.browser.js.map +1 -1
  3. package/dist/api/audits/index.d.ts +393 -403
  4. package/dist/api/audits/index.d.ts.map +1 -1
  5. package/dist/api/audits/index.js +25 -56
  6. package/dist/api/audits/index.js.map +1 -1
  7. package/dist/api/files/index.browser.js +31 -1
  8. package/dist/api/files/index.browser.js.map +1 -1
  9. package/dist/api/files/index.d.ts +313 -208
  10. package/dist/api/files/index.d.ts.map +1 -1
  11. package/dist/api/files/index.js +152 -42
  12. package/dist/api/files/index.js.map +1 -1
  13. package/dist/api/jobs/index.browser.js +2 -2
  14. package/dist/api/jobs/index.browser.js.map +1 -1
  15. package/dist/api/jobs/index.d.ts +282 -285
  16. package/dist/api/jobs/index.d.ts.map +1 -1
  17. package/dist/api/jobs/index.js +39 -33
  18. package/dist/api/jobs/index.js.map +1 -1
  19. package/dist/api/keys/index.d.ts +217 -222
  20. package/dist/api/keys/index.d.ts.map +1 -1
  21. package/dist/api/keys/index.js.map +1 -1
  22. package/dist/api/notifications/index.browser.js.map +1 -1
  23. package/dist/api/notifications/index.d.ts +188 -195
  24. package/dist/api/notifications/index.d.ts.map +1 -1
  25. package/dist/api/notifications/index.js.map +1 -1
  26. package/dist/api/oauth/index.d.ts +71 -76
  27. package/dist/api/oauth/index.d.ts.map +1 -1
  28. package/dist/api/oauth/index.js.map +1 -1
  29. package/dist/api/organizations/index.browser.js.map +1 -1
  30. package/dist/api/organizations/index.d.ts +104 -109
  31. package/dist/api/organizations/index.d.ts.map +1 -1
  32. package/dist/api/organizations/index.js.map +1 -1
  33. package/dist/api/parameters/index.browser.js +43 -16
  34. package/dist/api/parameters/index.browser.js.map +1 -1
  35. package/dist/api/parameters/index.d.ts +488 -344
  36. package/dist/api/parameters/index.d.ts.map +1 -1
  37. package/dist/api/parameters/index.js +175 -35
  38. package/dist/api/parameters/index.js.map +1 -1
  39. package/dist/api/payments/index.d.ts +396 -402
  40. package/dist/api/payments/index.d.ts.map +1 -1
  41. package/dist/api/payments/index.js.map +1 -1
  42. package/dist/api/subscriptions/index.d.ts +644 -652
  43. package/dist/api/subscriptions/index.d.ts.map +1 -1
  44. package/dist/api/subscriptions/index.js +1 -1
  45. package/dist/api/subscriptions/index.js.map +1 -1
  46. package/dist/api/users/index.browser.js +7 -0
  47. package/dist/api/users/index.browser.js.map +1 -1
  48. package/dist/api/users/index.d.ts +1106 -1005
  49. package/dist/api/users/index.d.ts.map +1 -1
  50. package/dist/api/users/index.js +307 -64
  51. package/dist/api/users/index.js.map +1 -1
  52. package/dist/api/verifications/index.browser.js.map +1 -1
  53. package/dist/api/verifications/index.d.ts +137 -143
  54. package/dist/api/verifications/index.d.ts.map +1 -1
  55. package/dist/api/verifications/index.js.map +1 -1
  56. package/dist/background/index.d.ts +95 -0
  57. package/dist/background/index.d.ts.map +1 -0
  58. package/dist/background/index.js +121 -0
  59. package/dist/background/index.js.map +1 -0
  60. package/dist/background/index.workerd.js +110 -0
  61. package/dist/background/index.workerd.js.map +1 -0
  62. package/dist/batch/index.d.ts +5 -7
  63. package/dist/batch/index.d.ts.map +1 -1
  64. package/dist/batch/index.js.map +1 -1
  65. package/dist/bin/index.js.map +1 -1
  66. package/dist/bucket/index.d.ts +76 -54
  67. package/dist/bucket/index.d.ts.map +1 -1
  68. package/dist/bucket/index.js +58 -11
  69. package/dist/bucket/index.js.map +1 -1
  70. package/dist/bucket/index.workerd.js +200 -5
  71. package/dist/bucket/index.workerd.js.map +1 -1
  72. package/dist/cache/core/index.d.ts +7 -10
  73. package/dist/cache/core/index.d.ts.map +1 -1
  74. package/dist/cache/core/index.js.map +1 -1
  75. package/dist/cache/core/index.workerd.js.map +1 -1
  76. package/dist/cache/database/index.d.ts +22 -26
  77. package/dist/cache/database/index.d.ts.map +1 -1
  78. package/dist/cache/database/index.js.map +1 -1
  79. package/dist/cache/redis/index.d.ts +4 -7
  80. package/dist/cache/redis/index.d.ts.map +1 -1
  81. package/dist/cache/redis/index.js.map +1 -1
  82. package/dist/captcha/index.d.ts +3 -6
  83. package/dist/captcha/index.d.ts.map +1 -1
  84. package/dist/captcha/index.js.map +1 -1
  85. package/dist/cli/config/index.d.ts.map +1 -1
  86. package/dist/cli/config/index.js.map +1 -1
  87. package/dist/cli/core/index.d.ts +458 -249
  88. package/dist/cli/core/index.d.ts.map +1 -1
  89. package/dist/cli/core/index.js +372 -660
  90. package/dist/cli/core/index.js.map +1 -1
  91. package/dist/cli/devtools/index.d.ts +3 -5
  92. package/dist/cli/devtools/index.d.ts.map +1 -1
  93. package/dist/cli/devtools/index.js.map +1 -1
  94. package/dist/cli/i18n/index.d.ts +20 -17
  95. package/dist/cli/i18n/index.d.ts.map +1 -1
  96. package/dist/cli/i18n/index.js +45 -11
  97. package/dist/cli/i18n/index.js.map +1 -1
  98. package/dist/cli/platform/index.d.ts +126 -1342
  99. package/dist/cli/platform/index.d.ts.map +1 -1
  100. package/dist/cli/platform/index.js +136 -2374
  101. package/dist/cli/platform/index.js.map +1 -1
  102. package/dist/cli/platform-lib/index.d.ts +1472 -0
  103. package/dist/cli/platform-lib/index.d.ts.map +1 -0
  104. package/dist/cli/platform-lib/index.js +2660 -0
  105. package/dist/cli/platform-lib/index.js.map +1 -0
  106. package/dist/cli/vendor/index.d.ts +17 -21
  107. package/dist/cli/vendor/index.d.ts.map +1 -1
  108. package/dist/cli/vendor/index.js.map +1 -1
  109. package/dist/command/index.d.ts +20 -19
  110. package/dist/command/index.d.ts.map +1 -1
  111. package/dist/command/index.js +39 -10
  112. package/dist/command/index.js.map +1 -1
  113. package/dist/{containers → container}/core/index.d.ts +13 -15
  114. package/dist/container/core/index.d.ts.map +1 -0
  115. package/dist/{containers → container}/core/index.js +23 -14
  116. package/dist/container/core/index.js.map +1 -0
  117. package/dist/{containers → container}/core/index.workerd.js +37 -22
  118. package/dist/container/core/index.workerd.js.map +1 -0
  119. package/dist/core/index.browser.js +27 -1
  120. package/dist/core/index.browser.js.map +1 -1
  121. package/dist/core/index.d.ts +48 -24
  122. package/dist/core/index.d.ts.map +1 -1
  123. package/dist/core/index.js +27 -1
  124. package/dist/core/index.js.map +1 -1
  125. package/dist/core/index.native.js +27 -1
  126. package/dist/core/index.native.js.map +1 -1
  127. package/dist/core/index.workerd.js +27 -1
  128. package/dist/core/index.workerd.js.map +1 -1
  129. package/dist/crypto/index.browser.js.map +1 -1
  130. package/dist/crypto/index.d.ts +5 -8
  131. package/dist/crypto/index.d.ts.map +1 -1
  132. package/dist/crypto/index.js.map +1 -1
  133. package/dist/datetime/index.d.ts +3 -4
  134. package/dist/datetime/index.d.ts.map +1 -1
  135. package/dist/datetime/index.js.map +1 -1
  136. package/dist/email/brevo/index.d.ts +2 -4
  137. package/dist/email/brevo/index.d.ts.map +1 -1
  138. package/dist/email/brevo/index.js.map +1 -1
  139. package/dist/email/cloudflare/index.d.ts +20 -7
  140. package/dist/email/cloudflare/index.d.ts.map +1 -1
  141. package/dist/email/cloudflare/index.js +46 -9
  142. package/dist/email/cloudflare/index.js.map +1 -1
  143. package/dist/email/core/index.d.ts +6 -9
  144. package/dist/email/core/index.d.ts.map +1 -1
  145. package/dist/email/core/index.js.map +1 -1
  146. package/dist/email/core/index.workerd.js.map +1 -1
  147. package/dist/email/smtp/index.d.ts +10 -13
  148. package/dist/email/smtp/index.d.ts.map +1 -1
  149. package/dist/email/smtp/index.js +107 -32
  150. package/dist/email/smtp/index.js.map +1 -1
  151. package/dist/fake/index.d.ts +1 -2
  152. package/dist/fake/index.d.ts.map +1 -1
  153. package/dist/fake/index.js.map +1 -1
  154. package/dist/lock/core/index.d.ts +9 -14
  155. package/dist/lock/core/index.d.ts.map +1 -1
  156. package/dist/lock/core/index.js.map +1 -1
  157. package/dist/lock/redis/index.d.ts +2 -4
  158. package/dist/lock/redis/index.d.ts.map +1 -1
  159. package/dist/lock/redis/index.js.map +1 -1
  160. package/dist/logger/index.d.ts +105 -76
  161. package/dist/logger/index.d.ts.map +1 -1
  162. package/dist/logger/index.js +196 -174
  163. package/dist/logger/index.js.map +1 -1
  164. package/dist/mcp/index.d.ts +25 -20
  165. package/dist/mcp/index.d.ts.map +1 -1
  166. package/dist/mcp/index.js +23 -0
  167. package/dist/mcp/index.js.map +1 -1
  168. package/dist/orm/core/index.browser.js.map +1 -1
  169. package/dist/orm/core/index.bun.js +19 -1
  170. package/dist/orm/core/index.bun.js.map +1 -1
  171. package/dist/orm/core/index.d.ts +76 -62
  172. package/dist/orm/core/index.d.ts.map +1 -1
  173. package/dist/orm/core/index.js +20 -2
  174. package/dist/orm/core/index.js.map +1 -1
  175. package/dist/orm/postgres/index.bun.js.map +1 -1
  176. package/dist/orm/postgres/index.d.ts +28 -20
  177. package/dist/orm/postgres/index.d.ts.map +1 -1
  178. package/dist/orm/postgres/index.js.map +1 -1
  179. package/dist/queue/core/index.d.ts +12 -15
  180. package/dist/queue/core/index.d.ts.map +1 -1
  181. package/dist/queue/core/index.js.map +1 -1
  182. package/dist/queue/core/index.workerd.js.map +1 -1
  183. package/dist/queue/redis/index.d.ts +3 -5
  184. package/dist/queue/redis/index.d.ts.map +1 -1
  185. package/dist/queue/redis/index.js.map +1 -1
  186. package/dist/react/auth/index.browser.js +9 -2
  187. package/dist/react/auth/index.browser.js.map +1 -1
  188. package/dist/react/auth/index.d.ts +14 -9
  189. package/dist/react/auth/index.d.ts.map +1 -1
  190. package/dist/react/auth/index.js +9 -2
  191. package/dist/react/auth/index.js.map +1 -1
  192. package/dist/react/core/index.d.ts +7 -8
  193. package/dist/react/core/index.d.ts.map +1 -1
  194. package/dist/react/core/index.js +6 -3
  195. package/dist/react/core/index.js.map +1 -1
  196. package/dist/react/form/index.d.ts +2 -5
  197. package/dist/react/form/index.d.ts.map +1 -1
  198. package/dist/react/form/index.js +16 -15
  199. package/dist/react/form/index.js.map +1 -1
  200. package/dist/react/head/index.browser.js.map +1 -1
  201. package/dist/react/head/index.d.ts +2 -4
  202. package/dist/react/head/index.d.ts.map +1 -1
  203. package/dist/react/head/index.js.map +1 -1
  204. package/dist/react/i18n/index.d.ts +90 -11
  205. package/dist/react/i18n/index.d.ts.map +1 -1
  206. package/dist/react/i18n/index.js +147 -11
  207. package/dist/react/i18n/index.js.map +1 -1
  208. package/dist/react/intro/index.d.ts +1 -2
  209. package/dist/react/intro/index.d.ts.map +1 -1
  210. package/dist/react/intro/index.js +2 -2
  211. package/dist/react/intro/index.js.map +1 -1
  212. package/dist/react/router/index.browser.js +193 -24
  213. package/dist/react/router/index.browser.js.map +1 -1
  214. package/dist/react/router/index.d.ts +434 -222
  215. package/dist/react/router/index.d.ts.map +1 -1
  216. package/dist/react/router/index.js +249 -35
  217. package/dist/react/router/index.js.map +1 -1
  218. package/dist/react/sitemap/index.browser.js +35 -0
  219. package/dist/react/sitemap/index.browser.js.map +1 -0
  220. package/dist/react/sitemap/index.d.ts +92 -0
  221. package/dist/react/sitemap/index.d.ts.map +1 -0
  222. package/dist/react/sitemap/index.js +131 -0
  223. package/dist/react/sitemap/index.js.map +1 -0
  224. package/dist/react/testing/index.d.ts +1 -2
  225. package/dist/react/testing/index.d.ts.map +1 -1
  226. package/dist/react/testing/index.js +16 -17
  227. package/dist/react/testing/index.js.map +1 -1
  228. package/dist/react/ui/index.d.ts +20 -25
  229. package/dist/react/ui/index.d.ts.map +1 -1
  230. package/dist/react/ui/index.js.map +1 -1
  231. package/dist/redis/index.bun.js.map +1 -1
  232. package/dist/redis/index.d.ts +17 -19
  233. package/dist/redis/index.d.ts.map +1 -1
  234. package/dist/redis/index.js.map +1 -1
  235. package/dist/retry/index.d.ts +2 -4
  236. package/dist/retry/index.d.ts.map +1 -1
  237. package/dist/retry/index.js.map +1 -1
  238. package/dist/router/index.d.ts.map +1 -1
  239. package/dist/router/index.js.map +1 -1
  240. package/dist/scheduler/index.d.ts +10 -13
  241. package/dist/scheduler/index.d.ts.map +1 -1
  242. package/dist/scheduler/index.js.map +1 -1
  243. package/dist/scheduler/index.workerd.js.map +1 -1
  244. package/dist/security/index.browser.js.map +1 -1
  245. package/dist/security/index.d.ts +45 -48
  246. package/dist/security/index.d.ts.map +1 -1
  247. package/dist/security/index.js.map +1 -1
  248. package/dist/server/auth/index.browser.js.map +1 -1
  249. package/dist/server/auth/index.d.ts +272 -173
  250. package/dist/server/auth/index.d.ts.map +1 -1
  251. package/dist/server/auth/index.js +1608 -15
  252. package/dist/server/auth/index.js.map +1 -1
  253. package/dist/server/cookies/index.browser.js.map +1 -1
  254. package/dist/server/cookies/index.d.ts +20 -7
  255. package/dist/server/cookies/index.d.ts.map +1 -1
  256. package/dist/server/cookies/index.js +22 -3
  257. package/dist/server/cookies/index.js.map +1 -1
  258. package/dist/server/core/index.browser.js.map +1 -1
  259. package/dist/server/core/index.d.ts +106 -73
  260. package/dist/server/core/index.d.ts.map +1 -1
  261. package/dist/server/core/index.js +44 -0
  262. package/dist/server/core/index.js.map +1 -1
  263. package/dist/server/cors/index.d.ts +11 -14
  264. package/dist/server/cors/index.d.ts.map +1 -1
  265. package/dist/server/cors/index.js.map +1 -1
  266. package/dist/server/etag/index.d.ts +6 -9
  267. package/dist/server/etag/index.d.ts.map +1 -1
  268. package/dist/server/etag/index.js.map +1 -1
  269. package/dist/server/health/index.d.ts +18 -21
  270. package/dist/server/health/index.d.ts.map +1 -1
  271. package/dist/server/health/index.js.map +1 -1
  272. package/dist/server/links/index.browser.js +2 -0
  273. package/dist/server/links/index.browser.js.map +1 -1
  274. package/dist/server/links/index.d.ts +63 -67
  275. package/dist/server/links/index.d.ts.map +1 -1
  276. package/dist/server/links/index.js +2 -0
  277. package/dist/server/links/index.js.map +1 -1
  278. package/dist/server/metrics/index.d.ts +5 -7
  279. package/dist/server/metrics/index.d.ts.map +1 -1
  280. package/dist/server/metrics/index.js.map +1 -1
  281. package/dist/server/proxy/index.d.ts +3 -5
  282. package/dist/server/proxy/index.d.ts.map +1 -1
  283. package/dist/server/proxy/index.js.map +1 -1
  284. package/dist/server/rate-limit/index.d.ts +10 -13
  285. package/dist/server/rate-limit/index.d.ts.map +1 -1
  286. package/dist/server/rate-limit/index.js.map +1 -1
  287. package/dist/server/static/index.d.ts +3 -5
  288. package/dist/server/static/index.d.ts.map +1 -1
  289. package/dist/server/static/index.js.map +1 -1
  290. package/dist/server/swagger/index.d.ts +5 -8
  291. package/dist/server/swagger/index.d.ts.map +1 -1
  292. package/dist/server/swagger/index.js.map +1 -1
  293. package/dist/sms/index.d.ts +3 -5
  294. package/dist/sms/index.d.ts.map +1 -1
  295. package/dist/sms/index.js.map +1 -1
  296. package/dist/system/index.browser.js.map +1 -1
  297. package/dist/system/index.d.ts +2 -4
  298. package/dist/system/index.d.ts.map +1 -1
  299. package/dist/system/index.js.map +1 -1
  300. package/dist/system/index.workerd.js.map +1 -1
  301. package/dist/topic/core/index.d.ts +4 -6
  302. package/dist/topic/core/index.d.ts.map +1 -1
  303. package/dist/topic/core/index.js.map +1 -1
  304. package/dist/topic/redis/index.d.ts +5 -8
  305. package/dist/topic/redis/index.d.ts.map +1 -1
  306. package/dist/topic/redis/index.js.map +1 -1
  307. package/package.json +59 -23
  308. package/src/api/audits/__tests__/AuditService.spec.ts +18 -110
  309. package/src/api/audits/controllers/AdminAuditController.ts +14 -0
  310. package/src/api/audits/services/AuditService.ts +21 -88
  311. package/src/api/files/__tests__/FileService.spec.ts +207 -2
  312. package/src/api/files/index.ts +3 -0
  313. package/src/api/files/schemas/fileCreatorSummarySchema.ts +22 -0
  314. package/src/api/files/schemas/fileResourceSchema.ts +10 -1
  315. package/src/api/files/services/FileService.ts +170 -72
  316. package/src/api/jobs/__tests__/$job.spec.ts +24 -1
  317. package/src/api/jobs/index.ts +4 -3
  318. package/src/api/jobs/primitives/$job.ts +7 -3
  319. package/src/api/jobs/providers/DirectJobDispatcher.ts +17 -36
  320. package/src/api/jobs/providers/JobProvider.ts +53 -24
  321. package/src/api/jobs/schemas/jobConfigAtom.ts +1 -1
  322. package/src/api/jobs/schemas/jobExecutionResourceSchema.ts +4 -1
  323. package/src/api/keys/schemas/adminApiKeyResourceSchema.ts +3 -1
  324. package/src/api/parameters/__tests__/$parameter.spec.ts +19 -2
  325. package/src/api/parameters/audits/ParameterAudits.ts +17 -0
  326. package/src/api/parameters/controllers/AdminParameterController.ts +95 -19
  327. package/src/api/parameters/index.ts +3 -0
  328. package/src/api/parameters/schemas/activateParameterBodySchema.ts +3 -3
  329. package/src/api/parameters/schemas/createParameterVersionBodySchema.ts +3 -2
  330. package/src/api/parameters/schemas/parameterCreatorSummarySchema.ts +25 -0
  331. package/src/api/parameters/schemas/parameterResponseSchema.ts +5 -0
  332. package/src/api/parameters/schemas/rollbackParameterBodySchema.ts +4 -2
  333. package/src/api/parameters/services/ParameterProvider.ts +69 -6
  334. package/src/api/subscriptions/jobs/SubscriptionJobs.ts +1 -1
  335. package/src/api/users/__tests__/AdminSessionController.spec.ts +37 -0
  336. package/src/api/users/audits/SessionAudits.ts +33 -0
  337. package/src/api/users/audits/UserAudits.ts +19 -43
  338. package/src/api/users/controllers/AdminUserController.ts +66 -1
  339. package/src/api/users/controllers/RealmController.ts +1 -0
  340. package/src/api/users/entities/sessions.ts +6 -0
  341. package/src/api/users/entities/users.ts +2 -0
  342. package/src/api/users/index.ts +9 -1
  343. package/src/api/users/primitives/$realm.ts +29 -0
  344. package/src/api/users/providers/RealmProvider.ts +15 -0
  345. package/src/api/users/schemas/realmConfigSchema.ts +14 -0
  346. package/src/api/users/schemas/sessionResourceSchema.ts +16 -0
  347. package/src/api/users/schemas/updateUserSchema.ts +1 -8
  348. package/src/api/users/schemas/userQuerySchema.ts +7 -0
  349. package/src/api/users/services/CredentialService.ts +15 -6
  350. package/src/api/users/services/IdentityService.ts +2 -1
  351. package/src/api/users/services/RegistrationService.ts +2 -1
  352. package/src/api/users/services/SessionCrudService.ts +19 -2
  353. package/src/api/users/services/SessionService.ts +39 -19
  354. package/src/api/users/services/UserService.ts +106 -8
  355. package/src/background/__tests__/BackgroundTaskProvider.spec.ts +96 -0
  356. package/src/background/index.ts +37 -0
  357. package/src/background/index.workerd.ts +28 -0
  358. package/src/background/providers/BackgroundTaskProvider.ts +70 -0
  359. package/src/background/providers/WorkerdBackgroundTaskProvider.ts +43 -0
  360. package/src/bucket/__tests__/$bucket.spec.ts +18 -0
  361. package/src/bucket/__tests__/LocalFileStorageProvider.spec.ts +5 -0
  362. package/src/bucket/__tests__/MemoryFileStorageProvider.spec.ts +5 -0
  363. package/src/bucket/__tests__/NodeS3BucketProvider.spec.ts +23 -4
  364. package/src/bucket/__tests__/shared.ts +30 -0
  365. package/src/bucket/index.ts +5 -5
  366. package/src/bucket/index.workerd.ts +11 -4
  367. package/src/bucket/primitives/$bucket.ts +27 -0
  368. package/src/bucket/providers/FileStorageProvider.ts +13 -0
  369. package/src/bucket/providers/LocalFileStorageProvider.ts +17 -1
  370. package/src/bucket/providers/MemoryFileStorageProvider.ts +7 -0
  371. package/src/bucket/providers/{CloudflareR2Provider.ts → R2FileStorageProvider.ts} +10 -1
  372. package/src/bucket/providers/{NodeS3BucketProvider.ts → S3FileStorageProvider.ts} +27 -5
  373. package/src/cli/core/__tests__/BuildDockerTask.spec.ts +25 -1
  374. package/src/cli/core/__tests__/init.spec.ts +0 -219
  375. package/src/cli/core/atoms/buildOptions.ts +0 -12
  376. package/src/cli/core/commands/__tests__/BuildCommand.spec.ts +43 -0
  377. package/src/cli/core/commands/build.ts +105 -37
  378. package/src/cli/core/commands/init.ts +0 -12
  379. package/src/cli/core/commands/pack.ts +133 -0
  380. package/src/cli/core/index.ts +3 -3
  381. package/src/cli/core/providers/ViteDevServerProvider.ts +40 -16
  382. package/src/cli/core/services/PackageManagerUtils.ts +0 -16
  383. package/src/cli/core/services/ProjectScaffolder.ts +29 -291
  384. package/src/cli/core/tasks/BuildCloudflareTask.ts +382 -56
  385. package/src/cli/core/tasks/BuildDockerTask.ts +33 -3
  386. package/src/cli/core/tasks/BuildPrerenderTask.ts +44 -7
  387. package/src/cli/core/tasks/BuildTask.ts +34 -0
  388. package/src/cli/core/templates/apiIndexTs.ts +1 -22
  389. package/src/cli/core/templates/mainCss.ts +0 -1
  390. package/src/cli/core/templates/webAppRouterTs.ts +0 -99
  391. package/src/cli/core/templates/webIndexTs.ts +1 -22
  392. package/src/cli/i18n/__tests__/I18nCheckService.spec.ts +48 -0
  393. package/src/cli/i18n/services/I18nCheckService.ts +65 -11
  394. package/src/cli/platform/__tests__/SecretsCommand.spec.ts +5 -3
  395. package/src/cli/platform/commands/SecretsCommand.ts +8 -6
  396. package/src/cli/platform/commands/platform.ts +192 -46
  397. package/src/cli/platform/index.ts +12 -52
  398. package/src/cli/{platform → platform-lib}/__tests__/CloudflareAdapter.spec.ts +426 -169
  399. package/src/cli/{platform → platform-lib}/__tests__/NamingService.spec.ts +91 -4
  400. package/src/cli/{platform → platform-lib}/__tests__/VercelAdapter.spec.ts +56 -85
  401. package/src/cli/{platform → platform-lib}/adapters/CloudflareAdapter.ts +519 -190
  402. package/src/cli/{platform → platform-lib}/adapters/PlatformAdapter.ts +62 -35
  403. package/src/cli/{platform → platform-lib}/adapters/VercelAdapter.ts +6 -10
  404. package/src/cli/{platform → platform-lib}/atoms/platformOptions.ts +34 -1
  405. package/src/cli/platform-lib/index.ts +67 -0
  406. package/src/cli/platform-lib/services/NamingService.ts +136 -0
  407. package/src/cli/{platform → platform-lib}/services/PlatformInspector.ts +60 -13
  408. package/src/cli/{platform → platform-lib}/services/PlatformOrchestrator.ts +54 -43
  409. package/src/cli/{platform → platform-lib}/services/WranglerApi.ts +4 -2
  410. package/src/command/__tests__/Runner.spec.ts +20 -0
  411. package/src/command/helpers/EnvUtils.ts +19 -3
  412. package/src/command/helpers/Runner.ts +12 -2
  413. package/src/command/providers/CliProvider.ts +34 -1
  414. package/src/{containers → container}/core/__tests__/$container.spec.ts +5 -5
  415. package/src/{containers → container}/core/index.ts +4 -4
  416. package/src/{containers → container}/core/index.workerd.ts +19 -3
  417. package/src/{containers → container}/core/primitives/$container.ts +1 -1
  418. package/src/{containers → container}/core/providers/CloudflareContainerProvider.ts +17 -19
  419. package/src/{containers → container}/core/providers/ContainerProvider.ts +16 -2
  420. package/src/{containers → container}/core/providers/MockContainerProvider.ts +1 -1
  421. package/src/core/Alepha.ts +49 -1
  422. package/src/core/__tests__/$env.spec.ts +42 -0
  423. package/src/core/__tests__/dump.spec.ts +47 -0
  424. package/src/email/cloudflare/__tests__/CloudflareEmailProvider.spec.ts +42 -10
  425. package/src/email/cloudflare/index.ts +14 -5
  426. package/src/email/cloudflare/providers/CloudflareEmailProvider.ts +54 -9
  427. package/src/logger/__tests__/Logger.spec.ts +55 -0
  428. package/src/logger/index.ts +13 -0
  429. package/src/logger/services/Logger.ts +31 -1
  430. package/src/mcp/__tests__/McpServerProvider.spec.ts +71 -0
  431. package/src/mcp/providers/McpServerProvider.ts +55 -0
  432. package/src/orm/__tests__/orm-showcase-tests.ts +27 -0
  433. package/src/orm/__tests__/orm-showcase.spec.ts +12 -0
  434. package/src/orm/core/interfaces/PgQuery.ts +4 -1
  435. package/src/orm/core/services/Repository.ts +27 -11
  436. package/src/react/auth/hooks/useAuth.ts +10 -5
  437. package/src/react/core/__tests__/useQuery.browser.spec.tsx +25 -0
  438. package/src/react/core/hooks/useAction.ts +14 -3
  439. package/src/react/core/hooks/useQuery.ts +24 -4
  440. package/src/react/form/__tests__/FormModel-submit-loading.spec.ts +71 -0
  441. package/src/react/form/__tests__/form-submitting-reactive.browser.spec.tsx +96 -0
  442. package/src/react/form/services/FormModel.ts +57 -39
  443. package/src/react/i18n/__tests__/I18nProvider.spec.ts +89 -0
  444. package/src/react/i18n/__tests__/locale-routing.spec.ts +107 -0
  445. package/src/react/i18n/components/Translate.tsx +47 -0
  446. package/src/react/i18n/index.ts +2 -0
  447. package/src/react/i18n/providers/I18nProvider.ts +171 -12
  448. package/src/react/intro/components/GettingStartedAdminSlide.tsx +2 -2
  449. package/src/react/router/__tests__/$page.spec.tsx +3 -2
  450. package/src/react/router/__tests__/RouterLocaleProvider.spec.ts +127 -0
  451. package/src/react/router/__tests__/page-can.spec.ts +18 -13
  452. package/src/react/router/hooks/useQueryParams.ts +114 -14
  453. package/src/react/router/index.browser.ts +4 -0
  454. package/src/react/router/index.shared.ts +1 -0
  455. package/src/react/router/index.ts +9 -0
  456. package/src/react/router/primitives/$page.ts +85 -4
  457. package/src/react/router/providers/ReactBrowserRouterProvider.ts +18 -8
  458. package/src/react/router/providers/ReactPageProvider.ts +12 -1
  459. package/src/react/router/providers/ReactServerProvider.ts +96 -14
  460. package/src/react/router/providers/RootComponentsProvider.ts +13 -0
  461. package/src/react/router/providers/RouterLocaleProvider.ts +125 -0
  462. package/src/react/router/providers/__tests__/RootComponentsProvider.spec.ts +15 -0
  463. package/src/react/router/providers/__tests__/rootComponents.ssr.browser.spec.tsx +67 -0
  464. package/src/react/sitemap/__tests__/$sitemap.spec.ts +131 -0
  465. package/src/react/sitemap/index.browser.ts +21 -0
  466. package/src/react/sitemap/index.ts +25 -0
  467. package/src/react/sitemap/primitives/$sitemap.browser.ts +26 -0
  468. package/src/react/sitemap/primitives/$sitemap.ts +196 -0
  469. package/src/react/ui/services/SchemaControl.ts +3 -4
  470. package/src/server/auth/__tests__/appleClientSecret.spec.ts +34 -0
  471. package/src/server/auth/__tests__/authFederationClient.spec.ts +40 -0
  472. package/src/server/auth/__tests__/federationAssertion.spec.ts +146 -0
  473. package/src/server/auth/__tests__/federationRedirectReplay.spec.ts +44 -0
  474. package/src/server/auth/helpers/appleClientSecret.ts +24 -0
  475. package/src/server/auth/helpers/federationAssertion.ts +74 -0
  476. package/src/server/auth/helpers/jtiReplayGuard.ts +41 -0
  477. package/src/server/auth/helpers/safeRedirectPath.ts +19 -0
  478. package/src/server/auth/index.ts +4 -0
  479. package/src/server/auth/primitives/$authFederationBroker.ts +273 -0
  480. package/src/server/auth/primitives/$authFederationClient.ts +89 -0
  481. package/src/server/auth/providers/ServerAuthProvider.ts +18 -4
  482. package/src/server/cookies/__tests__/ServerCookiesProvider.spec.ts +70 -0
  483. package/src/server/cookies/providers/ServerCookiesProvider.ts +23 -3
  484. package/src/server/core/interfaces/ServerRequest.ts +8 -0
  485. package/src/server/core/primitives/$route.ts +27 -0
  486. package/src/server/core/providers/ServerMultipartProvider.ts +19 -0
  487. package/src/server/links/providers/LinkProvider.ts +10 -0
  488. package/dist/containers/core/index.d.ts.map +0 -1
  489. package/dist/containers/core/index.js.map +0 -1
  490. package/dist/containers/core/index.workerd.js.map +0 -1
  491. package/src/cli/core/tasks/BuildSitemapTask.ts +0 -130
  492. package/src/cli/core/templates/componentsJsonTs.ts +0 -39
  493. package/src/cli/core/templates/saasAdminLayoutTsx.ts +0 -77
  494. package/src/cli/core/templates/saasAdminPagesTsx.ts +0 -26
  495. package/src/cli/core/templates/saasAuthLayoutTsx.ts +0 -22
  496. package/src/cli/core/templates/saasAuthPagesTsx.ts +0 -62
  497. package/src/cli/core/templates/saasRealmProviderTs.ts +0 -52
  498. package/src/cli/platform/services/NamingService.ts +0 -54
  499. /package/dist/orm/core/{chunk-o8xxKEmq.js → chunk-B4FMCO8f.js} +0 -0
  500. /package/dist/react/testing/{chunk-6Ep1yQYe.js → chunk-BpyX8vjI.js} +0 -0
  501. /package/src/cli/{platform → platform-lib}/__tests__/GitHubSecretStore.spec.ts +0 -0
  502. /package/src/cli/{platform → platform-lib}/__tests__/PlatformCacheProvider.spec.ts +0 -0
  503. /package/src/cli/{platform → platform-lib}/__tests__/PlatformInspector.spec.ts +0 -0
  504. /package/src/cli/{platform → platform-lib}/__tests__/PlatformOrchestrator.spec.ts +0 -0
  505. /package/src/cli/{platform → platform-lib}/__tests__/SecretFilterService.spec.ts +0 -0
  506. /package/src/cli/{platform → platform-lib}/__tests__/detectResources.spec.ts +0 -0
  507. /package/src/cli/{platform → platform-lib}/providers/GitHubSecretStore.ts +0 -0
  508. /package/src/cli/{platform → platform-lib}/providers/MemorySecretStore.ts +0 -0
  509. /package/src/cli/{platform → platform-lib}/providers/PlatformCacheProvider.ts +0 -0
  510. /package/src/cli/{platform → platform-lib}/providers/SecretStoreProvider.ts +0 -0
  511. /package/src/cli/{platform → platform-lib}/schemas/cloudflare.ts +0 -0
  512. /package/src/cli/{platform → platform-lib}/schemas/platform.ts +0 -0
  513. /package/src/cli/{platform → platform-lib}/schemas/vercel.ts +0 -0
  514. /package/src/cli/{platform → platform-lib}/services/CloudflareApi.ts +0 -0
  515. /package/src/cli/{platform → platform-lib}/services/SecretFilterService.ts +0 -0
  516. /package/src/cli/{platform → platform-lib}/services/VercelApi.ts +0 -0
  517. /package/src/cli/{platform → platform-lib}/services/VercelCli.ts +0 -0
  518. /package/src/{containers → container}/core/interfaces/ContainerOptions.ts +0 -0
  519. /package/src/{containers → container}/core/providers/NodeContainerProvider.ts +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../../src/cli/platform-lib/atoms/platformOptions.ts","../../../src/cli/platform-lib/providers/PlatformCacheProvider.ts","../../../src/cli/platform-lib/schemas/cloudflare.ts","../../../src/cli/platform-lib/services/WranglerApi.ts","../../../src/cli/platform-lib/services/CloudflareApi.ts","../../../src/cli/platform-lib/services/NamingService.ts","../../../src/cli/platform-lib/adapters/PlatformAdapter.ts","../../../src/cli/platform-lib/adapters/CloudflareAdapter.ts","../../../src/cli/platform-lib/schemas/vercel.ts","../../../src/cli/platform-lib/services/VercelCli.ts","../../../src/cli/platform-lib/services/VercelApi.ts","../../../src/cli/platform-lib/adapters/VercelAdapter.ts","../../../src/cli/platform-lib/providers/GitHubSecretStore.ts","../../../src/cli/platform-lib/providers/MemorySecretStore.ts","../../../src/cli/platform-lib/services/PlatformInspector.ts","../../../src/cli/platform-lib/services/PlatformOrchestrator.ts","../../../src/cli/platform-lib/services/SecretFilterService.ts","../../../src/cli/platform-lib/providers/SecretStoreProvider.ts","../../../src/cli/platform-lib/schemas/platform.ts","../../../src/cli/platform-lib/index.ts"],"sourcesContent":["import { $atom, type Static, t } from \"alepha\";\n\n/**\n * Platform deployment configuration atom.\n *\n * Filled from the `platform` section of `alepha.config.ts`.\n * Read by `PlatformCommand` to resolve environments and adapters.\n */\nexport const platformOptions = $atom({\n name: \"alepha.cli.platform.options\",\n description: \"Platform deployment configuration\",\n schema: t.optional(\n t.object({\n /**\n * Project name override. Defaults to root package.json \"name\".\n */\n name: t.optional(t.text()),\n\n /**\n * Default environment when --env is omitted.\n *\n * @default \"production\"\n */\n default: t.optional(t.text()),\n\n /**\n * Multi-tenancy mode — controls whether `--tenant <slug>` is\n * accepted/required and how it shapes resource names + the domain.\n *\n * - `none` (default): single instance. `--tenant` is rejected.\n * - `required`: every deploy needs `--tenant`; resources are named\n * `<tenant>-<project>-<env>` and the host becomes\n * `<tenant>.<domain>`. Omitting it errors.\n * - `optional`: a base instance (no `--tenant`) plus per-tenant\n * instances coexist.\n *\n * @default \"none\"\n */\n tenancy: t.optional(t.enum([\"none\", \"optional\", \"required\"])),\n\n /**\n * Secret store configuration for syncing .env secrets\n * to external providers (e.g. GitHub Actions environments).\n */\n secrets: t.optional(\n t.object({\n /**\n * Explicit override of the worker secret-key allowlist.\n *\n * By default the deploy `secrets` step uses the build manifest's\n * `env` list (every key the app declares via `$env`, captured at\n * build time) as the allowlist, resolving each value from\n * `.env.<env>[.local]` first, then `process.env`. This lets CI\n * deliver secrets via the job environment (no `.env` file on the\n * runner) while only ever pushing declared keys — ambient runner\n * vars (PATH, GITHUB_*, …) can never leak.\n *\n * Set `keys` to override that auto-detected list (e.g. to narrow it,\n * or to add a key read via `process.env` rather than `$env`). When\n * neither this nor a manifest is present, the `.env.<env>` file is\n * itself the allowlist (legacy fallback).\n */\n keys: t.optional(t.array(t.text())),\n\n /**\n * Secret store backend.\n */\n store: t.optional(t.enum([\"github\"])),\n\n /**\n * Pattern for resolving environment names in the store.\n * Placeholders: {project}, {env}.\n *\n * @default \"{project}-{env}\"\n */\n environmentPattern: t.optional(t.text()),\n }),\n ),\n\n /**\n * Named environments with their adapter and configuration.\n */\n environments: t.record(\n t.text({\n description:\n \"Environment name (e.g. 'production', 'staging', 'preview'). Used in resource naming and selected via --env.\",\n }),\n t.object({\n adapter: t.enum([\"cloudflare\", \"vercel\"]),\n /**\n * Custom domain for the deployed worker (e.g. \"api.example.com\").\n *\n * On Cloudflare this is attached as a custom-domain route.\n * Omit to use the adapter's default `*.workers.dev` / preview URL.\n *\n * Wildcards are supported for multi-tenant SaaS apps:\n * `\"*.club.alepha.dev\"` routes every subdomain to the worker.\n * Wildcard patterns require `zone` to be set, and the wildcard DNS\n * record must already exist (proxied) in the Cloudflare zone.\n */\n domain: t.optional(t.text()),\n /**\n * Cloudflare zone name (e.g. \"alepha.dev\") that owns `domain`.\n *\n * Required when `domain` contains a wildcard (`*`). Ignored for\n * plain custom domains, which Cloudflare resolves automatically.\n */\n zone: t.optional(t.text()),\n /**\n * Cloudflare data jurisdiction for R2 buckets and D1 databases.\n * - \"eu\": data stays within the EU\n * - \"fedramp\": FedRAMP-authorized regions\n *\n * Omit for the default (global) jurisdiction.\n */\n jurisdiction: t.optional(t.enum([\"eu\", \"fedramp\"])),\n /**\n * Cloudflare account ID to deploy into.\n *\n * Falls back to `CLOUDFLARE_ACCOUNT_ID` env var, then to the\n * token's account when the token is scoped to exactly one.\n * Required when the token has access to multiple accounts.\n */\n accountId: t.optional(t.text()),\n }),\n ),\n }),\n ),\n});\n\n/**\n * Type for platform options.\n */\nexport type PlatformOptions = Static<typeof platformOptions.schema>;\n\n/**\n * Configuration for a single named environment.\n */\nexport interface EnvironmentConfig {\n adapter: \"cloudflare\" | \"vercel\";\n domain?: string;\n zone?: string;\n vars?: Record<string, string>;\n jurisdiction?: \"eu\" | \"fedramp\";\n accountId?: string;\n}\n","import { $inject } from \"alepha\";\nimport { DateTimeProvider } from \"alepha/datetime\";\nimport { FileSystemProvider } from \"alepha/system\";\n\ninterface PlatformCache {\n [adapter: string]: {\n lastLoginCheck: number;\n accountId?: string;\n };\n}\n\n/**\n * Caches cloud provider login state to avoid slow auth checks.\n *\n * Stored in node_modules/.alepha/platform.json (gitignored, project-scoped).\n * TTL: 4 hours.\n */\nexport class PlatformCacheProvider {\n protected static readonly TTL_MS = 4 * 60 * 60 * 1000;\n\n protected readonly fs = $inject(FileSystemProvider);\n protected readonly dateTime = $inject(DateTimeProvider);\n\n protected cachePath(root: string): string {\n return this.fs.join(root, \"node_modules\", \".alepha\", \"platform.json\");\n }\n\n public async isLoginFresh(root: string, adapter: string): Promise<boolean> {\n const cache = await this.readCache(root);\n const entry = cache[adapter];\n if (!entry) {\n return false;\n }\n const age = this.dateTime.nowMillis() - entry.lastLoginCheck;\n return age < PlatformCacheProvider.TTL_MS;\n }\n\n public async getAccountId(\n root: string,\n adapter: string,\n ): Promise<string | undefined> {\n const cache = await this.readCache(root);\n return cache[adapter]?.accountId;\n }\n\n public async recordLogin(\n root: string,\n adapter: string,\n accountId?: string,\n ): Promise<void> {\n const cache = await this.readCache(root);\n cache[adapter] = {\n lastLoginCheck: this.dateTime.nowMillis(),\n accountId,\n };\n await this.writeCache(root, cache);\n }\n\n protected async readCache(root: string): Promise<PlatformCache> {\n const path = this.cachePath(root);\n try {\n return await this.fs.readJsonFile<PlatformCache>(path);\n } catch {\n return {};\n }\n }\n\n protected async writeCache(\n root: string,\n cache: PlatformCache,\n ): Promise<void> {\n const path = this.cachePath(root);\n const lastSlash = path.lastIndexOf(\"/\");\n const dir = lastSlash > 0 ? path.slice(0, lastSlash) : path;\n await this.fs.mkdir(dir, { recursive: true }).catch(() => null);\n await this.fs.writeFile(path, JSON.stringify(cache, null, 2));\n }\n}\n","import type { Static } from \"alepha\";\nimport { t } from \"alepha\";\n\n// ---------------------------------------------------------------------------\n// Account\n// ---------------------------------------------------------------------------\n\nexport const cloudflareAccountSchema = t.object({\n id: t.string(),\n name: t.string(),\n});\n\nexport type CloudflareAccount = Static<typeof cloudflareAccountSchema>;\n\n// ---------------------------------------------------------------------------\n// D1\n// ---------------------------------------------------------------------------\n\nexport const cloudflareD1Schema = t.object({\n uuid: t.string(),\n name: t.string(),\n});\n\nexport type CloudflareD1 = Static<typeof cloudflareD1Schema>;\n\n// ---------------------------------------------------------------------------\n// KV\n// ---------------------------------------------------------------------------\n\nexport const cloudflareKVSchema = t.object({\n id: t.string(),\n title: t.string(),\n});\n\nexport type CloudflareKV = Static<typeof cloudflareKVSchema>;\n\n// ---------------------------------------------------------------------------\n// R2\n// ---------------------------------------------------------------------------\n\nexport const cloudflareR2Schema = t.object({\n name: t.string(),\n creation_date: t.optional(t.string()),\n});\n\nexport type CloudflareR2 = Static<typeof cloudflareR2Schema>;\n\nexport const cloudflareR2ListSchema = t.object({\n buckets: t.array(cloudflareR2Schema),\n});\n\n// ---------------------------------------------------------------------------\n// Queue\n// ---------------------------------------------------------------------------\n\nexport const cloudflareQueueSchema = t.object({\n queue_id: t.string(),\n queue_name: t.string(),\n});\n\nexport type CloudflareQueue = Static<typeof cloudflareQueueSchema>;\n\nexport const cloudflareQueueConsumerSchema = t.object({\n consumer_id: t.string(),\n service: t.string(),\n environment: t.optional(t.string()),\n});\n\nexport type CloudflareQueueConsumer = Static<\n typeof cloudflareQueueConsumerSchema\n>;\n\n// ---------------------------------------------------------------------------\n// Hyperdrive\n// ---------------------------------------------------------------------------\n\nexport const cloudflareHyperdriveOriginSchema = t.object({\n host: t.string(),\n});\n\nexport const cloudflareHyperdriveSchema = t.object({\n id: t.string(),\n name: t.string(),\n origin: cloudflareHyperdriveOriginSchema,\n});\n\nexport type CloudflareHyperdrive = Static<typeof cloudflareHyperdriveSchema>;\n\n// ---------------------------------------------------------------------------\n// Worker\n// ---------------------------------------------------------------------------\n\nexport const cloudflareWorkerSchema = t.object({\n id: t.string(),\n created_on: t.string(),\n modified_on: t.string(),\n});\n\nexport type CloudflareWorker = Static<typeof cloudflareWorkerSchema>;\n\n// ---------------------------------------------------------------------------\n// Deployment\n// ---------------------------------------------------------------------------\n\nexport const cloudflareDeploymentVersionSchema = t.object({\n version_id: t.string(),\n percentage: t.number(),\n});\n\nexport const cloudflareDeploymentSchema = t.object({\n id: t.string(),\n versions: t.array(cloudflareDeploymentVersionSchema),\n created_on: t.string(),\n});\n\nexport type CloudflareDeployment = Static<typeof cloudflareDeploymentSchema>;\n\nexport const cloudflareDeploymentListSchema = t.object({\n deployments: t.array(cloudflareDeploymentSchema),\n});\n\n// ---------------------------------------------------------------------------\n// Version\n// ---------------------------------------------------------------------------\n\nexport const cloudflareVersionSchema = t.object({\n id: t.string(),\n metadata: t.object({\n created_on: t.string(),\n }),\n annotations: t.optional(t.record(t.string(), t.string())),\n});\n\nexport type CloudflareVersion = Static<typeof cloudflareVersionSchema>;\n\nexport const cloudflareVersionListSchema = t.object({\n items: t.array(cloudflareVersionSchema),\n});\n\n// ---------------------------------------------------------------------------\n// Secret\n// ---------------------------------------------------------------------------\n\nexport const cloudflareSecretSchema = t.object({\n name: t.string(),\n type: t.string(),\n});\n\nexport type CloudflareSecret = Static<typeof cloudflareSecretSchema>;\n\n// ---------------------------------------------------------------------------\n// Request bodies\n// ---------------------------------------------------------------------------\n\nexport const createD1BodySchema = t.object({\n name: t.string(),\n primary_location_hint: t.optional(t.string()),\n jurisdiction: t.optional(t.string()),\n});\n\nexport const createKVBodySchema = t.object({\n title: t.string(),\n});\n\nexport const createR2BodySchema = t.object({\n name: t.string(),\n});\n\n// ---------------------------------------------------------------------------\n// R2 API token (used by CLI teardown to wipe a bucket via the S3 protocol;\n// minted from a wrangler bearer token, revoked immediately after use)\n// ---------------------------------------------------------------------------\n\nexport const cloudflareR2TokenSchema = t.object({\n id: t.string(),\n accessKeyId: t.string(),\n secretAccessKey: t.string(),\n});\n\nexport type CloudflareR2Token = Static<typeof cloudflareR2TokenSchema>;\n\nexport const createR2TokenBodySchema = t.object({\n name: t.string(),\n policies: t.array(\n t.object({\n effect: t.string(),\n permissions: t.array(t.string()),\n buckets: t.optional(t.array(t.string())),\n }),\n ),\n});\n\nexport const createQueueBodySchema = t.object({\n queue_name: t.string(),\n});\n\nexport const createHyperdriveOriginSchema = t.object({\n scheme: t.string(),\n host: t.string(),\n port: t.number(),\n database: t.string(),\n user: t.string(),\n password: t.string(),\n});\n\nexport const createHyperdriveBodySchema = t.object({\n name: t.string(),\n origin: createHyperdriveOriginSchema,\n});\n\nexport const putSecretBodySchema = t.object({\n name: t.string(),\n text: t.string(),\n type: t.string(),\n});\n\n// ---------------------------------------------------------------------------\n// API envelope\n// ---------------------------------------------------------------------------\n\nexport const cloudflareApiErrorSchema = t.object({\n code: t.number(),\n message: t.string(),\n});\n\nexport type CloudflareApiError = Static<typeof cloudflareApiErrorSchema>;\n","import { $inject } from \"alepha\";\nimport { AlephaCliUtils, PackageManagerUtils } from \"alepha/cli\";\nimport { Runner, type RunnerMethod } from \"alepha/command\";\nimport { $logger } from \"alepha/logger\";\nimport { ShellProvider } from \"alepha/system\";\n\n/**\n * Wraps wrangler CLI commands that are kept as shell-outs.\n *\n * Only used for operations where wrangler provides value\n * beyond a raw API call: OAuth login, worker deploy (bundling/upload),\n * D1 migrations, and secret bulk push.\n */\nexport class WranglerApi {\n protected readonly log = $logger();\n protected readonly shell = $inject(ShellProvider);\n protected readonly utils = $inject(AlephaCliUtils);\n protected readonly pm = $inject(PackageManagerUtils);\n protected readonly runner = $inject(Runner);\n\n protected async runShell(\n command: string,\n options: Parameters<ShellProvider[\"run\"]>[1] = {},\n ) {\n const capture = options.capture;\n const output = await this.shell.run(command, {\n ...options,\n capture: capture ?? this.runner.useDynamicLogger,\n });\n\n if (capture && !this.runner.useDynamicLogger) {\n this.log.info(output);\n }\n\n return output;\n }\n\n // -------------------------------------------------------------------------\n // Auth\n // -------------------------------------------------------------------------\n\n /**\n * Ensure wrangler is installed in the project.\n */\n public async ensureInstalled(root: string, run: RunnerMethod): Promise<void> {\n await this.pm.ensureDependency(root, \"wrangler\", {\n dev: true,\n exec: async (cmd, opts) => {\n run.pause();\n try {\n await this.utils.exec(cmd, opts);\n } finally {\n run.resume();\n }\n },\n });\n }\n\n /**\n * Check if the user is authenticated. Returns the whoami output.\n */\n public async whoami(): Promise<string> {\n return await this.runShell(\"wrangler whoami\", {\n resolve: true,\n capture: true,\n });\n }\n\n /**\n * Open the browser-based OAuth login flow.\n */\n public async login(): Promise<void> {\n await this.runShell(\"wrangler login\", { resolve: true });\n }\n\n /**\n * Get the current auth token from wrangler (auto-refreshes if expired).\n */\n public async getAuthToken(): Promise<string> {\n const output = await this.shell.run(\"wrangler auth token --json\", {\n resolve: true,\n capture: true,\n });\n\n const parsed = JSON.parse(output) as { type: string; token: string };\n return parsed.token;\n }\n\n // -------------------------------------------------------------------------\n // Deploy\n // -------------------------------------------------------------------------\n\n /**\n * Deploy a worker via wrangler (handles bundling and upload).\n *\n * Returns the workers.dev URL if found in the output.\n */\n public async deploy(\n workerName: string,\n configPath: string,\n root?: string,\n ): Promise<string | undefined> {\n const output = await this.runShell(\n `wrangler deploy --name=${workerName} --no-bundle --config=${configPath}`,\n { resolve: true, capture: true, root },\n );\n\n const match = output.match(/https:\\/\\/[^\\s]*\\.workers\\.dev/);\n return match?.[0];\n }\n\n // -------------------------------------------------------------------------\n // D1 Migrations\n // -------------------------------------------------------------------------\n\n /**\n * Apply D1 migrations remotely.\n */\n public async d1MigrationsApply(\n dbName: string,\n configPath: string,\n root?: string,\n ): Promise<void> {\n await this.runShell(\n `wrangler d1 migrations apply ${dbName} --remote --config=${configPath}`,\n { resolve: true, env: { CI: \"1\" }, root },\n );\n }\n}\n","import { $inject, Alepha, AlephaError, type TSchema, t } from \"alepha\";\nimport { $logger } from \"alepha/logger\";\nimport type {\n CloudflareAccount,\n CloudflareApiError,\n CloudflareD1,\n CloudflareDeployment,\n CloudflareHyperdrive,\n CloudflareKV,\n CloudflareQueue,\n CloudflareQueueConsumer,\n CloudflareR2,\n CloudflareR2Token,\n CloudflareSecret,\n CloudflareVersion,\n CloudflareWorker,\n} from \"../schemas/cloudflare.ts\";\nimport {\n cloudflareAccountSchema,\n cloudflareD1Schema,\n cloudflareDeploymentListSchema,\n cloudflareHyperdriveSchema,\n cloudflareKVSchema,\n cloudflareQueueConsumerSchema,\n cloudflareQueueSchema,\n cloudflareR2Schema,\n cloudflareR2TokenSchema,\n cloudflareSecretSchema,\n cloudflareVersionSchema,\n cloudflareWorkerSchema,\n createD1BodySchema,\n createHyperdriveBodySchema,\n createKVBodySchema,\n createQueueBodySchema,\n createR2BodySchema,\n createR2TokenBodySchema,\n putSecretBodySchema,\n} from \"../schemas/cloudflare.ts\";\nimport { WranglerApi } from \"./WranglerApi.ts\";\n\nexport type {\n CloudflareD1,\n CloudflareDeployment,\n CloudflareHyperdrive,\n CloudflareKV,\n CloudflareQueue,\n CloudflareQueueConsumer,\n CloudflareR2,\n CloudflareR2Token,\n CloudflareSecret,\n CloudflareVersion,\n CloudflareWorker,\n};\n\n// ---------------------------------------------------------------------------\n// API client\n// ---------------------------------------------------------------------------\n\n/**\n * Thin wrapper over the Cloudflare REST API.\n *\n * Uses `wrangler auth token` to obtain credentials,\n * then calls `fetch()` directly for all CRUD operations.\n */\nexport class CloudflareApi {\n protected static readonly BASE = \"https://api.cloudflare.com/client/v4\";\n\n protected readonly log = $logger();\n protected readonly alepha = $inject(Alepha);\n protected readonly wrangler = $inject(WranglerApi);\n\n protected token?: string;\n protected accountId?: string;\n protected jurisdiction?: \"eu\" | \"fedramp\";\n\n /**\n * Set the Cloudflare data jurisdiction for R2 and D1 resources.\n *\n * R2 buckets and D1 databases created under a jurisdiction live in a\n * separate namespace — every R2 API call (list/create/delete) must include\n * the `cf-r2-jurisdiction` header, and D1 create must include the field\n * in the request body. Omit / pass `undefined` for the default (global).\n */\n public setJurisdiction(jurisdiction?: \"eu\" | \"fedramp\"): void {\n this.jurisdiction = jurisdiction;\n }\n\n /**\n * Override the Cloudflare account ID (from platform config).\n *\n * When unset, `resolveAccountId` falls back to `CLOUDFLARE_ACCOUNT_ID` env\n * var or the token's single account.\n */\n public setAccountId(accountId?: string): void {\n this.accountId = accountId;\n }\n\n // -------------------------------------------------------------------------\n // Auth\n // -------------------------------------------------------------------------\n\n /**\n * Obtain the current auth token from wrangler.\n */\n public async resolveToken(): Promise<string> {\n if (this.token) {\n return this.token;\n }\n\n this.token = await this.wrangler.getAuthToken();\n return this.token;\n }\n\n /**\n * Resolve the Cloudflare account ID.\n *\n * Calls /accounts and picks the first one. Cached after first call.\n */\n public async resolveAccountId(): Promise<string> {\n if (this.accountId) {\n return this.accountId;\n }\n\n const fromEnv = process.env.CLOUDFLARE_ACCOUNT_ID;\n if (fromEnv) {\n this.accountId = fromEnv;\n return this.accountId;\n }\n\n const res = await this.fetch<CloudflareAccount[]>(\"/accounts\", {\n schema: t.array(cloudflareAccountSchema),\n });\n\n if (res.length === 0) {\n throw new AlephaError(\"No Cloudflare accounts found for this token.\");\n }\n\n if (res.length > 1) {\n const list = res.map((a) => ` - ${a.id} ${a.name}`).join(\"\\n\");\n throw new AlephaError(\n `Cloudflare token has access to ${res.length} accounts; set ` +\n `\\`CLOUDFLARE_ACCOUNT_ID\\` or the \\`accountId\\` field in your ` +\n `platform config to pick one:\\n${list}`,\n );\n }\n\n this.accountId = res[0].id;\n return this.accountId;\n }\n\n // -------------------------------------------------------------------------\n // D1\n // -------------------------------------------------------------------------\n\n public async listD1(): Promise<CloudflareD1[]> {\n const accountId = await this.resolveAccountId();\n return await this.paginate<CloudflareD1>(\n `/accounts/${accountId}/d1/database`,\n cloudflareD1Schema,\n );\n }\n\n public async createD1(\n name: string,\n location = \"weur\", // TODO: move to config (or auto-resolve based on account info, or ask ?)\n ): Promise<CloudflareD1> {\n const accountId = await this.resolveAccountId();\n // When jurisdiction is set, `primary_location_hint` is silently ignored\n // by the API, so omit it to avoid confusion.\n const body: Record<string, unknown> = { name };\n if (this.jurisdiction) {\n body.jurisdiction = this.jurisdiction;\n } else {\n body.primary_location_hint = location;\n }\n return await this.fetch<CloudflareD1>(\n `/accounts/${accountId}/d1/database`,\n {\n method: \"POST\",\n body,\n bodySchema: createD1BodySchema,\n schema: cloudflareD1Schema,\n },\n );\n }\n\n public async deleteD1(databaseId: string): Promise<void> {\n const accountId = await this.resolveAccountId();\n await this.fetch(`/accounts/${accountId}/d1/database/${databaseId}`, {\n method: \"DELETE\",\n });\n }\n\n // -------------------------------------------------------------------------\n // KV\n // -------------------------------------------------------------------------\n\n public async listKV(): Promise<CloudflareKV[]> {\n const accountId = await this.resolveAccountId();\n return await this.paginate<CloudflareKV>(\n `/accounts/${accountId}/storage/kv/namespaces`,\n cloudflareKVSchema,\n 100, // KV list caps at 100 per page\n );\n }\n\n public async createKV(title: string): Promise<CloudflareKV> {\n const accountId = await this.resolveAccountId();\n return await this.fetch<CloudflareKV>(\n `/accounts/${accountId}/storage/kv/namespaces`,\n {\n method: \"POST\",\n body: { title },\n bodySchema: createKVBodySchema,\n schema: cloudflareKVSchema,\n },\n );\n }\n\n public async deleteKV(namespaceId: string): Promise<void> {\n const accountId = await this.resolveAccountId();\n await this.fetch(\n `/accounts/${accountId}/storage/kv/namespaces/${namespaceId}`,\n { method: \"DELETE\" },\n );\n }\n\n // -------------------------------------------------------------------------\n // R2\n // -------------------------------------------------------------------------\n\n public async listR2(): Promise<CloudflareR2[]> {\n const accountId = await this.resolveAccountId();\n return await this.paginateCursor<CloudflareR2>(\n `/accounts/${accountId}/r2/buckets`,\n \"buckets\",\n cloudflareR2Schema,\n );\n }\n\n public async createR2(name: string): Promise<void> {\n const accountId = await this.resolveAccountId();\n await this.fetch(`/accounts/${accountId}/r2/buckets`, {\n method: \"POST\",\n body: { name },\n bodySchema: createR2BodySchema,\n });\n }\n\n public async deleteR2(name: string): Promise<void> {\n const accountId = await this.resolveAccountId();\n await this.fetch(`/accounts/${accountId}/r2/buckets/${name}`, {\n method: \"DELETE\",\n });\n }\n\n /**\n * Mint a bucket-scoped R2 API token (S3 access key + secret) using the\n * current bearer token. Used by teardown to wipe a bucket over the S3\n * protocol without requiring users to pre-create R2 access keys.\n *\n * The returned token should be revoked with `deleteR2Token` as soon as the\n * wipe is done.\n */\n public async createR2Token(\n name: string,\n bucket: string,\n ): Promise<CloudflareR2Token> {\n const accountId = await this.resolveAccountId();\n return await this.fetch<CloudflareR2Token>(\n `/accounts/${accountId}/r2/api-tokens`,\n {\n method: \"POST\",\n body: {\n name,\n policies: [\n {\n effect: \"allow\",\n permissions: [\"admin-read-write\"],\n buckets: [bucket],\n },\n ],\n },\n bodySchema: createR2TokenBodySchema,\n schema: cloudflareR2TokenSchema,\n },\n );\n }\n\n public async deleteR2Token(tokenId: string): Promise<void> {\n const accountId = await this.resolveAccountId();\n await this.fetch(`/accounts/${accountId}/r2/api-tokens/${tokenId}`, {\n method: \"DELETE\",\n });\n }\n\n // -------------------------------------------------------------------------\n // Queues\n // -------------------------------------------------------------------------\n\n public async listQueues(): Promise<CloudflareQueue[]> {\n const accountId = await this.resolveAccountId();\n return await this.paginate<CloudflareQueue>(\n `/accounts/${accountId}/queues`,\n cloudflareQueueSchema,\n );\n }\n\n public async createQueue(name: string): Promise<CloudflareQueue> {\n const accountId = await this.resolveAccountId();\n return await this.fetch<CloudflareQueue>(`/accounts/${accountId}/queues`, {\n method: \"POST\",\n body: { queue_name: name },\n bodySchema: createQueueBodySchema,\n schema: cloudflareQueueSchema,\n });\n }\n\n public async deleteQueue(queueId: string): Promise<void> {\n const accountId = await this.resolveAccountId();\n await this.fetch(`/accounts/${accountId}/queues/${queueId}`, {\n method: \"DELETE\",\n });\n }\n\n public async listQueueConsumers(\n queueId: string,\n ): Promise<CloudflareQueueConsumer[]> {\n const accountId = await this.resolveAccountId();\n return await this.paginate<CloudflareQueueConsumer>(\n `/accounts/${accountId}/queues/${queueId}/consumers`,\n cloudflareQueueConsumerSchema,\n );\n }\n\n public async deleteQueueConsumer(\n queueId: string,\n consumerService: string,\n ): Promise<void> {\n const accountId = await this.resolveAccountId();\n const consumers = await this.listQueueConsumers(queueId);\n const consumer = consumers.find((c) => c.service === consumerService);\n if (!consumer) {\n return;\n }\n await this.fetch(\n `/accounts/${accountId}/queues/${queueId}/consumers/${consumer.consumer_id}`,\n { method: \"DELETE\" },\n );\n }\n\n // -------------------------------------------------------------------------\n // Hyperdrive\n // -------------------------------------------------------------------------\n\n public async listHyperdrive(): Promise<CloudflareHyperdrive[]> {\n const accountId = await this.resolveAccountId();\n return await this.paginate<CloudflareHyperdrive>(\n `/accounts/${accountId}/hyperdrive/configs`,\n cloudflareHyperdriveSchema,\n );\n }\n\n public async createHyperdrive(\n name: string,\n connectionString: string,\n ): Promise<CloudflareHyperdrive> {\n const accountId = await this.resolveAccountId();\n return await this.fetch<CloudflareHyperdrive>(\n `/accounts/${accountId}/hyperdrive/configs`,\n {\n method: \"POST\",\n body: {\n name,\n origin: this.parseConnectionString(connectionString),\n },\n bodySchema: createHyperdriveBodySchema,\n schema: cloudflareHyperdriveSchema,\n },\n );\n }\n\n public async deleteHyperdrive(configId: string): Promise<void> {\n const accountId = await this.resolveAccountId();\n await this.fetch(`/accounts/${accountId}/hyperdrive/configs/${configId}`, {\n method: \"DELETE\",\n });\n }\n\n // -------------------------------------------------------------------------\n // Workers\n // -------------------------------------------------------------------------\n\n public async getWorker(\n scriptName: string,\n ): Promise<CloudflareWorker | undefined> {\n const accountId = await this.resolveAccountId();\n try {\n return await this.fetch<CloudflareWorker>(\n `/accounts/${accountId}/workers/scripts/${scriptName}`,\n { schema: cloudflareWorkerSchema },\n );\n } catch {\n return undefined;\n }\n }\n\n public async deleteWorker(scriptName: string): Promise<void> {\n const accountId = await this.resolveAccountId();\n await this.fetch(`/accounts/${accountId}/workers/scripts/${scriptName}`, {\n method: \"DELETE\",\n query: { force: \"true\" },\n });\n }\n\n public async listDeployments(\n scriptName: string,\n ): Promise<CloudflareDeployment[]> {\n const accountId = await this.resolveAccountId();\n // Deployments list is wrapped in `{ deployments }` and returns newest\n // first; for picking the active deployment we only need the top page.\n const res = await this.fetch<{ deployments: CloudflareDeployment[] }>(\n `/accounts/${accountId}/workers/scripts/${scriptName}/deployments`,\n { schema: cloudflareDeploymentListSchema, query: { per_page: \"100\" } },\n );\n return res.deployments;\n }\n\n public async listVersions(scriptName: string): Promise<CloudflareVersion[]> {\n const accountId = await this.resolveAccountId();\n return await this.paginateCursor<CloudflareVersion>(\n `/accounts/${accountId}/workers/scripts/${scriptName}/versions`,\n \"items\",\n cloudflareVersionSchema,\n );\n }\n\n // -------------------------------------------------------------------------\n // Secrets\n // -------------------------------------------------------------------------\n\n public async listSecrets(scriptName: string): Promise<CloudflareSecret[]> {\n const accountId = await this.resolveAccountId();\n return await this.fetch<CloudflareSecret[]>(\n `/accounts/${accountId}/workers/scripts/${scriptName}/secrets`,\n { schema: t.array(cloudflareSecretSchema) },\n );\n }\n\n public async putSecret(\n scriptName: string,\n name: string,\n value: string,\n ): Promise<void> {\n const accountId = await this.resolveAccountId();\n await this.fetch(\n `/accounts/${accountId}/workers/scripts/${scriptName}/secrets`,\n {\n method: \"PUT\",\n body: { name, text: value, type: \"secret_text\" },\n bodySchema: putSecretBodySchema,\n },\n );\n }\n\n /**\n * Fetch the current worker bindings via the script-settings endpoint.\n * Used to merge new secrets into the existing binding set in one PATCH\n * (avoids the per-secret `putSecret` calls, each of which creates a\n * Cloudflare deployment — pushing 7 secrets meant 7 deployment rows).\n *\n * Secret bindings come back with `name` + `type` but no `text` (they're\n * write-only on Cloudflare's side); to preserve them across a PATCH we\n * forward each one as `{ type, name }` and Cloudflare keeps the stored\n * value.\n */\n public async getWorkerSettings(scriptName: string): Promise<{\n bindings: Array<{ type: string; name: string; text?: string }>;\n }> {\n const accountId = await this.resolveAccountId();\n return await this.fetch<{\n bindings: Array<{ type: string; name: string; text?: string }>;\n }>(`/accounts/${accountId}/workers/scripts/${scriptName}/settings`);\n }\n\n /**\n * Replace the worker's binding set in one call (= one Cloudflare\n * deployment, regardless of how many secrets are being updated).\n *\n * The endpoint expects multipart FormData with a `settings` field whose\n * value is a JSON-encoded `{ bindings: [...] }` — the `fetch` helper\n * above is JSON-only, so this one bypasses it and calls `globalThis.fetch`\n * directly. Mirrors what `wrangler secret bulk` does internally.\n */\n public async patchWorkerBindings(\n scriptName: string,\n bindings: Array<{ type: string; name: string; text?: string }>,\n ): Promise<void> {\n const accountId = await this.resolveAccountId();\n const token = await this.resolveToken();\n const url = `${CloudflareApi.BASE}/accounts/${accountId}/workers/scripts/${scriptName}/settings`;\n\n const form = new FormData();\n form.set(\"settings\", JSON.stringify({ bindings }));\n\n const response = await globalThis.fetch(url, {\n method: \"PATCH\",\n headers: { Authorization: `Bearer ${token}` },\n body: form,\n });\n\n const json = (await response.json().catch(() => null)) as {\n success?: boolean;\n errors?: CloudflareApiError[];\n } | null;\n\n if (!response.ok || !json?.success) {\n const messages = json?.errors?.map((e) => e.message).join(\", \");\n throw new AlephaError(\n `Cloudflare API error (PATCH /workers/scripts/${scriptName}/settings): ${\n messages ?? response.statusText\n }`,\n );\n }\n }\n\n // -------------------------------------------------------------------------\n // Core fetch\n // -------------------------------------------------------------------------\n\n protected async fetch<T = unknown>(\n path: string,\n options: {\n method?: string;\n body?: unknown;\n bodySchema?: TSchema;\n schema?: TSchema;\n query?: Record<string, string>;\n } = {},\n ): Promise<T> {\n const token = await this.resolveToken();\n const { method = \"GET\", body, query } = options;\n\n let url = `${CloudflareApi.BASE}${path}`;\n if (query) {\n const params = new URLSearchParams(query);\n url += `?${params.toString()}`;\n }\n\n const headers: Record<string, string> = {\n Authorization: `Bearer ${token}`,\n };\n\n if (this.jurisdiction && /\\/r2\\//.test(path)) {\n headers[\"cf-r2-jurisdiction\"] = this.jurisdiction;\n }\n\n const init: RequestInit = { method, headers };\n\n if (body) {\n headers[\"Content-Type\"] = \"application/json\";\n const validated = options.bodySchema\n ? this.alepha.codec.validate(options.bodySchema, body)\n : body;\n init.body = JSON.stringify(validated);\n }\n\n const response = await globalThis.fetch(url, init);\n const json = (await response.json()) as {\n success: boolean;\n result: T;\n errors: CloudflareApiError[];\n result_info?: {\n page: number;\n per_page: number;\n total_pages?: number;\n count?: number;\n total_count?: number;\n };\n };\n\n if (!json.success) {\n const messages = json.errors.map((e) => e.message).join(\", \");\n throw new AlephaError(\n `Cloudflare API error (${method} ${path}): ${messages}`,\n );\n }\n\n if (options.schema) {\n return this.alepha.codec.validate(options.schema, json.result) as T;\n }\n\n return json.result;\n }\n\n /**\n * Paginate a page-based list endpoint (`result_info.total_pages`).\n *\n * Cloudflare defaults to `per_page=20`; we push it to 1000 (max on most\n * list endpoints) and loop if more pages exist. Each page is validated\n * against the item schema.\n */\n protected async paginate<T>(\n path: string,\n itemSchema: TSchema,\n perPage = 1000,\n ): Promise<T[]> {\n const results: T[] = [];\n let page = 1;\n\n while (true) {\n const token = await this.resolveToken();\n const url = `${CloudflareApi.BASE}${path}?per_page=${perPage}&page=${page}`;\n\n const headers: Record<string, string> = {\n Authorization: `Bearer ${token}`,\n };\n if (this.jurisdiction && /\\/r2\\//.test(path)) {\n headers[\"cf-r2-jurisdiction\"] = this.jurisdiction;\n }\n\n const response = await globalThis.fetch(url, { method: \"GET\", headers });\n const json = (await response.json()) as {\n success: boolean;\n result: T[];\n errors: CloudflareApiError[];\n result_info?: { page: number; total_pages?: number };\n };\n\n if (!json.success) {\n const messages = json.errors.map((e) => e.message).join(\", \");\n throw new AlephaError(\n `Cloudflare API error (GET ${path}): ${messages}`,\n );\n }\n\n const validated = this.alepha.codec.validate(\n t.array(itemSchema),\n json.result,\n ) as T[];\n results.push(...validated);\n\n const totalPages = json.result_info?.total_pages;\n if (!totalPages || page >= totalPages || validated.length === 0) {\n break;\n }\n page++;\n }\n\n return results;\n }\n\n /**\n * Paginate a cursor-based list endpoint where `result` is an object\n * containing both the items array and a `cursor` field (R2 buckets,\n * Workers versions). Returns the flattened item array.\n */\n protected async paginateCursor<T>(\n path: string,\n itemsKey: string,\n itemSchema: TSchema,\n perPage = 1000,\n ): Promise<T[]> {\n const results: T[] = [];\n let cursor: string | undefined;\n\n while (true) {\n const query: Record<string, string> = { per_page: String(perPage) };\n if (cursor) {\n query.cursor = cursor;\n }\n\n const res = await this.fetch<Record<string, unknown>>(path, { query });\n const items = (res[itemsKey] as unknown[]) ?? [];\n const validated = this.alepha.codec.validate(\n t.array(itemSchema),\n items,\n ) as T[];\n results.push(...validated);\n\n const nextCursor = res.cursor as string | undefined;\n if (!nextCursor || validated.length === 0) {\n break;\n }\n cursor = nextCursor;\n }\n\n return results;\n }\n\n // -------------------------------------------------------------------------\n // Helpers\n // -------------------------------------------------------------------------\n\n /**\n * Parse a postgres:// connection string into Hyperdrive origin fields.\n */\n protected parseConnectionString(connectionString: string): {\n scheme: string;\n host: string;\n port: number;\n database: string;\n user: string;\n password: string;\n } {\n const url = new URL(connectionString);\n return {\n scheme: \"postgres\",\n host: url.hostname,\n port: Number(url.port) || 5432,\n database: url.pathname.slice(1),\n user: decodeURIComponent(url.username),\n password: decodeURIComponent(url.password),\n };\n }\n}\n","import { AlephaError } from \"alepha\";\n\n/**\n * Multi-tenancy mode for an app's deployments.\n *\n * - `none` (default): single-instance app. Passing `--tenant` is an\n * error — guards a non-tenanted app (e.g. the SaaS console) from\n * accidentally getting a tenant prefix.\n * - `required`: every deploy targets a tenant. Omitting `--tenant` is an\n * error — kills the \"forgot the flag → deployed to the apex\" footgun.\n * - `optional`: both work — a base instance (no `--tenant`) and per-tenant\n * instances coexist (distinct names + hosts).\n */\nexport type Tenancy = \"none\" | \"optional\" | \"required\";\n\n/**\n * Validate a `--tenant` value against the app's declared `tenancy` and\n * return the effective tenant (or `undefined` for a base/non-tenanted\n * deploy). Throws on any matrix violation so a misconfigured deploy fails\n * fast instead of landing on the wrong resource names / host.\n */\nexport function resolveTenant(\n tenancy: Tenancy | undefined,\n tenant: string | undefined,\n): string | undefined {\n const mode = tenancy ?? \"none\";\n\n if (tenant !== undefined && !/^[a-z0-9][a-z0-9-]*$/.test(tenant)) {\n throw new AlephaError(\n `Invalid --tenant \"${tenant}\": must be a slug (lowercase alphanumeric + dashes, e.g. \"b14\").`,\n );\n }\n\n if (mode === \"none\") {\n if (tenant !== undefined) {\n throw new AlephaError(\n `This app is not tenanted (tenancy: \"none\") but --tenant \"${tenant}\" was given. ` +\n `Set tenancy: \"optional\" | \"required\" in platform() to deploy per-tenant.`,\n );\n }\n return undefined;\n }\n\n if (mode === \"required\" && tenant === undefined) {\n throw new AlephaError(\n `This app requires a tenant (tenancy: \"required\"). Pass --tenant <slug>.`,\n );\n }\n\n // required+value or optional(+/- value) — value may be undefined for the\n // optional base instance.\n return tenant;\n}\n\n/**\n * Resolve the host a deploy is served on.\n *\n * - `override` (V2 custom domains, e.g. `reservation.club-b14.fr`) wins\n * outright when supplied — not wired to a flag today, but the single\n * seam a future `--domain` / Rocket `config.hostname` plugs into.\n * - else a tenant becomes the leftmost DNS label: `b14` + `alepha.club`\n * → `b14.alepha.club`.\n * - else the base domain is used as-is.\n */\nexport function tenantDomain(\n base: string | undefined,\n tenant: string | undefined,\n override?: string,\n): string | undefined {\n if (override) return override;\n if (!base) return base;\n return tenant ? `${tenant}.${base}` : base;\n}\n\n/**\n * Generates deterministic resource names for cloud deployments.\n *\n * Pattern: `<tenant>-<project>-<env>` (tenant segment omitted when the\n * deploy isn't tenanted).\n *\n * All segments are slugified (lowercase, alphanumeric + dashes, max 63\n * chars). One app per workspace — see `alepha platform`.\n */\nexport class NamingService {\n public forContext(\n project: string,\n env: string,\n tenant?: string,\n ): NamingContext {\n const prefix = [tenant, project, env]\n .filter((segment): segment is string => !!segment)\n .map((segment) => this.slugify(segment))\n .join(\"-\");\n return new NamingContext(prefix);\n }\n\n public slugify(name: string): string {\n return name\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, \"-\")\n .replace(/^-+|-+$/g, \"\")\n .slice(0, 63);\n }\n}\n\nexport class NamingContext {\n protected readonly prefix: string;\n\n constructor(prefix: string) {\n this.prefix = prefix;\n }\n\n public worker(): string {\n return this.prefix;\n }\n\n public d1(): string {\n return this.prefix;\n }\n\n public hyperdrive(): string {\n return this.prefix;\n }\n\n public r2(): string {\n return this.prefix;\n }\n\n public kv(): string {\n return this.prefix;\n }\n\n public queue(): string {\n return this.prefix;\n }\n}\n","import { AlephaError } from \"alepha\";\nimport type { AppEntry } from \"alepha/cli\";\nimport type { RunnerMethod } from \"alepha/command\";\nimport type { EnvironmentConfig } from \"../atoms/platformOptions.ts\";\nimport type { NamingContext } from \"../services/NamingService.ts\";\n\n/**\n * Options for {@link PlatformAdapter.exportDb}.\n */\nexport interface ExportDbOptions {\n /**\n * Destination file for the local snapshot. Adapter-specific default —\n * Cloudflare/D1 writes the dev SQLite at\n * `node_modules/.alepha/sqlite.db`.\n */\n output?: string;\n /**\n * Keep the intermediate `.sql` dump instead of deleting it after import.\n */\n keepSql?: boolean;\n}\n\n// ---------------------------------------------------------------------------\n// Context types\n// ---------------------------------------------------------------------------\n\nexport interface DetectedResources {\n hasDatabase: boolean;\n hasBucket: boolean;\n hasKV: boolean;\n hasQueue: boolean;\n hasCron: boolean;\n}\n\n/**\n * One workspace = one app. Used to be a per-app definition in a\n * monorepo-aware orchestrator; flattened into `PlatformContext` after\n * the `apps:` field was removed from platform options.\n */\nexport interface PlatformContext {\n /**\n * Slugified project name (from package.json or platform config).\n */\n project: string;\n\n /**\n * Environment key (e.g., \"production\", \"staging\", \"tmp-bug001\").\n */\n env: string;\n\n /**\n * Environment configuration from alepha.config.ts.\n */\n envConfig: EnvironmentConfig;\n\n /**\n * Workspace root path.\n */\n root: string;\n\n /**\n * Resolved entry points for the workspace. Stub (`{ root, server: \"\" }`)\n * in pre-built / manifest mode since no source booting happens.\n */\n entry: AppEntry;\n\n /**\n * Cloud resources the workspace uses — discovered at build time, read\n * from `dist/manifest.json` at deploy time.\n */\n resources: DetectedResources;\n\n /**\n * Resource name generator bound to this project+env(+tenant).\n */\n naming: NamingContext;\n\n /**\n * Active tenant slug for this deploy (apps with `tenancy: optional |\n * required`), or `undefined` for a base / non-tenanted deploy. Shapes\n * the served host (`<tenant>.<domain>`); resource names already fold it\n * in via {@link naming}.\n */\n tenant?: string;\n\n /**\n * Pre-built mode. When true, the adapter's `build()` should skip the\n * Vite bundle steps and only regenerate the deploy config\n * (wrangler.jsonc, Dockerfile, etc.) so it reflects current bindings +\n * per-tenant overrides.\n */\n prebuilt?: boolean;\n}\n\n/**\n * @deprecated Same as `PlatformContext` since the `apps:` collapse —\n * kept as a type alias so existing adapter signatures still compile.\n */\nexport type AppContext = PlatformContext;\n\n// ---------------------------------------------------------------------------\n// State types (returned by inspect)\n// ---------------------------------------------------------------------------\n\nexport interface ResourceState {\n name: string;\n exists: boolean;\n id?: string;\n detail?: string;\n}\n\nexport interface WorkerState extends ResourceState {\n version?: string;\n tag?: string;\n createdAt?: string;\n}\n\nexport interface SecretState {\n name: string;\n deployed: boolean;\n}\n\nexport interface PlatformState {\n workers: WorkerState[];\n databases: ResourceState[];\n buckets: ResourceState[];\n kvNamespaces: ResourceState[];\n queues: ResourceState[];\n secrets: SecretState[];\n}\n\n// ---------------------------------------------------------------------------\n// Adapter contract\n// ---------------------------------------------------------------------------\n\n/**\n * Abstract platform adapter.\n *\n * Each cloud provider (Cloudflare, AKS, docker-compose) implements this.\n * The PlatformOrchestrator calls these methods in the correct order.\n */\nexport abstract class PlatformAdapter {\n /**\n * Ensure the user is authenticated with the cloud provider.\n * May use cached credentials to avoid slow checks.\n */\n abstract authenticate(ctx: PlatformContext, run: RunnerMethod): Promise<void>;\n\n /**\n * Build artifacts for a single app.\n */\n abstract build(ctx: AppContext, run: RunnerMethod): Promise<void>;\n\n /**\n * Deploy a single app (upload + activate atomically, e.g., wrangler deploy).\n * Returns the live URL if the platform provides one.\n */\n abstract deploy(\n ctx: AppContext,\n run: RunnerMethod,\n ): Promise<string | undefined>;\n\n /**\n * Create/ensure cloud resources exist (DB, buckets, queues).\n * Not all adapters provision -- AKS defers to Helm.\n */\n async provision(_ctx: PlatformContext, _run: RunnerMethod): Promise<void> {}\n\n /**\n * Run database migrations.\n */\n async migrate(_ctx: PlatformContext, _run: RunnerMethod): Promise<void> {}\n\n /**\n * Export the deployed database to a local file — the remote → local dev\n * snapshot workflow. Adapter/dialect specific; the default refuses.\n */\n async exportDb(\n _ctx: PlatformContext,\n _run: RunnerMethod,\n _options: ExportDbOptions = {},\n ): Promise<void> {\n throw new AlephaError(\n `Database export is not supported by the '${this.constructor.name}' adapter.`,\n );\n }\n\n /**\n * Push runtime secrets to the deployed worker(s).\n *\n * Reads secrets from `.env.{env}` files (parsed, not from process.env),\n * filters out vars already handled by bindings (DATABASE_URL, R2, etc.),\n * and pushes the rest via the platform's secret management.\n */\n async secrets(_ctx: PlatformContext, _run: RunnerMethod): Promise<void> {}\n\n /**\n * Detect existing resources and their state.\n * Used by `plan` and `status` commands.\n */\n abstract inspect(\n ctx: PlatformContext,\n run: RunnerMethod,\n ): Promise<PlatformState>;\n\n /**\n * Tear down all resources for an environment.\n */\n abstract teardown(ctx: PlatformContext, run: RunnerMethod): Promise<void>;\n}\n","import { createHash } from \"node:crypto\";\nimport { readFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport {\n $inject,\n $state,\n Alepha,\n AlephaError,\n type Alepha as AlephaInstance,\n} from \"alepha\";\nimport {\n BuildCloudflareTask,\n type BuildManifest,\n type BuildTaskContext,\n} from \"alepha/cli\";\nimport { EnvUtils, Runner, type RunnerMethod } from \"alepha/command\";\nimport { $logger } from \"alepha/logger\";\nimport { FileSystemProvider, ShellProvider } from \"alepha/system\";\nimport { S3mini } from \"s3mini\";\nimport { platformOptions } from \"../atoms/platformOptions.ts\";\nimport { PlatformCacheProvider } from \"../providers/PlatformCacheProvider.ts\";\nimport { CloudflareApi } from \"../services/CloudflareApi.ts\";\nimport { tenantDomain } from \"../services/NamingService.ts\";\nimport { WranglerApi } from \"../services/WranglerApi.ts\";\nimport {\n type AppContext,\n type ExportDbOptions,\n PlatformAdapter,\n type PlatformContext,\n type PlatformState,\n} from \"./PlatformAdapter.ts\";\n\n/**\n * Cloudflare Workers adapter.\n *\n * Uses the Cloudflare REST API (via CloudflareApi) for resource provisioning\n * and teardown, and wrangler CLI (via WranglerApi) for login, deploy,\n * D1 migrations, and secret bulk push.\n */\nexport class CloudflareAdapter extends PlatformAdapter {\n protected readonly log = $logger();\n protected readonly fs = $inject(FileSystemProvider);\n protected readonly shell = $inject(ShellProvider);\n protected readonly cache = $inject(PlatformCacheProvider);\n protected readonly alepha = $inject(Alepha);\n protected readonly envUtils = $inject(EnvUtils);\n protected readonly api = $inject(CloudflareApi);\n protected readonly wrangler = $inject(WranglerApi);\n protected readonly runner = $inject(Runner);\n protected readonly buildTask = $inject(BuildCloudflareTask);\n protected readonly options = $state(platformOptions);\n\n protected provisionedD1Id?: string;\n protected provisionedHyperdriveId?: string;\n protected provisionedKVIds = new Map<string, string>();\n\n /**\n * Check if the user's DATABASE_URL points to an external Postgres database.\n * If so, we use Hyperdrive instead of D1.\n *\n * Reads from `.env.{env}` first, falls back to `process.env`.\n */\n protected async isPostgres(ctx: PlatformContext): Promise<boolean> {\n const envVars = await this.envUtils.parseEnv(ctx.root, [`.env.${ctx.env}`]);\n const dbUrl = envVars.DATABASE_URL ?? process.env.DATABASE_URL;\n return !!dbUrl?.startsWith(\"postgres:\");\n }\n\n /**\n * Propagate the environment's data-jurisdiction setting to the API client.\n *\n * Must be invoked at the top of every entry point (authenticate, build,\n * deploy, secrets, provision, migrate, inspect, teardown) because\n * CloudflareApi is a singleton reused across env invocations.\n */\n protected configureApi(ctx: PlatformContext): void {\n this.api.setJurisdiction(ctx.envConfig.jurisdiction);\n this.api.setAccountId(ctx.envConfig.accountId);\n }\n\n protected async runShell(\n command: string,\n options: Parameters<ShellProvider[\"run\"]>[1] = {},\n ) {\n const capture = options.capture;\n const output = await this.shell.run(command, {\n ...options,\n capture: capture ?? this.runner.useDynamicLogger,\n });\n\n if (capture && !this.runner.useDynamicLogger) {\n this.log.info(output);\n }\n\n return output;\n }\n\n // -------------------------------------------------------------------------\n // authenticate\n // -------------------------------------------------------------------------\n\n async authenticate(ctx: PlatformContext, run: RunnerMethod): Promise<void> {\n this.configureApi(ctx);\n await run({\n name: \"authenticate\",\n handler: async () => {\n await this.wrangler.ensureInstalled(ctx.root, run);\n\n // Always validate the token — refresh tokens can expire between runs\n // even when the cache TTL hasn't elapsed.\n let needsLogin = false;\n\n try {\n await this.wrangler.getAuthToken();\n } catch {\n needsLogin = true;\n }\n\n if (needsLogin) {\n run.pause();\n await this.wrangler.login();\n run.resume();\n }\n\n // Skip account resolution if cache is fresh\n if (await this.cache.isLoginFresh(ctx.root, \"cloudflare\")) {\n return;\n }\n\n // Resolve account ID via REST API (typed, no regex)\n try {\n const accountId = await this.api.resolveAccountId();\n await this.cache.recordLogin(ctx.root, \"cloudflare\", accountId);\n } catch {\n await this.cache.recordLogin(ctx.root, \"cloudflare\");\n }\n },\n });\n }\n\n // -------------------------------------------------------------------------\n // build\n // -------------------------------------------------------------------------\n\n async build(ctx: AppContext, run: RunnerMethod): Promise<void> {\n this.configureApi(ctx);\n const appDir = ctx.root;\n\n const env: Record<string, string> = {};\n\n if (ctx.resources.hasDatabase) {\n if (this.provisionedHyperdriveId) {\n env.HYPERDRIVE_ID = this.provisionedHyperdriveId;\n const envVars = await this.envUtils.parseEnv(ctx.root, [\n `.env.${ctx.env}`,\n ]);\n const pgSchema = envVars.POSTGRES_SCHEMA ?? process.env.POSTGRES_SCHEMA;\n if (pgSchema) {\n env.POSTGRES_SCHEMA = pgSchema;\n }\n } else if (this.provisionedD1Id) {\n const dbName = ctx.naming.d1();\n env.DATABASE_URL = `d1://${dbName}:${this.provisionedD1Id}`;\n }\n }\n\n if (ctx.resources.hasBucket) {\n env.R2_BUCKET_NAME = ctx.naming.r2();\n }\n\n if (ctx.resources.hasKV) {\n const kvName = ctx.naming.kv();\n env.CLOUDFLARE_KV_NAME = kvName;\n const kvId = this.provisionedKVIds.get(kvName);\n if (kvId) {\n env.CLOUDFLARE_KV_ID = kvId;\n }\n }\n\n if (ctx.resources.hasQueue) {\n env.CLOUDFLARE_QUEUE_NAME = ctx.naming.queue();\n }\n\n // For a tenanted deploy the host is `<tenant>.<domain>`; otherwise the\n // configured domain is used as-is. (V2 custom-domain override plugs in\n // via tenantDomain's third arg.)\n const host = tenantDomain(ctx.envConfig.domain, ctx.tenant);\n if (host) {\n if (host.includes(\"*\") && !ctx.envConfig.zone) {\n throw new AlephaError(\n `Wildcard domain \"${host}\" requires \"zone\" to be set in the environment config (the Cloudflare zone name, e.g. \"alepha.dev\").`,\n );\n }\n env.CLOUDFLARE_DOMAIN = host;\n if (ctx.envConfig.zone) {\n env.CLOUDFLARE_ZONE = ctx.envConfig.zone;\n }\n }\n\n if (ctx.envConfig.jurisdiction) {\n env.CLOUDFLARE_JURISDICTION = ctx.envConfig.jurisdiction;\n }\n\n // Two paths:\n // - `--prebuilt`: in-process call to BuildCloudflareTask. Reads\n // `dist/manifest.json` for resources/crons/containers, reads\n // per-tenant values from process.env (set below), and writes a\n // fresh `dist/wrangler.jsonc` + `dist/main.cloudflare.js`. No\n // Vite, no spawn, no `alepha` binary needed at the workspace\n // cwd — required for Rocket, which deploys a bare prebuilt\n // tarball with no `node_modules`.\n // - non-prebuilt: spawn the full `alepha build` for the CLI flow,\n // which still needs Vite analyze + bundle.\n if (ctx.prebuilt) {\n await run({\n name: \"alepha build -t cloudflare --prebuilt (in-process)\",\n handler: async () => {\n await this.runBuildInProcess(appDir, env);\n },\n });\n return;\n }\n\n const cmd = \"alepha build -t cloudflare\";\n await run({\n name: cmd,\n handler: async () => {\n await this.runShell(cmd, {\n root: appDir,\n env,\n });\n },\n });\n }\n\n /**\n * Library-embed of `alepha build -t cloudflare --prebuilt`. Loads the\n * pre-built `dist/manifest.json`, sets the per-tenant env vars on\n * `process.env` for the duration of the call (the task's enhance*\n * methods read them directly), then runs `BuildCloudflareTask`\n * against a synthetic context.\n *\n * `ctx.alepha` is intentionally null — in manifest mode the task\n * reads resources/crons/containers from `ctx.manifest` and never\n * dereferences `ctx.alepha`. Same for `entry` and `hasClient`:\n * prebuilt mode skips the bundle tasks; only the wrangler.jsonc /\n * worker-entrypoint emission runs.\n */\n protected async runBuildInProcess(\n root: string,\n env: Record<string, string>,\n ): Promise<void> {\n const manifestPath = join(root, \"dist\", \"manifest.json\");\n let manifest: BuildManifest;\n try {\n manifest = JSON.parse(await readFile(manifestPath, \"utf-8\"));\n } catch (err) {\n throw new AlephaError(\n `Cannot read ${manifestPath}: ${(err as Error).message}. ` +\n `Prebuilt deploys require dist/manifest.json (emitted by \\`alepha build -t cloudflare\\`).`,\n );\n }\n\n const ctx: BuildTaskContext = {\n // null at runtime — task takes the manifest path and never\n // dereferences alepha. Cast keeps the type signature happy.\n alepha: null as unknown as AlephaInstance,\n options: {\n target: \"cloudflare\",\n output: { dist: \"dist\", public: \"public\" },\n },\n run: this.runner.run,\n root,\n entry: { root, server: \"\" },\n hasClient: false,\n manifest,\n platformOptions: null,\n flags: { prebuilt: true },\n };\n\n const previous: Record<string, string | undefined> = {};\n for (const [k, v] of Object.entries(env)) {\n previous[k] = process.env[k];\n process.env[k] = v;\n }\n try {\n await this.buildTask.run(ctx);\n } finally {\n for (const [k, prev] of Object.entries(previous)) {\n if (prev === undefined) delete process.env[k];\n else process.env[k] = prev;\n }\n }\n }\n\n // -------------------------------------------------------------------------\n // deploy (wrangler — handles bundling/upload)\n // -------------------------------------------------------------------------\n\n async deploy(\n ctx: AppContext,\n run: RunnerMethod,\n ): Promise<string | undefined> {\n this.configureApi(ctx);\n const workerName = ctx.naming.worker();\n const distDir = this.fs.join(ctx.root, \"dist\");\n\n let url: string | undefined;\n\n await run({\n name: `deploy worker ${ctx.project}`,\n handler: async () => {\n url = await this.wrangler.deploy(\n workerName,\n `${distDir}/wrangler.jsonc`,\n ctx.root,\n );\n },\n });\n\n return url;\n }\n\n // -------------------------------------------------------------------------\n // secrets (wrangler — bulk push)\n // -------------------------------------------------------------------------\n\n /**\n * Vars that are handled by wrangler bindings or build config.\n * These should not be pushed as secrets.\n */\n static readonly EXCLUDED_SECRET_KEYS = new Set([\n \"DATABASE_URL\",\n \"R2_BUCKET_NAME\",\n \"CLOUDFLARE_DOMAIN\",\n \"CLOUDFLARE_ZONE\",\n \"CLOUDFLARE_JURISDICTION\",\n \"HYPERDRIVE_ID\",\n \"POSTGRES_SCHEMA\",\n \"NODE_ENV\",\n // Framework infra knobs (have defaults, never worker secrets). The\n // manifest's `env` auto-list surfaces every declared `$env` key, so\n // exclude these here to keep them out of the secret push even when a CI\n // runner happens to set them (LOG_LEVEL, DEBUG, etc.).\n \"LOG_LEVEL\",\n \"LOG_FORMAT\",\n \"SERVER_HOST\",\n \"SERVER_PORT\",\n \"TRUST_PROXY\",\n \"REACT_SSR_ENABLED\",\n \"DATABASE_SYNC\",\n \"DEBUG\",\n ]);\n\n /**\n * Read the build manifest's `env` list (every key the app declares via\n * `$env`) from `dist/manifest.json`. Used as the default worker-secret\n * allowlist. Returns `undefined` when the manifest is absent or predates\n * the `env` field, so the caller falls back to the `.env` file keys.\n */\n protected async readManifestEnvKeys(\n root: string,\n ): Promise<string[] | undefined> {\n try {\n const manifest = await this.fs.readJsonFile<Partial<BuildManifest>>(\n this.fs.join(root, \"dist\", \"manifest.json\"),\n );\n return Array.isArray(manifest.env) ? manifest.env : undefined;\n } catch {\n return undefined;\n }\n }\n\n override async secrets(\n ctx: PlatformContext,\n run: RunnerMethod,\n ): Promise<void> {\n this.configureApi(ctx);\n const envVars = await this.envUtils.parseEnv(ctx.root, [`.env.${ctx.env}`]);\n\n // The key set to push, by precedence:\n // 1. `platform.secrets.keys` — explicit override in alepha.config.ts.\n // 2. otherwise the UNION of:\n // a. `dist/manifest.json` `env` — every key the app declares via\n // `$env`, captured at build time (or the `.env.<env>` file keys as\n // a legacy fallback for artifacts built before the manifest carried\n // `env`). Lets CI deliver declared secrets from `process.env` with\n // no file on the runner.\n // b. `.env.<env>.local` keys — the per-deploy override layer. External\n // orchestrators (Alepha Rocket) write injected `config.vars` +\n // `config.secrets` (e.g. CLUB_CONFIG_JSON, per-tenant OAuth) here,\n // and those must reach the worker even though the prebuilt app\n // never declared them. Only `.local` is unioned, NOT the base\n // `.env.<env>` — so local infra creds (CLOUDFLARE_API_TOKEN, …)\n // can't leak in.\n // In every case the value resolves from `.env.<env>[.local]` first, then\n // `process.env`; ambient runner vars (PATH, GITHUB_*, …) can never leak.\n const declaredKeys = this.options?.secrets?.keys;\n const manifestKeys = await this.readManifestEnvKeys(ctx.root);\n const localKeys = Object.keys(\n await this.envUtils.parseEnv(ctx.root, [`.env.${ctx.env}.local`]),\n );\n const keys =\n declaredKeys ??\n Array.from(\n new Set([...(manifestKeys ?? Object.keys(envVars)), ...localKeys]),\n );\n\n // Filter out binding/build vars, VITE_* vars, and empty values\n const secrets: Record<string, string> = {};\n for (const key of keys) {\n if (CloudflareAdapter.EXCLUDED_SECRET_KEYS.has(key)) continue;\n if (key.startsWith(\"VITE_\")) continue;\n const value = envVars[key] ?? process.env[key];\n if (!value) continue;\n secrets[key] = value;\n }\n\n // Auto-derive PUBLIC_URL from the configured domain so absolute links\n // (emails, OAuth callbacks, sitemap) resolve at runtime — the Worker\n // entrypoint lifts it into `alepha.env` via `loadEnv`. Honors an explicit\n // PUBLIC_URL in `.env.<env>` (already collected above); never overrides it.\n if (!secrets.PUBLIC_URL) {\n const url = this.publicUrl(ctx);\n if (url) {\n secrets.PUBLIC_URL = url;\n }\n }\n\n if (Object.keys(secrets).length === 0) {\n return;\n }\n\n // Push all secrets for a worker in a single PATCH so each `up` only\n // mints one new deployment for the secrets step (regardless of how many\n // are being updated). Loop-based `putSecret` worked but generated N\n // deployment rows per push, cluttering the CF dashboard.\n //\n // Skip the PATCH entirely when nothing changed: we stamp a sha256 of the\n // sorted secret set onto the worker as a plain_text binding called\n // `ALEPHA_SECRETS_HASH`. On the next deploy we GET the settings, compare\n // the stored hash to the freshly-computed one, and bail out if they\n // match. The hash lives on Cloudflare (not on disk), so the cache works\n // identically in CI and locally.\n //\n // Net deploy count per `up`:\n // - code change, secrets unchanged: 1 (wrangler deploy only)\n // - secrets changed: 2 (wrangler deploy + bulk PATCH)\n //\n // Implementation mirrors `wrangler secret bulk`:\n // 1. GET current worker bindings via `/script/{name}/settings`.\n // 2. Compare ALEPHA_SECRETS_HASH binding to local hash → skip on match.\n // 3. Keep all non-secret bindings (D1, R2, KV, etc.) and any secret\n // bindings we are NOT overwriting (forwarded as `{type,name}` only\n // — CF preserves their stored values).\n // 4. Add/overwrite secrets as `{type,name,text}`, plus a fresh\n // ALEPHA_SECRETS_HASH binding so subsequent runs see it.\n // 5. PATCH the merged binding list in one call.\n const hash = computeSecretsHash(secrets);\n\n {\n const workerName = ctx.naming.worker();\n\n await run({\n name: `push secrets to ${workerName} (bulk)`,\n handler: async () => {\n const settings = await this.api.getWorkerSettings(workerName);\n const existingBindings = settings.bindings ?? [];\n\n const existingHashBinding = existingBindings.find(\n (b) =>\n b.type === \"plain_text\" &&\n b.name === CloudflareAdapter.SECRETS_HASH_BINDING,\n );\n\n if (existingHashBinding?.text === hash) {\n this.log.info(\n `Secrets for ${workerName} unchanged (hash ${hash.slice(0, 8)}…), skipping push.`,\n );\n return;\n }\n\n const overwriting = new Set(Object.keys(secrets));\n const inherit = existingBindings\n .filter(\n (b) =>\n // Drop the old hash binding — we'll write a fresh one below.\n !(\n b.type === \"plain_text\" &&\n b.name === CloudflareAdapter.SECRETS_HASH_BINDING\n ) &&\n // Drop secret bindings we're about to overwrite. Keep the\n // rest of the bindings (D1, R2, KV, untouched secrets) as\n // `{type,name}` only — CF preserves stored values.\n (b.type !== \"secret_text\" || !overwriting.has(b.name)),\n )\n .map((b) => ({ type: b.type, name: b.name }));\n\n const upsert = Object.entries(secrets).map(([name, text]) => ({\n type: \"secret_text\" as const,\n name,\n text,\n }));\n\n await this.api.patchWorkerBindings(workerName, [\n ...inherit,\n ...upsert,\n {\n type: \"plain_text\",\n name: CloudflareAdapter.SECRETS_HASH_BINDING,\n text: hash,\n },\n ]);\n },\n });\n }\n }\n\n /**\n * Public base URL for this deploy, derived from the configured domain\n * (honoring tenant subdomains). Returns undefined when no domain is set or\n * the host is a wildcard — there's no single resolvable origin to point at.\n */\n protected publicUrl(ctx: PlatformContext): string | undefined {\n const host = tenantDomain(ctx.envConfig.domain, ctx.tenant);\n if (!host || host.includes(\"*\")) {\n return undefined;\n }\n return `https://${host}`;\n }\n\n /**\n * Plain-text binding used to fingerprint the deployed secret set so the\n * next `up` can skip the PATCH when nothing has changed.\n */\n static readonly SECRETS_HASH_BINDING = \"ALEPHA_SECRETS_HASH\";\n\n // -------------------------------------------------------------------------\n // provision (REST API)\n // -------------------------------------------------------------------------\n\n override async provision(\n ctx: PlatformContext,\n run: RunnerMethod,\n ): Promise<void> {\n this.configureApi(ctx);\n const needsDB = ctx.resources.hasDatabase;\n const needsBucket = ctx.resources.hasBucket;\n const postgres = needsDB && (await this.isPostgres(ctx));\n\n const tasks: Array<{ name: string; handler: () => Promise<void> }> = [];\n\n if (needsDB) {\n if (postgres) {\n const hdName = ctx.naming.hyperdrive();\n const envVars = await this.envUtils.parseEnv(ctx.root, [\n `.env.${ctx.env}`,\n ]);\n const dbUrl = envVars.DATABASE_URL ?? process.env.DATABASE_URL!;\n tasks.push({\n name: `provision hyperdrive (${hdName})`,\n handler: async () => {\n this.provisionedHyperdriveId = await this.ensureHyperdrive(\n hdName,\n dbUrl,\n );\n },\n });\n } else {\n const dbName = ctx.naming.d1();\n tasks.push({\n name: `provision d1 (${dbName})`,\n handler: async () => {\n this.provisionedD1Id = await this.ensureD1(dbName);\n },\n });\n }\n }\n\n if (needsBucket) {\n const bucketName = ctx.naming.r2();\n tasks.push({\n name: `provision r2 (${bucketName})`,\n handler: async () => {\n await this.ensureR2(bucketName);\n },\n });\n }\n if (ctx.resources.hasKV) {\n const kvName = ctx.naming.kv();\n tasks.push({\n name: `provision kv (${kvName})`,\n handler: async () => {\n this.provisionedKVIds.set(kvName, await this.ensureKV(kvName));\n },\n });\n }\n\n if (ctx.resources.hasQueue) {\n const queueName = ctx.naming.queue();\n tasks.push({\n name: `provision queue (${queueName})`,\n handler: async () => {\n await this.ensureQueue(queueName);\n },\n });\n }\n\n await run(tasks);\n }\n\n // -------------------------------------------------------------------------\n // migrate (wrangler — D1 migration runner)\n // -------------------------------------------------------------------------\n\n override async migrate(\n ctx: PlatformContext,\n run: RunnerMethod,\n ): Promise<void> {\n this.configureApi(ctx);\n const needsDB = ctx.resources.hasDatabase;\n if (!needsDB) {\n return;\n }\n\n if (await this.isPostgres(ctx)) {\n await this.migratePostgres(ctx, run);\n } else {\n await this.migrateD1(ctx, run);\n }\n }\n\n override async exportDb(\n ctx: PlatformContext,\n run: RunnerMethod,\n options: ExportDbOptions = {},\n ): Promise<void> {\n this.configureApi(ctx);\n if (!ctx.resources.hasDatabase) {\n throw new AlephaError(\n \"No database detected for this app — nothing to export.\",\n );\n }\n if (await this.isPostgres(ctx)) {\n throw new AlephaError(\n \"Database export currently supports Cloudflare D1 only — Postgres/Hyperdrive export (pg_dump) is not implemented yet.\",\n );\n }\n\n const dbName = ctx.naming.d1();\n const tmpDir = this.fs.join(ctx.root, \"node_modules\", \".alepha\");\n const sqlPath = this.fs.join(tmpDir, `${dbName}.sql`);\n // D1 is SQLite — the natural local snapshot is the dev DB file that\n // `yarn dev` reads, so dev runs against a real remote snapshot.\n const dbPath = options.output ?? this.fs.join(tmpDir, \"sqlite.db\");\n\n await this.fs.mkdir(tmpDir, { recursive: true });\n\n await run(`wrangler d1 export ${dbName} --remote --output=${sqlPath}`, {\n alias: `export D1 ${dbName} → ${sqlPath}`,\n });\n\n // `sqlite3 '<db>' < dump.sql` aborts if the target already holds a\n // conflicting schema — start from a clean file. run() bypasses the\n // shell, so wrap the `<` redirection in `sh -c`.\n await this.fs.rm(dbPath, { force: true });\n await run(`sh -c \"sqlite3 '${dbPath}' < '${sqlPath}'\"`, {\n alias: `import dump → ${dbPath}`,\n });\n\n if (!options.keepSql) {\n await this.fs.rm(sqlPath, { force: true });\n }\n }\n\n protected async migrateD1(\n ctx: PlatformContext,\n run: RunnerMethod,\n ): Promise<void> {\n const dbName = ctx.naming.d1();\n\n await run({\n name: \"migrate d1\",\n handler: async () => {\n const migrationsDir = this.fs.join(ctx.root, \"migrations\", \"sqlite\");\n const dbUrl = this.provisionedD1Id\n ? `d1://${dbName}:${this.provisionedD1Id}`\n : `d1://${dbName}`;\n const env = { DATABASE_URL: dbUrl };\n\n // In prebuilt mode (Rocket) the tarball ships `migrations/`\n // straight from the build artifact — already checked + frozen\n // at pack time. Skip the live check/create cycle, which would\n // need to boot the user's app to introspect schema definitions\n // (impossible without the workspace's node_modules). For\n // non-prebuilt CLI deploys, still run the check (or create the\n // SQL when missing) so the deploy fails fast on a drifted\n // schema.\n if (!ctx.prebuilt) {\n if (await this.fs.exists(migrationsDir)) {\n await this.runShell(\n `alepha db migrations check --mode ${ctx.env}`,\n { resolve: true, env },\n );\n } else {\n await this.runShell(\n `alepha db migrations create --mode ${ctx.env}`,\n { resolve: true, env },\n );\n }\n }\n\n // Copy migrations to dist for wrangler, apply, then clean up\n const distMigrations = this.fs.join(ctx.root, \"dist\", \"migrations\");\n await this.fs.cp(migrationsDir, distMigrations);\n\n await this.wrangler.d1MigrationsApply(\n dbName,\n \"dist/wrangler.jsonc\",\n ctx.root,\n );\n\n await this.fs.rm(distMigrations, { recursive: true });\n },\n });\n }\n\n protected async migratePostgres(\n ctx: PlatformContext,\n run: RunnerMethod,\n ): Promise<void> {\n if (ctx.prebuilt) {\n // Postgres + Hyperdrive prebuilt deploys need a separate\n // migration story (an alepha-CLI-free `apply` against the\n // packed `migrations/postgres/` dir) — not implemented yet.\n // Rocket's v1 path is D1, which uses `wrangler d1 migrations\n // apply` and works fine in prebuilt mode.\n throw new AlephaError(\n \"Postgres migrations are not yet supported in prebuilt mode. Use the `alepha platform up` CLI for now.\",\n );\n }\n await run({\n name: \"migrate postgres\",\n handler: async () => {\n const envVars = await this.envUtils.parseEnv(ctx.root, [\n `.env.${ctx.env}`,\n ]);\n\n const env: Record<string, string> = {\n DATABASE_URL: envVars.DATABASE_URL ?? process.env.DATABASE_URL!,\n };\n\n if (envVars.POSTGRES_SCHEMA ?? process.env.POSTGRES_SCHEMA) {\n env.POSTGRES_SCHEMA = (envVars.POSTGRES_SCHEMA ??\n process.env.POSTGRES_SCHEMA)!;\n }\n\n await this.runShell(`alepha db migrations apply --mode ${ctx.env}`, {\n resolve: true,\n env,\n });\n },\n });\n }\n\n // -------------------------------------------------------------------------\n // inspect (REST API)\n // -------------------------------------------------------------------------\n\n async inspect(\n ctx: PlatformContext,\n run: RunnerMethod,\n ): Promise<PlatformState> {\n this.configureApi(ctx);\n const state: PlatformState = {\n workers: [],\n databases: [],\n buckets: [],\n kvNamespaces: [],\n queues: [],\n secrets: [],\n };\n\n const tasks: Array<{ name: string; handler: () => Promise<void> }> = [];\n\n // Workers\n {\n const name = ctx.naming.worker();\n\n tasks.push({\n name: `inspect worker (${name})`,\n handler: async () => {\n try {\n const deployment = await this.getActiveDeployment(name);\n if (deployment) {\n state.workers.push({\n name,\n exists: true,\n version: deployment.versionId,\n tag: deployment.tag,\n createdAt: deployment.createdAt,\n });\n } else {\n state.workers.push({ name, exists: false });\n }\n } catch {\n state.workers.push({ name, exists: false });\n }\n },\n });\n }\n\n // Database\n const needsDB = ctx.resources.hasDatabase;\n if (needsDB) {\n if (await this.isPostgres(ctx)) {\n const hdName = ctx.naming.hyperdrive();\n tasks.push({\n name: `inspect hyperdrive (${hdName})`,\n handler: async () => {\n const configs = await this.api.listHyperdrive();\n const existing = configs.find((c) => c.name === hdName);\n state.databases.push({\n name: hdName,\n exists: !!existing,\n id: existing?.id,\n detail: existing?.origin.host,\n });\n },\n });\n } else {\n const dbName = ctx.naming.d1();\n tasks.push({\n name: `inspect d1 (${dbName})`,\n handler: async () => {\n const databases = await this.api.listD1();\n const existing = databases.find((db) => db.name === dbName);\n state.databases.push({\n name: dbName,\n exists: !!existing,\n id: existing?.uuid,\n });\n },\n });\n }\n }\n\n // R2\n const needsBucket = ctx.resources.hasBucket;\n if (needsBucket) {\n const bucketName = ctx.naming.r2();\n tasks.push({\n name: `inspect r2 (${bucketName})`,\n handler: async () => {\n const buckets = await this.api.listR2();\n const existing = buckets.find((b) => b.name === bucketName);\n state.buckets.push({\n name: bucketName,\n exists: !!existing,\n id: existing?.creation_date,\n });\n },\n });\n }\n if (ctx.resources.hasKV) {\n const kvName = ctx.naming.kv();\n tasks.push({\n name: `inspect kv (${kvName})`,\n handler: async () => {\n const namespaces = await this.api.listKV();\n const existing = namespaces.find((ns) => ns.title === kvName);\n state.kvNamespaces.push({\n name: kvName,\n exists: !!existing,\n id: existing?.id,\n });\n },\n });\n }\n if (ctx.resources.hasQueue) {\n const queueName = ctx.naming.queue();\n tasks.push({\n name: `inspect queue (${queueName})`,\n handler: async () => {\n const queues = await this.api.listQueues();\n const existing = queues.find((q) => q.queue_name === queueName);\n state.queues.push({\n name: queueName,\n exists: !!existing,\n id: existing?.queue_id,\n });\n },\n });\n }\n\n // Secrets\n const envVars = await this.envUtils.parseEnv(ctx.root, [`.env.${ctx.env}`]);\n const expectedSecrets = Object.keys(envVars).filter(\n (key) =>\n envVars[key] &&\n !CloudflareAdapter.EXCLUDED_SECRET_KEYS.has(key) &&\n !key.startsWith(\"VITE_\"),\n );\n\n if (expectedSecrets.length > 0) {\n const workerName = ctx.naming.worker();\n tasks.push({\n name: \"inspect secrets\",\n handler: async () => {\n try {\n const deployed = await this.api.listSecrets(workerName);\n const deployedNames = new Set(deployed.map((s) => s.name));\n for (const key of expectedSecrets) {\n state.secrets.push({\n name: key,\n deployed: deployedNames.has(key),\n });\n }\n } catch {\n for (const key of expectedSecrets) {\n state.secrets.push({ name: key, deployed: false });\n }\n }\n },\n });\n }\n\n await run(tasks);\n\n return state;\n }\n\n // -------------------------------------------------------------------------\n // teardown (REST API)\n // -------------------------------------------------------------------------\n\n async teardown(ctx: PlatformContext, run: RunnerMethod): Promise<void> {\n this.configureApi(ctx);\n if (ctx.resources.hasQueue) {\n const workerName = ctx.naming.worker();\n const queueName = ctx.naming.queue();\n await run({\n name: `unbind queue consumer ${queueName}`,\n handler: async () => {\n try {\n const queues = await this.api.listQueues();\n const queue = queues.find((q) => q.queue_name === queueName);\n if (queue) {\n await this.api.deleteQueueConsumer(queue.queue_id, workerName);\n }\n } catch (error: any) {\n this.log.warn(\n `Failed to unbind queue consumer: ${String(error.message || \"\")}`,\n );\n }\n },\n });\n }\n\n // 2. Delete workers\n {\n const name = ctx.naming.worker();\n await run({\n name: `delete worker ${name}`,\n handler: async () => {\n try {\n await this.api.deleteWorker(name);\n } catch (error: any) {\n this.log.warn(\n `Failed to delete worker ${name}: ${String(error.message || \"\")}`,\n );\n }\n },\n });\n }\n if (ctx.resources.hasQueue) {\n const name = ctx.naming.queue();\n await run({\n name: `delete queue ${name}`,\n handler: async () => {\n try {\n const queues = await this.api.listQueues();\n const queue = queues.find((q) => q.queue_name === name);\n if (!queue) {\n this.log.debug(`Queue ${name} not found — skipping.`);\n return;\n }\n await this.api.deleteQueue(queue.queue_id);\n } catch (error: any) {\n this.log.warn(\n `Failed to delete queue ${name}: ${String(error.message || \"\")}`,\n );\n }\n },\n });\n }\n if (ctx.resources.hasKV) {\n const name = ctx.naming.kv();\n await run({\n name: `delete kv ${name}`,\n handler: async () => {\n try {\n const namespaces = await this.api.listKV();\n const existing = namespaces.find((ns) => ns.title === name);\n if (!existing) {\n this.log.debug(`KV namespace ${name} not found — skipping.`);\n return;\n }\n await this.api.deleteKV(existing.id);\n } catch (error: any) {\n this.log.warn(\n `Failed to delete kv ${name}: ${String(error.message || \"\")}`,\n );\n }\n },\n });\n }\n\n // 5. Delete R2 bucket. An empty bucket is removed by the REST DELETE\n // directly; only a non-empty one needs an S3 wipe first. Crucially the\n // wipe is NOT a precondition of the delete — a wipe that can't run (no\n // creds) must never strand an otherwise-deletable bucket.\n const needsBucket = ctx.resources.hasBucket;\n if (needsBucket) {\n const name = ctx.naming.r2();\n await run({\n name: `delete r2 ${name}`,\n handler: async () => {\n try {\n await this.deleteR2Bucket(name, ctx);\n } catch (error: any) {\n const msg = String(error.message || \"\");\n if (this.isMissingBucketError(msg)) {\n this.log.debug(`Bucket ${name} not found — skipping.`);\n } else {\n this.log.warn(`Failed to delete r2 ${name}: ${msg}`);\n }\n }\n },\n });\n }\n\n // 6. Delete D1 or Hyperdrive\n const needsDB = ctx.resources.hasDatabase;\n if (needsDB) {\n if (await this.isPostgres(ctx)) {\n const name = ctx.naming.hyperdrive();\n await run({\n name: `delete hyperdrive ${name}`,\n handler: async () => {\n try {\n const configs = await this.api.listHyperdrive();\n const existing = configs.find((c) => c.name === name);\n if (!existing) {\n this.log.debug(`Hyperdrive ${name} not found — skipping.`);\n return;\n }\n await this.api.deleteHyperdrive(existing.id);\n } catch (error: any) {\n this.log.warn(\n `Failed to delete hyperdrive ${name}: ${String(error.message || \"\")}`,\n );\n }\n },\n });\n } else {\n const name = ctx.naming.d1();\n await run({\n name: `delete d1 ${name}`,\n handler: async () => {\n try {\n const databases = await this.api.listD1();\n const existing = databases.find((db) => db.name === name);\n if (!existing) {\n this.log.debug(`D1 database ${name} not found — skipping.`);\n return;\n }\n await this.api.deleteD1(existing.uuid);\n } catch (error: any) {\n this.log.warn(\n `Failed to delete d1 ${name}: ${String(error.message || \"\")}`,\n );\n }\n },\n });\n }\n }\n }\n\n // -------------------------------------------------------------------------\n // Resource helpers (REST API)\n // -------------------------------------------------------------------------\n\n protected async ensureD1(name: string): Promise<string> {\n const databases = await this.api.listD1();\n const existing = databases.find((db) => db.name === name);\n if (existing) {\n return existing.uuid;\n }\n\n const created = await this.api.createD1(name);\n return created.uuid;\n }\n\n protected async ensureHyperdrive(\n name: string,\n connectionString: string,\n ): Promise<string> {\n const configs = await this.api.listHyperdrive();\n const existing = configs.find((c) => c.name === name);\n if (existing) {\n return existing.id;\n }\n\n const created = await this.api.createHyperdrive(name, connectionString);\n return created.id;\n }\n\n protected async ensureR2(name: string): Promise<void> {\n const buckets = await this.api.listR2();\n const existing = buckets.find((b) => b.name === name);\n if (existing) {\n return;\n }\n\n await this.api.createR2(name);\n }\n\n /** Whether a Cloudflare error message indicates the bucket is already gone. */\n protected isMissingBucketError(msg: string): boolean {\n return (\n msg.includes(\"does not exist\") ||\n msg.includes(\"NoSuchBucket\") ||\n msg.includes(\"bucket not found\")\n );\n }\n\n /**\n * Resolve S3 credentials for wiping an R2 bucket over the S3 protocol.\n *\n * Prefers the account's R2 S3 credentials from the environment\n * (`S3_ACCESS_KEY_ID` / `S3_SECRET_ACCESS_KEY`) — these are already\n * provisioned for the deploy (artifact registry) and are account-scoped,\n * so they can empty any bucket without minting anything. Returns `null`\n * when not configured, letting the caller fall back to token minting.\n */\n protected resolveR2Credentials(): {\n accessKeyId: string;\n secretAccessKey: string;\n } | null {\n const accessKeyId = process.env.S3_ACCESS_KEY_ID;\n const secretAccessKey = process.env.S3_SECRET_ACCESS_KEY;\n if (accessKeyId && secretAccessKey) {\n return { accessKeyId, secretAccessKey };\n }\n return null;\n }\n\n /**\n * Delete an R2 bucket, emptying it first only when necessary.\n *\n * Cloudflare's REST `DELETE /r2/buckets/:name` succeeds on an empty bucket\n * but rejects a non-empty one. So we attempt the delete directly (the\n * common teardown case — no objects, no creds needed), and only on failure\n * empty the bucket over the S3 protocol and retry. A missing bucket is a\n * no-op, so teardown is idempotent.\n */\n protected async deleteR2Bucket(\n name: string,\n ctx: PlatformContext,\n ): Promise<void> {\n try {\n await this.api.deleteR2(name);\n return;\n } catch (error: any) {\n const msg = String(error.message || \"\");\n if (this.isMissingBucketError(msg)) {\n return; // already gone\n }\n // Most often the bucket is non-empty — empty it then retry once.\n this.log.debug(\n `Direct delete of r2 ${name} failed (${msg}); emptying then retrying.`,\n );\n }\n\n await this.wipeR2Bucket(name, ctx);\n\n try {\n await this.api.deleteR2(name);\n } catch (error: any) {\n const msg = String(error.message || \"\");\n if (this.isMissingBucketError(msg)) {\n return;\n }\n throw error;\n }\n }\n\n /**\n * Empty an R2 bucket via the S3-compatible API.\n *\n * Cloudflare's REST API has no object-level endpoints — objects must be\n * listed and deleted over the S3 protocol. We use the account's R2 S3\n * credentials (`S3_ACCESS_KEY_ID` / `S3_SECRET_ACCESS_KEY`) when present;\n * otherwise we fall back to minting a short-lived bucket-scoped token via\n * the CF API (requires a user-scoped `CLOUDFLARE_API_TOKEN`) and revoke it\n * after. When neither is available the wipe is skipped with a warning —\n * the caller still attempts the delete, which succeeds for empty buckets.\n *\n * Also aborts any pending multipart uploads — those count as bucket\n * contents from R2's perspective and would otherwise block the delete.\n */\n protected async wipeR2Bucket(\n bucketName: string,\n ctx: PlatformContext,\n ): Promise<void> {\n let creds = this.resolveR2Credentials();\n let mintedTokenId: string | undefined;\n\n if (!creds) {\n // No env S3 creds — try minting a bucket-scoped token. This needs a\n // user-scoped `CLOUDFLARE_API_TOKEN`; an account-scoped one (or the\n // wrangler OAuth bearer) can't mint, so we skip rather than throw and\n // let the caller's delete attempt proceed (fine for empty buckets).\n if (!process.env.CLOUDFLARE_API_TOKEN) {\n this.log.warn(\n `Skipping R2 wipe for ${bucketName}: no S3 credentials ` +\n `(S3_ACCESS_KEY_ID / S3_SECRET_ACCESS_KEY) and no ` +\n `CLOUDFLARE_API_TOKEN to mint a bucket-scoped token. A non-empty ` +\n `bucket must be emptied manually in the Cloudflare dashboard.`,\n );\n return;\n }\n try {\n const tokenName = `alepha-teardown-${bucketName}-${Date.now()}`;\n const token = await this.api.createR2Token(tokenName, bucketName);\n mintedTokenId = token.id;\n creds = {\n accessKeyId: token.accessKeyId,\n secretAccessKey: token.secretAccessKey,\n };\n } catch (error: any) {\n this.log.warn(\n `Skipping R2 wipe for ${bucketName}: could not mint an R2 token ` +\n `(${String(error.message || \"\")}). Set S3_ACCESS_KEY_ID / ` +\n `S3_SECRET_ACCESS_KEY for reliable teardown.`,\n );\n return;\n }\n }\n\n try {\n const accountId = await this.api.resolveAccountId();\n const jur = ctx.envConfig.jurisdiction;\n const host = jur\n ? `${accountId}.${jur}.r2.cloudflarestorage.com`\n : `${accountId}.r2.cloudflarestorage.com`;\n\n const client = new S3mini({\n accessKeyId: creds.accessKeyId,\n secretAccessKey: creds.secretAccessKey,\n region: \"auto\",\n endpoint: `https://${host}/${bucketName}`,\n });\n\n // Abort pending multipart uploads. R2 surfaces these as bucket contents\n // and they block deletion even after all completed objects are gone.\n try {\n const mp = await client.listMultipartUploads();\n if (\"listMultipartUploadsResult\" in mp) {\n const uploads = mp.listMultipartUploadsResult.uploads ?? [];\n for (const upload of uploads) {\n const u = upload as unknown as {\n Key?: string;\n key?: string;\n UploadId?: string;\n uploadId?: string;\n };\n const key = u.Key ?? u.key;\n const uploadId = u.UploadId ?? u.uploadId;\n if (key && uploadId) {\n await client.abortMultipartUpload(key, uploadId);\n }\n }\n }\n } catch (error: any) {\n this.log.debug(\n `listMultipartUploads on ${bucketName} failed: ${String(error.message || \"\")}`,\n );\n }\n\n // Page through objects and delete in batches of up to 1000 (S3 cap).\n let cursor: string | undefined;\n let total = 0;\n while (true) {\n const page = await client.listObjectsPaged(\n undefined,\n undefined,\n 1000,\n cursor,\n );\n const objects = page?.objects ?? [];\n if (objects.length === 0) {\n break;\n }\n await client.deleteObjects(objects.map((o) => o.Key));\n total += objects.length;\n cursor = page?.nextContinuationToken;\n if (!cursor) {\n break;\n }\n }\n\n if (total > 0) {\n this.log.info(`Emptied ${total} object(s) from bucket ${bucketName}.`);\n }\n } finally {\n // Revoke only a token we minted here — env S3 creds are long-lived and\n // must not be deleted. Always revoke, even if the wipe failed mid-way.\n if (mintedTokenId) {\n try {\n await this.api.deleteR2Token(mintedTokenId);\n } catch (error: any) {\n this.log.warn(\n `Failed to revoke ephemeral R2 token ${mintedTokenId}: ${String(error.message || \"\")}`,\n );\n }\n }\n }\n }\n\n protected async ensureKV(name: string): Promise<string> {\n const namespaces = await this.api.listKV();\n const existing = namespaces.find((ns) => ns.title === name);\n if (existing) {\n return existing.id;\n }\n\n const created = await this.api.createKV(name);\n return created.id;\n }\n\n protected async ensureQueue(name: string): Promise<void> {\n const queues = await this.api.listQueues();\n const existing = queues.find((q) => q.queue_name === name);\n if (existing) {\n return;\n }\n\n await this.api.createQueue(name);\n }\n\n /**\n * Get the currently active deployment for a worker.\n */\n protected async getActiveDeployment(\n workerName: string,\n ): Promise<\n { versionId: string; tag?: string; createdAt?: string } | undefined\n > {\n const deployments = await this.api.listDeployments(workerName);\n\n // API ordering is not guaranteed across releases — sort explicitly.\n const sorted = [...deployments].sort((a, b) =>\n b.created_on.localeCompare(a.created_on),\n );\n const latest = sorted[0];\n if (!latest?.versions?.[0]) {\n return undefined;\n }\n\n const activeVersionId = latest.versions[0].version_id;\n\n const versions = await this.api.listVersions(workerName);\n const version = versions.find((v) => v.id === activeVersionId);\n\n return {\n versionId: activeVersionId,\n tag: version?.annotations?.[\"workers/tag\"],\n createdAt: version?.metadata.created_on,\n };\n }\n}\n\n/**\n * Stable SHA-256 of the secret set. Keys are sorted so reordering `.env`\n * lines does not invalidate the cache. Used as a fingerprint by\n * `CloudflareAdapter.secrets` — see the comment block there.\n */\nfunction computeSecretsHash(secrets: Record<string, string>): string {\n const sorted = Object.keys(secrets)\n .sort()\n .map((k) => `${k}=${secrets[k]}`)\n .join(\"\\n\");\n return createHash(\"sha256\").update(sorted).digest(\"hex\");\n}\n","import type { Static } from \"alepha\";\nimport { t } from \"alepha\";\n\n// ---------------------------------------------------------------------------\n// Project\n// ---------------------------------------------------------------------------\n\nexport const vercelProjectSchema = t.object({\n id: t.string(),\n name: t.string(),\n accountId: t.string(),\n});\n\nexport type VercelProject = Static<typeof vercelProjectSchema>;\n\nexport const createProjectBodySchema = t.object({\n name: t.string(),\n framework: t.optional(t.null()),\n});\n\n// ---------------------------------------------------------------------------\n// Deployment\n// ---------------------------------------------------------------------------\n\nexport const vercelDeploymentSchema = t.object({\n uid: t.string(),\n name: t.string(),\n url: t.string(),\n state: t.optional(t.string()),\n readyState: t.optional(t.string()),\n created: t.optional(t.number()),\n target: t.optional(t.string()),\n alias: t.optional(t.array(t.string())),\n});\n\nexport type VercelDeployment = Static<typeof vercelDeploymentSchema>;\n\n// ---------------------------------------------------------------------------\n// Environment Variable\n// ---------------------------------------------------------------------------\n\nexport const vercelEnvVarSchema = t.object({\n id: t.string(),\n key: t.string(),\n value: t.optional(t.string()),\n type: t.string(),\n target: t.array(t.string()),\n});\n\nexport type VercelEnvVar = Static<typeof vercelEnvVarSchema>;\n\nexport const createEnvVarBodySchema = t.object({\n key: t.string(),\n value: t.string(),\n type: t.string(),\n target: t.array(t.string()),\n});\n","import { homedir, platform } from \"node:os\";\nimport { join } from \"node:path\";\nimport { $inject, AlephaError } from \"alepha\";\nimport { AlephaCliUtils, PackageManagerUtils } from \"alepha/cli\";\nimport { Runner, type RunnerMethod } from \"alepha/command\";\nimport { $logger } from \"alepha/logger\";\nimport { FileSystemProvider, ShellProvider } from \"alepha/system\";\n\n/**\n * Wraps Vercel CLI commands and token management.\n *\n * Used for operations where the Vercel CLI provides value:\n * OAuth login, prebuilt deploy, and auth token extraction.\n */\nexport class VercelCli {\n protected readonly log = $logger();\n protected readonly shell = $inject(ShellProvider);\n protected readonly fs = $inject(FileSystemProvider);\n protected readonly utils = $inject(AlephaCliUtils);\n protected readonly pm = $inject(PackageManagerUtils);\n protected readonly runner = $inject(Runner);\n\n protected async runShell(\n command: string,\n options: Parameters<ShellProvider[\"run\"]>[1] = {},\n ) {\n const capture = options.capture;\n const output = await this.shell.run(command, {\n ...options,\n capture: capture ?? this.runner.useDynamicLogger,\n });\n\n if (capture && !this.runner.useDynamicLogger) {\n this.log.info(output);\n }\n\n return output;\n }\n\n // -------------------------------------------------------------------------\n // Install\n // -------------------------------------------------------------------------\n\n /**\n * Ensure vercel CLI is installed in the project.\n */\n public async ensureInstalled(root: string, run: RunnerMethod): Promise<void> {\n await this.pm.ensureDependency(root, \"vercel\", {\n dev: true,\n exec: async (cmd, opts) => {\n run.pause();\n try {\n await this.utils.exec(cmd, opts);\n } finally {\n run.resume();\n }\n },\n });\n }\n\n // -------------------------------------------------------------------------\n // Auth\n // -------------------------------------------------------------------------\n\n /**\n * Get the Vercel auth token.\n *\n * Priority:\n * 1. VERCEL_TOKEN environment variable (CI/CD)\n * 2. Vercel CLI auth.json file (local dev)\n */\n public async getAuthToken(): Promise<string> {\n const envToken = process.env.VERCEL_TOKEN;\n if (envToken) {\n return envToken;\n }\n\n const authPath = this.getAuthFilePath();\n if (!(await this.fs.exists(authPath))) {\n throw new AlephaError(\n \"Vercel auth token not found. Run `vercel login` or set VERCEL_TOKEN.\",\n );\n }\n\n const content = await this.fs.readFile(authPath);\n const parsed = JSON.parse(content.toString()) as { token?: string };\n\n if (!parsed.token) {\n throw new AlephaError(\n \"Vercel auth.json exists but contains no token. Run `vercel login`.\",\n );\n }\n\n return parsed.token;\n }\n\n /**\n * Validate the current auth token.\n */\n public async whoami(): Promise<string> {\n return await this.runShell(\"vercel whoami\", {\n resolve: true,\n capture: true,\n });\n }\n\n /**\n * Open the browser-based login flow.\n */\n public async login(): Promise<void> {\n await this.runShell(\"vercel login\", { resolve: true });\n }\n\n // -------------------------------------------------------------------------\n // Deploy\n // -------------------------------------------------------------------------\n\n /**\n * Deploy a prebuilt .vercel/output/ directory.\n *\n * Returns the deployment URL.\n */\n public async deploy(\n distDir: string,\n options: { prod?: boolean; token?: string },\n ): Promise<string | undefined> {\n const args = [\"vercel\", \"deploy\", \"--prebuilt\"];\n\n if (options.prod) {\n args.push(\"--prod\");\n }\n\n if (options.token) {\n args.push(`--token=${options.token}`);\n }\n\n const output = await this.runShell(args.join(\" \"), {\n resolve: true,\n capture: true,\n root: distDir,\n });\n\n // Vercel CLI outputs the deployment URL on the last non-empty line\n const lines = output.trim().split(\"\\n\");\n const url = lines\n .reverse()\n .find((line) => line.trim().startsWith(\"https://\"));\n return url?.trim();\n }\n\n // -------------------------------------------------------------------------\n // Helpers\n // -------------------------------------------------------------------------\n\n /**\n * Resolve the path to Vercel CLI auth.json.\n */\n protected getAuthFilePath(): string {\n const os = platform();\n\n if (os === \"darwin\") {\n return join(\n homedir(),\n \"Library\",\n \"Application Support\",\n \"com.vercel.cli\",\n \"auth.json\",\n );\n }\n\n if (os === \"win32\") {\n return join(\n homedir(),\n \"AppData\",\n \"Roaming\",\n \"xdg.data\",\n \"com.vercel.cli\",\n \"auth.json\",\n );\n }\n\n // Linux / other\n return join(homedir(), \".local\", \"share\", \"com.vercel.cli\", \"auth.json\");\n }\n}\n","import { $inject, Alepha, AlephaError, type TSchema, t } from \"alepha\";\nimport { $logger } from \"alepha/logger\";\nimport type {\n VercelDeployment,\n VercelEnvVar,\n VercelProject,\n} from \"../schemas/vercel.ts\";\nimport {\n createEnvVarBodySchema,\n createProjectBodySchema,\n vercelDeploymentSchema,\n vercelEnvVarSchema,\n vercelProjectSchema,\n} from \"../schemas/vercel.ts\";\nimport { VercelCli } from \"./VercelCli.ts\";\n\n/**\n * Thin wrapper over the Vercel REST API.\n *\n * Uses the auth token from VercelCli for all requests.\n */\nexport class VercelApi {\n protected static readonly BASE = \"https://api.vercel.com\";\n\n protected readonly log = $logger();\n protected readonly alepha = $inject(Alepha);\n protected readonly vercelCli = $inject(VercelCli);\n\n protected token?: string;\n\n // -------------------------------------------------------------------------\n // Auth\n // -------------------------------------------------------------------------\n\n /**\n * Obtain the current auth token from the Vercel CLI.\n */\n public async resolveToken(): Promise<string> {\n if (this.token) {\n return this.token;\n }\n\n this.token = await this.vercelCli.getAuthToken();\n return this.token;\n }\n\n // -------------------------------------------------------------------------\n // Projects\n // -------------------------------------------------------------------------\n\n public async listProjects(): Promise<VercelProject[]> {\n const res = await this.fetch<{ projects: VercelProject[] }>(\n \"/v10/projects\",\n { schema: t.object({ projects: t.array(vercelProjectSchema) }) },\n );\n return res.projects;\n }\n\n public async getProject(\n nameOrId: string,\n ): Promise<VercelProject | undefined> {\n try {\n return await this.fetch<VercelProject>(\n `/v9/projects/${encodeURIComponent(nameOrId)}`,\n { schema: vercelProjectSchema },\n );\n } catch {\n return undefined;\n }\n }\n\n public async createProject(name: string): Promise<VercelProject> {\n return await this.fetch<VercelProject>(\"/v11/projects\", {\n method: \"POST\",\n body: { name, framework: null },\n bodySchema: createProjectBodySchema,\n schema: vercelProjectSchema,\n });\n }\n\n public async updateProject(\n nameOrId: string,\n settings: { framework?: null },\n ): Promise<void> {\n await this.fetch(`/v9/projects/${encodeURIComponent(nameOrId)}`, {\n method: \"PATCH\",\n body: settings,\n });\n }\n\n public async deleteProject(nameOrId: string): Promise<void> {\n await this.fetch(`/v9/projects/${encodeURIComponent(nameOrId)}`, {\n method: \"DELETE\",\n });\n }\n\n // -------------------------------------------------------------------------\n // Deployments\n // -------------------------------------------------------------------------\n\n public async listDeployments(\n projectId: string,\n options?: { limit?: number; target?: string },\n ): Promise<VercelDeployment[]> {\n const query: Record<string, string> = { projectId };\n if (options?.limit) {\n query.limit = String(options.limit);\n }\n if (options?.target) {\n query.target = options.target;\n }\n\n const res = await this.fetch<{ deployments: VercelDeployment[] }>(\n \"/v6/deployments\",\n {\n query,\n schema: t.object({ deployments: t.array(vercelDeploymentSchema) }),\n },\n );\n return res.deployments;\n }\n\n // -------------------------------------------------------------------------\n // Environment Variables\n // -------------------------------------------------------------------------\n\n public async listEnvVars(projectId: string): Promise<VercelEnvVar[]> {\n const res = await this.fetch<{ envs: VercelEnvVar[] }>(\n `/v10/projects/${encodeURIComponent(projectId)}/env`,\n {\n query: { decrypt: \"true\" },\n schema: t.object({ envs: t.array(vercelEnvVarSchema) }),\n },\n );\n return res.envs;\n }\n\n public async upsertEnvVars(\n projectId: string,\n vars: Array<{\n key: string;\n value: string;\n target: string[];\n }>,\n ): Promise<void> {\n for (const v of vars) {\n await this.fetch(`/v10/projects/${encodeURIComponent(projectId)}/env`, {\n method: \"POST\",\n query: { upsert: \"true\" },\n body: {\n key: v.key,\n value: v.value,\n type: \"encrypted\",\n target: v.target,\n },\n bodySchema: createEnvVarBodySchema,\n });\n }\n }\n\n public async deleteEnvVar(\n projectId: string,\n envVarId: string,\n ): Promise<void> {\n await this.fetch(\n `/v9/projects/${encodeURIComponent(projectId)}/env/${envVarId}`,\n { method: \"DELETE\" },\n );\n }\n\n // -------------------------------------------------------------------------\n // Core fetch\n // -------------------------------------------------------------------------\n\n protected async fetch<T = unknown>(\n path: string,\n options: {\n method?: string;\n body?: unknown;\n bodySchema?: TSchema;\n schema?: TSchema;\n query?: Record<string, string>;\n } = {},\n ): Promise<T> {\n const token = await this.resolveToken();\n const { method = \"GET\", body, query } = options;\n\n let url = `${VercelApi.BASE}${path}`;\n if (query) {\n const params = new URLSearchParams(query);\n url += `?${params.toString()}`;\n }\n\n const headers: Record<string, string> = {\n Authorization: `Bearer ${token}`,\n };\n\n const init: RequestInit = { method, headers };\n\n if (body) {\n headers[\"Content-Type\"] = \"application/json\";\n const validated = options.bodySchema\n ? this.alepha.codec.validate(options.bodySchema, body)\n : body;\n init.body = JSON.stringify(validated);\n }\n\n const response = await globalThis.fetch(url, init);\n\n // DELETE returns 204 with no body\n if (response.status === 204) {\n return undefined as T;\n }\n\n const json = await response.json();\n\n // Vercel error format: { error: { message, code } }\n if (json.error) {\n throw new AlephaError(\n `Vercel API error (${method} ${path}): ${json.error.message ?? JSON.stringify(json.error)}`,\n );\n }\n\n if (!response.ok) {\n throw new AlephaError(\n `Vercel API error (${method} ${path}): HTTP ${response.status}`,\n );\n }\n\n if (options.schema) {\n return this.alepha.codec.validate(options.schema, json) as T;\n }\n\n return json as T;\n }\n}\n","import { $inject, Alepha } from \"alepha\";\nimport { AlephaCliUtils } from \"alepha/cli\";\nimport { EnvUtils, Runner, type RunnerMethod } from \"alepha/command\";\nimport { $logger } from \"alepha/logger\";\nimport { FileSystemProvider, ShellProvider } from \"alepha/system\";\nimport { PlatformCacheProvider } from \"../providers/PlatformCacheProvider.ts\";\nimport { VercelApi } from \"../services/VercelApi.ts\";\nimport { VercelCli } from \"../services/VercelCli.ts\";\nimport {\n type AppContext,\n PlatformAdapter,\n type PlatformContext,\n type PlatformState,\n} from \"./PlatformAdapter.ts\";\n\n/**\n * Vercel platform adapter.\n *\n * Uses the Vercel CLI for login and deploy (--prebuilt),\n * and the Vercel REST API for project management, env vars, and inspection.\n *\n * v1 scope: deploy pipeline only. No DB/storage/KV provisioning.\n */\nexport class VercelAdapter extends PlatformAdapter {\n protected readonly log = $logger();\n protected readonly fs = $inject(FileSystemProvider);\n protected readonly shell = $inject(ShellProvider);\n protected readonly utils = $inject(AlephaCliUtils);\n protected readonly cache = $inject(PlatformCacheProvider);\n protected readonly alepha = $inject(Alepha);\n protected readonly envUtils = $inject(EnvUtils);\n protected readonly api = $inject(VercelApi);\n protected readonly vercelCli = $inject(VercelCli);\n protected readonly runner = $inject(Runner);\n\n /**\n * Vars that should not be pushed as env vars.\n * These are either handled by the build or are internal.\n */\n static readonly EXCLUDED_SECRET_KEYS = new Set([\"NODE_ENV\"]);\n\n protected async runShell(\n command: string,\n options: Parameters<ShellProvider[\"run\"]>[1] = {},\n ) {\n const capture = options.capture;\n const output = await this.shell.run(command, {\n ...options,\n capture: capture ?? this.runner.useDynamicLogger,\n });\n\n if (capture && !this.runner.useDynamicLogger) {\n this.log.info(output);\n }\n\n return output;\n }\n\n // -------------------------------------------------------------------------\n // authenticate\n // -------------------------------------------------------------------------\n\n async authenticate(ctx: PlatformContext, run: RunnerMethod): Promise<void> {\n await run({\n name: \"authenticate\",\n handler: async () => {\n await this.vercelCli.ensureInstalled(ctx.root, run);\n\n let needsLogin = false;\n\n try {\n await this.vercelCli.getAuthToken();\n await this.vercelCli.whoami();\n } catch {\n needsLogin = true;\n }\n\n if (needsLogin) {\n run.pause();\n await this.vercelCli.login();\n run.resume();\n }\n\n if (await this.cache.isLoginFresh(ctx.root, \"vercel\")) {\n return;\n }\n\n await this.cache.recordLogin(ctx.root, \"vercel\");\n },\n });\n }\n\n // -------------------------------------------------------------------------\n // build\n // -------------------------------------------------------------------------\n\n async build(ctx: AppContext, run: RunnerMethod): Promise<void> {\n const appDir = ctx.root;\n\n await run({\n name: \"alepha build -t vercel\",\n handler: async () => {\n await this.runShell(\"alepha build -t vercel\", {\n root: appDir,\n });\n },\n });\n }\n\n // -------------------------------------------------------------------------\n // deploy\n // -------------------------------------------------------------------------\n\n async deploy(\n ctx: AppContext,\n run: RunnerMethod,\n ): Promise<string | undefined> {\n const distDir = this.fs.join(ctx.root, \"dist\");\n\n const projectName = ctx.naming.worker();\n\n let url: string | undefined;\n\n await run({\n name: `deploy ${ctx.project}`,\n handler: async () => {\n // Ensure project exists and has framework: null for prebuilt deploys\n let project = await this.api.getProject(projectName);\n if (!project) {\n project = await this.api.createProject(projectName);\n }\n await this.api.updateProject(projectName, { framework: null });\n\n // Write project.json so vercel CLI knows which project to deploy to\n const vercelDir = this.fs.join(distDir, \".vercel\");\n await this.fs.mkdir(vercelDir);\n await this.fs.writeFile(\n this.fs.join(vercelDir, \"project.json\"),\n JSON.stringify(\n {\n projectId: project.id,\n orgId: project.accountId,\n },\n null,\n 2,\n ),\n );\n\n // Use env token for deploy if available (CI)\n const token = process.env.VERCEL_TOKEN;\n\n await this.vercelCli.deploy(distDir, {\n prod: true,\n token,\n });\n\n // Resolve production URL from latest deployment alias\n const deployments = await this.api.listDeployments(project.id, {\n limit: 1,\n target: \"production\",\n });\n const latest = deployments[0];\n url = latest?.alias?.[0]\n ? `https://${latest.alias[0]}`\n : `https://${projectName}.vercel.app`;\n },\n });\n\n return url;\n }\n\n // -------------------------------------------------------------------------\n // secrets\n // -------------------------------------------------------------------------\n\n override async secrets(\n ctx: PlatformContext,\n run: RunnerMethod,\n ): Promise<void> {\n const envVars = await this.envUtils.parseEnv(ctx.root, [`.env.${ctx.env}`]);\n\n const vars: Array<{ key: string; value: string; target: string[] }> = [];\n for (const [key, value] of Object.entries(envVars)) {\n if (!value) continue;\n if (VercelAdapter.EXCLUDED_SECRET_KEYS.has(key)) continue;\n if (key.startsWith(\"VITE_\")) continue;\n vars.push({\n key,\n value,\n target: [\"production\", \"preview\"],\n });\n }\n\n if (vars.length === 0) {\n return;\n }\n\n {\n const projectName = ctx.naming.worker();\n\n await run({\n name: `push env vars to ${projectName}`,\n handler: async () => {\n await this.api.upsertEnvVars(projectName, vars);\n },\n });\n }\n }\n\n // -------------------------------------------------------------------------\n // inspect\n // -------------------------------------------------------------------------\n\n async inspect(\n ctx: PlatformContext,\n run: RunnerMethod,\n ): Promise<PlatformState> {\n const state: PlatformState = {\n workers: [],\n databases: [],\n buckets: [],\n kvNamespaces: [],\n queues: [],\n secrets: [],\n };\n\n const tasks: Array<{ name: string; handler: () => Promise<void> }> = [];\n\n // Projects/deployments (mapped to \"workers\" in PlatformState)\n {\n const projectName = ctx.naming.worker();\n\n tasks.push({\n name: `inspect project (${projectName})`,\n handler: async () => {\n const project = await this.api.getProject(projectName);\n if (!project) {\n state.workers.push({ name: projectName, exists: false });\n return;\n }\n\n const deployments = await this.api.listDeployments(project.id, {\n limit: 1,\n });\n const latest = deployments[0];\n\n state.workers.push({\n name: projectName,\n exists: true,\n version: latest?.uid,\n createdAt: latest?.created\n ? new Date(latest.created).toISOString()\n : undefined,\n });\n },\n });\n }\n\n // Env vars (mapped to \"secrets\")\n const envVars = await this.envUtils.parseEnv(ctx.root, [`.env.${ctx.env}`]);\n const expectedVars = Object.keys(envVars).filter(\n (key) =>\n envVars[key] &&\n !VercelAdapter.EXCLUDED_SECRET_KEYS.has(key) &&\n !key.startsWith(\"VITE_\"),\n );\n\n if (expectedVars.length > 0) {\n const projectName = ctx.naming.worker();\n\n tasks.push({\n name: \"inspect env vars\",\n handler: async () => {\n try {\n const deployed = await this.api.listEnvVars(projectName);\n const deployedKeys = new Set(deployed.map((v) => v.key));\n for (const key of expectedVars) {\n state.secrets.push({\n name: key,\n deployed: deployedKeys.has(key),\n });\n }\n } catch {\n for (const key of expectedVars) {\n state.secrets.push({ name: key, deployed: false });\n }\n }\n },\n });\n }\n\n await run(tasks);\n\n return state;\n }\n\n // -------------------------------------------------------------------------\n // teardown\n // -------------------------------------------------------------------------\n\n async teardown(ctx: PlatformContext, run: RunnerMethod): Promise<void> {\n {\n const projectName = ctx.naming.worker();\n\n await run({\n name: `delete project ${projectName}`,\n handler: async () => {\n try {\n await this.api.deleteProject(projectName);\n } catch (error: any) {\n this.log.warn(\n `Failed to delete project ${projectName}: ${String(error.message || \"\")}`,\n );\n }\n },\n });\n }\n }\n}\n","import { $inject, AlephaError } from \"alepha\";\nimport { $logger } from \"alepha/logger\";\nimport { FileSystemProvider, ShellProvider } from \"alepha/system\";\nimport type {\n RemoteSecret,\n SecretStoreProvider,\n} from \"./SecretStoreProvider.ts\";\n\n/**\n * GitHub Actions secret store backed by the `gh` CLI.\n *\n * Requires the GitHub CLI (`gh`) to be installed and authenticated.\n * Pushes secrets into GitHub Actions environments.\n */\nexport class GitHubSecretStore implements SecretStoreProvider {\n protected readonly log = $logger();\n protected readonly shell = $inject(ShellProvider);\n protected readonly fs = $inject(FileSystemProvider);\n\n /**\n * Verify that `gh` is installed and authenticated.\n */\n public async ensureAvailable(): Promise<void> {\n const installed = await this.shell.isInstalled(\"gh\");\n if (!installed) {\n throw new AlephaError(\n \"GitHub CLI (gh) is not installed. Install it from https://cli.github.com\",\n );\n }\n\n try {\n await this.shell.run(\"gh auth status\", { capture: true });\n } catch {\n throw new AlephaError(\n \"GitHub CLI is not authenticated. Run `gh auth login` first.\",\n );\n }\n }\n\n /**\n * Create the GitHub Actions environment if it doesn't exist.\n */\n public async ensureEnvironment(environment: string): Promise<void> {\n await this.shell.run(\n `gh api --method PUT /repos/{owner}/{repo}/environments/${environment} --silent`,\n { capture: true },\n );\n this.log.debug(`Ensured environment \"${environment}\" exists`);\n }\n\n /**\n * List all secrets in a GitHub Actions environment.\n */\n public async list(environment: string): Promise<RemoteSecret[]> {\n try {\n const output = await this.shell.run(\n `gh secret list --env ${environment} --json name,updatedAt`,\n { capture: true },\n );\n\n const parsed = JSON.parse(output || \"[]\") as Array<{\n name: string;\n updatedAt?: string;\n }>;\n\n return parsed.map((s) => ({\n name: s.name,\n updatedAt: s.updatedAt,\n }));\n } catch (error) {\n this.log.debug(\"Failed to list secrets\", { environment, error });\n return [];\n }\n }\n\n /**\n * Set a secret in a GitHub Actions environment.\n *\n * Writes a dotenv-formatted file and uses `gh secret set --env-file` to\n * avoid shell pipe issues with NodeShellProvider escaping the `|` character.\n */\n public async set(\n environment: string,\n key: string,\n value: string,\n ): Promise<void> {\n const tmpFile = `/tmp/alepha-secret-${key}-${Date.now()}`;\n const escaped = value\n .replace(/\\\\/g, \"\\\\\\\\\")\n .replace(/\"/g, '\\\\\"')\n .replace(/\\n/g, \"\\\\n\");\n await this.fs.writeFile(tmpFile, `${key}=\"${escaped}\"\\n`);\n try {\n const output = await this.shell.run(\n `gh secret set -f ${tmpFile} --env ${environment}`,\n { capture: true },\n );\n this.log.debug(`Secret set: ${key}`, { output });\n } finally {\n await this.fs.rm(tmpFile);\n }\n }\n\n /**\n * Delete a secret from a GitHub Actions environment.\n */\n public async delete(environment: string, key: string): Promise<void> {\n await this.shell.run(`gh secret delete ${key} --env ${environment}`, {\n capture: true,\n });\n }\n}\n","import { AlephaError } from \"alepha\";\nimport type {\n RemoteSecret,\n SecretStoreProvider,\n} from \"./SecretStoreProvider.ts\";\n\nexport interface MemorySecretStoreCall {\n method: \"ensureAvailable\" | \"ensureEnvironment\" | \"list\" | \"set\" | \"delete\";\n environment?: string;\n key?: string;\n value?: string;\n}\n\n/**\n * In-memory implementation of SecretStoreProvider for testing.\n * Records all operations and stores secrets in a nested Map.\n */\nexport class MemorySecretStore implements SecretStoreProvider {\n /**\n * Secrets keyed by environment, then by key.\n */\n public secrets = new Map<string, Map<string, string>>();\n\n /**\n * All recorded operations.\n */\n public calls: MemorySecretStoreCall[] = [];\n\n /**\n * When set, ensureAvailable() will throw with this message.\n */\n public availableError: string | null = null;\n\n public async ensureAvailable(): Promise<void> {\n this.calls.push({ method: \"ensureAvailable\" });\n if (this.availableError) {\n throw new AlephaError(this.availableError);\n }\n }\n\n public async ensureEnvironment(environment: string): Promise<void> {\n this.calls.push({ method: \"ensureEnvironment\", environment });\n if (!this.secrets.has(environment)) {\n this.secrets.set(environment, new Map());\n }\n }\n\n public async list(environment: string): Promise<RemoteSecret[]> {\n this.calls.push({ method: \"list\", environment });\n const envSecrets = this.secrets.get(environment);\n if (!envSecrets) return [];\n\n return Array.from(envSecrets.keys()).map((name) => ({ name }));\n }\n\n public async set(\n environment: string,\n key: string,\n value: string,\n ): Promise<void> {\n this.calls.push({ method: \"set\", environment, key, value });\n\n let envSecrets = this.secrets.get(environment);\n if (!envSecrets) {\n envSecrets = new Map();\n this.secrets.set(environment, envSecrets);\n }\n envSecrets.set(key, value);\n }\n\n public async delete(environment: string, key: string): Promise<void> {\n this.calls.push({ method: \"delete\", environment, key });\n this.secrets.get(environment)?.delete(key);\n }\n\n /**\n * Check if set() was called for a given environment and key.\n */\n public wasSet(environment: string, key: string): boolean {\n return this.calls.some(\n (c) =>\n c.method === \"set\" && c.environment === environment && c.key === key,\n );\n }\n\n /**\n * Check if delete() was called for a given environment and key.\n */\n public wasDeleted(environment: string, key: string): boolean {\n return this.calls.some(\n (c) =>\n c.method === \"delete\" && c.environment === environment && c.key === key,\n );\n }\n\n /**\n * Get all set() calls for a given environment.\n */\n public getSetCalls(\n environment: string,\n ): Array<{ key: string; value: string }> {\n return this.calls\n .filter((c) => c.method === \"set\" && c.environment === environment)\n .map((c) => ({ key: c.key!, value: c.value! }));\n }\n\n /**\n * Reset all state.\n */\n public reset(): void {\n this.secrets.clear();\n this.calls = [];\n this.availableError = null;\n }\n}\n","import { $inject, $state, Alepha, AlephaError } from \"alepha\";\nimport { Asker } from \"alepha/command\";\nimport { $logger } from \"alepha/logger\";\nimport { FileSystemProvider } from \"alepha/system\";\nimport {\n type EnvironmentConfig,\n platformOptions,\n} from \"../atoms/platformOptions.ts\";\nimport { NamingService, type Tenancy } from \"./NamingService.ts\";\n\nexport interface ResolvedPlatformConfig {\n project: string;\n defaultEnv: string;\n /** App tenancy mode (undefined ⇒ \"none\"). */\n tenancy?: Tenancy;\n environments: Record<string, EnvironmentConfig>;\n}\n\n/**\n * Reads platform config and resolves project topology.\n *\n * Validates project name and environment configuration. Does NOT\n * introspect app code for resources — that happens at deploy time via\n * ViteBuildProvider.\n *\n * Each app self-declares its platform topology via its own\n * `alepha.config.ts`. Run `alepha platform <op>` from the app's\n * directory; no monorepo-root orchestration here.\n */\nexport class PlatformInspector {\n protected readonly log = $logger();\n protected readonly alepha = $inject(Alepha);\n protected readonly fs = $inject(FileSystemProvider);\n protected readonly asker = $inject(Asker);\n protected readonly options = $state(platformOptions);\n protected readonly naming = $inject(NamingService);\n\n /**\n * Resolve and validate the full platform configuration.\n *\n * Source priority:\n * 1. `platformOptions` atom (set by `alepha.config.ts` during the\n * configure hook) — local dev / from-source deploys.\n * 2. `dist/manifest.json` (written by `alepha build`) — pre-built\n * deploys via Alepha Rocket or any `--prebuilt` consumer that\n * ships only the build artifact without `alepha.config.ts`.\n */\n public async resolveConfig(root: string): Promise<ResolvedPlatformConfig> {\n if (this.options) {\n const opts = this.options;\n const project = await this.resolveProjectName(root, opts.name);\n return {\n project: this.naming.slugify(project),\n defaultEnv: opts.default ?? \"production\",\n tenancy: opts.tenancy,\n environments: opts.environments as Record<string, EnvironmentConfig>,\n };\n }\n\n // Fallback: read dist/manifest.json. Lets prebuilt artifacts deploy\n // without shipping alepha.config.ts in the tarball.\n const manifest = await this.readManifest(root);\n if (manifest) {\n return {\n project: this.naming.slugify(manifest.project),\n defaultEnv: manifest.defaultEnv ?? \"production\",\n tenancy: manifest.tenancy,\n environments: manifest.environments as Record<\n string,\n EnvironmentConfig\n >,\n };\n }\n\n this.log.warn(` alepha.config.ts not found or missing platform config.\n\nPlease add a \"platform\" section to alepha.config.ts:\n\nexport default defineConfig({\n platform: {\n environments: {\n production: { adapter: \"cloudflare\" },\n },\n },\n});\n `);\n throw new AlephaError(\"Missing platform configuration.\");\n }\n\n /**\n * Read `dist/manifest.json` if present. Returns null on any error so\n * callers fall back to the strict alepha.config.ts path.\n */\n protected async readManifest(root: string): Promise<{\n project: string;\n defaultEnv?: string;\n tenancy?: Tenancy;\n environments?: Record<string, unknown>;\n } | null> {\n try {\n const fs = await import(\"node:fs/promises\");\n const path = await import(\"node:path\");\n const raw = await fs.readFile(\n path.join(root, \"dist\", \"manifest.json\"),\n \"utf-8\",\n );\n return JSON.parse(raw);\n } catch {\n return null;\n }\n }\n\n /**\n * Resolve a specific environment, validating it exists.\n */\n public async resolveEnvironment(\n root: string,\n envName: string,\n ): Promise<EnvironmentConfig> {\n const config = await this.resolveConfig(root);\n const envConfig = config.environments[envName];\n\n if (!envConfig) {\n const available = Object.keys(config.environments).join(\", \");\n throw new AlephaError(\n `Unknown environment \"${envName}\". Available: ${available}`,\n );\n }\n\n return envConfig;\n }\n\n protected async resolveProjectName(\n root: string,\n configName?: string,\n ): Promise<string> {\n if (configName) {\n return configName;\n }\n\n try {\n const pkgPath = this.fs.join(root, \"package.json\");\n const pkg = await this.fs.readJsonFile<{ name?: string }>(pkgPath);\n if (pkg.name) {\n return pkg.name;\n }\n } catch {}\n\n throw new AlephaError(\n 'Missing project name. Set \"name\" in alepha.config.ts or add a \"name\" field to package.json.',\n );\n }\n}\n","import { $inject, Alepha, AlephaError } from \"alepha\";\nimport type { AppEntry } from \"alepha/cli\";\nimport type { RunnerMethod } from \"alepha/command\";\nimport { $logger, ConsoleColorProvider } from \"alepha/logger\";\nimport { CloudflareAdapter } from \"../adapters/CloudflareAdapter.ts\";\nimport type {\n DetectedResources,\n PlatformAdapter,\n PlatformContext,\n PlatformState,\n} from \"../adapters/PlatformAdapter.ts\";\nimport { VercelAdapter } from \"../adapters/VercelAdapter.ts\";\nimport {\n type NamingContext,\n NamingService,\n resolveTenant,\n tenantDomain,\n} from \"./NamingService.ts\";\nimport {\n PlatformInspector,\n type ResolvedPlatformConfig,\n} from \"./PlatformInspector.ts\";\n\n/**\n * Orchestrates platform lifecycle operations.\n *\n * Coordinates adapter calls in the correct order for\n * up (build -> migrate -> deploy), down, plan, and status.\n */\nexport class PlatformOrchestrator {\n protected readonly log = $logger();\n protected readonly color = $inject(ConsoleColorProvider);\n protected readonly inspector = $inject(PlatformInspector);\n protected readonly naming = $inject(NamingService);\n protected readonly cloudflareAdapter = $inject(CloudflareAdapter);\n protected readonly vercelAdapter = $inject(VercelAdapter);\n protected readonly alepha = $inject(Alepha);\n\n // -------------------------------------------------------------------------\n // Adapter resolution\n // -------------------------------------------------------------------------\n\n public resolveAdapter(adapterName: string): PlatformAdapter {\n switch (adapterName) {\n case \"cloudflare\":\n return this.cloudflareAdapter;\n case \"vercel\":\n return this.vercelAdapter;\n default:\n throw new AlephaError(`Unknown adapter: \"${adapterName}\"`);\n }\n }\n\n // -------------------------------------------------------------------------\n // up\n // -------------------------------------------------------------------------\n\n public async up(options: {\n root: string;\n env: string;\n entry: AppEntry;\n resources: DetectedResources;\n run: RunnerMethod;\n /**\n * Pre-built mode — the artifact's `dist/` is already produced.\n *\n * Still runs auth → provision → build → migrate → deploy → secrets,\n * but the `build` step shells out to `alepha build --prebuilt` which\n * only regenerates the target-specific deploy config (e.g.\n * `wrangler.jsonc`) and skips the Vite client + server builds.\n * Used by external orchestrators (Rocket) that ship a pre-built\n * `dist/` and just need the wrangler config refreshed for\n * per-tenant overrides on every deploy.\n */\n prebuilt?: boolean;\n /** Tenant slug (apps with tenancy optional|required). */\n tenant?: string;\n }): Promise<{ urls: string[]; domain?: string }> {\n const { root, env, entry, resources, run, prebuilt } = options;\n const envConfig = await this.inspector.resolveEnvironment(root, env);\n const config = await this.inspector.resolveConfig(root);\n const adapter = this.resolveAdapter(envConfig.adapter);\n const tenant = resolveTenant(config.tenancy, options.tenant);\n const namingCtx = this.naming.forContext(config.project, env, tenant);\n\n const ctx: PlatformContext = {\n project: config.project,\n env,\n envConfig,\n root,\n entry,\n resources,\n naming: namingCtx,\n tenant,\n prebuilt,\n };\n\n await adapter.authenticate(ctx, run);\n await adapter.provision(ctx, run);\n // `build` always runs — adapter checks `ctx.prebuilt` to decide\n // whether to do a full bundle build or only regenerate deploy config.\n await adapter.build(ctx, run);\n await adapter.migrate(ctx, run);\n const url = await adapter.deploy(ctx, run);\n await adapter.secrets(ctx, run);\n\n run.end();\n\n return {\n urls: url ? [url] : [],\n domain: tenantDomain(envConfig.domain, tenant),\n };\n }\n\n /**\n * Pretty-print the `up()` result to stdout. Matches the formatting the\n * orchestrator used to emit inline; split out so callers that want\n * JSON output can skip this branch.\n */\n public printUpSummary(result: { urls: string[]; domain?: string }): void {\n const c = this.color;\n if (result.domain) {\n this.log.info(\"\");\n const display = result.domain.includes(\"*\")\n ? `https://${result.domain} (wildcard route)`\n : `https://${result.domain}`;\n this.log.info(` ${c.set(\"GREEN\", \"\\u2192\")} ${c.set(\"CYAN\", display)}`);\n this.log.info(\"\");\n } else {\n for (const url of result.urls) {\n this.log.info(\"\");\n this.log.info(` ${c.set(\"GREEN\", \"\\u2192\")} ${c.set(\"CYAN\", url)}`);\n this.log.info(\"\");\n }\n }\n }\n\n // -------------------------------------------------------------------------\n // down\n // -------------------------------------------------------------------------\n\n public async down(options: {\n root: string;\n env: string;\n entry: AppEntry;\n resources: DetectedResources;\n run: RunnerMethod;\n confirm: (prompt: string) => Promise<string>;\n /** Tenant slug (apps with tenancy optional|required). */\n tenant?: string;\n }): Promise<boolean> {\n const { root, env, entry, resources, run, confirm } = options;\n const envConfig = await this.inspector.resolveEnvironment(root, env);\n const config = await this.inspector.resolveConfig(root);\n const adapter = this.resolveAdapter(envConfig.adapter);\n const tenant = resolveTenant(config.tenancy, options.tenant);\n const namingCtx = this.naming.forContext(config.project, env, tenant);\n\n const ctx: PlatformContext = {\n project: config.project,\n env,\n envConfig,\n root,\n entry,\n resources,\n naming: namingCtx,\n tenant,\n };\n\n // Confirm (skip for tmp envs)\n if (!this.isTmpEnv(env)) {\n const answer = await confirm(`Type \"${env}\" to confirm teardown:`);\n\n if (answer !== env) {\n this.log.info(\"Aborted.\");\n return false;\n }\n }\n\n // Auth\n await adapter.authenticate(ctx, run);\n\n // Teardown\n await adapter.teardown(ctx, run);\n run.end();\n\n return true;\n }\n\n // -------------------------------------------------------------------------\n // plan\n // -------------------------------------------------------------------------\n\n public async plan(options: {\n root: string;\n env: string;\n resources: DetectedResources;\n /** Tenant slug (apps with tenancy optional|required). */\n tenant?: string;\n }): Promise<{\n config: ResolvedPlatformConfig;\n naming: NamingContext;\n resources: DetectedResources;\n }> {\n const { root, env, resources } = options;\n const config = await this.inspector.resolveConfig(root);\n const tenant = resolveTenant(config.tenancy, options.tenant);\n const namingCtx = this.naming.forContext(config.project, env, tenant);\n return { config, naming: namingCtx, resources };\n }\n\n // -------------------------------------------------------------------------\n // status\n // -------------------------------------------------------------------------\n\n public async status(options: {\n root: string;\n env: string;\n entry: AppEntry;\n resources: DetectedResources;\n run: RunnerMethod;\n /** Tenant slug (apps with tenancy optional|required). */\n tenant?: string;\n }): Promise<{ config: ResolvedPlatformConfig; state: PlatformState }> {\n const { root, env, entry, resources, run } = options;\n const envConfig = await this.inspector.resolveEnvironment(root, env);\n const config = await this.inspector.resolveConfig(root);\n const adapter = this.resolveAdapter(envConfig.adapter);\n const tenant = resolveTenant(config.tenancy, options.tenant);\n const namingCtx = this.naming.forContext(config.project, env, tenant);\n\n const ctx: PlatformContext = {\n project: config.project,\n env,\n envConfig,\n root,\n entry,\n resources,\n naming: namingCtx,\n tenant,\n };\n\n await adapter.authenticate(ctx, run);\n const state = await adapter.inspect(ctx, run);\n\n return { config, state };\n }\n\n // -------------------------------------------------------------------------\n // Helpers\n // -------------------------------------------------------------------------\n\n public isTmpEnv(env: string): boolean {\n return env.startsWith(\"tmp\");\n }\n}\n","/**\n * Filters environment variables for secret store syncing.\n *\n * Excludes platform-managed vars (NODE_ENV), build-time vars (VITE_*),\n * and empty values. Keeps everything else — including DATABASE_URL\n * and POSTGRES_SCHEMA which GitHub Actions needs.\n *\n * Also handles renaming GITHUB_* keys since GitHub Actions rejects\n * secret names starting with GITHUB_.\n */\nexport class SecretFilterService {\n protected static readonly EXCLUDED_KEYS = new Set([\"NODE_ENV\"]);\n protected static readonly GITHUB_PREFIX = \"GITHUB_\";\n protected static readonly REMOTE_PREFIX = \"APP_GITHUB_\";\n\n /**\n * Return only the entries that should be pushed to a secret store.\n */\n public filter(envVars: Record<string, string>): Record<string, string> {\n const result: Record<string, string> = {};\n\n for (const [key, value] of Object.entries(envVars)) {\n if (!value) continue;\n if (SecretFilterService.EXCLUDED_KEYS.has(key)) continue;\n if (key.startsWith(\"VITE_\")) continue;\n result[key] = value;\n }\n\n return result;\n }\n\n /**\n * Convert a local env key to a remote secret name.\n *\n * GITHUB_* keys are prefixed with APP_ since GitHub Actions rejects\n * secret names starting with GITHUB_.\n */\n public toRemoteName(key: string): string {\n if (key.startsWith(SecretFilterService.GITHUB_PREFIX)) {\n return `${SecretFilterService.REMOTE_PREFIX}${key.slice(SecretFilterService.GITHUB_PREFIX.length)}`;\n }\n return key;\n }\n\n /**\n * Convert a remote secret name back to the local env key.\n */\n public toLocalName(remoteName: string): string {\n if (remoteName.startsWith(SecretFilterService.REMOTE_PREFIX)) {\n return `${SecretFilterService.GITHUB_PREFIX}${remoteName.slice(SecretFilterService.REMOTE_PREFIX.length)}`;\n }\n return remoteName;\n }\n}\n","/**\n * A secret stored in a remote secret store.\n */\nexport interface RemoteSecret {\n name: string;\n updatedAt?: string;\n}\n\n/**\n * Abstract provider for managing secrets in an external store.\n *\n * Implementations: GitHubSecretStore, MemorySecretStore\n */\nexport abstract class SecretStoreProvider {\n /**\n * Verify the backing store is reachable and authenticated.\n */\n abstract ensureAvailable(): Promise<void>;\n\n /**\n * Ensure the target environment exists in the store, creating it if needed.\n */\n abstract ensureEnvironment(environment: string): Promise<void>;\n\n /**\n * List all secrets in a given environment.\n */\n abstract list(environment: string): Promise<RemoteSecret[]>;\n\n /**\n * Set (create or update) a secret in a given environment.\n */\n abstract set(environment: string, key: string, value: string): Promise<void>;\n\n /**\n * Delete a secret from a given environment.\n */\n abstract delete(environment: string, key: string): Promise<void>;\n}\n","import type { Static } from \"alepha\";\nimport { t } from \"alepha\";\n\n// ---------------------------------------------------------------------------\n// Status output\n// ---------------------------------------------------------------------------\n\nexport const platformStatusWorkerSchema = t.object({\n name: t.string(),\n exists: t.boolean(),\n id: t.optional(t.string()),\n detail: t.optional(t.string()),\n version: t.optional(t.string()),\n tag: t.optional(t.string()),\n createdAt: t.optional(t.string()),\n});\n\nexport const platformStatusResourceSchema = t.object({\n name: t.string(),\n exists: t.boolean(),\n id: t.optional(t.string()),\n detail: t.optional(t.string()),\n});\n\nexport const platformStatusSecretSchema = t.object({\n name: t.string(),\n deployed: t.boolean(),\n});\n\nexport const platformStatusSchema = t.object({\n project: t.string(),\n env: t.string(),\n adapter: t.string(),\n workers: t.array(platformStatusWorkerSchema),\n databases: t.array(platformStatusResourceSchema),\n buckets: t.array(platformStatusResourceSchema),\n kvNamespaces: t.array(platformStatusResourceSchema),\n queues: t.array(platformStatusResourceSchema),\n secrets: t.array(platformStatusSecretSchema),\n});\n\nexport type PlatformStatusOutput = Static<typeof platformStatusSchema>;\n\n// ---------------------------------------------------------------------------\n// Plan output\n// ---------------------------------------------------------------------------\n\nexport const platformPlanAppResourcesSchema = t.object({\n hasDatabase: t.boolean(),\n hasBucket: t.boolean(),\n hasKV: t.boolean(),\n hasQueue: t.boolean(),\n hasCron: t.boolean(),\n});\n\nexport const platformPlanAppSchema = t.object({\n name: t.string(),\n path: t.string(),\n resources: platformPlanAppResourcesSchema,\n});\n\nexport const platformPlanEnvironmentSchema = t.object({\n adapter: t.string(),\n domain: t.optional(t.string()),\n zone: t.optional(t.string()),\n});\n\nexport const platformPlanResourceSchema = t.object({\n label: t.string(),\n value: t.string(),\n});\n\nexport const platformPlanSchema = t.object({\n project: t.string(),\n env: t.string(),\n mode: t.enum([\"monorepo\", \"standalone\"]),\n apps: t.array(platformPlanAppSchema),\n environments: t.record(t.string(), platformPlanEnvironmentSchema),\n resources: t.array(platformPlanResourceSchema),\n secretCount: t.number(),\n});\n\nexport type PlatformPlanOutput = Static<typeof platformPlanSchema>;\n","import { $module } from \"alepha\";\nimport { CloudflareAdapter } from \"./adapters/CloudflareAdapter.ts\";\nimport { VercelAdapter } from \"./adapters/VercelAdapter.ts\";\nimport { GitHubSecretStore } from \"./providers/GitHubSecretStore.ts\";\nimport { MemorySecretStore } from \"./providers/MemorySecretStore.ts\";\nimport { PlatformCacheProvider } from \"./providers/PlatformCacheProvider.ts\";\nimport { CloudflareApi } from \"./services/CloudflareApi.ts\";\nimport { NamingService } from \"./services/NamingService.ts\";\nimport { PlatformInspector } from \"./services/PlatformInspector.ts\";\nimport { PlatformOrchestrator } from \"./services/PlatformOrchestrator.ts\";\nimport { SecretFilterService } from \"./services/SecretFilterService.ts\";\nimport { VercelApi } from \"./services/VercelApi.ts\";\nimport { VercelCli } from \"./services/VercelCli.ts\";\nimport { WranglerApi } from \"./services/WranglerApi.ts\";\n\n/**\n * Framework-agnostic platform deploy services.\n *\n * Exports `PlatformOrchestrator` + adapters + secret stores + the\n * `platformOptions` atom — everything needed to drive a deploy\n * programmatically. **No `$command` instances** and **no\n * `AppEntryProvider` / `ViteBuildProvider` dependency** — so consumers\n * importing this subpath don't pull in the CLI argv-parser or Vite.\n *\n * Used by Alepha Rocket (and other non-CLI deploy orchestrators) to\n * call `orchestrator.up({ ... })` directly. For CLI usage\n * (`alepha platform up`), import `AlephaCliPlatformPlugin` from\n * `alepha/cli/platform` — that one adds the command layer on top.\n */\nexport const AlephaPlatformLibPlugin = $module({\n name: \"alepha.cli.platform-lib\",\n services: [\n CloudflareAdapter,\n CloudflareApi,\n VercelAdapter,\n VercelApi,\n VercelCli,\n WranglerApi,\n PlatformCacheProvider,\n GitHubSecretStore,\n MemorySecretStore,\n NamingService,\n SecretFilterService,\n PlatformInspector,\n PlatformOrchestrator,\n ],\n});\n\nexport * from \"./adapters/CloudflareAdapter.ts\";\nexport * from \"./adapters/PlatformAdapter.ts\";\nexport * from \"./adapters/VercelAdapter.ts\";\nexport * from \"./atoms/platformOptions.ts\";\nexport * from \"./providers/GitHubSecretStore.ts\";\nexport * from \"./providers/MemorySecretStore.ts\";\nexport * from \"./providers/PlatformCacheProvider.ts\";\nexport * from \"./providers/SecretStoreProvider.ts\";\nexport * from \"./schemas/cloudflare.ts\";\nexport * from \"./schemas/platform.ts\";\nexport * from \"./schemas/vercel.ts\";\nexport * from \"./services/CloudflareApi.ts\";\nexport * from \"./services/NamingService.ts\";\nexport * from \"./services/PlatformInspector.ts\";\nexport * from \"./services/PlatformOrchestrator.ts\";\nexport * from \"./services/SecretFilterService.ts\";\nexport * from \"./services/VercelApi.ts\";\nexport * from \"./services/VercelCli.ts\";\nexport * from \"./services/WranglerApi.ts\";\n"],"mappings":"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"}
@@ -1,11 +1,7 @@
1
- import * as _$alepha from "alepha";
2
1
  import { Static } from "alepha";
3
2
  import { PackageManagerUtils } from "alepha/cli";
4
- import * as _$alepha_command0 from "alepha/command";
5
- import * as _$alepha_logger0 from "alepha/logger";
6
3
  import { ConsoleColorProvider } from "alepha/logger";
7
4
  import { FileSystemProvider, ShellProvider } from "alepha/system";
8
- import * as _$typebox from "typebox";
9
5
 
10
6
  //#region ../../src/cli/vendor/atoms/vendorOptions.d.ts
11
7
  /**
@@ -14,19 +10,19 @@ import * as _$typebox from "typebox";
14
10
  * Filled from the `vendor` section of `alepha.config.ts`.
15
11
  * Read by `VendorCommand` to resolve remote, branch, and packages.
16
12
  */
17
- declare const vendorOptions: _$alepha.Atom<_$typebox.TOptional<_$typebox.TObject<{
13
+ declare const vendorOptions: import("alepha").Atom<import("typebox").TOptional<import("typebox").TObject<{
18
14
  /**
19
15
  * Git remote URL.
20
16
  *
21
17
  * @default "git@github.com:feunard/alepha.git"
22
18
  */
23
- remote: _$typebox.TOptional<_$typebox.TString>;
19
+ remote: import("typebox").TOptional<import("typebox").TString>;
24
20
  /**
25
21
  * Branch to sync from.
26
22
  *
27
23
  * @default "main"
28
24
  */
29
- branch: _$typebox.TOptional<_$typebox.TString>;
25
+ branch: import("typebox").TOptional<import("typebox").TString>;
30
26
  /**
31
27
  * Parent directory holding the vendored packages in the local project.
32
28
  * Relative to the project root. Also where the `vendor.json` lock file
@@ -35,13 +31,13 @@ declare const vendorOptions: _$alepha.Atom<_$typebox.TOptional<_$typebox.TObject
35
31
  *
36
32
  * @default ".vendor"
37
33
  */
38
- dir: _$typebox.TOptional<_$typebox.TString>;
34
+ dir: import("typebox").TOptional<import("typebox").TString>;
39
35
  /**
40
36
  * Package directory names under `dir` to sync.
41
37
  *
42
38
  * @example ["alepha", "@alepha/payments-stripe"]
43
39
  */
44
- packages: _$typebox.TArray<_$typebox.TString>;
40
+ packages: import("typebox").TArray<import("typebox").TString>;
45
41
  }>>, "alepha.cli.vendor.options">;
46
42
  /**
47
43
  * Type for vendor options.
@@ -129,7 +125,7 @@ interface VendorLock {
129
125
  * Handles syncing and diffing vendored packages from a remote git repository.
130
126
  */
131
127
  declare class VendorService {
132
- protected readonly log: _$alepha_logger0.Logger;
128
+ protected readonly log: import("alepha/logger").Logger;
133
129
  protected readonly shell: ShellProvider;
134
130
  protected readonly fs: FileSystemProvider;
135
131
  /**
@@ -208,7 +204,7 @@ declare class VendorService {
208
204
  //#endregion
209
205
  //#region ../../src/cli/vendor/commands/VendorCommand.d.ts
210
206
  declare class VendorCommand {
211
- protected readonly log: _$alepha_logger0.Logger;
207
+ protected readonly log: import("alepha/logger").Logger;
212
208
  protected readonly options: Readonly<{
213
209
  remote?: string | undefined;
214
210
  branch?: string | undefined;
@@ -227,17 +223,17 @@ declare class VendorCommand {
227
223
  dir: string;
228
224
  packages: string[];
229
225
  };
230
- protected readonly syncFlags: _$typebox.TObject<{
231
- force: _$typebox.TOptional<_$typebox.TBoolean>;
232
- remote: _$typebox.TOptional<_$typebox.TString>;
226
+ protected readonly syncFlags: import("typebox").TObject<{
227
+ force: import("typebox").TOptional<import("typebox").TBoolean>;
228
+ remote: import("typebox").TOptional<import("typebox").TString>;
233
229
  }>;
234
- protected readonly sync: _$alepha_command0.CommandPrimitive<_$typebox.TObject<{
235
- force: _$typebox.TOptional<_$typebox.TBoolean>;
236
- remote: _$typebox.TOptional<_$typebox.TString>;
237
- }>, _$typebox.TSchema, _$typebox.TObject<_$typebox.TProperties>>;
238
- protected readonly diff: _$alepha_command0.CommandPrimitive<_$typebox.TObject<_$typebox.TProperties>, _$typebox.TSchema, _$typebox.TObject<_$typebox.TProperties>>;
230
+ protected readonly sync: import("alepha/command").CommandPrimitive<import("typebox").TObject<{
231
+ force: import("typebox").TOptional<import("typebox").TBoolean>;
232
+ remote: import("typebox").TOptional<import("typebox").TString>;
233
+ }>, import("typebox").TSchema, import("typebox").TObject<import("typebox").TProperties>>;
234
+ protected readonly diff: import("alepha/command").CommandPrimitive<import("typebox").TObject<import("typebox").TProperties>, import("typebox").TSchema, import("typebox").TObject<import("typebox").TProperties>>;
239
235
  protected printPackageDiff(pkg: VendorPackageDiff): void;
240
- readonly vendor: _$alepha_command0.CommandPrimitive<_$typebox.TObject<_$typebox.TProperties>, _$typebox.TSchema, _$typebox.TObject<_$typebox.TProperties>>;
236
+ readonly vendor: import("alepha/command").CommandPrimitive<import("typebox").TObject<import("typebox").TProperties>, import("typebox").TSchema, import("typebox").TObject<import("typebox").TProperties>>;
241
237
  }
242
238
  //#endregion
243
239
  //#region ../../src/cli/vendor/index.d.ts
@@ -267,7 +263,7 @@ declare class VendorCommand {
267
263
  * });
268
264
  * ```
269
265
  */
270
- declare const AlephaCliVendorPlugin: _$alepha.Service<_$alepha.Module>;
266
+ declare const AlephaCliVendorPlugin: import("alepha").Service<import("alepha").Module>;
271
267
  declare const vendor: (options: VendorOptions) => () => void;
272
268
  //#endregion
273
269
  export { AlephaCliVendorPlugin, VendorCommand, VendorDiffOptions, VendorDiffResult, VendorFileDiff, VendorLineDiff, VendorLock, VendorOptions, VendorPackageDiff, VendorService, VendorSyncOptions, VendorSyncResult, vendor, vendorOptions };