alepha 0.19.0 → 0.19.2

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 (638) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +6 -9
  3. package/dist/api/audits/index.d.ts +378 -346
  4. package/dist/api/audits/index.d.ts.map +1 -1
  5. package/dist/api/files/index.d.ts +216 -184
  6. package/dist/api/files/index.d.ts.map +1 -1
  7. package/dist/api/files/index.js +5 -1
  8. package/dist/api/files/index.js.map +1 -1
  9. package/dist/api/jobs/index.d.ts +528 -496
  10. package/dist/api/jobs/index.d.ts.map +1 -1
  11. package/dist/api/jobs/index.js +3 -3
  12. package/dist/api/jobs/index.js.map +1 -1
  13. package/dist/api/keys/index.d.ts +202 -202
  14. package/dist/api/keys/index.d.ts.map +1 -1
  15. package/dist/api/notifications/index.d.ts +152 -152
  16. package/dist/api/notifications/index.d.ts.map +1 -1
  17. package/dist/api/organizations/index.browser.js +48 -0
  18. package/dist/api/organizations/index.browser.js.map +1 -0
  19. package/dist/api/organizations/index.d.ts +516 -0
  20. package/dist/api/organizations/index.d.ts.map +1 -0
  21. package/dist/api/organizations/index.js +202 -0
  22. package/dist/api/organizations/index.js.map +1 -0
  23. package/dist/api/parameters/index.d.ts +391 -358
  24. package/dist/api/parameters/index.d.ts.map +1 -1
  25. package/dist/api/parameters/index.js +5 -1
  26. package/dist/api/parameters/index.js.map +1 -1
  27. package/dist/api/users/index.browser.js +7 -5
  28. package/dist/api/users/index.browser.js.map +1 -1
  29. package/dist/api/users/index.d.ts +989 -931
  30. package/dist/api/users/index.d.ts.map +1 -1
  31. package/dist/api/users/index.js +292 -146
  32. package/dist/api/users/index.js.map +1 -1
  33. package/dist/api/verifications/index.d.ts +132 -132
  34. package/dist/api/verifications/index.d.ts.map +1 -1
  35. package/dist/api/verifications/index.js +2 -2
  36. package/dist/api/verifications/index.js.map +1 -1
  37. package/dist/batch/index.d.ts +6 -6
  38. package/dist/batch/index.d.ts.map +1 -1
  39. package/dist/billing/index.d.ts +1048 -0
  40. package/dist/billing/index.d.ts.map +1 -0
  41. package/dist/billing/index.js +713 -0
  42. package/dist/billing/index.js.map +1 -0
  43. package/dist/bin/index.js +0 -2
  44. package/dist/bin/index.js.map +1 -1
  45. package/dist/bucket/index.d.ts +10 -10
  46. package/dist/bucket/index.d.ts.map +1 -1
  47. package/dist/bucket/index.js +2 -2
  48. package/dist/bucket/index.js.map +1 -1
  49. package/dist/cache/core/index.d.ts +9 -9
  50. package/dist/cache/core/index.d.ts.map +1 -1
  51. package/dist/cache/core/index.js +2 -2
  52. package/dist/cache/core/index.js.map +1 -1
  53. package/dist/cache/core/index.workerd.js +2 -2
  54. package/dist/cache/core/index.workerd.js.map +1 -1
  55. package/dist/cache/redis/index.d.ts +6 -6
  56. package/dist/cache/redis/index.d.ts.map +1 -1
  57. package/dist/cache/redis/index.js +2 -2
  58. package/dist/cache/redis/index.js.map +1 -1
  59. package/dist/cli/config/index.d.ts +12 -2
  60. package/dist/cli/config/index.d.ts.map +1 -1
  61. package/dist/cli/config/index.js +4 -0
  62. package/dist/cli/config/index.js.map +1 -1
  63. package/dist/cli/core/index.d.ts +183 -139
  64. package/dist/cli/core/index.d.ts.map +1 -1
  65. package/dist/cli/core/index.js +283 -86
  66. package/dist/cli/core/index.js.map +1 -1
  67. package/dist/cli/devtools/index.d.ts +45 -0
  68. package/dist/cli/devtools/index.d.ts.map +1 -0
  69. package/dist/cli/devtools/index.js +170 -0
  70. package/dist/cli/devtools/index.js.map +1 -0
  71. package/dist/cli/platform/index.d.ts +383 -492
  72. package/dist/cli/platform/index.d.ts.map +1 -1
  73. package/dist/cli/platform/index.js +42 -511
  74. package/dist/cli/platform/index.js.map +1 -1
  75. package/dist/cli/vendor/index.d.ts +196 -0
  76. package/dist/cli/vendor/index.d.ts.map +1 -0
  77. package/dist/cli/vendor/index.js +384 -0
  78. package/dist/cli/vendor/index.js.map +1 -0
  79. package/dist/command/index.d.ts +18 -18
  80. package/dist/command/index.d.ts.map +1 -1
  81. package/dist/command/index.js +2 -2
  82. package/dist/command/index.js.map +1 -1
  83. package/dist/core/index.browser.js +4 -4
  84. package/dist/core/index.browser.js.map +1 -1
  85. package/dist/core/index.d.ts +10 -10
  86. package/dist/core/index.d.ts.map +1 -1
  87. package/dist/core/index.js +4 -4
  88. package/dist/core/index.js.map +1 -1
  89. package/dist/core/index.native.js +4 -4
  90. package/dist/core/index.native.js.map +1 -1
  91. package/dist/core/index.workerd.js +4 -4
  92. package/dist/core/index.workerd.js.map +1 -1
  93. package/dist/crypto/index.d.ts +7 -7
  94. package/dist/crypto/index.d.ts.map +1 -1
  95. package/dist/datetime/index.d.ts +4 -4
  96. package/dist/datetime/index.d.ts.map +1 -1
  97. package/dist/email/brevo/index.d.ts +4 -4
  98. package/dist/email/brevo/index.d.ts.map +1 -1
  99. package/dist/email/core/index.d.ts +15 -11
  100. package/dist/email/core/index.d.ts.map +1 -1
  101. package/dist/email/core/index.js +12 -35
  102. package/dist/email/core/index.js.map +1 -1
  103. package/dist/email/smtp/index.d.ts +12 -12
  104. package/dist/email/smtp/index.d.ts.map +1 -1
  105. package/dist/email/smtp/index.js +7 -4
  106. package/dist/email/smtp/index.js.map +1 -1
  107. package/dist/fake/index.d.ts +4 -8
  108. package/dist/fake/index.d.ts.map +1 -1
  109. package/dist/fake/index.js +55 -889
  110. package/dist/fake/index.js.map +1 -1
  111. package/dist/lock/core/index.d.ts +13 -13
  112. package/dist/lock/core/index.d.ts.map +1 -1
  113. package/dist/lock/core/index.js +2 -2
  114. package/dist/lock/core/index.js.map +1 -1
  115. package/dist/lock/redis/index.d.ts +4 -4
  116. package/dist/lock/redis/index.d.ts.map +1 -1
  117. package/dist/logger/index.d.ts +16 -15
  118. package/dist/logger/index.d.ts.map +1 -1
  119. package/dist/logger/index.js +5 -2
  120. package/dist/logger/index.js.map +1 -1
  121. package/dist/mcp/index.d.ts +11 -11
  122. package/dist/mcp/index.d.ts.map +1 -1
  123. package/dist/mcp/index.js +2 -2
  124. package/dist/mcp/index.js.map +1 -1
  125. package/dist/orm/core/index.browser.js +11 -1
  126. package/dist/orm/core/index.browser.js.map +1 -1
  127. package/dist/orm/core/index.bun.js +53 -16
  128. package/dist/orm/core/index.bun.js.map +1 -1
  129. package/dist/orm/core/index.d.ts +95 -51
  130. package/dist/orm/core/index.d.ts.map +1 -1
  131. package/dist/orm/core/index.js +55 -14
  132. package/dist/orm/core/index.js.map +1 -1
  133. package/dist/orm/postgres/index.bun.js +17 -11
  134. package/dist/orm/postgres/index.bun.js.map +1 -1
  135. package/dist/orm/postgres/index.d.ts +21 -15
  136. package/dist/orm/postgres/index.d.ts.map +1 -1
  137. package/dist/orm/postgres/index.js +19 -13
  138. package/dist/orm/postgres/index.js.map +1 -1
  139. package/dist/queue/core/index.d.ts +14 -14
  140. package/dist/queue/core/index.d.ts.map +1 -1
  141. package/dist/queue/core/index.js +2 -2
  142. package/dist/queue/core/index.js.map +1 -1
  143. package/dist/queue/core/index.workerd.js +2 -2
  144. package/dist/queue/core/index.workerd.js.map +1 -1
  145. package/dist/queue/redis/index.d.ts +4 -4
  146. package/dist/queue/redis/index.d.ts.map +1 -1
  147. package/dist/queue/redis/index.js +2 -2
  148. package/dist/queue/redis/index.js.map +1 -1
  149. package/dist/react/auth/index.d.ts +9 -9
  150. package/dist/react/auth/index.d.ts.map +1 -1
  151. package/dist/react/core/index.d.ts +6 -6
  152. package/dist/react/core/index.d.ts.map +1 -1
  153. package/dist/react/core/index.js +5 -4
  154. package/dist/react/core/index.js.map +1 -1
  155. package/dist/react/form/index.d.ts +4 -4
  156. package/dist/react/form/index.d.ts.map +1 -1
  157. package/dist/react/head/index.d.ts +4 -4
  158. package/dist/react/head/index.d.ts.map +1 -1
  159. package/dist/react/i18n/index.d.ts +9 -9
  160. package/dist/react/i18n/index.d.ts.map +1 -1
  161. package/dist/react/intro/index.d.ts +2 -2
  162. package/dist/react/intro/index.d.ts.map +1 -1
  163. package/dist/react/intro/index.js +3 -4
  164. package/dist/react/intro/index.js.map +1 -1
  165. package/dist/react/router/index.browser.js +4 -5
  166. package/dist/react/router/index.browser.js.map +1 -1
  167. package/dist/react/router/index.d.ts +215 -215
  168. package/dist/react/router/index.d.ts.map +1 -1
  169. package/dist/react/router/index.js +6 -7
  170. package/dist/react/router/index.js.map +1 -1
  171. package/dist/react/testing/index.d.ts +2 -2
  172. package/dist/react/testing/index.d.ts.map +1 -1
  173. package/dist/react/testing/index.js +2 -4
  174. package/dist/react/testing/index.js.map +1 -1
  175. package/dist/redis/index.d.ts +19 -19
  176. package/dist/redis/index.d.ts.map +1 -1
  177. package/dist/retry/index.d.ts +4 -4
  178. package/dist/retry/index.d.ts.map +1 -1
  179. package/dist/scheduler/index.d.ts +13 -13
  180. package/dist/scheduler/index.d.ts.map +1 -1
  181. package/dist/scheduler/index.js +2 -2
  182. package/dist/scheduler/index.js.map +1 -1
  183. package/dist/scheduler/index.workerd.js +2 -2
  184. package/dist/scheduler/index.workerd.js.map +1 -1
  185. package/dist/security/index.browser.js +1 -1
  186. package/dist/security/index.browser.js.map +1 -1
  187. package/dist/security/index.d.ts +47 -47
  188. package/dist/security/index.d.ts.map +1 -1
  189. package/dist/security/index.js +9 -12
  190. package/dist/security/index.js.map +1 -1
  191. package/dist/server/auth/index.d.ts +170 -169
  192. package/dist/server/auth/index.d.ts.map +1 -1
  193. package/dist/server/auth/index.js +16 -2
  194. package/dist/server/auth/index.js.map +1 -1
  195. package/dist/server/cookies/index.d.ts +7 -7
  196. package/dist/server/cookies/index.d.ts.map +1 -1
  197. package/dist/server/core/index.d.ts +76 -76
  198. package/dist/server/core/index.d.ts.map +1 -1
  199. package/dist/server/core/index.js +23 -17
  200. package/dist/server/core/index.js.map +1 -1
  201. package/dist/server/cors/index.d.ts +13 -13
  202. package/dist/server/cors/index.d.ts.map +1 -1
  203. package/dist/server/cors/index.js +2 -2
  204. package/dist/server/cors/index.js.map +1 -1
  205. package/dist/server/etag/index.d.ts +9 -9
  206. package/dist/server/etag/index.d.ts.map +1 -1
  207. package/dist/server/health/index.d.ts +20 -20
  208. package/dist/server/health/index.d.ts.map +1 -1
  209. package/dist/server/links/index.browser.js +2 -2
  210. package/dist/server/links/index.browser.js.map +1 -1
  211. package/dist/server/links/index.d.ts +66 -66
  212. package/dist/server/links/index.d.ts.map +1 -1
  213. package/dist/server/links/index.js +4 -4
  214. package/dist/server/links/index.js.map +1 -1
  215. package/dist/server/metrics/index.d.ts +7 -7
  216. package/dist/server/metrics/index.d.ts.map +1 -1
  217. package/dist/server/proxy/index.d.ts +5 -5
  218. package/dist/server/proxy/index.d.ts.map +1 -1
  219. package/dist/server/rate-limit/index.d.ts +12 -12
  220. package/dist/server/rate-limit/index.d.ts.map +1 -1
  221. package/dist/server/rate-limit/index.js +2 -2
  222. package/dist/server/rate-limit/index.js.map +1 -1
  223. package/dist/server/static/index.d.ts +5 -5
  224. package/dist/server/static/index.d.ts.map +1 -1
  225. package/dist/server/swagger/index.d.ts +7 -7
  226. package/dist/server/swagger/index.d.ts.map +1 -1
  227. package/dist/server/swagger/index.js +2 -2
  228. package/dist/server/swagger/index.js.map +1 -1
  229. package/dist/sms/index.d.ts +11 -7
  230. package/dist/sms/index.d.ts.map +1 -1
  231. package/dist/sms/index.js +9 -15
  232. package/dist/sms/index.js.map +1 -1
  233. package/dist/system/index.d.ts +4 -4
  234. package/dist/system/index.d.ts.map +1 -1
  235. package/dist/topic/core/index.d.ts +6 -6
  236. package/dist/topic/core/index.d.ts.map +1 -1
  237. package/dist/topic/redis/index.d.ts +7 -7
  238. package/dist/topic/redis/index.d.ts.map +1 -1
  239. package/dist/topic/redis/index.js +2 -2
  240. package/dist/topic/redis/index.js.map +1 -1
  241. package/dist/websocket/index.d.ts +36 -36
  242. package/dist/websocket/index.d.ts.map +1 -1
  243. package/dist/websocket/index.js +2 -2
  244. package/dist/websocket/index.js.map +1 -1
  245. package/package.json +37 -32
  246. package/src/api/files/{controllers → __tests__}/FileController.spec.ts +189 -143
  247. package/src/api/files/{services → __tests__}/FileService.spec.ts +50 -30
  248. package/src/api/files/controllers/FileController.ts +6 -0
  249. package/src/api/jobs/{services → __tests__}/JobService.spec.ts +1 -1
  250. package/src/api/jobs/providers/JobProvider.ts +3 -3
  251. package/src/api/keys/{services → __tests__}/ApiKeyService.spec.ts +1 -1
  252. package/src/api/organizations/__tests__/OrganizationService.spec.ts +193 -0
  253. package/src/api/organizations/controllers/AdminOrganizationController.ts +103 -0
  254. package/src/api/organizations/entities/organizations.ts +20 -0
  255. package/src/api/organizations/index.browser.ts +10 -0
  256. package/src/api/organizations/index.ts +31 -0
  257. package/src/api/organizations/schemas/createOrganizationSchema.ts +10 -0
  258. package/src/api/organizations/schemas/organizationQuerySchema.ts +10 -0
  259. package/src/api/organizations/schemas/organizationResourceSchema.ts +6 -0
  260. package/src/api/organizations/schemas/updateOrganizationSchema.ts +7 -0
  261. package/src/api/organizations/services/OrganizationService.ts +75 -0
  262. package/src/api/parameters/services/ParameterProvider.ts +6 -1
  263. package/src/api/users/__tests__/$realm.spec.ts +191 -0
  264. package/src/api/users/__tests__/RealmProvider.spec.ts +53 -0
  265. package/src/api/users/__tests__/SessionService.spec.ts +778 -0
  266. package/src/api/users/{jobs → __tests__}/UserJobs.spec.ts +1 -1
  267. package/src/api/users/atoms/realmAuthSettingsAtom.ts +24 -0
  268. package/src/api/users/controllers/RealmController.ts +5 -11
  269. package/src/api/users/entities/users.ts +9 -3
  270. package/src/api/users/index.ts +23 -3
  271. package/src/api/users/primitives/$realm.ts +23 -11
  272. package/src/api/users/providers/RealmProvider.ts +23 -3
  273. package/src/api/users/services/RegistrationService.ts +3 -2
  274. package/src/api/users/services/SessionService.ts +249 -8
  275. package/src/api/users/services/UserService.ts +1 -1
  276. package/src/api/verifications/{jobs → __tests__}/VerificationJobs.spec.ts +4 -2
  277. package/src/api/verifications/parameters/VerificationParameters.ts +2 -2
  278. package/src/billing/__tests__/BillingService.spec.ts +136 -0
  279. package/src/billing/__tests__/PaymentMethodService.spec.ts +78 -0
  280. package/src/billing/controllers/AdminBillingController.ts +149 -0
  281. package/src/billing/controllers/BillingController.ts +108 -0
  282. package/src/billing/entities/paymentIntents.ts +34 -0
  283. package/src/billing/entities/paymentMethods.ts +24 -0
  284. package/src/billing/entities/refunds.ts +22 -0
  285. package/src/billing/errors/BillingError.ts +5 -0
  286. package/src/billing/index.ts +76 -0
  287. package/src/billing/providers/BillingProvider.ts +79 -0
  288. package/src/billing/providers/MemoryBillingProvider.ts +139 -0
  289. package/src/billing/schemas/intentSchemas.ts +60 -0
  290. package/src/billing/schemas/paymentMethodSchemas.ts +13 -0
  291. package/src/billing/schemas/refundSchemas.ts +6 -0
  292. package/src/billing/services/BillingService.ts +325 -0
  293. package/src/billing/services/PaymentMethodService.ts +82 -0
  294. package/src/bin/index.ts +0 -2
  295. package/src/bucket/providers/LocalFileStorageProvider.ts +2 -2
  296. package/src/cache/core/{primitives → __tests__}/$cache.middleware.spec.ts +1 -1
  297. package/src/cache/core/{providers → __tests__}/MemoryCacheProvider.spec.ts +1 -1
  298. package/src/cache/core/primitives/$cache.ts +2 -2
  299. package/src/cache/redis/providers/RedisCacheProvider.ts +2 -2
  300. package/src/cli/config/defineConfig.ts +20 -0
  301. package/src/cli/core/{services → __tests__}/ProjectScaffolder.spec.ts +1 -1
  302. package/src/cli/core/{commands/gen → __tests__}/changelog.spec.ts +1 -1
  303. package/src/cli/core/{commands → __tests__}/init.spec.ts +4 -12
  304. package/src/cli/core/assets.ts +0 -1
  305. package/src/cli/core/atoms/devOptions.ts +0 -5
  306. package/src/cli/core/commands/build.ts +2 -2
  307. package/src/cli/core/commands/dev.ts +165 -30
  308. package/src/cli/core/commands/gen/changelog.ts +2 -2
  309. package/src/cli/core/commands/init.ts +2 -7
  310. package/src/cli/core/commands/verify.ts +0 -1
  311. package/src/cli/core/providers/AppEntryProvider.ts +2 -2
  312. package/src/cli/core/providers/ViteDevServerProvider.ts +53 -46
  313. package/src/cli/core/services/PackageManagerUtils.ts +8 -3
  314. package/src/cli/core/services/ProjectScaffolder.ts +20 -20
  315. package/src/cli/core/tasks/BuildClientTask.ts +8 -0
  316. package/src/cli/core/tasks/BuildServerTask.ts +17 -4
  317. package/src/cli/core/templates/alephaConfigTs.ts +0 -6
  318. package/src/cli/core/templates/webAdminDashboardTsx.ts +17 -0
  319. package/src/cli/core/templates/webAppRouterTs.ts +85 -2
  320. package/src/cli/devtools/atoms/devtoolsOptions.ts +26 -0
  321. package/src/cli/devtools/index.ts +194 -0
  322. package/src/cli/platform/{adapters → __tests__}/CloudflareAdapter.spec.ts +2 -2
  323. package/src/cli/platform/{providers → __tests__}/GitHubSecretStore.spec.ts +1 -1
  324. package/src/cli/platform/{services → __tests__}/NamingService.spec.ts +1 -1
  325. package/src/cli/platform/{providers → __tests__}/PlatformCacheProvider.spec.ts +1 -1
  326. package/src/cli/platform/{services → __tests__}/PlatformInspector.spec.ts +1 -1
  327. package/src/cli/platform/{services → __tests__}/PlatformOrchestrator.spec.ts +3 -3
  328. package/src/cli/platform/{services → __tests__}/SecretFilterService.spec.ts +1 -1
  329. package/src/cli/platform/{commands → __tests__}/SecretsCommand.spec.ts +1 -1
  330. package/src/cli/platform/{adapters → __tests__}/VercelAdapter.spec.ts +2 -2
  331. package/src/cli/platform/atoms/platformOptions.ts +2 -10
  332. package/src/cli/platform/commands/SecretsCommand.ts +2 -2
  333. package/src/cli/platform/commands/platform.ts +2 -11
  334. package/src/cli/platform/index.ts +34 -11
  335. package/src/cli/platform/services/PlatformInspector.ts +2 -2
  336. package/src/cli/platform/services/PlatformOrchestrator.ts +0 -9
  337. package/src/cli/vendor/__tests__/VendorService.spec.ts +407 -0
  338. package/src/cli/vendor/atoms/vendorOptions.ts +41 -0
  339. package/src/cli/vendor/commands/VendorCommand.ts +204 -0
  340. package/src/cli/vendor/index.ts +43 -0
  341. package/src/cli/vendor/services/VendorService.ts +338 -0
  342. package/src/command/{providers → __tests__}/CliProvider.spec.ts +1 -1
  343. package/src/command/{helpers → __tests__}/EnvUtils.spec.ts +1 -1
  344. package/src/command/providers/CliProvider.ts +2 -2
  345. package/src/core/{primitives → __tests__}/$atom.spec.ts +2 -2
  346. package/src/core/{primitives → __tests__}/$memoize.spec.ts +1 -1
  347. package/src/core/{primitives → __tests__}/$mode.spec.ts +1 -1
  348. package/src/core/{primitives → __tests__}/$pipeline.spec.ts +1 -1
  349. package/src/core/{primitives → __tests__}/$scope.spec.ts +2 -2
  350. package/src/core/{providers → __tests__}/KeylessJsonSchemaCodec.spec.ts +1 -1
  351. package/src/core/{providers → __tests__}/SchemaValidator.spec.ts +1 -1
  352. package/src/core/{helpers → __tests__}/jsonSchemaToTypeBox.spec.ts +1 -1
  353. package/src/core/index.shared.ts +1 -1
  354. package/src/core/primitives/{$use.ts → $state.ts} +4 -4
  355. package/src/crypto/{providers → __tests__}/BrowserCryptoProvider.browser.spec.ts +1 -1
  356. package/src/crypto/{providers → __tests__}/CryptoProvider.spec.ts +1 -1
  357. package/src/datetime/{primitives → __tests__}/$debounce.spec.ts +1 -1
  358. package/src/datetime/{primitives → __tests__}/$throttle.spec.ts +1 -1
  359. package/src/datetime/{primitives → __tests__}/$timeout.spec.ts +1 -1
  360. package/src/email/brevo/{providers → __tests__}/BrevoEmailProvider.spec.ts +1 -1
  361. package/src/email/core/{providers → __tests__}/LocalEmailProvider.spec.ts +39 -150
  362. package/src/email/core/providers/LocalEmailProvider.ts +13 -51
  363. package/src/email/smtp/providers/NodemailerEmailProvider.ts +2 -2
  364. package/src/lock/core/{primitives → __tests__}/$lock.middleware.spec.ts +1 -1
  365. package/src/lock/core/primitives/$lock.ts +2 -2
  366. package/src/logger/index.ts +10 -4
  367. package/src/mcp/transports/SseMcpTransport.ts +2 -2
  368. package/src/orm/__tests__/ModelBuilder-tests.ts +53 -0
  369. package/src/orm/__tests__/ModelBuilder.spec.ts +80 -0
  370. package/src/orm/__tests__/organization-tests.ts +200 -0
  371. package/src/orm/__tests__/organization.spec.ts +103 -0
  372. package/src/orm/core/{providers/drivers → __tests__}/BunSqliteProvider.bun.spec.ts +5 -2
  373. package/src/orm/core/constants/PG_SYMBOLS.ts +2 -0
  374. package/src/orm/core/index.shared.ts +1 -0
  375. package/src/orm/core/primitives/$entity.ts +31 -0
  376. package/src/orm/core/providers/DatabaseTypeProvider.ts +11 -0
  377. package/src/orm/core/providers/DrizzleKitProvider.ts +1 -1
  378. package/src/orm/core/providers/drivers/BunSqliteProvider.ts +2 -2
  379. package/src/orm/core/providers/drivers/NodeSqliteProvider.ts +3 -3
  380. package/src/orm/core/services/ModelBuilder.ts +11 -0
  381. package/src/orm/core/services/QueryManager.ts +16 -2
  382. package/src/orm/core/services/Repository.ts +70 -10
  383. package/src/orm/postgres/{providers → __tests__}/BunPostgresProvider.bun.spec.ts +1 -1
  384. package/src/orm/postgres/services/PostgresModelBuilder.ts +9 -1
  385. package/src/queue/core/providers/WorkerProvider.ts +2 -2
  386. package/src/queue/redis/providers/RedisQueueProvider.ts +2 -2
  387. package/src/react/core/{hooks → __tests__}/useAction.browser.spec.tsx +1 -1
  388. package/src/react/core/hooks/useAction.ts +7 -6
  389. package/src/react/head/{providers → __tests__}/BrowserHeadProvider.browser.spec.ts +1 -1
  390. package/src/react/head/{helpers → __tests__}/SeoExpander.spec.ts +1 -1
  391. package/src/react/i18n/{providers → __tests__}/I18nProvider.spec.ts +1 -1
  392. package/src/react/i18n/{hooks → __tests__}/useI18n.browser.spec.tsx +1 -1
  393. package/src/react/intro/components/GettingStartedDevtoolsSlide.tsx +3 -6
  394. package/src/react/router/{providers → __tests__}/ReactBrowserProvider.browser.spec.ts +1 -1
  395. package/src/react/router/providers/ReactBrowserProvider.ts +2 -2
  396. package/src/react/router/providers/ReactPageProvider.ts +2 -2
  397. package/src/react/router/providers/ReactServerProvider.ts +3 -3
  398. package/src/redis/{providers → __tests__}/BunRedisProvider.bun.spec.ts +4 -4
  399. package/src/retry/{primitives → __tests__}/$retry.middleware.spec.ts +1 -1
  400. package/src/router/{TemplatedPathParser.spec.ts → __tests__/TemplatedPathParser.spec.ts} +1 -1
  401. package/src/scheduler/primitives/$scheduler.ts +2 -2
  402. package/src/security/{primitives → __tests__}/$secure-browser.spec.ts +1 -1
  403. package/src/security/{primitives → __tests__}/$secure.spec.ts +1 -1
  404. package/src/security/primitives/$issuer.ts +1 -1
  405. package/src/security/providers/JwtProvider.ts +6 -10
  406. package/src/security/providers/SecurityProvider.ts +6 -11
  407. package/src/security/schemas/userAccountInfoSchema.ts +3 -3
  408. package/src/server/auth/providers/ServerAuthProvider.ts +24 -2
  409. package/src/server/cookies/{services → __tests__}/CookieParser.spec.ts +1 -1
  410. package/src/server/core/{primitives → __tests__}/$circuit.spec.ts +1 -1
  411. package/src/server/core/{providers → __tests__}/NodeHttpServerProvider.spec.ts +1 -1
  412. package/src/server/core/{providers → __tests__}/ServerBodyParserProvider.spec.ts +31 -1
  413. package/src/server/core/{providers → __tests__}/ServerCompressProvider.spec.ts +1 -1
  414. package/src/server/core/{providers → __tests__}/ServerHelmetProvider.spec.ts +4 -1
  415. package/src/server/core/{providers → __tests__}/ServerMultipartProvider.spec.ts +1 -1
  416. package/src/server/core/{services → __tests__}/ServerRequestParser.spec.ts +1 -1
  417. package/src/server/core/primitives/$action.ts +2 -2
  418. package/src/server/core/primitives/$sse.ts +2 -2
  419. package/src/server/core/providers/ServerBodyParserProvider.ts +21 -12
  420. package/src/server/core/providers/ServerCompressProvider.ts +2 -2
  421. package/src/server/core/providers/ServerHelmetProvider.ts +2 -2
  422. package/src/server/core/providers/ServerMultipartProvider.ts +2 -2
  423. package/src/server/core/providers/ServerRouterProvider.ts +1 -5
  424. package/src/server/cors/{primitives → __tests__}/$cors.spec.ts +1 -1
  425. package/src/server/cors/providers/ServerCorsProvider.ts +2 -2
  426. package/src/server/links/{services → __tests__}/BatchCollector.spec.ts +1 -1
  427. package/src/server/links/providers/LinkProvider.ts +2 -2
  428. package/src/server/links/providers/RemotePrimitiveProvider.ts +2 -2
  429. package/src/server/links/providers/ServerLinksProvider.ts +2 -2
  430. package/src/server/rate-limit/{primitives → __tests__}/$rateLimit.spec.ts +1 -1
  431. package/src/server/rate-limit/providers/ServerRateLimitProvider.ts +2 -2
  432. package/src/server/swagger/providers/ServerSwaggerProvider.ts +2 -2
  433. package/src/sms/{providers → __tests__}/LocalSmsProvider.spec.ts +35 -29
  434. package/src/sms/providers/LocalSmsProvider.ts +13 -24
  435. package/src/system/{providers → __tests__}/MemoryFileSystemProvider.spec.ts +1 -1
  436. package/src/system/{providers → __tests__}/MemoryShellProvider.spec.ts +1 -1
  437. package/src/topic/redis/providers/RedisTopicProvider.ts +2 -2
  438. package/src/websocket/{services → __tests__}/RoomManager.spec.ts +1 -1
  439. package/src/websocket/providers/NodeWebSocketServerProvider.ts +2 -2
  440. package/tsconfig.base.json +1 -0
  441. package/assets/devtools-ui/200.html +0 -10
  442. package/assets/devtools-ui/200.html.br +0 -0
  443. package/assets/devtools-ui/404.html +0 -10
  444. package/assets/devtools-ui/404.html.br +0 -0
  445. package/assets/devtools-ui/CNAME +0 -1
  446. package/assets/devtools-ui/asset.CHpVij2M.css +0 -1
  447. package/assets/devtools-ui/asset.CHpVij2M.css.br +0 -0
  448. package/assets/devtools-ui/asset.DJ-i0UDz.css +0 -1
  449. package/assets/devtools-ui/asset.DJ-i0UDz.css.br +0 -0
  450. package/assets/devtools-ui/chunk.1jwpJORo.js +0 -1
  451. package/assets/devtools-ui/chunk.1jwpJORo.js.br +0 -0
  452. package/assets/devtools-ui/chunk.B0r2wfUL.js +0 -1
  453. package/assets/devtools-ui/chunk.B0r2wfUL.js.br +0 -0
  454. package/assets/devtools-ui/chunk.BScN4dVR.js +0 -84
  455. package/assets/devtools-ui/chunk.BScN4dVR.js.br +0 -0
  456. package/assets/devtools-ui/chunk.BispuoY4.js +0 -1
  457. package/assets/devtools-ui/chunk.BispuoY4.js.br +0 -0
  458. package/assets/devtools-ui/chunk.BtrPUUd7.js +0 -2
  459. package/assets/devtools-ui/chunk.BtrPUUd7.js.br +0 -0
  460. package/assets/devtools-ui/chunk.C-KMHgqf.js +0 -1
  461. package/assets/devtools-ui/chunk.C-KMHgqf.js.br +0 -0
  462. package/assets/devtools-ui/chunk.C2zQ3CF6.js +0 -7
  463. package/assets/devtools-ui/chunk.C2zQ3CF6.js.br +0 -0
  464. package/assets/devtools-ui/chunk.C619McpO.js +0 -1
  465. package/assets/devtools-ui/chunk.C619McpO.js.br +0 -0
  466. package/assets/devtools-ui/chunk.C9OsYsVl.js +0 -1
  467. package/assets/devtools-ui/chunk.C9OsYsVl.js.br +0 -3
  468. package/assets/devtools-ui/chunk.CAC_-151.js +0 -1
  469. package/assets/devtools-ui/chunk.CAC_-151.js.br +0 -0
  470. package/assets/devtools-ui/chunk.CCmesWfx.js +0 -1
  471. package/assets/devtools-ui/chunk.CCmesWfx.js.br +0 -0
  472. package/assets/devtools-ui/chunk.CFQDmrcV.js +0 -1
  473. package/assets/devtools-ui/chunk.CFQDmrcV.js.br +0 -0
  474. package/assets/devtools-ui/chunk.CgM71Zau.js +0 -1
  475. package/assets/devtools-ui/chunk.CgM71Zau.js.br +0 -0
  476. package/assets/devtools-ui/chunk.CmHq336a.js +0 -1
  477. package/assets/devtools-ui/chunk.CmHq336a.js.br +0 -0
  478. package/assets/devtools-ui/chunk.CthNMCar.js +0 -1
  479. package/assets/devtools-ui/chunk.CthNMCar.js.br +0 -0
  480. package/assets/devtools-ui/chunk.D2brVJP1.js +0 -1
  481. package/assets/devtools-ui/chunk.D2brVJP1.js.br +0 -0
  482. package/assets/devtools-ui/chunk.DgBKGkiw.js +0 -1
  483. package/assets/devtools-ui/chunk.DgBKGkiw.js.br +0 -0
  484. package/assets/devtools-ui/chunk.NNHHCQsa.js +0 -1
  485. package/assets/devtools-ui/chunk.NNHHCQsa.js.br +0 -0
  486. package/assets/devtools-ui/chunk._CDKKWMo.js +0 -1
  487. package/assets/devtools-ui/chunk._CDKKWMo.js.br +0 -0
  488. package/assets/devtools-ui/entry.B_nOjAod.js +0 -2
  489. package/assets/devtools-ui/entry.B_nOjAod.js.br +0 -0
  490. package/assets/devtools-ui/index.html +0 -10
  491. package/assets/devtools-ui/index.html.br +0 -0
  492. package/dist/devtools/index.browser.js +0 -224
  493. package/dist/devtools/index.browser.js.map +0 -1
  494. package/dist/devtools/index.d.ts +0 -499
  495. package/dist/devtools/index.d.ts.map +0 -1
  496. package/dist/devtools/index.js +0 -782
  497. package/dist/devtools/index.js.map +0 -1
  498. package/dist/mqtt/index.d.ts +0 -164
  499. package/dist/mqtt/index.d.ts.map +0 -1
  500. package/dist/mqtt/index.js +0 -214
  501. package/dist/mqtt/index.js.map +0 -1
  502. package/dist/topic/mqtt/index.d.ts +0 -87
  503. package/dist/topic/mqtt/index.d.ts.map +0 -1
  504. package/dist/topic/mqtt/index.js +0 -88
  505. package/dist/topic/mqtt/index.js.map +0 -1
  506. package/src/api/users/parameters/UserParameters.ts +0 -23
  507. package/src/api/users/services/SessionService.spec.ts +0 -303
  508. package/src/cli/platform/adapters/DockerAdapter.spec.ts +0 -378
  509. package/src/cli/platform/adapters/DockerAdapter.ts +0 -417
  510. package/src/cli/platform/services/DockerComposeGenerator.spec.ts +0 -490
  511. package/src/cli/platform/services/DockerComposeGenerator.ts +0 -353
  512. package/src/cli/platform/services/DockerSshService.spec.ts +0 -47
  513. package/src/cli/platform/services/DockerSshService.ts +0 -61
  514. package/src/devtools/__tests__/DevCollectorProvider.spec.ts +0 -7
  515. package/src/devtools/assets.ts +0 -6
  516. package/src/devtools/entities/logs.ts +0 -21
  517. package/src/devtools/index.browser.ts +0 -11
  518. package/src/devtools/index.shared.ts +0 -15
  519. package/src/devtools/index.ts +0 -39
  520. package/src/devtools/providers/DevToolsMetadataProvider.ts +0 -459
  521. package/src/devtools/providers/DevToolsProvider.ts +0 -280
  522. package/src/devtools/schemas/DevActionMetadata.ts +0 -30
  523. package/src/devtools/schemas/DevAtomMetadata.ts +0 -26
  524. package/src/devtools/schemas/DevBucketMetadata.ts +0 -11
  525. package/src/devtools/schemas/DevCacheMetadata.ts +0 -10
  526. package/src/devtools/schemas/DevEntityMetadata.ts +0 -60
  527. package/src/devtools/schemas/DevEnvMetadata.ts +0 -22
  528. package/src/devtools/schemas/DevMetadata.ts +0 -47
  529. package/src/devtools/schemas/DevModuleMetadata.ts +0 -8
  530. package/src/devtools/schemas/DevPageMetadata.ts +0 -24
  531. package/src/devtools/schemas/DevProviderMetadata.ts +0 -10
  532. package/src/devtools/schemas/DevQueueMetadata.ts +0 -10
  533. package/src/devtools/schemas/DevRealmMetadata.ts +0 -19
  534. package/src/devtools/schemas/DevRouteMetadata.ts +0 -8
  535. package/src/devtools/schemas/DevSchedulerMetadata.ts +0 -11
  536. package/src/devtools/schemas/DevTopicMetadata.ts +0 -11
  537. package/src/mqtt/index.ts +0 -32
  538. package/src/mqtt/providers/MqttClientProvider.ts +0 -63
  539. package/src/mqtt/providers/MqttJsClientProvider.spec.ts +0 -165
  540. package/src/mqtt/providers/MqttJsClientProvider.ts +0 -309
  541. package/src/topic/mqtt/index.ts +0 -30
  542. package/src/topic/mqtt/providers/MqttTopicProvider.spec.ts +0 -160
  543. package/src/topic/mqtt/providers/MqttTopicProvider.ts +0 -146
  544. /package/src/api/audits/{primitives → __tests__}/$audit.spec.ts +0 -0
  545. /package/src/api/audits/{services → __tests__}/AuditService.spec.ts +0 -0
  546. /package/src/api/files/{controllers → __tests__}/AdminFileStatsController.spec.ts +0 -0
  547. /package/src/api/files/{jobs → __tests__}/FileJobs.spec.ts +0 -0
  548. /package/src/api/jobs/{primitives → __tests__}/$job-middleware.spec.ts +0 -0
  549. /package/src/api/parameters/{primitives → __tests__}/$parameter.spec.ts +0 -0
  550. /package/src/api/users/{controllers → __tests__}/AdminIdentityController.spec.ts +0 -0
  551. /package/src/api/users/{controllers → __tests__}/AdminSessionController.spec.ts +0 -0
  552. /package/src/api/users/{controllers → __tests__}/AdminUserController.spec.ts +0 -0
  553. /package/src/api/users/{services → __tests__}/CredentialService.spec.ts +0 -0
  554. /package/src/api/users/{services → __tests__}/RegistrationService.spec.ts +0 -0
  555. /package/src/batch/{primitives → __tests__}/$batch.spec.ts +0 -0
  556. /package/src/batch/{providers → __tests__}/BatchProvider.spec.ts +0 -0
  557. /package/src/bucket/{primitives → __tests__}/$bucket.spec.ts +0 -0
  558. /package/src/bucket/{providers → __tests__}/FileStorageProvider.spec.ts +0 -0
  559. /package/src/bucket/{providers → __tests__}/LocalFileStorageProvider.spec.ts +0 -0
  560. /package/src/bucket/{providers → __tests__}/MemoryFileStorageProvider.spec.ts +0 -0
  561. /package/src/cache/core/{primitives → __tests__}/$cache.spec.ts +0 -0
  562. /package/src/cache/redis/{providers → __tests__}/RedisCacheProvider.spec.ts +0 -0
  563. /package/src/command/{primitives → __tests__}/$command.spec.ts +0 -0
  564. /package/src/command/{helpers → __tests__}/Asker.spec.ts +0 -0
  565. /package/src/command/{helpers → __tests__}/Runner.spec.ts +0 -0
  566. /package/src/core/{primitives → __tests__}/$context.spec.ts +0 -0
  567. /package/src/core/{primitives → __tests__}/$env.spec.ts +0 -0
  568. /package/src/core/{primitives → __tests__}/$hook.spec.ts +0 -0
  569. /package/src/core/{primitives → __tests__}/$inject.spec.ts +0 -0
  570. /package/src/core/{primitives → __tests__}/$module.spec.ts +0 -0
  571. /package/src/core/{providers → __tests__}/CodecManager.spec.ts +0 -0
  572. /package/src/core/{providers → __tests__}/EventManager.spec.ts +0 -0
  573. /package/src/core/{providers → __tests__}/StateManager.spec.ts +0 -0
  574. /package/src/core/{providers → __tests__}/TypeProvider.spec.ts +0 -0
  575. /package/src/datetime/{primitives → __tests__}/$interval.spec.ts +0 -0
  576. /package/src/datetime/{providers → __tests__}/DateTimeProvider.spec.ts +0 -0
  577. /package/src/email/core/{primitives → __tests__}/$email.spec.ts +0 -0
  578. /package/src/fake/{providers → __tests__}/FakeProvider.spec.ts +0 -0
  579. /package/src/lock/core/{providers → __tests__}/MemoryLockProvider.spec.ts +0 -0
  580. /package/src/lock/redis/{providers → __tests__}/RedisLockProvider.spec.ts +0 -0
  581. /package/src/logger/{primitives → __tests__}/$logger.spec.ts +0 -0
  582. /package/src/logger/{services → __tests__}/Logger.spec.ts +0 -0
  583. /package/src/mcp/{primitives → __tests__}/$prompt.spec.ts +0 -0
  584. /package/src/mcp/{primitives → __tests__}/$resource.spec.ts +0 -0
  585. /package/src/mcp/{primitives → __tests__}/$tool.spec.ts +0 -0
  586. /package/src/mcp/{providers → __tests__}/McpServerProvider.spec.ts +0 -0
  587. /package/src/mcp/{helpers → __tests__}/jsonrpc.spec.ts +0 -0
  588. /package/src/orm/core/{helpers → __tests__}/parseQueryString.spec.ts +0 -0
  589. /package/src/queue/core/{primitives → __tests__}/$consumer.spec.ts +0 -0
  590. /package/src/queue/core/{providers → __tests__}/MemoryQueueProvider.spec.ts +0 -0
  591. /package/src/queue/core/{providers → __tests__}/WorkerProvider.spec.ts +0 -0
  592. /package/src/queue/redis/{providers → __tests__}/RedisQueueProvider.spec.ts +0 -0
  593. /package/src/react/form/{hooks → __tests__}/useForm.browser.spec.tsx +0 -0
  594. /package/src/react/head/{hooks → __tests__}/useHead.spec.tsx +0 -0
  595. /package/src/react/i18n/{components → __tests__}/Localize.spec.tsx +0 -0
  596. /package/src/react/router/{primitives → __tests__}/$page.browser.spec.tsx +0 -0
  597. /package/src/react/router/{primitives → __tests__}/$page.middleware.spec.tsx +0 -0
  598. /package/src/react/router/{primitives → __tests__}/$page.spec.tsx +0 -0
  599. /package/src/react/router/{providers → __tests__}/ReactPreloadProvider.spec.ts +0 -0
  600. /package/src/react/router/{providers → __tests__}/ReactServerProvider.spec.tsx +0 -0
  601. /package/src/react/router/{providers → __tests__}/ReactServerTemplateProvider.spec.ts +0 -0
  602. /package/src/retry/{primitives → __tests__}/$retry.spec.ts +0 -0
  603. /package/src/retry/{providers → __tests__}/RetryProvider.spec.ts +0 -0
  604. /package/src/router/{providers → __tests__}/RouterProvider.spec.ts +0 -0
  605. /package/src/security/{primitives → __tests__}/$issuer.spec.ts +0 -0
  606. /package/src/security/{primitives → __tests__}/$permission.spec.ts +0 -0
  607. /package/src/security/{primitives → __tests__}/$role.spec.ts +0 -0
  608. /package/src/security/{primitives → __tests__}/$serviceAccount.spec.ts +0 -0
  609. /package/src/security/{providers → __tests__}/SecurityProvider.spec.ts +0 -0
  610. /package/src/server/cookies/{providers → __tests__}/ServerCookiesProvider.spec.ts +0 -0
  611. /package/src/server/core/{primitives → __tests__}/$action.spec.ts +0 -0
  612. /package/src/server/core/{primitives → __tests__}/$middleware.spec.ts +0 -0
  613. /package/src/server/core/{primitives → __tests__}/$route.spec.ts +0 -0
  614. /package/src/server/core/{primitives → __tests__}/$sse.spec.ts +0 -0
  615. /package/src/server/core/{providers → __tests__}/BunHttpServerProvider.bun.spec.ts +0 -0
  616. /package/src/server/core/{services → __tests__}/HttpClient.spec.ts +0 -0
  617. /package/src/server/core/{providers → __tests__}/ServerLoggerProvider.spec.ts +0 -0
  618. /package/src/server/core/{services → __tests__}/UserAgentParser.spec.ts +0 -0
  619. /package/src/server/cors/{providers → __tests__}/ServerCorsProvider.spec.ts +0 -0
  620. /package/src/server/etag/{providers → __tests__}/ServerEtagProvider.spec.ts +0 -0
  621. /package/src/server/health/{providers → __tests__}/ServerHealthProvider.spec.ts +0 -0
  622. /package/src/server/links/{primitives → __tests__}/$remote.spec.ts +0 -0
  623. /package/src/server/links/{services → __tests__}/BatchEndpoint.spec.ts +0 -0
  624. /package/src/server/links/{providers → __tests__}/LinkProvider.spec.ts +0 -0
  625. /package/src/server/links/{providers → __tests__}/ServerLinksProvider.spec.ts +0 -0
  626. /package/src/server/metrics/{providers → __tests__}/ServerMetricsProvider.spec.ts +0 -0
  627. /package/src/server/proxy/{primitives → __tests__}/$proxy.spec.ts +0 -0
  628. /package/src/server/rate-limit/{providers → __tests__}/ServerRateLimitProvider.spec.ts +0 -0
  629. /package/src/server/static/{primitives → __tests__}/$serve.spec.ts +0 -0
  630. /package/src/server/swagger/{primitives → __tests__}/$swagger.spec.ts +0 -0
  631. /package/src/sms/{primitives → __tests__}/$sms.spec.ts +0 -0
  632. /package/src/sms/{providers → __tests__}/MemorySmsProvider.spec.ts +0 -0
  633. /package/src/system/{services → __tests__}/FileDetector.spec.ts +0 -0
  634. /package/src/system/{providers → __tests__}/NodeFileSystemProvider.spec.ts +0 -0
  635. /package/src/topic/core/{primitives → __tests__}/$subscriber.spec.ts +0 -0
  636. /package/src/topic/core/{providers → __tests__}/MemoryTopicProvider.spec.ts +0 -0
  637. /package/src/topic/redis/{providers → __tests__}/RedisTopicProvider.spec.ts +0 -0
  638. /package/src/websocket/{primitives → __tests__}/$channel.spec.ts +0 -0
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../../src/cli/platform/providers/PlatformCacheProvider.ts","../../../src/cli/platform/schemas/cloudflare.ts","../../../src/cli/platform/services/WranglerApi.ts","../../../src/cli/platform/services/CloudflareApi.ts","../../../src/cli/platform/adapters/PlatformAdapter.ts","../../../src/cli/platform/adapters/CloudflareAdapter.ts","../../../src/cli/platform/services/DockerComposeGenerator.ts","../../../src/cli/platform/services/DockerSshService.ts","../../../src/cli/platform/adapters/DockerAdapter.ts","../../../src/cli/platform/schemas/vercel.ts","../../../src/cli/platform/services/VercelCli.ts","../../../src/cli/platform/services/VercelApi.ts","../../../src/cli/platform/adapters/VercelAdapter.ts","../../../src/cli/platform/atoms/platformOptions.ts","../../../src/cli/platform/services/NamingService.ts","../../../src/cli/platform/services/PlatformInspector.ts","../../../src/cli/platform/services/PlatformOrchestrator.ts","../../../src/cli/platform/providers/GitHubSecretStore.ts","../../../src/cli/platform/services/SecretFilterService.ts","../../../src/cli/platform/commands/SecretsCommand.ts","../../../src/cli/platform/commands/platform.ts","../../../src/cli/platform/providers/MemorySecretStore.ts","../../../src/cli/platform/providers/SecretStoreProvider.ts","../../../src/cli/platform/schemas/platform.ts","../../../src/cli/platform/index.ts"],"sourcesContent":["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.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 service: t.string(),\n environment: 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\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 ): Promise<string | undefined> {\n const output = await this.runShell(\n `wrangler deploy --name=${workerName} --no-bundle --config=${configPath}`,\n { resolve: true, capture: true },\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 ): Promise<void> {\n await this.runShell(\n `wrangler d1 migrations apply ${dbName} --remote --config=${configPath}`,\n { resolve: true, env: { CI: \"1\" } },\n );\n }\n\n // -------------------------------------------------------------------------\n // Secrets\n // -------------------------------------------------------------------------\n\n /**\n * Push secrets in bulk to a worker.\n */\n public async secretBulk(\n secretsPath: string,\n workerName: string,\n ): Promise<void> {\n await this.runShell(\n `wrangler secret bulk ${secretsPath} --name=${workerName}`,\n { resolve: true },\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 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 cloudflareR2ListSchema,\n cloudflareSecretSchema,\n cloudflareVersionListSchema,\n cloudflareWorkerSchema,\n createD1BodySchema,\n createHyperdriveBodySchema,\n createKVBodySchema,\n createQueueBodySchema,\n createR2BodySchema,\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 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\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 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 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.fetch<CloudflareD1[]>(\n `/accounts/${accountId}/d1/database`,\n { schema: t.array(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 return await this.fetch<CloudflareD1>(\n `/accounts/${accountId}/d1/database`,\n {\n method: \"POST\",\n body: { name, primary_location_hint: location },\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.fetch<CloudflareKV[]>(\n `/accounts/${accountId}/storage/kv/namespaces`,\n { schema: t.array(cloudflareKVSchema) },\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 const res = await this.fetch<{ buckets: CloudflareR2[] }>(\n `/accounts/${accountId}/r2/buckets`,\n { schema: cloudflareR2ListSchema },\n );\n return res.buckets;\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 // Queues\n // -------------------------------------------------------------------------\n\n public async listQueues(): Promise<CloudflareQueue[]> {\n const accountId = await this.resolveAccountId();\n return await this.fetch<CloudflareQueue[]>(\n `/accounts/${accountId}/queues`,\n { schema: t.array(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.fetch<CloudflareQueueConsumer[]>(\n `/accounts/${accountId}/queues/${queueId}/consumers`,\n { schema: t.array(cloudflareQueueConsumerSchema) },\n );\n }\n\n public async deleteQueueConsumer(\n queueId: string,\n consumerService: string,\n ): Promise<void> {\n const accountId = await this.resolveAccountId();\n await this.fetch(\n `/accounts/${accountId}/queues/${queueId}/consumers/${consumerService}`,\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.fetch<CloudflareHyperdrive[]>(\n `/accounts/${accountId}/hyperdrive/configs`,\n { schema: t.array(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 const res = await this.fetch<{ deployments: CloudflareDeployment[] }>(\n `/accounts/${accountId}/workers/scripts/${scriptName}/deployments`,\n { schema: cloudflareDeploymentListSchema },\n );\n return res.deployments;\n }\n\n public async listVersions(scriptName: string): Promise<CloudflareVersion[]> {\n const accountId = await this.resolveAccountId();\n const res = await this.fetch<{ items: CloudflareVersion[] }>(\n `/accounts/${accountId}/workers/scripts/${scriptName}/versions`,\n { schema: cloudflareVersionListSchema },\n );\n return res.items;\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 // 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 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 };\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 // 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 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// Context types\n// ---------------------------------------------------------------------------\n\nexport interface DetectedResources {\n hasDatabase: boolean;\n hasBucket: boolean;\n hasKV: boolean;\n hasQueue: boolean;\n hasCron: boolean;\n}\n\nexport interface AppDefinition {\n /**\n * Slugified app name (from package.json).\n */\n name: string;\n\n /**\n * Relative path from root (e.g., \"apps/api\").\n * Empty string for standalone apps.\n */\n path: string;\n\n /**\n * Resolved entry points for this app.\n */\n entry: AppEntry;\n\n /**\n * Cloud resources detected by introspecting the app.\n */\n resources: DetectedResources;\n}\n\nexport interface PlatformContext {\n /**\n * Slugified project name (from root package.json or 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 * All apps in the project.\n */\n apps: AppDefinition[];\n\n /**\n * Monorepo/project root path.\n */\n root: string;\n\n /**\n * Resource name generator bound to this project+env.\n */\n naming: NamingContext;\n}\n\nexport interface AppContext extends PlatformContext {\n /**\n * The specific app being operated on.\n */\n app: AppDefinition;\n}\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 * 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 { $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 { CloudflareApi } from \"../services/CloudflareApi.ts\";\nimport { WranglerApi } from \"../services/WranglerApi.ts\";\nimport {\n type AppContext,\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 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(CloudflareApi);\n protected readonly wrangler = $inject(WranglerApi);\n protected readonly runner = $inject(Runner);\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 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.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 const appDir = ctx.app.path\n ? this.fs.join(ctx.root, ctx.app.path)\n : ctx.root;\n\n const env: Record<string, string> = {};\n\n if (ctx.app.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.app.resources.hasBucket) {\n env.R2_BUCKET_NAME = ctx.naming.r2();\n }\n\n if (ctx.app.resources.hasKV) {\n const kvName = ctx.naming.kv(\n ctx.apps.length > 1 ? ctx.app.name : undefined,\n );\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.app.resources.hasQueue) {\n env.CLOUDFLARE_QUEUE_NAME = ctx.naming.queue(\n ctx.apps.length > 1 ? ctx.app.name : undefined,\n );\n }\n\n if (ctx.envConfig.domain) {\n env.CLOUDFLARE_DOMAIN = ctx.envConfig.domain;\n }\n\n await run({\n name: \"alepha build -t cloudflare\",\n handler: async () => {\n await this.runShell(\"alepha build -t cloudflare\", {\n root: appDir,\n env,\n });\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 const workerName = ctx.naming.worker(\n ctx.apps.length > 1 ? ctx.app.name : undefined,\n );\n const distDir = ctx.app.path\n ? this.fs.join(ctx.root, ctx.app.path, \"dist\")\n : this.fs.join(ctx.root, \"dist\");\n\n let url: string | undefined;\n\n await run({\n name: `deploy worker ${ctx.app.name}`,\n handler: async () => {\n url = await this.wrangler.deploy(\n workerName,\n `${distDir}/wrangler.jsonc`,\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 \"HYPERDRIVE_ID\",\n \"POSTGRES_SCHEMA\",\n \"NODE_ENV\",\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 // Filter out binding/build vars, VITE_* vars, and empty values\n const secrets: Record<string, string> = {};\n for (const [key, value] of Object.entries(envVars)) {\n if (!value) continue;\n if (CloudflareAdapter.EXCLUDED_SECRET_KEYS.has(key)) continue;\n if (key.startsWith(\"VITE_\")) continue;\n secrets[key] = value;\n }\n\n if (Object.keys(secrets).length === 0) {\n return;\n }\n\n // Push secrets to each worker\n for (const app of ctx.apps) {\n const workerName = ctx.naming.worker(\n ctx.apps.length > 1 ? app.name : undefined,\n );\n\n await run({\n name: `push secrets to ${workerName}`,\n handler: async () => {\n const secretsPath = await this.utils.writeConfigFile(\n \"secrets.json\",\n JSON.stringify(secrets),\n ctx.root,\n );\n\n await this.wrangler.secretBulk(secretsPath, workerName);\n },\n });\n }\n }\n\n // -------------------------------------------------------------------------\n // provision (REST API)\n // -------------------------------------------------------------------------\n\n override async provision(\n ctx: PlatformContext,\n run: RunnerMethod,\n ): Promise<void> {\n const needsDB = ctx.apps.some((a) => a.resources.hasDatabase);\n const needsBucket = ctx.apps.some((a) => a.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\n for (const app of ctx.apps) {\n if (app.resources.hasKV) {\n const kvName = ctx.naming.kv(\n ctx.apps.length > 1 ? app.name : undefined,\n );\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 (app.resources.hasQueue) {\n const queueName = ctx.naming.queue(\n ctx.apps.length > 1 ? app.name : undefined,\n );\n tasks.push({\n name: `provision queue (${queueName})`,\n handler: async () => {\n await this.ensureQueue(queueName);\n },\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 const needsDB = ctx.apps.some((a) => a.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 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 if (await this.fs.exists(migrationsDir)) {\n await this.runShell(`alepha db migrations check --mode ${ctx.env}`, {\n resolve: true,\n env,\n });\n } else {\n await this.runShell(`alepha db migrations create --mode ${ctx.env}`, {\n resolve: true,\n env,\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(dbName, \"dist/wrangler.jsonc\");\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 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 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 for (const app of ctx.apps) {\n const name = ctx.naming.worker(\n ctx.apps.length > 1 ? app.name : undefined,\n );\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.apps.some((a) => a.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.apps.some((a) => a.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\n // KV\n for (const app of ctx.apps) {\n if (app.resources.hasKV) {\n const kvName = ctx.naming.kv(\n ctx.apps.length > 1 ? app.name : undefined,\n );\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 }\n\n // Queues\n for (const app of ctx.apps) {\n if (app.resources.hasQueue) {\n const queueName = ctx.naming.queue(\n ctx.apps.length > 1 ? app.name : undefined,\n );\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\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 ctx.apps.length > 1 ? ctx.apps[0].name : undefined,\n );\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 // 1. Remove queue consumers (must happen before worker or queue deletion)\n for (const app of ctx.apps) {\n if (app.resources.hasQueue) {\n const workerName = ctx.naming.worker(\n ctx.apps.length > 1 ? app.name : undefined,\n );\n const queueName = ctx.naming.queue(\n ctx.apps.length > 1 ? app.name : undefined,\n );\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\n // 2. Delete workers\n for (const app of ctx.apps) {\n const name = ctx.naming.worker(\n ctx.apps.length > 1 ? app.name : undefined,\n );\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\n // 3. Delete queues (after worker is gone)\n for (const app of ctx.apps) {\n if (app.resources.hasQueue) {\n const name = ctx.naming.queue(\n ctx.apps.length > 1 ? app.name : undefined,\n );\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 }\n\n // 4. Delete KV namespaces\n for (const app of ctx.apps) {\n if (app.resources.hasKV) {\n const name = ctx.naming.kv(ctx.apps.length > 1 ? app.name : undefined);\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\n // 5. Delete R2 bucket\n // TODO: empty bucket via S3-compatible API before deletion (needs native S3 client)\n // const needsBucket = ctx.apps.some((a) => a.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.api.deleteR2(name);\n // } catch (error: any) {\n // const msg = String(error.message || \"\");\n // if (\n // msg.includes(\"does not exist\") ||\n // msg.includes(\"NoSuchBucket\")\n // ) {\n // // Already gone, nothing to do\n // } else if (\n // msg.includes(\"not empty\") ||\n // msg.includes(\"BucketNotEmpty\")\n // ) {\n // this.log.warn(\n // `Bucket ${name} is not empty -- skipped. Empty it manually.`,\n // );\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.apps.some((a) => a.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 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 const latest = deployments.at(-1);\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","import type { AppDefinition } from \"../adapters/PlatformAdapter.ts\";\nimport type { NamingContext } from \"./NamingService.ts\";\n\nexport interface LocalComposeOptions {\n project: string;\n env: string;\n naming: NamingContext;\n apps: AppDefinition[];\n envVars: Record<string, string>;\n}\n\nexport interface RemoteComposeOptions {\n project: string;\n env: string;\n naming: NamingContext;\n domain?: string;\n domains?: Record<string, string>;\n apps: AppDefinition[];\n envVars: Record<string, string>;\n}\n\n/**\n * Generates docker-compose.yml content for local, remote, and shared Traefik.\n *\n * Pure logic — no I/O, no DI. Takes context, returns YAML string.\n */\nexport class DockerComposeGenerator {\n /**\n * Generate the shared Traefik compose.\n *\n * This is a static singleton — one per VPS at /opt/alepha/traefik/.\n * It creates the alepha-proxy network that project composes connect to.\n */\n generateTraefik(): string {\n return [\n \"# Auto-generated by Alepha. Do not edit.\",\n \"services:\",\n \" traefik:\",\n \" image: traefik:v3\",\n \" container_name: alepha-traefik\",\n \" command:\",\n \" - --providers.docker=true\",\n \" - --providers.docker.exposedbydefault=false\",\n \" - --entrypoints.web.address=:80\",\n \" - --entrypoints.websecure.address=:443\",\n \" - --certificatesresolvers.letsencrypt.acme.httpchallenge.entrypoint=web\",\n \" - --certificatesresolvers.letsencrypt.acme.storage=/letsencrypt/acme.json\",\n \" ports:\",\n ' - \"80:80\"',\n ' - \"443:443\"',\n \" volumes:\",\n \" - /var/run/docker.sock:/var/run/docker.sock\",\n \" - traefik_certs:/letsencrypt\",\n \" networks:\",\n \" - alepha-proxy\",\n \" restart: unless-stopped\",\n \"\",\n \"networks:\",\n \" alepha-proxy:\",\n \" name: alepha-proxy\",\n \"\",\n \"volumes:\",\n \" traefik_certs:\",\n \"\",\n ].join(\"\\n\");\n }\n\n /**\n * Generate compose for local dev (services only: postgres, redis).\n * Returns null if no services are needed.\n */\n generateLocal(options: LocalComposeOptions): string | null {\n const services: string[] = [];\n const volumes: string[] = [];\n\n const needsPostgres =\n this.anyAppHas(options.apps, \"hasDatabase\") &&\n !options.envVars.DATABASE_URL;\n\n const needsRedis =\n (this.anyAppHas(options.apps, \"hasKV\") ||\n this.anyAppHas(options.apps, \"hasQueue\")) &&\n !options.envVars.REDIS_URL;\n\n const needsRustFS =\n this.anyAppHas(options.apps, \"hasBucket\") && !options.envVars.S3_ENDPOINT;\n\n if (needsPostgres) {\n const dbName = `${options.project}_${options.env}`.replace(/-/g, \"_\");\n services.push(\n [\n \" postgres:\",\n \" image: postgres:17-alpine\",\n ' ports: [\"5432:5432\"]',\n \" environment:\",\n ` POSTGRES_DB: ${dbName}`,\n \" POSTGRES_USER: alepha\",\n \" POSTGRES_PASSWORD: alepha\",\n \" volumes:\",\n \" - postgres_data:/var/lib/postgresql/data\",\n ].join(\"\\n\"),\n );\n volumes.push(\" postgres_data:\");\n }\n\n if (needsRedis) {\n services.push(\n [\n \" redis:\",\n \" image: redis:7-alpine\",\n ' ports: [\"6379:6379\"]',\n ].join(\"\\n\"),\n );\n }\n\n if (needsRustFS) {\n services.push(\n [\n \" rustfs:\",\n \" image: rustfs/rustfs:latest\",\n ' ports: [\"9000:9000\"]',\n \" environment:\",\n \" RUSTFS_ROOT_USER: alepha\",\n \" RUSTFS_ROOT_PASSWORD: alepha\",\n \" volumes:\",\n \" - rustfs_data:/data\",\n ].join(\"\\n\"),\n );\n volumes.push(\" rustfs_data:\");\n }\n\n if (services.length === 0) {\n return null;\n }\n\n const parts = [\n \"# Auto-generated by Alepha. Do not edit.\",\n \"services:\",\n ...services,\n ];\n\n if (volumes.length > 0) {\n parts.push(\"\", \"volumes:\", ...volumes);\n }\n\n return `${parts.join(\"\\n\")}\\n`;\n }\n\n /**\n * Generate compose for a remote project.\n *\n * - With `domain`: app connects to shared alepha-proxy network + Traefik labels\n * - Without `domain`: app exposed directly on port 3000, no Traefik involvement\n *\n * Traefik itself is NEVER in this compose — it's a separate shared compose.\n */\n generateRemote(options: RemoteComposeOptions): string {\n const hasDomain =\n !!options.domain || Object.keys(options.domains ?? {}).length > 0;\n const services: string[] = [];\n const volumes: string[] = [];\n\n // App containers\n const isMultiApp = options.apps.length > 1;\n const needsInternal =\n hasDomain && this.anyAppNeedsInternal(options.apps, options.envVars);\n\n for (let i = 0; i < options.apps.length; i++) {\n const app = options.apps[i];\n const serviceName = isMultiApp ? `app-${app.name}` : \"app\";\n const buildPath = isMultiApp ? `./dist/${app.name}` : \"./dist\";\n\n const appLines = [\n ` ${serviceName}:`,\n ` build: ${buildPath}`,\n ` env_file: .env.${options.env}`,\n ];\n\n const appDomain = this.resolveAppDomain(\n app.name,\n isMultiApp,\n options.domain,\n options.domains,\n );\n\n if (appDomain) {\n // Traefik mode: labels for routing + SSL, connect to shared network\n const routerName = serviceName.replace(/-/g, \"\");\n appLines.push(\n \" labels:\",\n \" - traefik.enable=true\",\n ` - traefik.http.routers.${routerName}.rule=Host(\\`${appDomain}\\`)`,\n ` - traefik.http.routers.${routerName}.tls.certresolver=letsencrypt`,\n \" networks:\",\n \" - alepha-proxy\",\n );\n if (needsInternal) {\n appLines.push(\" - internal\");\n }\n } else {\n // Direct mode: expose port, no Traefik\n const port = 3000 + i;\n appLines.push(\" ports:\", ` - \"${port}:3000\"`);\n }\n\n appLines.push(\" restart: unless-stopped\");\n\n // Dependencies\n const deps: string[] = [];\n if (app.resources.hasDatabase && !options.envVars.DATABASE_URL) {\n deps.push(\" - postgres\");\n }\n if (\n (app.resources.hasKV || app.resources.hasQueue) &&\n !options.envVars.REDIS_URL\n ) {\n deps.push(\" - redis\");\n }\n if (app.resources.hasBucket && !options.envVars.S3_ENDPOINT) {\n deps.push(\" - rustfs\");\n }\n if (deps.length > 0) {\n appLines.push(\" depends_on:\", ...deps);\n }\n\n services.push(appLines.join(\"\\n\"));\n }\n\n // Postgres\n const needsPostgres =\n this.anyAppHas(options.apps, \"hasDatabase\") &&\n !options.envVars.DATABASE_URL;\n\n if (needsPostgres) {\n const dbName = `${options.project}_${options.env}`.replace(/-/g, \"_\");\n const pgLines = [\n \" postgres:\",\n \" image: postgres:17-alpine\",\n \" environment:\",\n ` POSTGRES_DB: ${dbName}`,\n \" POSTGRES_USER: alepha\",\n \" POSTGRES_PASSWORD: ${DB_PASSWORD}\",\n \" volumes:\",\n \" - postgres_data:/var/lib/postgresql/data\",\n ];\n if (hasDomain) {\n pgLines.push(\" networks:\", \" - internal\");\n }\n pgLines.push(\" restart: unless-stopped\");\n services.push(pgLines.join(\"\\n\"));\n volumes.push(\" postgres_data:\");\n }\n\n // Redis\n const needsRedis =\n (this.anyAppHas(options.apps, \"hasKV\") ||\n this.anyAppHas(options.apps, \"hasQueue\")) &&\n !options.envVars.REDIS_URL;\n\n if (needsRedis) {\n const redisLines = [\" redis:\", \" image: redis:7-alpine\"];\n if (hasDomain) {\n redisLines.push(\" networks:\", \" - internal\");\n }\n redisLines.push(\" restart: unless-stopped\");\n services.push(redisLines.join(\"\\n\"));\n }\n\n // RustFS (S3-compatible object storage)\n const needsRustFS =\n this.anyAppHas(options.apps, \"hasBucket\") && !options.envVars.S3_ENDPOINT;\n\n if (needsRustFS) {\n const rustfsLines = [\n \" rustfs:\",\n \" image: rustfs/rustfs:latest\",\n \" environment:\",\n \" RUSTFS_ROOT_USER: alepha\",\n \" RUSTFS_ROOT_PASSWORD: ${S3_SECRET_KEY}\",\n \" volumes:\",\n \" - rustfs_data:/data\",\n ];\n if (hasDomain) {\n rustfsLines.push(\" networks:\", \" - internal\");\n }\n rustfsLines.push(\" restart: unless-stopped\");\n services.push(rustfsLines.join(\"\\n\"));\n volumes.push(\" rustfs_data:\");\n }\n\n const parts = [\n \"# Auto-generated by Alepha. Do not edit.\",\n \"services:\",\n ...services,\n ];\n\n // Networks — only when domain is set (connect to shared Traefik network)\n if (hasDomain) {\n parts.push(\"\", \"networks:\", \" alepha-proxy:\", \" external: true\");\n if (needsInternal) {\n parts.push(\" internal:\");\n }\n }\n\n if (volumes.length > 0) {\n parts.push(\"\", \"volumes:\", ...volumes);\n }\n\n return `${parts.join(\"\\n\")}\\n`;\n }\n\n /**\n * Resolve the domain for an app.\n *\n * Priority:\n * 1. `domains[appName]` — explicit override (e.g. shop → myshop.com)\n * 2. `<appName>.<domain>` — convention for multi-app (e.g. api → api.company.com)\n * 3. `domain` — used directly for single-app projects (e.g. myapp.com)\n */\n resolveAppDomain(\n appName: string,\n isMultiApp: boolean,\n domain?: string,\n domains?: Record<string, string>,\n ): string | undefined {\n if (domains?.[appName]) {\n return domains[appName];\n }\n if (domain && isMultiApp) {\n return `${appName}.${domain}`;\n }\n return domain;\n }\n\n protected anyAppHas(\n apps: AppDefinition[],\n resource: keyof AppDefinition[\"resources\"],\n ): boolean {\n return apps.some((app) => app.resources[resource]);\n }\n\n protected anyAppNeedsInternal(\n apps: AppDefinition[],\n envVars: Record<string, string>,\n ): boolean {\n return (\n (this.anyAppHas(apps, \"hasDatabase\") && !envVars.DATABASE_URL) ||\n ((this.anyAppHas(apps, \"hasKV\") || this.anyAppHas(apps, \"hasQueue\")) &&\n !envVars.REDIS_URL) ||\n (this.anyAppHas(apps, \"hasBucket\") && !envVars.S3_ENDPOINT)\n );\n }\n}\n","import { $inject, AlephaError } from \"alepha\";\nimport { ShellProvider } from \"alepha/system\";\n\n/**\n * Wraps SSH and SCP operations for remote Docker deployments.\n */\nexport class DockerSshService {\n protected readonly shell = $inject(ShellProvider);\n\n /**\n * Validate an IP address or hostname to prevent shell injection.\n */\n protected validateHost(ip: string): void {\n // Allow IPv4, IPv6, and hostnames (alphanumeric, dots, hyphens, colons)\n if (!/^[a-zA-Z0-9.:_-]+$/.test(ip)) {\n throw new AlephaError(`Invalid host: ${ip}`);\n }\n }\n\n /**\n * Validate a file path to prevent shell injection.\n */\n protected validatePath(path: string): void {\n // Reject shell metacharacters\n if (/[;&|`$(){}'\"\\\\!#~<>*?[\\]\\n\\r]/.test(path)) {\n throw new AlephaError(`Invalid path: ${path}`);\n }\n }\n\n /**\n * Verify SSH connectivity to the remote host.\n */\n async checkConnection(ip: string): Promise<void> {\n this.validateHost(ip);\n await this.shell.run(`ssh root@${ip} echo ok`);\n }\n\n /**\n * Execute a command on the remote host via SSH.\n */\n async exec(ip: string, command: string): Promise<string> {\n this.validateHost(ip);\n // Escape single quotes in the command and wrap in single quotes\n const escaped = command.replace(/'/g, \"'\\\\''\");\n return this.shell.run(`ssh root@${ip} '${escaped}'`, { capture: true });\n }\n\n /**\n * Upload a file to the remote host via SCP.\n */\n async upload(\n ip: string,\n localPath: string,\n remotePath: string,\n ): Promise<void> {\n this.validateHost(ip);\n this.validatePath(localPath);\n this.validatePath(remotePath);\n await this.shell.run(`scp ${localPath} root@${ip}:${remotePath}`);\n }\n}\n","import { dirname } from \"node:path\";\nimport { $inject } from \"alepha\";\nimport { EnvUtils, type RunnerMethod } from \"alepha/command\";\nimport { $logger } from \"alepha/logger\";\nimport { FileSystemProvider, ShellProvider } from \"alepha/system\";\nimport { DockerComposeGenerator } from \"../services/DockerComposeGenerator.ts\";\nimport { DockerSshService } from \"../services/DockerSshService.ts\";\nimport {\n type AppContext,\n PlatformAdapter,\n type PlatformContext,\n type PlatformState,\n} from \"./PlatformAdapter.ts\";\n\n/**\n * Docker platform adapter.\n *\n * Handles both local development (docker compose for services)\n * and remote VPS deployment (SSH + Docker).\n *\n * Mode is determined by the `ip` field in environment config:\n * - No `ip`: local mode — compose up services (Postgres, Redis)\n * - With `ip`: remote mode — SSH to VPS, push dist, compose up\n *\n * Traefik is a shared singleton per VPS at /opt/alepha/traefik/.\n * Auto-provisioned on first deploy with `domain`, skipped if already running.\n */\nexport class DockerAdapter extends PlatformAdapter {\n protected readonly log = $logger();\n protected readonly fs = $inject(FileSystemProvider);\n protected readonly shell = $inject(ShellProvider);\n protected readonly envUtils = $inject(EnvUtils);\n protected readonly generator = $inject(DockerComposeGenerator);\n protected readonly ssh = $inject(DockerSshService);\n\n protected readonly TRAEFIK_PATH = \"/opt/alepha/traefik\";\n protected readonly TRAEFIK_CONTAINER = \"alepha-traefik\";\n\n protected isRemote(ctx: PlatformContext): boolean {\n return !!ctx.envConfig.ip;\n }\n\n protected composePath(ctx: PlatformContext): string {\n return this.fs.join(ctx.root, \"node_modules/.alepha/docker-compose.yml\");\n }\n\n protected remotePath(ctx: PlatformContext): string {\n return `/opt/alepha/${ctx.project}-${ctx.env}`;\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.shell.run(\"docker --version\");\n\n if (this.isRemote(ctx)) {\n await this.ssh.checkConnection(ctx.envConfig.ip!);\n }\n },\n });\n }\n\n // ---------------------------------------------------------------------------\n // build\n // ---------------------------------------------------------------------------\n\n async build(ctx: AppContext, run: RunnerMethod): Promise<void> {\n if (!this.isRemote(ctx)) {\n return;\n }\n\n const appDir = ctx.app.path\n ? this.fs.join(ctx.root, ctx.app.path)\n : ctx.root;\n\n await run(\"alepha build -t docker\", {\n root: appDir,\n });\n }\n\n // ---------------------------------------------------------------------------\n // deploy\n // ---------------------------------------------------------------------------\n\n async deploy(\n ctx: AppContext,\n run: RunnerMethod,\n ): Promise<string | undefined> {\n if (!this.isRemote(ctx)) {\n return undefined;\n }\n\n const ip = ctx.envConfig.ip!;\n const remote = this.remotePath(ctx);\n\n await run({\n name: \"deploy\",\n handler: async () => {\n await this.shell.run(\"tar czf dist.tar.gz dist\", { root: ctx.root });\n await this.ssh.exec(ip, `mkdir -p ${remote}`);\n await this.ssh.upload(\n ip,\n this.fs.join(ctx.root, \"dist.tar.gz\"),\n `${remote}/dist.tar.gz`,\n );\n await this.ssh.exec(\n ip,\n `cd ${remote} && tar xzf dist.tar.gz && docker compose build && docker compose up -d`,\n );\n },\n });\n\n return ctx.envConfig.domain ? `https://${ctx.envConfig.domain}` : undefined;\n }\n\n // ---------------------------------------------------------------------------\n // provision\n // ---------------------------------------------------------------------------\n\n async provision(ctx: PlatformContext, run: RunnerMethod): Promise<void> {\n const envVars = await this.envUtils.parseEnv(ctx.root, [\n `.env.${ctx.env}`,\n \".env\",\n ]);\n\n if (this.isRemote(ctx)) {\n await this.provisionRemote(ctx, run, envVars);\n } else {\n await this.provisionLocal(ctx, run, envVars);\n }\n }\n\n protected async provisionLocal(\n ctx: PlatformContext,\n run: RunnerMethod,\n envVars: Record<string, string>,\n ): Promise<void> {\n const compose = this.generator.generateLocal({\n project: ctx.project,\n env: ctx.env,\n naming: ctx.naming,\n apps: ctx.apps,\n envVars,\n });\n\n if (!compose) {\n return;\n }\n\n await run({\n name: \"provision (docker compose)\",\n handler: async () => {\n const composePath = this.composePath(ctx);\n await this.fs.mkdir(dirname(composePath), { recursive: true });\n await this.fs.writeFile(composePath, compose);\n\n await this.shell.run(\n `docker compose -f ${composePath} -p ${ctx.project}-${ctx.env} up -d`,\n );\n },\n });\n }\n\n protected async provisionRemote(\n ctx: PlatformContext,\n run: RunnerMethod,\n envVars: Record<string, string>,\n ): Promise<void> {\n const ip = ctx.envConfig.ip!;\n const remote = this.remotePath(ctx);\n\n // Provision shared Traefik if any domain is configured\n const hasDomain =\n !!ctx.envConfig.domain ||\n Object.keys(ctx.envConfig.domains ?? {}).length > 0;\n\n if (hasDomain) {\n await this.ensureTraefik(ip, run);\n }\n\n // Generate project compose (never contains Traefik)\n const compose = this.generator.generateRemote({\n project: ctx.project,\n env: ctx.env,\n naming: ctx.naming,\n domain: ctx.envConfig.domain,\n domains: ctx.envConfig.domains,\n apps: ctx.apps,\n envVars,\n });\n\n await run({\n name: \"provision (remote)\",\n handler: async () => {\n const localCompose = this.composePath(ctx);\n await this.fs.mkdir(dirname(localCompose), { recursive: true });\n await this.fs.writeFile(localCompose, compose);\n\n await this.ssh.exec(ip, `mkdir -p ${remote}`);\n await this.ssh.upload(ip, localCompose, `${remote}/docker-compose.yml`);\n\n const envFile = this.fs.join(ctx.root, `.env.${ctx.env}`);\n if (await this.fs.exists(envFile)) {\n await this.ssh.upload(ip, envFile, `${remote}/.env.${ctx.env}`);\n }\n },\n });\n }\n\n /**\n * Ensure the shared Traefik instance is running on the VPS.\n * If already running, this is a no-op.\n */\n protected async ensureTraefik(ip: string, run: RunnerMethod): Promise<void> {\n const output = await this.ssh.exec(\n ip,\n `docker ps --filter name=${this.TRAEFIK_CONTAINER} --format '{{.Names}}'`,\n );\n\n if (output.trim() === this.TRAEFIK_CONTAINER) {\n return;\n }\n\n await run({\n name: \"provision (shared traefik)\",\n handler: async () => {\n const traefikCompose = this.generator.generateTraefik();\n const localPath = this.fs.join(\n \"node_modules/.alepha/traefik-compose.yml\",\n );\n await this.fs.mkdir(dirname(localPath), { recursive: true });\n await this.fs.writeFile(localPath, traefikCompose);\n\n await this.ssh.exec(ip, `mkdir -p ${this.TRAEFIK_PATH}`);\n await this.ssh.upload(\n ip,\n localPath,\n `${this.TRAEFIK_PATH}/docker-compose.yml`,\n );\n await this.ssh.exec(\n ip,\n `cd ${this.TRAEFIK_PATH} && docker compose up -d`,\n );\n },\n });\n }\n\n // ---------------------------------------------------------------------------\n // migrate\n // ---------------------------------------------------------------------------\n\n async migrate(ctx: PlatformContext, run: RunnerMethod): Promise<void> {\n const hasDatabase = ctx.apps.some((app) => app.resources.hasDatabase);\n if (!hasDatabase) {\n return;\n }\n\n await run({\n name: \"migrate\",\n handler: async () => {\n if (this.isRemote(ctx)) {\n const ip = ctx.envConfig.ip!;\n const remote = this.remotePath(ctx);\n await this.ssh.exec(\n ip,\n `cd ${remote} && docker compose exec app node -e \"require('./migrate')\"`,\n );\n } else {\n await this.shell.run(\"alepha db migrations apply\", {\n root: ctx.root,\n });\n }\n },\n });\n }\n\n // ---------------------------------------------------------------------------\n // secrets\n // ---------------------------------------------------------------------------\n\n async secrets(ctx: PlatformContext, run: RunnerMethod): Promise<void> {\n if (!this.isRemote(ctx)) {\n return;\n }\n\n const ip = ctx.envConfig.ip!;\n const remote = this.remotePath(ctx);\n const envFile = this.fs.join(ctx.root, `.env.${ctx.env}`);\n\n if (!(await this.fs.exists(envFile))) {\n return;\n }\n\n await run({\n name: \"push secrets\",\n handler: async () => {\n await this.ssh.upload(ip, envFile, `${remote}/.env.${ctx.env}`);\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 await run({\n name: \"inspect\",\n handler: async () => {\n if (this.isRemote(ctx)) {\n const ip = ctx.envConfig.ip!;\n const remote = this.remotePath(ctx);\n try {\n const output = await this.ssh.exec(\n ip,\n `cd ${remote} && docker compose ps --format json 2>/dev/null || echo \"[]\"`,\n );\n const containers = this.parseContainers(output);\n for (const c of containers) {\n state.workers.push({\n name: c.name,\n exists: c.state === \"running\",\n detail: c.state,\n });\n }\n } catch {\n // Remote not reachable or no compose — empty state\n }\n } else {\n const composePath = this.composePath(ctx);\n if (await this.fs.exists(composePath)) {\n try {\n const output = await this.shell.run(\n `docker compose -f ${composePath} -p ${ctx.project}-${ctx.env} ps --format json`,\n { capture: true },\n );\n const containers = this.parseContainers(output);\n for (const c of containers) {\n state.workers.push({\n name: c.name,\n exists: c.state === \"running\",\n detail: c.state,\n });\n }\n } catch {\n // Compose not running — empty state\n }\n }\n }\n },\n });\n\n return state;\n }\n\n // ---------------------------------------------------------------------------\n // teardown\n // ---------------------------------------------------------------------------\n\n async teardown(ctx: PlatformContext, run: RunnerMethod): Promise<void> {\n await run({\n name: \"teardown\",\n handler: async () => {\n if (this.isRemote(ctx)) {\n const ip = ctx.envConfig.ip!;\n const remote = this.remotePath(ctx);\n await this.ssh.exec(ip, `cd ${remote} && docker compose down`);\n } else {\n const composePath = this.composePath(ctx);\n if (await this.fs.exists(composePath)) {\n await this.shell.run(\n `docker compose -f ${composePath} -p ${ctx.project}-${ctx.env} down`,\n );\n }\n }\n },\n });\n }\n\n // ---------------------------------------------------------------------------\n // Helpers\n // ---------------------------------------------------------------------------\n\n protected parseContainers(\n output: string,\n ): Array<{ name: string; state: string }> {\n try {\n const lines = output.trim().split(\"\\n\").filter(Boolean);\n return lines.map((line) => {\n const obj = JSON.parse(line);\n return {\n name: obj.Name ?? obj.Service ?? \"unknown\",\n state: obj.State ?? \"unknown\",\n };\n });\n } catch {\n return [];\n }\n }\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.app.path\n ? this.fs.join(ctx.root, ctx.app.path)\n : 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 = ctx.app.path\n ? this.fs.join(ctx.root, ctx.app.path, \"dist\")\n : this.fs.join(ctx.root, \"dist\");\n\n const projectName = ctx.naming.worker(\n ctx.apps.length > 1 ? ctx.app.name : undefined,\n );\n\n let url: string | undefined;\n\n await run({\n name: `deploy ${ctx.app.name}`,\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 for (const app of ctx.apps) {\n const projectName = ctx.naming.worker(\n ctx.apps.length > 1 ? app.name : undefined,\n );\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 for (const app of ctx.apps) {\n const projectName = ctx.naming.worker(\n ctx.apps.length > 1 ? app.name : undefined,\n );\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 ctx.apps.length > 1 ? ctx.apps[0].name : undefined,\n );\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 for (const app of ctx.apps) {\n const projectName = ctx.naming.worker(\n ctx.apps.length > 1 ? app.name : undefined,\n );\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 { $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 * Monorepo app paths relative to root. Omit for standalone apps.\n */\n apps: t.optional(t.array(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 * 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 * Secret store backend.\n */\n store: 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 t.object({\n adapter: t.enum([\n \"cloudflare\",\n \"vercel\",\n \"docker\",\n \"docker-compose\",\n \"aks\",\n ]),\n domain: t.optional(t.text()),\n domains: t.optional(t.record(t.text(), t.text())),\n ip: 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\" | \"docker\" | \"docker-compose\" | \"aks\";\n domain?: string;\n domains?: Record<string, string>;\n ip?: string;\n vars?: Record<string, string>;\n}\n","/**\n * Generates deterministic resource names for cloud deployments.\n *\n * Pattern: <project>-<env>[-<app>]\n *\n * All segments are slugified (lowercase, alphanumeric + dashes, max 63 chars).\n */\nexport class NamingService {\n public forContext(project: string, env: string): NamingContext {\n const prefix = `${this.slugify(project)}-${this.slugify(env)}`;\n return new NamingContext(prefix, this);\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 protected readonly naming: NamingService;\n\n constructor(prefix: string, naming: NamingService) {\n this.prefix = prefix;\n this.naming = naming;\n }\n\n public worker(app?: string): string {\n return app ? `${this.prefix}-${this.naming.slugify(app)}` : 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(app?: string): string {\n return app ? `${this.prefix}-${this.naming.slugify(app)}` : this.prefix;\n }\n\n public queue(app?: string): string {\n return app ? `${this.prefix}-${this.naming.slugify(app)}` : this.prefix;\n }\n}\n","import { $inject, $use, 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 } from \"./NamingService.ts\";\n\nexport interface ResolvedPlatformConfig {\n project: string;\n defaultEnv: string;\n environments: Record<string, EnvironmentConfig>;\n isMonorepo: boolean;\n appPaths: string[];\n appNames: Map<string, string>;\n}\n\n/**\n * Reads platform config and resolves project topology.\n *\n * Validates project names, app paths, and environment configuration.\n * Does NOT introspect app code for resources — that happens at deploy time\n * via ViteBuildProvider.\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 = $use(platformOptions);\n protected readonly naming = $inject(NamingService);\n\n /**\n * Resolve and validate the full platform configuration.\n */\n public async resolveConfig(root: string): Promise<ResolvedPlatformConfig> {\n if (!this.options) {\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 // Re-read after potential wizard\n const opts = this.options;\n const platform = opts;\n\n // Resolve project name\n const project = await this.resolveProjectName(root, opts.name);\n\n // Resolve apps\n const appPaths = opts.apps ?? [];\n const isMonorepo = appPaths.length > 0;\n const appNames = new Map<string, string>();\n\n for (const appPath of appPaths) {\n const name = await this.resolveAppName(root, appPath);\n appNames.set(appPath, name);\n }\n\n return {\n project: this.naming.slugify(project),\n defaultEnv: platform.default ?? \"production\",\n environments: platform.environments as Record<string, EnvironmentConfig>,\n isMonorepo,\n appPaths,\n appNames,\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 protected async resolveAppName(\n root: string,\n appPath: string,\n ): Promise<string> {\n const pkgPath = this.fs.join(root, appPath, \"package.json\");\n\n try {\n const pkg = await this.fs.readJsonFile<{ name?: string }>(pkgPath);\n if (pkg.name) {\n return this.naming.slugify(pkg.name);\n }\n } catch {}\n\n throw new AlephaError(\n `Missing \"name\" field in package.json for app at ${appPath}.`,\n );\n }\n}\n","import { $inject, AlephaError } from \"alepha\";\nimport type { RunnerMethod } from \"alepha/command\";\nimport { $logger, ConsoleColorProvider } from \"alepha/logger\";\nimport { CloudflareAdapter } from \"../adapters/CloudflareAdapter.ts\";\nimport { DockerAdapter } from \"../adapters/DockerAdapter.ts\";\nimport type {\n AppDefinition,\n PlatformAdapter,\n PlatformContext,\n PlatformState,\n} from \"../adapters/PlatformAdapter.ts\";\nimport { VercelAdapter } from \"../adapters/VercelAdapter.ts\";\nimport { type NamingContext, NamingService } 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 dockerAdapter = $inject(DockerAdapter);\n protected readonly vercelAdapter = $inject(VercelAdapter);\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 \"docker\":\n case \"docker-compose\":\n return this.dockerAdapter;\n case \"vercel\":\n return this.vercelAdapter;\n case \"aks\":\n throw new AlephaError(\n `Adapter \"${adapterName}\" is not yet available. Currently supported: cloudflare, docker, vercel`,\n );\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 app?: string;\n apps: AppDefinition[];\n run: RunnerMethod;\n }): Promise<void> {\n const { root, env, app: appFilter, apps, 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 namingCtx = this.naming.forContext(config.project, env);\n\n const ctx: PlatformContext = {\n project: config.project,\n env,\n envConfig,\n apps,\n root,\n naming: namingCtx,\n };\n\n // 1. Auth\n await adapter.authenticate(ctx, run);\n\n // 2. Filter apps\n const targetApps = appFilter\n ? apps.filter((a) => a.name === appFilter)\n : apps;\n\n if (targetApps.length === 0 && appFilter) {\n throw new AlephaError(\n `App \"${appFilter}\" not found. Available: ${apps.map((a) => a.name).join(\", \")}`,\n );\n }\n\n // 3. Provision (before build so resource IDs are available for wrangler config)\n await adapter.provision(ctx, run);\n\n // 4. Build\n for (const a of targetApps) {\n await adapter.build({ ...ctx, app: a }, run);\n }\n\n // 5. Migrate\n await adapter.migrate(ctx, run);\n\n // 6. Deploy\n const urls: string[] = [];\n for (const a of targetApps) {\n const url = await adapter.deploy({ ...ctx, app: a }, run);\n if (url) {\n urls.push(url);\n }\n }\n\n // 7. Secrets (push .env.{env} secrets to deployed workers)\n await adapter.secrets(ctx, run);\n\n run.end();\n\n const c = this.color;\n\n if (envConfig.domain) {\n this.log.info(\"\");\n this.log.info(\n ` ${c.set(\"GREEN\", \"\\u2192\")} ${c.set(\"CYAN\", `https://${envConfig.domain}`)}`,\n );\n this.log.info(\"\");\n } else {\n for (const url of 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 app?: string;\n apps: AppDefinition[];\n run: RunnerMethod;\n confirm: (prompt: string) => Promise<string>;\n }): Promise<boolean> {\n const { root, env, app: appFilter, apps, 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 namingCtx = this.naming.forContext(config.project, env);\n\n const ctx: PlatformContext = {\n project: config.project,\n env,\n envConfig,\n apps: appFilter ? apps.filter((a) => a.name === appFilter) : apps,\n root,\n naming: namingCtx,\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 apps: AppDefinition[];\n }): Promise<{\n config: ResolvedPlatformConfig;\n naming: NamingContext;\n apps: AppDefinition[];\n }> {\n const { root, env, apps } = options;\n const config = await this.inspector.resolveConfig(root);\n const namingCtx = this.naming.forContext(config.project, env);\n return { config, naming: namingCtx, apps };\n }\n\n // -------------------------------------------------------------------------\n // status\n // -------------------------------------------------------------------------\n\n public async status(options: {\n root: string;\n env: string;\n apps: AppDefinition[];\n run: RunnerMethod;\n }): Promise<{ config: ResolvedPlatformConfig; state: PlatformState }> {\n const { root, env, apps, 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 namingCtx = this.naming.forContext(config.project, env);\n\n const ctx: PlatformContext = {\n project: config.project,\n env,\n envConfig,\n apps,\n root,\n naming: namingCtx,\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","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","/**\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","import { $inject, $use, AlephaError, t } from \"alepha\";\nimport { $command, EnvUtils } from \"alepha/command\";\nimport { $logger, ConsoleColorProvider } from \"alepha/logger\";\nimport { platformOptions } from \"../atoms/platformOptions.ts\";\nimport { GitHubSecretStore } from \"../providers/GitHubSecretStore.ts\";\nimport type { SecretStoreProvider } from \"../providers/SecretStoreProvider.ts\";\nimport { NamingService } from \"../services/NamingService.ts\";\nimport { PlatformInspector } from \"../services/PlatformInspector.ts\";\nimport { SecretFilterService } from \"../services/SecretFilterService.ts\";\n\nexport class SecretsCommand {\n protected readonly log = $logger();\n protected readonly options = $use(platformOptions);\n protected readonly inspector = $inject(PlatformInspector);\n protected readonly naming = $inject(NamingService);\n protected readonly envUtils = $inject(EnvUtils);\n protected readonly githubStore = $inject(GitHubSecretStore);\n protected readonly filter = $inject(SecretFilterService);\n protected readonly color = $inject(ConsoleColorProvider);\n\n protected readonly envFlags = t.object({\n env: t.optional(\n t.text({\n aliases: [\"e\"],\n description: \"Target environment\",\n }),\n ),\n });\n\n // -----------------------------------------------------------------------\n // alepha p secrets list\n // -----------------------------------------------------------------------\n\n protected readonly list = $command({\n name: \"list\",\n aliases: [\"ls\"],\n description: \"List secrets in the remote store\",\n flags: t.object({\n env: t.optional(\n t.text({\n aliases: [\"e\"],\n description: \"Target environment\",\n }),\n ),\n format: t.optional(\n t.text({\n aliases: [\"f\"],\n description: \"Output format: table (default), gha\",\n }),\n ),\n }),\n handler: async ({ flags, root, run }) => {\n const config = await this.inspector.resolveConfig(root);\n const env = flags.env ?? config.defaultEnv;\n const envName = this.resolveEnvironmentName(config.project, env);\n const format = flags.format ?? \"table\";\n\n const store = this.resolveStore();\n await store.ensureAvailable();\n const remoteSecrets = await store.list(envName);\n\n run.end();\n\n if (format === \"gha\") {\n process.stdout.write(\n `# Generated by alepha — environment: ${envName}\\n`,\n );\n process.stdout.write(\"env:\\n\");\n for (const secret of remoteSecrets) {\n const localName = this.filter.toLocalName(secret.name);\n process.stdout.write(\n ` ${localName}: \\${{ secrets.${secret.name} }}\\n`,\n );\n }\n return;\n }\n\n // table format\n const c = this.color;\n\n if (remoteSecrets.length === 0) {\n process.stdout.write(\n `\\nNo secrets in environment ${c.set(\"CYAN\", envName)}.\\n\\n`,\n );\n return;\n }\n\n process.stdout.write(\n `\\n${c.set(\"GREY_LIGHT\", \"Environment:\")} ${c.set(\"CYAN\", envName)}\\n\\n`,\n );\n\n const maxNameLen = Math.max(\n ...remoteSecrets.map((s) => s.name.length),\n 4,\n );\n\n process.stdout.write(\n ` ${c.set(\"GREY_LIGHT\", \"NAME\".padEnd(maxNameLen + 2))}${c.set(\"GREY_LIGHT\", \"UPDATED\")}\\n`,\n );\n\n for (const secret of remoteSecrets) {\n const updated = secret.updatedAt\n ? new Date(secret.updatedAt).toLocaleString()\n : \"-\";\n process.stdout.write(\n ` ${c.set(\"CYAN\", secret.name.padEnd(maxNameLen + 2))}${c.set(\"GREY_DARK\", updated)}\\n`,\n );\n }\n\n process.stdout.write(\"\\n\");\n },\n });\n\n // -----------------------------------------------------------------------\n // alepha p secrets diff\n // -----------------------------------------------------------------------\n\n protected readonly diff = $command({\n name: \"diff\",\n description: \"Compare local .env keys with remote store\",\n flags: this.envFlags,\n handler: async ({ flags, root, run }) => {\n const config = await this.inspector.resolveConfig(root);\n const env = flags.env ?? config.defaultEnv;\n const envName = this.resolveEnvironmentName(config.project, env);\n\n const envVars = await this.envUtils.parseEnv(root, [`.env.${env}`]);\n const filtered = this.filter.filter(envVars);\n const localKeys = new Set(\n Object.keys(filtered).map((k) => this.filter.toRemoteName(k)),\n );\n\n const store = this.resolveStore();\n await store.ensureAvailable();\n const remoteSecrets = await store.list(envName);\n const remoteKeys = new Set(remoteSecrets.map((s) => s.name));\n\n run.end();\n\n const c = this.color;\n const allKeys = [...new Set([...localKeys, ...remoteKeys])].sort();\n\n process.stdout.write(\n `\\n${c.set(\"GREY_LIGHT\", \"Environment:\")} ${c.set(\"CYAN\", envName)}\\n\\n`,\n );\n\n let hasChanges = false;\n for (const key of allKeys) {\n const inLocal = localKeys.has(key);\n const inRemote = remoteKeys.has(key);\n\n if (inLocal && !inRemote) {\n process.stdout.write(` ${c.set(\"GREEN\", \"+\")} ${key}\\n`);\n hasChanges = true;\n } else if (!inLocal && inRemote) {\n process.stdout.write(` ${c.set(\"RED\", \"-\")} ${key}\\n`);\n hasChanges = true;\n } else {\n process.stdout.write(` ${c.set(\"GREY_DARK\", \"=\")} ${key}\\n`);\n }\n }\n\n if (!hasChanges) {\n process.stdout.write(\n ` ${c.set(\"GREEN\", \"Local and remote are in sync.\")}\\n`,\n );\n }\n\n process.stdout.write(\"\\n\");\n },\n });\n\n // -----------------------------------------------------------------------\n // alepha p secrets apply\n // -----------------------------------------------------------------------\n\n protected readonly apply = $command({\n name: \"apply\",\n description: \"Push local .env secrets to the remote store\",\n flags: t.object({\n env: t.optional(\n t.text({\n aliases: [\"e\"],\n description: \"Target environment\",\n }),\n ),\n \"dry-run\": t.optional(\n t.boolean({\n description: \"Preview changes without pushing\",\n }),\n ),\n }),\n handler: async ({ flags, root, run }) => {\n const config = await this.inspector.resolveConfig(root);\n const env = flags.env ?? config.defaultEnv;\n const envName = this.resolveEnvironmentName(config.project, env);\n const dryRun = flags[\"dry-run\"] ?? false;\n\n const envVars = await this.envUtils.parseEnv(root, [`.env.${env}`]);\n const filtered = this.filter.filter(envVars);\n const keys = Object.keys(filtered);\n\n if (keys.length === 0) {\n run.end();\n process.stdout.write(\"\\nNo secrets to push.\\n\\n\");\n return;\n }\n\n if (dryRun) {\n run.end();\n const c = this.color;\n process.stdout.write(\n `\\n${c.set(\"GREY_LIGHT\", \"Dry run — environment:\")} ${c.set(\"CYAN\", envName)}\\n\\n`,\n );\n for (const key of keys) {\n process.stdout.write(` ${c.set(\"GREEN\", \"+\")} ${key}\\n`);\n }\n process.stdout.write(\n `\\n ${keys.length} secret(s) would be pushed.\\n\\n`,\n );\n return;\n }\n\n const store = this.resolveStore();\n await store.ensureAvailable();\n await store.ensureEnvironment(envName);\n\n for (const key of keys) {\n const remoteName = this.filter.toRemoteName(key);\n await run({\n name: `push ${remoteName}`,\n handler: async () => {\n await store.set(envName, remoteName, filtered[key]);\n },\n });\n }\n\n run.end();\n process.stdout.write(\n `\\n${keys.length} secret(s) pushed to ${envName}.\\n`,\n );\n },\n });\n\n // -----------------------------------------------------------------------\n // Parent command\n // -----------------------------------------------------------------------\n\n public readonly secrets = $command({\n name: \"secrets\",\n aliases: [\"sec\"],\n description: \"Manage secrets in external stores\",\n children: [this.list, this.diff, this.apply],\n handler: async ({ help }) => {\n help();\n },\n });\n\n // -----------------------------------------------------------------------\n // Helpers\n // -----------------------------------------------------------------------\n\n public resolveStore(): SecretStoreProvider {\n const storeName = this.options?.secrets?.store ?? \"github\";\n switch (storeName) {\n case \"github\":\n return this.githubStore;\n default:\n throw new AlephaError(\n `Unknown secret store \"${storeName}\". Available: github`,\n );\n }\n }\n\n protected resolveEnvironmentName(project: string, env: string): string {\n const pattern =\n this.options?.secrets?.environmentPattern ?? \"{project}-{env}\";\n\n return pattern\n .replace(\"{project}\", this.naming.slugify(project))\n .replace(\"{env}\", this.naming.slugify(env));\n }\n}\n","import { $inject, $use, AlephaError, t } from \"alepha\";\nimport { AppEntryProvider, ViteBuildProvider } from \"alepha/cli\";\nimport { $command, EnvUtils } from \"alepha/command\";\nimport { $logger, ConsoleColorProvider } from \"alepha/logger\";\nimport { CloudflareAdapter } from \"../adapters/CloudflareAdapter.ts\";\nimport type {\n AppDefinition,\n DetectedResources,\n} from \"../adapters/PlatformAdapter.ts\";\nimport { VercelAdapter } from \"../adapters/VercelAdapter.ts\";\nimport { platformOptions } from \"../atoms/platformOptions.ts\";\nimport type {\n PlatformPlanOutput,\n PlatformStatusOutput,\n} from \"../schemas/platform.ts\";\nimport { NamingService } from \"../services/NamingService.ts\";\nimport {\n PlatformInspector,\n type ResolvedPlatformConfig,\n} from \"../services/PlatformInspector.ts\";\nimport { PlatformOrchestrator } from \"../services/PlatformOrchestrator.ts\";\nimport { SecretsCommand } from \"./SecretsCommand.ts\";\n\nexport class PlatformCommand {\n protected readonly log = $logger();\n protected readonly options = $use(platformOptions);\n protected readonly orchestrator = $inject(PlatformOrchestrator);\n protected readonly inspector = $inject(PlatformInspector);\n protected readonly naming = $inject(NamingService);\n protected readonly boot = $inject(AppEntryProvider);\n protected readonly viteBuild = $inject(ViteBuildProvider);\n protected readonly color = $inject(ConsoleColorProvider);\n protected readonly envUtils = $inject(EnvUtils);\n protected readonly secretsCommand = $inject(SecretsCommand);\n\n /**\n * Common flags for env/app targeting.\n */\n protected readonly envFlags = t.object({\n env: t.optional(\n t.text({\n aliases: [\"e\"],\n description: \"Target environment\",\n }),\n ),\n app: t.optional(\n t.text({\n aliases: [\"a\"],\n description: \"Target specific app (monorepo)\",\n }),\n ),\n verbose: t.optional(\n t.boolean({\n aliases: [\"v\"],\n description: \"Verbose output\",\n }),\n ),\n json: t.optional(\n t.boolean({\n description: \"Output as JSON\",\n }),\n ),\n });\n\n // -----------------------------------------------------------------------\n // alepha p plan\n // -----------------------------------------------------------------------\n\n protected readonly plan = $command({\n name: \"plan\",\n description: \"Show project topology and resource names\",\n flags: this.envFlags,\n handler: async ({ flags, root }) => {\n const config = await this.inspector.resolveConfig(root);\n const env = flags.env ?? config.defaultEnv;\n const envConfig = config.environments[env];\n const adapterName = envConfig?.adapter ?? \"cloudflare\";\n\n const apps = await this.resolveApps(\n root,\n config,\n this.isServerless(adapterName),\n );\n const namingCtx = this.naming.forContext(config.project, env);\n\n // --- Data collection ---\n\n const hasDB = apps.some((a) => a.resources.hasDatabase);\n const hasBucket = apps.some((a) => a.resources.hasBucket);\n const envVars = await this.envUtils.parseEnv(root, [`.env.${env}`]);\n\n const resources: Array<{ label: string; value: string }> = [];\n\n const deployLabel = adapterName === \"vercel\" ? \"Project\" : \"Worker\";\n if (config.isMonorepo) {\n for (const app of apps) {\n resources.push({\n label: deployLabel,\n value: namingCtx.worker(app.name),\n });\n }\n } else {\n resources.push({ label: deployLabel, value: namingCtx.worker() });\n }\n\n if (adapterName === \"cloudflare\") {\n if (hasDB) {\n const dbUrl = envVars.DATABASE_URL ?? process.env.DATABASE_URL;\n if (dbUrl?.startsWith(\"postgres:\")) {\n resources.push({\n label: \"Hyperdrive\",\n value: namingCtx.hyperdrive(),\n });\n } else {\n resources.push({ label: \"D1\", value: namingCtx.d1() });\n }\n }\n\n if (hasBucket) {\n resources.push({ label: \"R2\", value: namingCtx.r2() });\n }\n\n for (const app of apps) {\n if (app.resources.hasKV) {\n resources.push({\n label: \"KV\",\n value: namingCtx.kv(config.isMonorepo ? app.name : undefined),\n });\n }\n if (app.resources.hasQueue) {\n resources.push({\n label: \"Queue\",\n value: namingCtx.queue(config.isMonorepo ? app.name : undefined),\n });\n }\n }\n }\n\n if (adapterName === \"docker\" || adapterName === \"docker-compose\") {\n if (hasDB && !envVars.DATABASE_URL) {\n resources.push({ label: \"Postgres\", value: \"postgres:17-alpine\" });\n }\n if (hasBucket && !envVars.S3_ENDPOINT) {\n resources.push({ label: \"RustFS\", value: \"rustfs/rustfs:latest\" });\n }\n }\n\n const excludedKeys =\n adapterName === \"vercel\"\n ? VercelAdapter.EXCLUDED_SECRET_KEYS\n : CloudflareAdapter.EXCLUDED_SECRET_KEYS;\n const secretCount = Object.entries(envVars).filter(\n ([key, value]) =>\n value && !excludedKeys.has(key) && !key.startsWith(\"VITE_\"),\n ).length;\n\n // --- JSON output ---\n\n if (flags.json) {\n const environments: Record<\n string,\n { adapter: string; domain?: string }\n > = {};\n for (const [key, val] of Object.entries(config.environments)) {\n environments[key] = {\n adapter: val.adapter,\n ...(val.domain ? { domain: val.domain } : {}),\n };\n }\n\n const output: PlatformPlanOutput = {\n project: config.project,\n env,\n mode: config.isMonorepo ? \"monorepo\" : \"standalone\",\n apps: apps.map((a) => ({\n name: a.name,\n path: a.path,\n resources: a.resources,\n })),\n environments,\n resources,\n secretCount,\n };\n\n process.stdout.write(`${JSON.stringify(output, null, 2)}\\n`);\n return;\n }\n\n // --- Tree output ---\n\n const c = this.color;\n\n process.stdout.write(\n `\\n\\u{1F4E6} ${c.set(\"WHITE_BOLD\", config.project)} ${c.set(\"GREY_DARK\", \"\\u2014\")} ${c.set(\"CYAN\", env)}\\n\\n`,\n );\n\n if (config.isMonorepo) {\n process.stdout.write(\n ` ${c.set(\"GREY_LIGHT\", \"Mode:\")} monorepo (${config.appPaths.length} apps)\\n`,\n );\n for (const [i, appPath] of config.appPaths.entries()) {\n const appName = config.appNames.get(appPath) ?? appPath;\n const prefix =\n i === config.appPaths.length - 1\n ? \"\\u2514\\u2500\\u2500\"\n : \"\\u251C\\u2500\\u2500\";\n process.stdout.write(\n ` ${c.set(\"GREY_DARK\", prefix)} ${c.set(\"CYAN\", appName.padEnd(10))} ${c.set(\"GREY_DARK\", appPath)}\\n`,\n );\n }\n } else {\n process.stdout.write(` ${c.set(\"GREY_LIGHT\", \"Mode:\")} standalone\\n`);\n }\n\n process.stdout.write(`\\n ${c.set(\"GREY_LIGHT\", \"Environments:\")}\\n`);\n const envKeys = Object.keys(config.environments);\n for (const [i, envKey] of envKeys.entries()) {\n const envConfig = config.environments[envKey];\n const prefix =\n i === envKeys.length - 1\n ? \"\\u2514\\u2500\\u2500\"\n : \"\\u251C\\u2500\\u2500\";\n const domain = envConfig.domain\n ? ` ${c.set(\"GREY_DARK\", envConfig.domain)}`\n : \"\";\n const marker = envKey === env ? ` ${c.set(\"GREEN\", \"\\u25C0\")}` : \"\";\n process.stdout.write(\n ` ${c.set(\"GREY_DARK\", prefix)} ${c.set(\"CYAN\", envKey.padEnd(10))} ${c.set(\"GREY_LIGHT\", envConfig.adapter)}${domain}${marker}\\n`,\n );\n }\n\n process.stdout.write(`\\n ${c.set(\"GREY_LIGHT\", \"Resources:\")}\\n`);\n\n if (secretCount > 0) {\n resources.push({\n label: \"Secrets\",\n value: `${secretCount} from .env.${env}`,\n });\n }\n\n for (const [i, res] of resources.entries()) {\n const isLast = i === resources.length - 1;\n const branch = isLast ? \"\\u2514\\u2500\\u2500\" : \"\\u251C\\u2500\\u2500\";\n process.stdout.write(\n ` ${c.set(\"GREY_DARK\", branch)} ${c.set(\"GREY_LIGHT\", res.label.padEnd(11))} ${c.set(\"CYAN\", res.value)}\\n`,\n );\n }\n\n process.stdout.write(\"\\n\");\n },\n });\n\n // -----------------------------------------------------------------------\n // alepha p up\n // -----------------------------------------------------------------------\n\n protected readonly up = $command({\n name: \"up\",\n mode: \"production\",\n description: \"Build, migrate, and deploy\",\n flags: this.envFlags,\n handler: async ({ flags, root, run }) => {\n process.env.NODE_ENV = \"production\";\n\n const config = await this.inspector.resolveConfig(root);\n const env = flags.env ?? config.defaultEnv;\n const adapter = config.environments[env]?.adapter ?? \"cloudflare\";\n const apps = await this.resolveApps(\n root,\n config,\n this.isServerless(adapter),\n );\n\n await this.orchestrator.up({\n root,\n env,\n app: flags.app,\n apps,\n run,\n });\n },\n });\n\n // -----------------------------------------------------------------------\n // alepha p down\n // -----------------------------------------------------------------------\n\n protected readonly down = $command({\n name: \"down\",\n description: \"Tear down an environment\",\n flags: this.envFlags,\n handler: async ({ flags, root, run, ask }) => {\n if (!flags.env) {\n throw new AlephaError(\n \"--env is required for teardown. This command deletes resources.\",\n );\n }\n\n const config = await this.inspector.resolveConfig(root);\n const adapter = config.environments[flags.env]?.adapter ?? \"cloudflare\";\n const apps = await this.resolveApps(\n root,\n config,\n this.isServerless(adapter),\n );\n\n await this.orchestrator.down({\n root,\n env: flags.env,\n app: flags.app,\n apps,\n run,\n confirm: async (prompt) => {\n ask.intro(\"Confirm teardown\");\n const value = await ask(prompt);\n ask.outro(\"\");\n return value;\n },\n });\n },\n });\n\n // -----------------------------------------------------------------------\n // alepha p status\n // -----------------------------------------------------------------------\n\n protected readonly status = $command({\n name: \"status\",\n aliases: [\"s\"],\n description: \"Show deployed state\",\n flags: this.envFlags,\n handler: async ({ flags, root, run }) => {\n const config = await this.inspector.resolveConfig(root);\n const env = flags.env ?? config.defaultEnv;\n const adapter = config.environments[env]?.adapter ?? \"cloudflare\";\n const apps = await this.resolveApps(\n root,\n config,\n this.isServerless(adapter),\n );\n\n const { state } = await this.orchestrator.status({\n root,\n env,\n apps,\n run,\n });\n\n // --- JSON output ---\n\n if (flags.json) {\n run.end();\n\n const output: PlatformStatusOutput = {\n project: config.project,\n env,\n adapter: config.environments[env].adapter,\n ...state,\n };\n\n process.stdout.write(`${JSON.stringify(output, null, 2)}\\n`);\n return;\n }\n\n // --- Tree output ---\n\n run.end();\n\n const c = this.color;\n\n process.stdout.write(\n `\\n\\u{1F4E6} ${c.set(\"WHITE_BOLD\", config.project)} ${c.set(\"GREY_DARK\", \"\\u2014\")} ${c.set(\"CYAN\", env)} ${c.set(\"GREY_DARK\", `(${config.environments[env].adapter})`)}\\n\\n`,\n );\n\n const hasDB = state.databases.length > 0;\n const hasBuckets = state.buckets.length > 0;\n\n process.stdout.write(` ${c.set(\"GREY_LIGHT\", \"Workers:\")}\\n`);\n for (const [i, w] of state.workers.entries()) {\n const isLast = i === state.workers.length - 1;\n const branch = isLast ? \"\\u2514\\u2500\\u2500\" : \"\\u251C\\u2500\\u2500\";\n if (w.exists) {\n const versionShort = w.version?.slice(0, 8) ?? \"unknown\";\n const tag = w.tag ? ` ${c.set(\"GREY_DARK\", `(${w.tag})`)}` : \"\";\n const date = w.createdAt\n ? ` ${c.set(\"GREY_DARK\", \"\\u2014\")} ${c.set(\"GREY_DARK\", new Date(w.createdAt).toLocaleString())}`\n : \"\";\n process.stdout.write(\n ` ${c.set(\"GREY_DARK\", branch)} ${c.set(\"CYAN\", w.name)} ${c.set(\"GREEN\", \"\\u2713\")} ${c.set(\"GREY_LIGHT\", versionShort)}${tag}${date}\\n`,\n );\n } else {\n process.stdout.write(\n ` ${c.set(\"GREY_DARK\", branch)} ${c.set(\"CYAN\", w.name)} ${c.set(\"RED\", \"\\u2717\")} ${c.set(\"RED\", \"not deployed\")}\\n`,\n );\n }\n }\n\n if (hasDB) {\n const envVars = await this.envUtils.parseEnv(root, [`.env.${env}`]);\n const dbUrl = envVars.DATABASE_URL ?? process.env.DATABASE_URL;\n const dbLabel = dbUrl?.startsWith(\"postgres:\")\n ? \"Hyperdrive:\"\n : \"Database:\";\n process.stdout.write(`\\n ${c.set(\"GREY_LIGHT\", dbLabel)}\\n`);\n for (const [i, db] of state.databases.entries()) {\n const isLast = i === state.databases.length - 1;\n const branch = isLast ? \"\\u2514\\u2500\\u2500\" : \"\\u251C\\u2500\\u2500\";\n if (db.exists) {\n const id = db.id\n ? ` ${c.set(\"GREY_LIGHT\", db.id.slice(0, 8))}`\n : \"\";\n const detail = db.detail\n ? ` ${c.set(\"GREY_DARK\", \"\\u2014\")} ${c.set(\"GREY_DARK\", db.detail.slice(0, 40))}`\n : \"\";\n process.stdout.write(\n ` ${c.set(\"GREY_DARK\", branch)} ${c.set(\"CYAN\", db.name)} ${c.set(\"GREEN\", \"\\u2713\")}${id}${detail}\\n`,\n );\n } else {\n process.stdout.write(\n ` ${c.set(\"GREY_DARK\", branch)} ${c.set(\"CYAN\", db.name)} ${c.set(\"RED\", \"\\u2717\")} ${c.set(\"RED\", \"not provisioned\")}\\n`,\n );\n }\n }\n }\n\n if (hasBuckets) {\n process.stdout.write(`\\n ${c.set(\"GREY_LIGHT\", \"Buckets:\")}\\n`);\n for (const [i, b] of state.buckets.entries()) {\n const isLast = i === state.buckets.length - 1;\n const branch = isLast ? \"\\u2514\\u2500\\u2500\" : \"\\u251C\\u2500\\u2500\";\n if (b.exists) {\n process.stdout.write(\n ` ${c.set(\"GREY_DARK\", branch)} ${c.set(\"CYAN\", b.name)} ${c.set(\"GREEN\", \"\\u2713\")}\\n`,\n );\n } else {\n process.stdout.write(\n ` ${c.set(\"GREY_DARK\", branch)} ${c.set(\"CYAN\", b.name)} ${c.set(\"RED\", \"\\u2717\")} ${c.set(\"RED\", \"not provisioned\")}\\n`,\n );\n }\n }\n }\n\n if (state.kvNamespaces.length > 0) {\n process.stdout.write(`\\n ${c.set(\"GREY_LIGHT\", \"KV:\")}\\n`);\n for (const [i, kv] of state.kvNamespaces.entries()) {\n const isLast = i === state.kvNamespaces.length - 1;\n const branch = isLast ? \"\\u2514\\u2500\\u2500\" : \"\\u251C\\u2500\\u2500\";\n if (kv.exists) {\n const id = kv.id\n ? ` ${c.set(\"GREY_LIGHT\", kv.id.slice(0, 8))}`\n : \"\";\n process.stdout.write(\n ` ${c.set(\"GREY_DARK\", branch)} ${c.set(\"CYAN\", kv.name)} ${c.set(\"GREEN\", \"\\u2713\")}${id}\\n`,\n );\n } else {\n process.stdout.write(\n ` ${c.set(\"GREY_DARK\", branch)} ${c.set(\"CYAN\", kv.name)} ${c.set(\"RED\", \"\\u2717\")} ${c.set(\"RED\", \"not provisioned\")}\\n`,\n );\n }\n }\n }\n\n if (state.queues.length > 0) {\n process.stdout.write(`\\n ${c.set(\"GREY_LIGHT\", \"Queues:\")}\\n`);\n for (const [i, q] of state.queues.entries()) {\n const isLast = i === state.queues.length - 1;\n const branch = isLast ? \"\\u2514\\u2500\\u2500\" : \"\\u251C\\u2500\\u2500\";\n if (q.exists) {\n const id = q.id ? ` ${c.set(\"GREY_LIGHT\", q.id.slice(0, 8))}` : \"\";\n process.stdout.write(\n ` ${c.set(\"GREY_DARK\", branch)} ${c.set(\"CYAN\", q.name)} ${c.set(\"GREEN\", \"\\u2713\")}${id}\\n`,\n );\n } else {\n process.stdout.write(\n ` ${c.set(\"GREY_DARK\", branch)} ${c.set(\"CYAN\", q.name)} ${c.set(\"RED\", \"\\u2717\")} ${c.set(\"RED\", \"not provisioned\")}\\n`,\n );\n }\n }\n }\n\n if (state.secrets.length > 0) {\n process.stdout.write(`\\n ${c.set(\"GREY_LIGHT\", \"Secrets:\")}\\n`);\n for (const [i, s] of state.secrets.entries()) {\n const isLast = i === state.secrets.length - 1;\n const branch = isLast ? \"\\u2514\\u2500\\u2500\" : \"\\u251C\\u2500\\u2500\";\n const icon = s.deployed\n ? c.set(\"GREEN\", \"\\u2713\")\n : c.set(\"RED\", \"\\u2717\");\n process.stdout.write(\n ` ${c.set(\"GREY_DARK\", branch)} ${c.set(\"CYAN\", s.name)} ${icon}\\n`,\n );\n }\n }\n\n process.stdout.write(\"\\n\");\n },\n });\n\n // -----------------------------------------------------------------------\n // Granular commands\n // -----------------------------------------------------------------------\n\n protected readonly build = $command({\n name: \"build\",\n mode: \"production\",\n description: \"Build all apps locally\",\n flags: this.envFlags,\n handler: async ({ flags, root, run }) => {\n process.env.NODE_ENV = \"production\";\n const config = await this.inspector.resolveConfig(root);\n const env = flags.env ?? config.defaultEnv;\n const envConfig = config.environments[env];\n const adapter = this.orchestrator.resolveAdapter(envConfig.adapter);\n const apps = await this.resolveApps(\n root,\n config,\n this.isServerless(envConfig.adapter),\n );\n const namingCtx = this.naming.forContext(config.project, env);\n\n const ctx = {\n project: config.project,\n env,\n envConfig,\n apps,\n root,\n naming: namingCtx,\n };\n\n const targets = flags.app\n ? apps.filter((a) => a.name === flags.app)\n : apps;\n\n for (const app of targets) {\n await adapter.build({ ...ctx, app }, run);\n }\n },\n });\n\n protected readonly deploy = $command({\n name: \"deploy\",\n description: \"Deploy apps to cloud\",\n flags: this.envFlags,\n handler: async ({ flags, root, run }) => {\n const config = await this.inspector.resolveConfig(root);\n const env = flags.env ?? config.defaultEnv;\n const envConfig = config.environments[env];\n const adapter = this.orchestrator.resolveAdapter(envConfig.adapter);\n const apps = await this.resolveApps(\n root,\n config,\n this.isServerless(envConfig.adapter),\n );\n const namingCtx = this.naming.forContext(config.project, env);\n\n const ctx = {\n project: config.project,\n env,\n envConfig,\n apps,\n root,\n naming: namingCtx,\n };\n\n await adapter.authenticate(ctx, run);\n\n const targets = flags.app\n ? apps.filter((a) => a.name === flags.app)\n : apps;\n\n for (const app of targets) {\n await adapter.deploy({ ...ctx, app }, run);\n }\n },\n });\n\n protected readonly migrate = $command({\n name: \"migrate\",\n description: \"Run database migrations\",\n flags: this.envFlags,\n handler: async ({ flags, root, run }) => {\n const config = await this.inspector.resolveConfig(root);\n const env = flags.env ?? config.defaultEnv;\n const envConfig = config.environments[env];\n const adapter = this.orchestrator.resolveAdapter(envConfig.adapter);\n const apps = await this.resolveApps(\n root,\n config,\n this.isServerless(envConfig.adapter),\n );\n const namingCtx = this.naming.forContext(config.project, env);\n\n const ctx = {\n project: config.project,\n env,\n envConfig,\n apps,\n root,\n naming: namingCtx,\n };\n\n await adapter.authenticate(ctx, run);\n await adapter.migrate(ctx, run);\n },\n });\n\n // -----------------------------------------------------------------------\n // Parent command\n // -----------------------------------------------------------------------\n\n public readonly platform = $command({\n name: \"platform\",\n aliases: [\"p\"],\n description: \"Cloud deployment orchestrator\",\n children: [\n this.plan,\n this.up,\n this.down,\n this.status,\n this.build,\n this.deploy,\n this.migrate,\n this.secretsCommand.secrets,\n ],\n handler: async ({ help, root }) => {\n await this.inspector.resolveConfig(root);\n help();\n },\n });\n\n // -----------------------------------------------------------------------\n // Helpers\n // -----------------------------------------------------------------------\n\n /**\n * Resolve app definitions.\n *\n * For standalone: returns a single app from the root.\n * For monorepo: resolves each app path, introspects for resources.\n *\n * NOTE: Resource detection (hasDatabase, hasBucket, etc.) requires\n * ViteBuildProvider.init() per app. This is expensive -- only done\n * for up/down/status, not for plan.\n */\n protected async resolveApps(\n root: string,\n config: ResolvedPlatformConfig,\n isServerless: boolean,\n ): Promise<AppDefinition[]> {\n if (!config.isMonorepo) {\n const entry = await this.boot.getAppEntry(root);\n if (isServerless) {\n process.env.ALEPHA_SERVERLESS = \"true\";\n }\n const appAlepha = await this.viteBuild.init({ entry });\n delete process.env.ALEPHA_SERVERLESS;\n const resources = this.detectResources(appAlepha);\n\n return [\n {\n name: config.project,\n path: \"\",\n entry,\n resources,\n },\n ];\n }\n\n const apps: AppDefinition[] = [];\n for (const appPath of config.appPaths) {\n const appRoot = `${root}/${appPath}`;\n const entry = await this.boot.getAppEntry(appRoot);\n if (isServerless) {\n process.env.ALEPHA_SERVERLESS = \"true\";\n }\n const appAlepha = await this.viteBuild.init({ entry });\n delete process.env.ALEPHA_SERVERLESS;\n const name = config.appNames.get(appPath) ?? appPath;\n const resources = this.detectResources(appAlepha);\n\n apps.push({ name, path: appPath, entry, resources });\n }\n\n return apps;\n }\n\n protected isServerless(adapter: string): boolean {\n return adapter === \"vercel\" || adapter === \"cloudflare\";\n }\n\n protected detectResources(alepha: any): DetectedResources {\n let hasDatabase = false;\n let hasBucket = false;\n let hasKV = false;\n let hasQueue = false;\n let hasCron = false;\n\n try {\n const repo = alepha.inject(\"RepositoryProvider\");\n hasDatabase = repo.getRepositories().length > 0;\n } catch {}\n\n try {\n const buckets = alepha.primitives(\"$bucket\");\n hasBucket = buckets.length > 0;\n } catch {}\n\n try {\n hasKV =\n alepha\n .primitives(\"cache\")\n .filter((it: any) => it.options?.provider !== \"memory\").length > 0;\n } catch {}\n\n try {\n hasQueue = alepha.primitives(\"queue\").length > 0;\n } catch {}\n\n try {\n const cron = alepha.inject(\"CronProvider\");\n hasCron = cron.getCronJobs().length > 0;\n } catch {}\n\n return { hasDatabase, hasBucket, hasKV, hasQueue, hasCron };\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","/**\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});\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 { AlephaCli } from \"alepha/cli\";\nimport { CloudflareAdapter } from \"./adapters/CloudflareAdapter.ts\";\nimport { DockerAdapter } from \"./adapters/DockerAdapter.ts\";\nimport { VercelAdapter } from \"./adapters/VercelAdapter.ts\";\nimport { PlatformCommand } from \"./commands/platform.ts\";\nimport { SecretsCommand } from \"./commands/SecretsCommand.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 { DockerComposeGenerator } from \"./services/DockerComposeGenerator.ts\";\nimport { DockerSshService } from \"./services/DockerSshService.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\nexport const AlephaCliPlatform = $module({\n name: \"alepha.cli.platform\",\n services: [\n AlephaCli,\n PlatformCommand,\n SecretsCommand,\n CloudflareAdapter,\n CloudflareApi,\n DockerAdapter,\n DockerComposeGenerator,\n DockerSshService,\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\n// ---------------------------------------------------------------------------\n\nexport * from \"./adapters/CloudflareAdapter.ts\";\nexport * from \"./adapters/DockerAdapter.ts\";\nexport * from \"./adapters/PlatformAdapter.ts\";\nexport * from \"./adapters/VercelAdapter.ts\";\nexport * from \"./atoms/platformOptions.ts\";\nexport * from \"./commands/platform.ts\";\nexport * from \"./commands/SecretsCommand.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/DockerComposeGenerator.ts\";\nexport * from \"./services/DockerSshService.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
+ {"version":3,"file":"index.js","names":[],"sources":["../../../src/cli/platform/providers/PlatformCacheProvider.ts","../../../src/cli/platform/schemas/cloudflare.ts","../../../src/cli/platform/services/WranglerApi.ts","../../../src/cli/platform/services/CloudflareApi.ts","../../../src/cli/platform/adapters/PlatformAdapter.ts","../../../src/cli/platform/adapters/CloudflareAdapter.ts","../../../src/cli/platform/schemas/vercel.ts","../../../src/cli/platform/services/VercelCli.ts","../../../src/cli/platform/services/VercelApi.ts","../../../src/cli/platform/adapters/VercelAdapter.ts","../../../src/cli/platform/atoms/platformOptions.ts","../../../src/cli/platform/services/NamingService.ts","../../../src/cli/platform/services/PlatformInspector.ts","../../../src/cli/platform/services/PlatformOrchestrator.ts","../../../src/cli/platform/providers/GitHubSecretStore.ts","../../../src/cli/platform/services/SecretFilterService.ts","../../../src/cli/platform/commands/SecretsCommand.ts","../../../src/cli/platform/commands/platform.ts","../../../src/cli/platform/providers/MemorySecretStore.ts","../../../src/cli/platform/providers/SecretStoreProvider.ts","../../../src/cli/platform/schemas/platform.ts","../../../src/cli/platform/index.ts"],"sourcesContent":["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.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 service: t.string(),\n environment: 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\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 ): Promise<string | undefined> {\n const output = await this.runShell(\n `wrangler deploy --name=${workerName} --no-bundle --config=${configPath}`,\n { resolve: true, capture: true },\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 ): Promise<void> {\n await this.runShell(\n `wrangler d1 migrations apply ${dbName} --remote --config=${configPath}`,\n { resolve: true, env: { CI: \"1\" } },\n );\n }\n\n // -------------------------------------------------------------------------\n // Secrets\n // -------------------------------------------------------------------------\n\n /**\n * Push secrets in bulk to a worker.\n */\n public async secretBulk(\n secretsPath: string,\n workerName: string,\n ): Promise<void> {\n await this.runShell(\n `wrangler secret bulk ${secretsPath} --name=${workerName}`,\n { resolve: true },\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 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 cloudflareR2ListSchema,\n cloudflareSecretSchema,\n cloudflareVersionListSchema,\n cloudflareWorkerSchema,\n createD1BodySchema,\n createHyperdriveBodySchema,\n createKVBodySchema,\n createQueueBodySchema,\n createR2BodySchema,\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 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\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 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 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.fetch<CloudflareD1[]>(\n `/accounts/${accountId}/d1/database`,\n { schema: t.array(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 return await this.fetch<CloudflareD1>(\n `/accounts/${accountId}/d1/database`,\n {\n method: \"POST\",\n body: { name, primary_location_hint: location },\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.fetch<CloudflareKV[]>(\n `/accounts/${accountId}/storage/kv/namespaces`,\n { schema: t.array(cloudflareKVSchema) },\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 const res = await this.fetch<{ buckets: CloudflareR2[] }>(\n `/accounts/${accountId}/r2/buckets`,\n { schema: cloudflareR2ListSchema },\n );\n return res.buckets;\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 // Queues\n // -------------------------------------------------------------------------\n\n public async listQueues(): Promise<CloudflareQueue[]> {\n const accountId = await this.resolveAccountId();\n return await this.fetch<CloudflareQueue[]>(\n `/accounts/${accountId}/queues`,\n { schema: t.array(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.fetch<CloudflareQueueConsumer[]>(\n `/accounts/${accountId}/queues/${queueId}/consumers`,\n { schema: t.array(cloudflareQueueConsumerSchema) },\n );\n }\n\n public async deleteQueueConsumer(\n queueId: string,\n consumerService: string,\n ): Promise<void> {\n const accountId = await this.resolveAccountId();\n await this.fetch(\n `/accounts/${accountId}/queues/${queueId}/consumers/${consumerService}`,\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.fetch<CloudflareHyperdrive[]>(\n `/accounts/${accountId}/hyperdrive/configs`,\n { schema: t.array(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 const res = await this.fetch<{ deployments: CloudflareDeployment[] }>(\n `/accounts/${accountId}/workers/scripts/${scriptName}/deployments`,\n { schema: cloudflareDeploymentListSchema },\n );\n return res.deployments;\n }\n\n public async listVersions(scriptName: string): Promise<CloudflareVersion[]> {\n const accountId = await this.resolveAccountId();\n const res = await this.fetch<{ items: CloudflareVersion[] }>(\n `/accounts/${accountId}/workers/scripts/${scriptName}/versions`,\n { schema: cloudflareVersionListSchema },\n );\n return res.items;\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 // 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 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 };\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 // 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 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// Context types\n// ---------------------------------------------------------------------------\n\nexport interface DetectedResources {\n hasDatabase: boolean;\n hasBucket: boolean;\n hasKV: boolean;\n hasQueue: boolean;\n hasCron: boolean;\n}\n\nexport interface AppDefinition {\n /**\n * Slugified app name (from package.json).\n */\n name: string;\n\n /**\n * Relative path from root (e.g., \"apps/api\").\n * Empty string for standalone apps.\n */\n path: string;\n\n /**\n * Resolved entry points for this app.\n */\n entry: AppEntry;\n\n /**\n * Cloud resources detected by introspecting the app.\n */\n resources: DetectedResources;\n}\n\nexport interface PlatformContext {\n /**\n * Slugified project name (from root package.json or 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 * All apps in the project.\n */\n apps: AppDefinition[];\n\n /**\n * Monorepo/project root path.\n */\n root: string;\n\n /**\n * Resource name generator bound to this project+env.\n */\n naming: NamingContext;\n}\n\nexport interface AppContext extends PlatformContext {\n /**\n * The specific app being operated on.\n */\n app: AppDefinition;\n}\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 * 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 { $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 { CloudflareApi } from \"../services/CloudflareApi.ts\";\nimport { WranglerApi } from \"../services/WranglerApi.ts\";\nimport {\n type AppContext,\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 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(CloudflareApi);\n protected readonly wrangler = $inject(WranglerApi);\n protected readonly runner = $inject(Runner);\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 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.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 const appDir = ctx.app.path\n ? this.fs.join(ctx.root, ctx.app.path)\n : ctx.root;\n\n const env: Record<string, string> = {};\n\n if (ctx.app.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.app.resources.hasBucket) {\n env.R2_BUCKET_NAME = ctx.naming.r2();\n }\n\n if (ctx.app.resources.hasKV) {\n const kvName = ctx.naming.kv(\n ctx.apps.length > 1 ? ctx.app.name : undefined,\n );\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.app.resources.hasQueue) {\n env.CLOUDFLARE_QUEUE_NAME = ctx.naming.queue(\n ctx.apps.length > 1 ? ctx.app.name : undefined,\n );\n }\n\n if (ctx.envConfig.domain) {\n env.CLOUDFLARE_DOMAIN = ctx.envConfig.domain;\n }\n\n await run({\n name: \"alepha build -t cloudflare\",\n handler: async () => {\n await this.runShell(\"alepha build -t cloudflare\", {\n root: appDir,\n env,\n });\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 const workerName = ctx.naming.worker(\n ctx.apps.length > 1 ? ctx.app.name : undefined,\n );\n const distDir = ctx.app.path\n ? this.fs.join(ctx.root, ctx.app.path, \"dist\")\n : this.fs.join(ctx.root, \"dist\");\n\n let url: string | undefined;\n\n await run({\n name: `deploy worker ${ctx.app.name}`,\n handler: async () => {\n url = await this.wrangler.deploy(\n workerName,\n `${distDir}/wrangler.jsonc`,\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 \"HYPERDRIVE_ID\",\n \"POSTGRES_SCHEMA\",\n \"NODE_ENV\",\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 // Filter out binding/build vars, VITE_* vars, and empty values\n const secrets: Record<string, string> = {};\n for (const [key, value] of Object.entries(envVars)) {\n if (!value) continue;\n if (CloudflareAdapter.EXCLUDED_SECRET_KEYS.has(key)) continue;\n if (key.startsWith(\"VITE_\")) continue;\n secrets[key] = value;\n }\n\n if (Object.keys(secrets).length === 0) {\n return;\n }\n\n // Push secrets to each worker\n for (const app of ctx.apps) {\n const workerName = ctx.naming.worker(\n ctx.apps.length > 1 ? app.name : undefined,\n );\n\n await run({\n name: `push secrets to ${workerName}`,\n handler: async () => {\n const secretsPath = await this.utils.writeConfigFile(\n \"secrets.json\",\n JSON.stringify(secrets),\n ctx.root,\n );\n\n await this.wrangler.secretBulk(secretsPath, workerName);\n },\n });\n }\n }\n\n // -------------------------------------------------------------------------\n // provision (REST API)\n // -------------------------------------------------------------------------\n\n override async provision(\n ctx: PlatformContext,\n run: RunnerMethod,\n ): Promise<void> {\n const needsDB = ctx.apps.some((a) => a.resources.hasDatabase);\n const needsBucket = ctx.apps.some((a) => a.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\n for (const app of ctx.apps) {\n if (app.resources.hasKV) {\n const kvName = ctx.naming.kv(\n ctx.apps.length > 1 ? app.name : undefined,\n );\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 (app.resources.hasQueue) {\n const queueName = ctx.naming.queue(\n ctx.apps.length > 1 ? app.name : undefined,\n );\n tasks.push({\n name: `provision queue (${queueName})`,\n handler: async () => {\n await this.ensureQueue(queueName);\n },\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 const needsDB = ctx.apps.some((a) => a.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 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 if (await this.fs.exists(migrationsDir)) {\n await this.runShell(`alepha db migrations check --mode ${ctx.env}`, {\n resolve: true,\n env,\n });\n } else {\n await this.runShell(`alepha db migrations create --mode ${ctx.env}`, {\n resolve: true,\n env,\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(dbName, \"dist/wrangler.jsonc\");\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 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 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 for (const app of ctx.apps) {\n const name = ctx.naming.worker(\n ctx.apps.length > 1 ? app.name : undefined,\n );\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.apps.some((a) => a.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.apps.some((a) => a.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\n // KV\n for (const app of ctx.apps) {\n if (app.resources.hasKV) {\n const kvName = ctx.naming.kv(\n ctx.apps.length > 1 ? app.name : undefined,\n );\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 }\n\n // Queues\n for (const app of ctx.apps) {\n if (app.resources.hasQueue) {\n const queueName = ctx.naming.queue(\n ctx.apps.length > 1 ? app.name : undefined,\n );\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\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 ctx.apps.length > 1 ? ctx.apps[0].name : undefined,\n );\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 // 1. Remove queue consumers (must happen before worker or queue deletion)\n for (const app of ctx.apps) {\n if (app.resources.hasQueue) {\n const workerName = ctx.naming.worker(\n ctx.apps.length > 1 ? app.name : undefined,\n );\n const queueName = ctx.naming.queue(\n ctx.apps.length > 1 ? app.name : undefined,\n );\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\n // 2. Delete workers\n for (const app of ctx.apps) {\n const name = ctx.naming.worker(\n ctx.apps.length > 1 ? app.name : undefined,\n );\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\n // 3. Delete queues (after worker is gone)\n for (const app of ctx.apps) {\n if (app.resources.hasQueue) {\n const name = ctx.naming.queue(\n ctx.apps.length > 1 ? app.name : undefined,\n );\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 }\n\n // 4. Delete KV namespaces\n for (const app of ctx.apps) {\n if (app.resources.hasKV) {\n const name = ctx.naming.kv(ctx.apps.length > 1 ? app.name : undefined);\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\n // 5. Delete R2 bucket\n // TODO: empty bucket via S3-compatible API before deletion (needs native S3 client)\n // const needsBucket = ctx.apps.some((a) => a.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.api.deleteR2(name);\n // } catch (error: any) {\n // const msg = String(error.message || \"\");\n // if (\n // msg.includes(\"does not exist\") ||\n // msg.includes(\"NoSuchBucket\")\n // ) {\n // // Already gone, nothing to do\n // } else if (\n // msg.includes(\"not empty\") ||\n // msg.includes(\"BucketNotEmpty\")\n // ) {\n // this.log.warn(\n // `Bucket ${name} is not empty -- skipped. Empty it manually.`,\n // );\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.apps.some((a) => a.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 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 const latest = deployments.at(-1);\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","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.app.path\n ? this.fs.join(ctx.root, ctx.app.path)\n : 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 = ctx.app.path\n ? this.fs.join(ctx.root, ctx.app.path, \"dist\")\n : this.fs.join(ctx.root, \"dist\");\n\n const projectName = ctx.naming.worker(\n ctx.apps.length > 1 ? ctx.app.name : undefined,\n );\n\n let url: string | undefined;\n\n await run({\n name: `deploy ${ctx.app.name}`,\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 for (const app of ctx.apps) {\n const projectName = ctx.naming.worker(\n ctx.apps.length > 1 ? app.name : undefined,\n );\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 for (const app of ctx.apps) {\n const projectName = ctx.naming.worker(\n ctx.apps.length > 1 ? app.name : undefined,\n );\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 ctx.apps.length > 1 ? ctx.apps[0].name : undefined,\n );\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 for (const app of ctx.apps) {\n const projectName = ctx.naming.worker(\n ctx.apps.length > 1 ? app.name : undefined,\n );\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 { $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 * Monorepo app paths relative to root. Omit for standalone apps.\n */\n apps: t.optional(t.array(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 * 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 * Secret store backend.\n */\n store: 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 t.object({\n adapter: t.enum([\"cloudflare\", \"vercel\"]),\n domain: t.optional(t.text()),\n domains: t.optional(t.record(t.text(), 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 domains?: Record<string, string>;\n vars?: Record<string, string>;\n}\n","/**\n * Generates deterministic resource names for cloud deployments.\n *\n * Pattern: <project>-<env>[-<app>]\n *\n * All segments are slugified (lowercase, alphanumeric + dashes, max 63 chars).\n */\nexport class NamingService {\n public forContext(project: string, env: string): NamingContext {\n const prefix = `${this.slugify(project)}-${this.slugify(env)}`;\n return new NamingContext(prefix, this);\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 protected readonly naming: NamingService;\n\n constructor(prefix: string, naming: NamingService) {\n this.prefix = prefix;\n this.naming = naming;\n }\n\n public worker(app?: string): string {\n return app ? `${this.prefix}-${this.naming.slugify(app)}` : 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(app?: string): string {\n return app ? `${this.prefix}-${this.naming.slugify(app)}` : this.prefix;\n }\n\n public queue(app?: string): string {\n return app ? `${this.prefix}-${this.naming.slugify(app)}` : this.prefix;\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 } from \"./NamingService.ts\";\n\nexport interface ResolvedPlatformConfig {\n project: string;\n defaultEnv: string;\n environments: Record<string, EnvironmentConfig>;\n isMonorepo: boolean;\n appPaths: string[];\n appNames: Map<string, string>;\n}\n\n/**\n * Reads platform config and resolves project topology.\n *\n * Validates project names, app paths, and environment configuration.\n * Does NOT introspect app code for resources — that happens at deploy time\n * via ViteBuildProvider.\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 public async resolveConfig(root: string): Promise<ResolvedPlatformConfig> {\n if (!this.options) {\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 // Re-read after potential wizard\n const opts = this.options;\n const platform = opts;\n\n // Resolve project name\n const project = await this.resolveProjectName(root, opts.name);\n\n // Resolve apps\n const appPaths = opts.apps ?? [];\n const isMonorepo = appPaths.length > 0;\n const appNames = new Map<string, string>();\n\n for (const appPath of appPaths) {\n const name = await this.resolveAppName(root, appPath);\n appNames.set(appPath, name);\n }\n\n return {\n project: this.naming.slugify(project),\n defaultEnv: platform.default ?? \"production\",\n environments: platform.environments as Record<string, EnvironmentConfig>,\n isMonorepo,\n appPaths,\n appNames,\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 protected async resolveAppName(\n root: string,\n appPath: string,\n ): Promise<string> {\n const pkgPath = this.fs.join(root, appPath, \"package.json\");\n\n try {\n const pkg = await this.fs.readJsonFile<{ name?: string }>(pkgPath);\n if (pkg.name) {\n return this.naming.slugify(pkg.name);\n }\n } catch {}\n\n throw new AlephaError(\n `Missing \"name\" field in package.json for app at ${appPath}.`,\n );\n }\n}\n","import { $inject, AlephaError } from \"alepha\";\nimport type { RunnerMethod } from \"alepha/command\";\nimport { $logger, ConsoleColorProvider } from \"alepha/logger\";\nimport { CloudflareAdapter } from \"../adapters/CloudflareAdapter.ts\";\nimport type {\n AppDefinition,\n PlatformAdapter,\n PlatformContext,\n PlatformState,\n} from \"../adapters/PlatformAdapter.ts\";\nimport { VercelAdapter } from \"../adapters/VercelAdapter.ts\";\nimport { type NamingContext, NamingService } 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\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 app?: string;\n apps: AppDefinition[];\n run: RunnerMethod;\n }): Promise<void> {\n const { root, env, app: appFilter, apps, 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 namingCtx = this.naming.forContext(config.project, env);\n\n const ctx: PlatformContext = {\n project: config.project,\n env,\n envConfig,\n apps,\n root,\n naming: namingCtx,\n };\n\n // 1. Auth\n await adapter.authenticate(ctx, run);\n\n // 2. Filter apps\n const targetApps = appFilter\n ? apps.filter((a) => a.name === appFilter)\n : apps;\n\n if (targetApps.length === 0 && appFilter) {\n throw new AlephaError(\n `App \"${appFilter}\" not found. Available: ${apps.map((a) => a.name).join(\", \")}`,\n );\n }\n\n // 3. Provision (before build so resource IDs are available for wrangler config)\n await adapter.provision(ctx, run);\n\n // 4. Build\n for (const a of targetApps) {\n await adapter.build({ ...ctx, app: a }, run);\n }\n\n // 5. Migrate\n await adapter.migrate(ctx, run);\n\n // 6. Deploy\n const urls: string[] = [];\n for (const a of targetApps) {\n const url = await adapter.deploy({ ...ctx, app: a }, run);\n if (url) {\n urls.push(url);\n }\n }\n\n // 7. Secrets (push .env.{env} secrets to deployed workers)\n await adapter.secrets(ctx, run);\n\n run.end();\n\n const c = this.color;\n\n if (envConfig.domain) {\n this.log.info(\"\");\n this.log.info(\n ` ${c.set(\"GREEN\", \"\\u2192\")} ${c.set(\"CYAN\", `https://${envConfig.domain}`)}`,\n );\n this.log.info(\"\");\n } else {\n for (const url of 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 app?: string;\n apps: AppDefinition[];\n run: RunnerMethod;\n confirm: (prompt: string) => Promise<string>;\n }): Promise<boolean> {\n const { root, env, app: appFilter, apps, 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 namingCtx = this.naming.forContext(config.project, env);\n\n const ctx: PlatformContext = {\n project: config.project,\n env,\n envConfig,\n apps: appFilter ? apps.filter((a) => a.name === appFilter) : apps,\n root,\n naming: namingCtx,\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 apps: AppDefinition[];\n }): Promise<{\n config: ResolvedPlatformConfig;\n naming: NamingContext;\n apps: AppDefinition[];\n }> {\n const { root, env, apps } = options;\n const config = await this.inspector.resolveConfig(root);\n const namingCtx = this.naming.forContext(config.project, env);\n return { config, naming: namingCtx, apps };\n }\n\n // -------------------------------------------------------------------------\n // status\n // -------------------------------------------------------------------------\n\n public async status(options: {\n root: string;\n env: string;\n apps: AppDefinition[];\n run: RunnerMethod;\n }): Promise<{ config: ResolvedPlatformConfig; state: PlatformState }> {\n const { root, env, apps, 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 namingCtx = this.naming.forContext(config.project, env);\n\n const ctx: PlatformContext = {\n project: config.project,\n env,\n envConfig,\n apps,\n root,\n naming: namingCtx,\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","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","/**\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","import { $inject, $state, AlephaError, t } from \"alepha\";\nimport { $command, EnvUtils } from \"alepha/command\";\nimport { $logger, ConsoleColorProvider } from \"alepha/logger\";\nimport { platformOptions } from \"../atoms/platformOptions.ts\";\nimport { GitHubSecretStore } from \"../providers/GitHubSecretStore.ts\";\nimport type { SecretStoreProvider } from \"../providers/SecretStoreProvider.ts\";\nimport { NamingService } from \"../services/NamingService.ts\";\nimport { PlatformInspector } from \"../services/PlatformInspector.ts\";\nimport { SecretFilterService } from \"../services/SecretFilterService.ts\";\n\nexport class SecretsCommand {\n protected readonly log = $logger();\n protected readonly options = $state(platformOptions);\n protected readonly inspector = $inject(PlatformInspector);\n protected readonly naming = $inject(NamingService);\n protected readonly envUtils = $inject(EnvUtils);\n protected readonly githubStore = $inject(GitHubSecretStore);\n protected readonly filter = $inject(SecretFilterService);\n protected readonly color = $inject(ConsoleColorProvider);\n\n protected readonly envFlags = t.object({\n env: t.optional(\n t.text({\n aliases: [\"e\"],\n description: \"Target environment\",\n }),\n ),\n });\n\n // -----------------------------------------------------------------------\n // alepha p secrets list\n // -----------------------------------------------------------------------\n\n protected readonly list = $command({\n name: \"list\",\n aliases: [\"ls\"],\n description: \"List secrets in the remote store\",\n flags: t.object({\n env: t.optional(\n t.text({\n aliases: [\"e\"],\n description: \"Target environment\",\n }),\n ),\n format: t.optional(\n t.text({\n aliases: [\"f\"],\n description: \"Output format: table (default), gha\",\n }),\n ),\n }),\n handler: async ({ flags, root, run }) => {\n const config = await this.inspector.resolveConfig(root);\n const env = flags.env ?? config.defaultEnv;\n const envName = this.resolveEnvironmentName(config.project, env);\n const format = flags.format ?? \"table\";\n\n const store = this.resolveStore();\n await store.ensureAvailable();\n const remoteSecrets = await store.list(envName);\n\n run.end();\n\n if (format === \"gha\") {\n process.stdout.write(\n `# Generated by alepha — environment: ${envName}\\n`,\n );\n process.stdout.write(\"env:\\n\");\n for (const secret of remoteSecrets) {\n const localName = this.filter.toLocalName(secret.name);\n process.stdout.write(\n ` ${localName}: \\${{ secrets.${secret.name} }}\\n`,\n );\n }\n return;\n }\n\n // table format\n const c = this.color;\n\n if (remoteSecrets.length === 0) {\n process.stdout.write(\n `\\nNo secrets in environment ${c.set(\"CYAN\", envName)}.\\n\\n`,\n );\n return;\n }\n\n process.stdout.write(\n `\\n${c.set(\"GREY_LIGHT\", \"Environment:\")} ${c.set(\"CYAN\", envName)}\\n\\n`,\n );\n\n const maxNameLen = Math.max(\n ...remoteSecrets.map((s) => s.name.length),\n 4,\n );\n\n process.stdout.write(\n ` ${c.set(\"GREY_LIGHT\", \"NAME\".padEnd(maxNameLen + 2))}${c.set(\"GREY_LIGHT\", \"UPDATED\")}\\n`,\n );\n\n for (const secret of remoteSecrets) {\n const updated = secret.updatedAt\n ? new Date(secret.updatedAt).toLocaleString()\n : \"-\";\n process.stdout.write(\n ` ${c.set(\"CYAN\", secret.name.padEnd(maxNameLen + 2))}${c.set(\"GREY_DARK\", updated)}\\n`,\n );\n }\n\n process.stdout.write(\"\\n\");\n },\n });\n\n // -----------------------------------------------------------------------\n // alepha p secrets diff\n // -----------------------------------------------------------------------\n\n protected readonly diff = $command({\n name: \"diff\",\n description: \"Compare local .env keys with remote store\",\n flags: this.envFlags,\n handler: async ({ flags, root, run }) => {\n const config = await this.inspector.resolveConfig(root);\n const env = flags.env ?? config.defaultEnv;\n const envName = this.resolveEnvironmentName(config.project, env);\n\n const envVars = await this.envUtils.parseEnv(root, [`.env.${env}`]);\n const filtered = this.filter.filter(envVars);\n const localKeys = new Set(\n Object.keys(filtered).map((k) => this.filter.toRemoteName(k)),\n );\n\n const store = this.resolveStore();\n await store.ensureAvailable();\n const remoteSecrets = await store.list(envName);\n const remoteKeys = new Set(remoteSecrets.map((s) => s.name));\n\n run.end();\n\n const c = this.color;\n const allKeys = [...new Set([...localKeys, ...remoteKeys])].sort();\n\n process.stdout.write(\n `\\n${c.set(\"GREY_LIGHT\", \"Environment:\")} ${c.set(\"CYAN\", envName)}\\n\\n`,\n );\n\n let hasChanges = false;\n for (const key of allKeys) {\n const inLocal = localKeys.has(key);\n const inRemote = remoteKeys.has(key);\n\n if (inLocal && !inRemote) {\n process.stdout.write(` ${c.set(\"GREEN\", \"+\")} ${key}\\n`);\n hasChanges = true;\n } else if (!inLocal && inRemote) {\n process.stdout.write(` ${c.set(\"RED\", \"-\")} ${key}\\n`);\n hasChanges = true;\n } else {\n process.stdout.write(` ${c.set(\"GREY_DARK\", \"=\")} ${key}\\n`);\n }\n }\n\n if (!hasChanges) {\n process.stdout.write(\n ` ${c.set(\"GREEN\", \"Local and remote are in sync.\")}\\n`,\n );\n }\n\n process.stdout.write(\"\\n\");\n },\n });\n\n // -----------------------------------------------------------------------\n // alepha p secrets apply\n // -----------------------------------------------------------------------\n\n protected readonly apply = $command({\n name: \"apply\",\n description: \"Push local .env secrets to the remote store\",\n flags: t.object({\n env: t.optional(\n t.text({\n aliases: [\"e\"],\n description: \"Target environment\",\n }),\n ),\n \"dry-run\": t.optional(\n t.boolean({\n description: \"Preview changes without pushing\",\n }),\n ),\n }),\n handler: async ({ flags, root, run }) => {\n const config = await this.inspector.resolveConfig(root);\n const env = flags.env ?? config.defaultEnv;\n const envName = this.resolveEnvironmentName(config.project, env);\n const dryRun = flags[\"dry-run\"] ?? false;\n\n const envVars = await this.envUtils.parseEnv(root, [`.env.${env}`]);\n const filtered = this.filter.filter(envVars);\n const keys = Object.keys(filtered);\n\n if (keys.length === 0) {\n run.end();\n process.stdout.write(\"\\nNo secrets to push.\\n\\n\");\n return;\n }\n\n if (dryRun) {\n run.end();\n const c = this.color;\n process.stdout.write(\n `\\n${c.set(\"GREY_LIGHT\", \"Dry run — environment:\")} ${c.set(\"CYAN\", envName)}\\n\\n`,\n );\n for (const key of keys) {\n process.stdout.write(` ${c.set(\"GREEN\", \"+\")} ${key}\\n`);\n }\n process.stdout.write(\n `\\n ${keys.length} secret(s) would be pushed.\\n\\n`,\n );\n return;\n }\n\n const store = this.resolveStore();\n await store.ensureAvailable();\n await store.ensureEnvironment(envName);\n\n for (const key of keys) {\n const remoteName = this.filter.toRemoteName(key);\n await run({\n name: `push ${remoteName}`,\n handler: async () => {\n await store.set(envName, remoteName, filtered[key]);\n },\n });\n }\n\n run.end();\n process.stdout.write(\n `\\n${keys.length} secret(s) pushed to ${envName}.\\n`,\n );\n },\n });\n\n // -----------------------------------------------------------------------\n // Parent command\n // -----------------------------------------------------------------------\n\n public readonly secrets = $command({\n name: \"secrets\",\n aliases: [\"sec\"],\n description: \"Manage secrets in external stores\",\n children: [this.list, this.diff, this.apply],\n handler: async ({ help }) => {\n help();\n },\n });\n\n // -----------------------------------------------------------------------\n // Helpers\n // -----------------------------------------------------------------------\n\n public resolveStore(): SecretStoreProvider {\n const storeName = this.options?.secrets?.store ?? \"github\";\n switch (storeName) {\n case \"github\":\n return this.githubStore;\n default:\n throw new AlephaError(\n `Unknown secret store \"${storeName}\". Available: github`,\n );\n }\n }\n\n protected resolveEnvironmentName(project: string, env: string): string {\n const pattern =\n this.options?.secrets?.environmentPattern ?? \"{project}-{env}\";\n\n return pattern\n .replace(\"{project}\", this.naming.slugify(project))\n .replace(\"{env}\", this.naming.slugify(env));\n }\n}\n","import { $inject, $state, AlephaError, t } from \"alepha\";\nimport { AppEntryProvider, ViteBuildProvider } from \"alepha/cli\";\nimport { $command, EnvUtils } from \"alepha/command\";\nimport { $logger, ConsoleColorProvider } from \"alepha/logger\";\nimport { CloudflareAdapter } from \"../adapters/CloudflareAdapter.ts\";\nimport type {\n AppDefinition,\n DetectedResources,\n} from \"../adapters/PlatformAdapter.ts\";\nimport { VercelAdapter } from \"../adapters/VercelAdapter.ts\";\nimport { platformOptions } from \"../atoms/platformOptions.ts\";\nimport type {\n PlatformPlanOutput,\n PlatformStatusOutput,\n} from \"../schemas/platform.ts\";\nimport { NamingService } from \"../services/NamingService.ts\";\nimport {\n PlatformInspector,\n type ResolvedPlatformConfig,\n} from \"../services/PlatformInspector.ts\";\nimport { PlatformOrchestrator } from \"../services/PlatformOrchestrator.ts\";\nimport { SecretsCommand } from \"./SecretsCommand.ts\";\n\nexport class PlatformCommand {\n protected readonly log = $logger();\n protected readonly options = $state(platformOptions);\n protected readonly orchestrator = $inject(PlatformOrchestrator);\n protected readonly inspector = $inject(PlatformInspector);\n protected readonly naming = $inject(NamingService);\n protected readonly boot = $inject(AppEntryProvider);\n protected readonly viteBuild = $inject(ViteBuildProvider);\n protected readonly color = $inject(ConsoleColorProvider);\n protected readonly envUtils = $inject(EnvUtils);\n protected readonly secretsCommand = $inject(SecretsCommand);\n\n /**\n * Common flags for env/app targeting.\n */\n protected readonly envFlags = t.object({\n env: t.optional(\n t.text({\n aliases: [\"e\"],\n description: \"Target environment\",\n }),\n ),\n app: t.optional(\n t.text({\n aliases: [\"a\"],\n description: \"Target specific app (monorepo)\",\n }),\n ),\n verbose: t.optional(\n t.boolean({\n aliases: [\"v\"],\n description: \"Verbose output\",\n }),\n ),\n json: t.optional(\n t.boolean({\n description: \"Output as JSON\",\n }),\n ),\n });\n\n // -----------------------------------------------------------------------\n // alepha p plan\n // -----------------------------------------------------------------------\n\n protected readonly plan = $command({\n name: \"plan\",\n description: \"Show project topology and resource names\",\n flags: this.envFlags,\n handler: async ({ flags, root }) => {\n const config = await this.inspector.resolveConfig(root);\n const env = flags.env ?? config.defaultEnv;\n const envConfig = config.environments[env];\n const adapterName = envConfig?.adapter ?? \"cloudflare\";\n\n const apps = await this.resolveApps(\n root,\n config,\n this.isServerless(adapterName),\n );\n const namingCtx = this.naming.forContext(config.project, env);\n\n // --- Data collection ---\n\n const hasDB = apps.some((a) => a.resources.hasDatabase);\n const hasBucket = apps.some((a) => a.resources.hasBucket);\n const envVars = await this.envUtils.parseEnv(root, [`.env.${env}`]);\n\n const resources: Array<{ label: string; value: string }> = [];\n\n const deployLabel = adapterName === \"vercel\" ? \"Project\" : \"Worker\";\n if (config.isMonorepo) {\n for (const app of apps) {\n resources.push({\n label: deployLabel,\n value: namingCtx.worker(app.name),\n });\n }\n } else {\n resources.push({ label: deployLabel, value: namingCtx.worker() });\n }\n\n if (adapterName === \"cloudflare\") {\n if (hasDB) {\n const dbUrl = envVars.DATABASE_URL ?? process.env.DATABASE_URL;\n if (dbUrl?.startsWith(\"postgres:\")) {\n resources.push({\n label: \"Hyperdrive\",\n value: namingCtx.hyperdrive(),\n });\n } else {\n resources.push({ label: \"D1\", value: namingCtx.d1() });\n }\n }\n\n if (hasBucket) {\n resources.push({ label: \"R2\", value: namingCtx.r2() });\n }\n\n for (const app of apps) {\n if (app.resources.hasKV) {\n resources.push({\n label: \"KV\",\n value: namingCtx.kv(config.isMonorepo ? app.name : undefined),\n });\n }\n if (app.resources.hasQueue) {\n resources.push({\n label: \"Queue\",\n value: namingCtx.queue(config.isMonorepo ? app.name : undefined),\n });\n }\n }\n }\n\n const excludedKeys =\n adapterName === \"vercel\"\n ? VercelAdapter.EXCLUDED_SECRET_KEYS\n : CloudflareAdapter.EXCLUDED_SECRET_KEYS;\n const secretCount = Object.entries(envVars).filter(\n ([key, value]) =>\n value && !excludedKeys.has(key) && !key.startsWith(\"VITE_\"),\n ).length;\n\n // --- JSON output ---\n\n if (flags.json) {\n const environments: Record<\n string,\n { adapter: string; domain?: string }\n > = {};\n for (const [key, val] of Object.entries(config.environments)) {\n environments[key] = {\n adapter: val.adapter,\n ...(val.domain ? { domain: val.domain } : {}),\n };\n }\n\n const output: PlatformPlanOutput = {\n project: config.project,\n env,\n mode: config.isMonorepo ? \"monorepo\" : \"standalone\",\n apps: apps.map((a) => ({\n name: a.name,\n path: a.path,\n resources: a.resources,\n })),\n environments,\n resources,\n secretCount,\n };\n\n process.stdout.write(`${JSON.stringify(output, null, 2)}\\n`);\n return;\n }\n\n // --- Tree output ---\n\n const c = this.color;\n\n process.stdout.write(\n `\\n\\u{1F4E6} ${c.set(\"WHITE_BOLD\", config.project)} ${c.set(\"GREY_DARK\", \"\\u2014\")} ${c.set(\"CYAN\", env)}\\n\\n`,\n );\n\n if (config.isMonorepo) {\n process.stdout.write(\n ` ${c.set(\"GREY_LIGHT\", \"Mode:\")} monorepo (${config.appPaths.length} apps)\\n`,\n );\n for (const [i, appPath] of config.appPaths.entries()) {\n const appName = config.appNames.get(appPath) ?? appPath;\n const prefix =\n i === config.appPaths.length - 1\n ? \"\\u2514\\u2500\\u2500\"\n : \"\\u251C\\u2500\\u2500\";\n process.stdout.write(\n ` ${c.set(\"GREY_DARK\", prefix)} ${c.set(\"CYAN\", appName.padEnd(10))} ${c.set(\"GREY_DARK\", appPath)}\\n`,\n );\n }\n } else {\n process.stdout.write(` ${c.set(\"GREY_LIGHT\", \"Mode:\")} standalone\\n`);\n }\n\n process.stdout.write(`\\n ${c.set(\"GREY_LIGHT\", \"Environments:\")}\\n`);\n const envKeys = Object.keys(config.environments);\n for (const [i, envKey] of envKeys.entries()) {\n const envConfig = config.environments[envKey];\n const prefix =\n i === envKeys.length - 1\n ? \"\\u2514\\u2500\\u2500\"\n : \"\\u251C\\u2500\\u2500\";\n const domain = envConfig.domain\n ? ` ${c.set(\"GREY_DARK\", envConfig.domain)}`\n : \"\";\n const marker = envKey === env ? ` ${c.set(\"GREEN\", \"\\u25C0\")}` : \"\";\n process.stdout.write(\n ` ${c.set(\"GREY_DARK\", prefix)} ${c.set(\"CYAN\", envKey.padEnd(10))} ${c.set(\"GREY_LIGHT\", envConfig.adapter)}${domain}${marker}\\n`,\n );\n }\n\n process.stdout.write(`\\n ${c.set(\"GREY_LIGHT\", \"Resources:\")}\\n`);\n\n if (secretCount > 0) {\n resources.push({\n label: \"Secrets\",\n value: `${secretCount} from .env.${env}`,\n });\n }\n\n for (const [i, res] of resources.entries()) {\n const isLast = i === resources.length - 1;\n const branch = isLast ? \"\\u2514\\u2500\\u2500\" : \"\\u251C\\u2500\\u2500\";\n process.stdout.write(\n ` ${c.set(\"GREY_DARK\", branch)} ${c.set(\"GREY_LIGHT\", res.label.padEnd(11))} ${c.set(\"CYAN\", res.value)}\\n`,\n );\n }\n\n process.stdout.write(\"\\n\");\n },\n });\n\n // -----------------------------------------------------------------------\n // alepha p up\n // -----------------------------------------------------------------------\n\n protected readonly up = $command({\n name: \"up\",\n mode: \"production\",\n description: \"Build, migrate, and deploy\",\n flags: this.envFlags,\n handler: async ({ flags, root, run }) => {\n process.env.NODE_ENV = \"production\";\n\n const config = await this.inspector.resolveConfig(root);\n const env = flags.env ?? config.defaultEnv;\n const adapter = config.environments[env]?.adapter ?? \"cloudflare\";\n const apps = await this.resolveApps(\n root,\n config,\n this.isServerless(adapter),\n );\n\n await this.orchestrator.up({\n root,\n env,\n app: flags.app,\n apps,\n run,\n });\n },\n });\n\n // -----------------------------------------------------------------------\n // alepha p down\n // -----------------------------------------------------------------------\n\n protected readonly down = $command({\n name: \"down\",\n description: \"Tear down an environment\",\n flags: this.envFlags,\n handler: async ({ flags, root, run, ask }) => {\n if (!flags.env) {\n throw new AlephaError(\n \"--env is required for teardown. This command deletes resources.\",\n );\n }\n\n const config = await this.inspector.resolveConfig(root);\n const adapter = config.environments[flags.env]?.adapter ?? \"cloudflare\";\n const apps = await this.resolveApps(\n root,\n config,\n this.isServerless(adapter),\n );\n\n await this.orchestrator.down({\n root,\n env: flags.env,\n app: flags.app,\n apps,\n run,\n confirm: async (prompt) => {\n ask.intro(\"Confirm teardown\");\n const value = await ask(prompt);\n ask.outro(\"\");\n return value;\n },\n });\n },\n });\n\n // -----------------------------------------------------------------------\n // alepha p status\n // -----------------------------------------------------------------------\n\n protected readonly status = $command({\n name: \"status\",\n aliases: [\"s\"],\n description: \"Show deployed state\",\n flags: this.envFlags,\n handler: async ({ flags, root, run }) => {\n const config = await this.inspector.resolveConfig(root);\n const env = flags.env ?? config.defaultEnv;\n const adapter = config.environments[env]?.adapter ?? \"cloudflare\";\n const apps = await this.resolveApps(\n root,\n config,\n this.isServerless(adapter),\n );\n\n const { state } = await this.orchestrator.status({\n root,\n env,\n apps,\n run,\n });\n\n // --- JSON output ---\n\n if (flags.json) {\n run.end();\n\n const output: PlatformStatusOutput = {\n project: config.project,\n env,\n adapter: config.environments[env].adapter,\n ...state,\n };\n\n process.stdout.write(`${JSON.stringify(output, null, 2)}\\n`);\n return;\n }\n\n // --- Tree output ---\n\n run.end();\n\n const c = this.color;\n\n process.stdout.write(\n `\\n\\u{1F4E6} ${c.set(\"WHITE_BOLD\", config.project)} ${c.set(\"GREY_DARK\", \"\\u2014\")} ${c.set(\"CYAN\", env)} ${c.set(\"GREY_DARK\", `(${config.environments[env].adapter})`)}\\n\\n`,\n );\n\n const hasDB = state.databases.length > 0;\n const hasBuckets = state.buckets.length > 0;\n\n process.stdout.write(` ${c.set(\"GREY_LIGHT\", \"Workers:\")}\\n`);\n for (const [i, w] of state.workers.entries()) {\n const isLast = i === state.workers.length - 1;\n const branch = isLast ? \"\\u2514\\u2500\\u2500\" : \"\\u251C\\u2500\\u2500\";\n if (w.exists) {\n const versionShort = w.version?.slice(0, 8) ?? \"unknown\";\n const tag = w.tag ? ` ${c.set(\"GREY_DARK\", `(${w.tag})`)}` : \"\";\n const date = w.createdAt\n ? ` ${c.set(\"GREY_DARK\", \"\\u2014\")} ${c.set(\"GREY_DARK\", new Date(w.createdAt).toLocaleString())}`\n : \"\";\n process.stdout.write(\n ` ${c.set(\"GREY_DARK\", branch)} ${c.set(\"CYAN\", w.name)} ${c.set(\"GREEN\", \"\\u2713\")} ${c.set(\"GREY_LIGHT\", versionShort)}${tag}${date}\\n`,\n );\n } else {\n process.stdout.write(\n ` ${c.set(\"GREY_DARK\", branch)} ${c.set(\"CYAN\", w.name)} ${c.set(\"RED\", \"\\u2717\")} ${c.set(\"RED\", \"not deployed\")}\\n`,\n );\n }\n }\n\n if (hasDB) {\n const envVars = await this.envUtils.parseEnv(root, [`.env.${env}`]);\n const dbUrl = envVars.DATABASE_URL ?? process.env.DATABASE_URL;\n const dbLabel = dbUrl?.startsWith(\"postgres:\")\n ? \"Hyperdrive:\"\n : \"Database:\";\n process.stdout.write(`\\n ${c.set(\"GREY_LIGHT\", dbLabel)}\\n`);\n for (const [i, db] of state.databases.entries()) {\n const isLast = i === state.databases.length - 1;\n const branch = isLast ? \"\\u2514\\u2500\\u2500\" : \"\\u251C\\u2500\\u2500\";\n if (db.exists) {\n const id = db.id\n ? ` ${c.set(\"GREY_LIGHT\", db.id.slice(0, 8))}`\n : \"\";\n const detail = db.detail\n ? ` ${c.set(\"GREY_DARK\", \"\\u2014\")} ${c.set(\"GREY_DARK\", db.detail.slice(0, 40))}`\n : \"\";\n process.stdout.write(\n ` ${c.set(\"GREY_DARK\", branch)} ${c.set(\"CYAN\", db.name)} ${c.set(\"GREEN\", \"\\u2713\")}${id}${detail}\\n`,\n );\n } else {\n process.stdout.write(\n ` ${c.set(\"GREY_DARK\", branch)} ${c.set(\"CYAN\", db.name)} ${c.set(\"RED\", \"\\u2717\")} ${c.set(\"RED\", \"not provisioned\")}\\n`,\n );\n }\n }\n }\n\n if (hasBuckets) {\n process.stdout.write(`\\n ${c.set(\"GREY_LIGHT\", \"Buckets:\")}\\n`);\n for (const [i, b] of state.buckets.entries()) {\n const isLast = i === state.buckets.length - 1;\n const branch = isLast ? \"\\u2514\\u2500\\u2500\" : \"\\u251C\\u2500\\u2500\";\n if (b.exists) {\n process.stdout.write(\n ` ${c.set(\"GREY_DARK\", branch)} ${c.set(\"CYAN\", b.name)} ${c.set(\"GREEN\", \"\\u2713\")}\\n`,\n );\n } else {\n process.stdout.write(\n ` ${c.set(\"GREY_DARK\", branch)} ${c.set(\"CYAN\", b.name)} ${c.set(\"RED\", \"\\u2717\")} ${c.set(\"RED\", \"not provisioned\")}\\n`,\n );\n }\n }\n }\n\n if (state.kvNamespaces.length > 0) {\n process.stdout.write(`\\n ${c.set(\"GREY_LIGHT\", \"KV:\")}\\n`);\n for (const [i, kv] of state.kvNamespaces.entries()) {\n const isLast = i === state.kvNamespaces.length - 1;\n const branch = isLast ? \"\\u2514\\u2500\\u2500\" : \"\\u251C\\u2500\\u2500\";\n if (kv.exists) {\n const id = kv.id\n ? ` ${c.set(\"GREY_LIGHT\", kv.id.slice(0, 8))}`\n : \"\";\n process.stdout.write(\n ` ${c.set(\"GREY_DARK\", branch)} ${c.set(\"CYAN\", kv.name)} ${c.set(\"GREEN\", \"\\u2713\")}${id}\\n`,\n );\n } else {\n process.stdout.write(\n ` ${c.set(\"GREY_DARK\", branch)} ${c.set(\"CYAN\", kv.name)} ${c.set(\"RED\", \"\\u2717\")} ${c.set(\"RED\", \"not provisioned\")}\\n`,\n );\n }\n }\n }\n\n if (state.queues.length > 0) {\n process.stdout.write(`\\n ${c.set(\"GREY_LIGHT\", \"Queues:\")}\\n`);\n for (const [i, q] of state.queues.entries()) {\n const isLast = i === state.queues.length - 1;\n const branch = isLast ? \"\\u2514\\u2500\\u2500\" : \"\\u251C\\u2500\\u2500\";\n if (q.exists) {\n const id = q.id ? ` ${c.set(\"GREY_LIGHT\", q.id.slice(0, 8))}` : \"\";\n process.stdout.write(\n ` ${c.set(\"GREY_DARK\", branch)} ${c.set(\"CYAN\", q.name)} ${c.set(\"GREEN\", \"\\u2713\")}${id}\\n`,\n );\n } else {\n process.stdout.write(\n ` ${c.set(\"GREY_DARK\", branch)} ${c.set(\"CYAN\", q.name)} ${c.set(\"RED\", \"\\u2717\")} ${c.set(\"RED\", \"not provisioned\")}\\n`,\n );\n }\n }\n }\n\n if (state.secrets.length > 0) {\n process.stdout.write(`\\n ${c.set(\"GREY_LIGHT\", \"Secrets:\")}\\n`);\n for (const [i, s] of state.secrets.entries()) {\n const isLast = i === state.secrets.length - 1;\n const branch = isLast ? \"\\u2514\\u2500\\u2500\" : \"\\u251C\\u2500\\u2500\";\n const icon = s.deployed\n ? c.set(\"GREEN\", \"\\u2713\")\n : c.set(\"RED\", \"\\u2717\");\n process.stdout.write(\n ` ${c.set(\"GREY_DARK\", branch)} ${c.set(\"CYAN\", s.name)} ${icon}\\n`,\n );\n }\n }\n\n process.stdout.write(\"\\n\");\n },\n });\n\n // -----------------------------------------------------------------------\n // Granular commands\n // -----------------------------------------------------------------------\n\n protected readonly build = $command({\n name: \"build\",\n mode: \"production\",\n description: \"Build all apps locally\",\n flags: this.envFlags,\n handler: async ({ flags, root, run }) => {\n process.env.NODE_ENV = \"production\";\n const config = await this.inspector.resolveConfig(root);\n const env = flags.env ?? config.defaultEnv;\n const envConfig = config.environments[env];\n const adapter = this.orchestrator.resolveAdapter(envConfig.adapter);\n const apps = await this.resolveApps(\n root,\n config,\n this.isServerless(envConfig.adapter),\n );\n const namingCtx = this.naming.forContext(config.project, env);\n\n const ctx = {\n project: config.project,\n env,\n envConfig,\n apps,\n root,\n naming: namingCtx,\n };\n\n const targets = flags.app\n ? apps.filter((a) => a.name === flags.app)\n : apps;\n\n for (const app of targets) {\n await adapter.build({ ...ctx, app }, run);\n }\n },\n });\n\n protected readonly deploy = $command({\n name: \"deploy\",\n description: \"Deploy apps to cloud\",\n flags: this.envFlags,\n handler: async ({ flags, root, run }) => {\n const config = await this.inspector.resolveConfig(root);\n const env = flags.env ?? config.defaultEnv;\n const envConfig = config.environments[env];\n const adapter = this.orchestrator.resolveAdapter(envConfig.adapter);\n const apps = await this.resolveApps(\n root,\n config,\n this.isServerless(envConfig.adapter),\n );\n const namingCtx = this.naming.forContext(config.project, env);\n\n const ctx = {\n project: config.project,\n env,\n envConfig,\n apps,\n root,\n naming: namingCtx,\n };\n\n await adapter.authenticate(ctx, run);\n\n const targets = flags.app\n ? apps.filter((a) => a.name === flags.app)\n : apps;\n\n for (const app of targets) {\n await adapter.deploy({ ...ctx, app }, run);\n }\n },\n });\n\n protected readonly migrate = $command({\n name: \"migrate\",\n description: \"Run database migrations\",\n flags: this.envFlags,\n handler: async ({ flags, root, run }) => {\n const config = await this.inspector.resolveConfig(root);\n const env = flags.env ?? config.defaultEnv;\n const envConfig = config.environments[env];\n const adapter = this.orchestrator.resolveAdapter(envConfig.adapter);\n const apps = await this.resolveApps(\n root,\n config,\n this.isServerless(envConfig.adapter),\n );\n const namingCtx = this.naming.forContext(config.project, env);\n\n const ctx = {\n project: config.project,\n env,\n envConfig,\n apps,\n root,\n naming: namingCtx,\n };\n\n await adapter.authenticate(ctx, run);\n await adapter.migrate(ctx, run);\n },\n });\n\n // -----------------------------------------------------------------------\n // Parent command\n // -----------------------------------------------------------------------\n\n public readonly platform = $command({\n name: \"platform\",\n aliases: [\"p\"],\n description: \"Cloud deployment orchestrator\",\n children: [\n this.plan,\n this.up,\n this.down,\n this.status,\n this.build,\n this.deploy,\n this.migrate,\n this.secretsCommand.secrets,\n ],\n handler: async ({ help, root }) => {\n await this.inspector.resolveConfig(root);\n help();\n },\n });\n\n // -----------------------------------------------------------------------\n // Helpers\n // -----------------------------------------------------------------------\n\n /**\n * Resolve app definitions.\n *\n * For standalone: returns a single app from the root.\n * For monorepo: resolves each app path, introspects for resources.\n *\n * NOTE: Resource detection (hasDatabase, hasBucket, etc.) requires\n * ViteBuildProvider.init() per app. This is expensive -- only done\n * for up/down/status, not for plan.\n */\n protected async resolveApps(\n root: string,\n config: ResolvedPlatformConfig,\n isServerless: boolean,\n ): Promise<AppDefinition[]> {\n if (!config.isMonorepo) {\n const entry = await this.boot.getAppEntry(root);\n if (isServerless) {\n process.env.ALEPHA_SERVERLESS = \"true\";\n }\n const appAlepha = await this.viteBuild.init({ entry });\n delete process.env.ALEPHA_SERVERLESS;\n const resources = this.detectResources(appAlepha);\n\n return [\n {\n name: config.project,\n path: \"\",\n entry,\n resources,\n },\n ];\n }\n\n const apps: AppDefinition[] = [];\n for (const appPath of config.appPaths) {\n const appRoot = `${root}/${appPath}`;\n const entry = await this.boot.getAppEntry(appRoot);\n if (isServerless) {\n process.env.ALEPHA_SERVERLESS = \"true\";\n }\n const appAlepha = await this.viteBuild.init({ entry });\n delete process.env.ALEPHA_SERVERLESS;\n const name = config.appNames.get(appPath) ?? appPath;\n const resources = this.detectResources(appAlepha);\n\n apps.push({ name, path: appPath, entry, resources });\n }\n\n return apps;\n }\n\n protected isServerless(adapter: string): boolean {\n return adapter === \"vercel\" || adapter === \"cloudflare\";\n }\n\n protected detectResources(alepha: any): DetectedResources {\n let hasDatabase = false;\n let hasBucket = false;\n let hasKV = false;\n let hasQueue = false;\n let hasCron = false;\n\n try {\n const repo = alepha.inject(\"RepositoryProvider\");\n hasDatabase = repo.getRepositories().length > 0;\n } catch {}\n\n try {\n const buckets = alepha.primitives(\"$bucket\");\n hasBucket = buckets.length > 0;\n } catch {}\n\n try {\n hasKV =\n alepha\n .primitives(\"cache\")\n .filter((it: any) => it.options?.provider !== \"memory\").length > 0;\n } catch {}\n\n try {\n hasQueue = alepha.primitives(\"queue\").length > 0;\n } catch {}\n\n try {\n const cron = alepha.inject(\"CronProvider\");\n hasCron = cron.getCronJobs().length > 0;\n } catch {}\n\n return { hasDatabase, hasBucket, hasKV, hasQueue, hasCron };\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","/**\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});\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 { AlephaCli } from \"alepha/cli\";\nimport { CloudflareAdapter } from \"./adapters/CloudflareAdapter.ts\";\nimport { VercelAdapter } from \"./adapters/VercelAdapter.ts\";\nimport { PlatformCommand } from \"./commands/platform.ts\";\nimport { SecretsCommand } from \"./commands/SecretsCommand.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\n/**\n * CLI plugin for multi-cloud deployment orchestration.\n *\n * Manages the full lifecycle of deploying Alepha apps: provision resources,\n * build, migrate databases, deploy, and sync secrets. Supports Cloudflare\n * Workers and Vercel.\n *\n * Commands:\n * - `alepha platform plan` — show project topology and resource names\n * - `alepha platform up` — full deployment pipeline\n * - `alepha platform down` — teardown an environment\n * - `alepha platform status` — inspect deployed resources\n * - `alepha platform build` — build apps locally\n * - `alepha platform deploy` — deploy to cloud\n * - `alepha platform migrate` — run database migrations\n * - `alepha platform secrets` — manage external secret stores\n *\n * Configuration in `alepha.config.ts`:\n *\n * ```typescript\n * import { AlephaCliPlatform } from \"alepha/cli/platform\";\n *\n * export default defineConfig({\n * services: [AlephaCliPlatform],\n * platform: {\n * environments: {\n * production: { adapter: \"cloudflare\", domain: \"myapp.com\" },\n * },\n * },\n * });\n * ```\n */\nexport const AlephaCliPlatformPlugin = $module({\n name: \"alepha.cli.plugins.platform\",\n services: [\n AlephaCli,\n PlatformCommand,\n SecretsCommand,\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\n// ---------------------------------------------------------------------------\n\nexport * from \"./adapters/CloudflareAdapter.ts\";\nexport * from \"./adapters/PlatformAdapter.ts\";\nexport * from \"./adapters/VercelAdapter.ts\";\nexport * from \"./atoms/platformOptions.ts\";\nexport * from \"./commands/platform.ts\";\nexport * from \"./commands/SecretsCommand.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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"}