@alchemy.run/fly 0.0.0 → 2.0.0-beta.85

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 (499) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +57 -4
  3. package/lib/App.d.ts +230 -0
  4. package/lib/App.d.ts.map +1 -0
  5. package/lib/App.js +338 -0
  6. package/lib/App.js.map +1 -0
  7. package/lib/AuthProvider.d.ts +22 -0
  8. package/lib/AuthProvider.d.ts.map +1 -0
  9. package/lib/AuthProvider.js +48 -0
  10. package/lib/AuthProvider.js.map +1 -0
  11. package/lib/BindService.d.ts +159 -0
  12. package/lib/BindService.d.ts.map +1 -0
  13. package/lib/BindService.js +222 -0
  14. package/lib/BindService.js.map +1 -0
  15. package/lib/Bootstrap.d.ts +8 -0
  16. package/lib/Bootstrap.d.ts.map +1 -0
  17. package/lib/Bootstrap.js +41 -0
  18. package/lib/Bootstrap.js.map +1 -0
  19. package/lib/Bucket.d.ts +278 -0
  20. package/lib/Bucket.d.ts.map +1 -0
  21. package/lib/Bucket.js +658 -0
  22. package/lib/Bucket.js.map +1 -0
  23. package/lib/BucketBinding.d.ts +33 -0
  24. package/lib/BucketBinding.d.ts.map +1 -0
  25. package/lib/BucketBinding.js +70 -0
  26. package/lib/BucketBinding.js.map +1 -0
  27. package/lib/Catalog.d.ts +28 -0
  28. package/lib/Catalog.d.ts.map +1 -0
  29. package/lib/Catalog.js +31 -0
  30. package/lib/Catalog.js.map +1 -0
  31. package/lib/Certificate.d.ts +189 -0
  32. package/lib/Certificate.d.ts.map +1 -0
  33. package/lib/Certificate.js +380 -0
  34. package/lib/Certificate.js.map +1 -0
  35. package/lib/Checkpoint.d.ts +55 -0
  36. package/lib/Checkpoint.d.ts.map +1 -0
  37. package/lib/Checkpoint.js +3 -0
  38. package/lib/Checkpoint.js.map +1 -0
  39. package/lib/CheckpointHttp.d.ts +22 -0
  40. package/lib/CheckpointHttp.d.ts.map +1 -0
  41. package/lib/CheckpointHttp.js +53 -0
  42. package/lib/CheckpointHttp.js.map +1 -0
  43. package/lib/ConnectPostgres.d.ts +58 -0
  44. package/lib/ConnectPostgres.d.ts.map +1 -0
  45. package/lib/ConnectPostgres.js +13 -0
  46. package/lib/ConnectPostgres.js.map +1 -0
  47. package/lib/ConnectPostgresHttp.d.ts +26 -0
  48. package/lib/ConnectPostgresHttp.d.ts.map +1 -0
  49. package/lib/ConnectPostgresHttp.js +57 -0
  50. package/lib/ConnectPostgresHttp.js.map +1 -0
  51. package/lib/Contributions.d.ts +7 -0
  52. package/lib/Contributions.d.ts.map +1 -0
  53. package/lib/Contributions.js +6 -0
  54. package/lib/Contributions.js.map +1 -0
  55. package/lib/Credentials.d.ts +33 -0
  56. package/lib/Credentials.d.ts.map +1 -0
  57. package/lib/Credentials.js +55 -0
  58. package/lib/Credentials.js.map +1 -0
  59. package/lib/Decrypt.d.ts +52 -0
  60. package/lib/Decrypt.d.ts.map +1 -0
  61. package/lib/Decrypt.js +3 -0
  62. package/lib/Decrypt.js.map +1 -0
  63. package/lib/DecryptHttp.d.ts +22 -0
  64. package/lib/DecryptHttp.d.ts.map +1 -0
  65. package/lib/DecryptHttp.js +43 -0
  66. package/lib/DecryptHttp.js.map +1 -0
  67. package/lib/DeleteObject.d.ts +29 -0
  68. package/lib/DeleteObject.d.ts.map +1 -0
  69. package/lib/DeleteObject.js +3 -0
  70. package/lib/DeleteObject.js.map +1 -0
  71. package/lib/DeleteObjectHttp.d.ts +12 -0
  72. package/lib/DeleteObjectHttp.d.ts.map +1 -0
  73. package/lib/DeleteObjectHttp.js +17 -0
  74. package/lib/DeleteObjectHttp.js.map +1 -0
  75. package/lib/Deployment.d.ts +51 -0
  76. package/lib/Deployment.d.ts.map +1 -0
  77. package/lib/Deployment.js +62 -0
  78. package/lib/Deployment.js.map +1 -0
  79. package/lib/DeploymentImages.d.ts +18 -0
  80. package/lib/DeploymentImages.d.ts.map +1 -0
  81. package/lib/DeploymentImages.js +61 -0
  82. package/lib/DeploymentImages.js.map +1 -0
  83. package/lib/DeploymentState.d.ts +17 -0
  84. package/lib/DeploymentState.d.ts.map +1 -0
  85. package/lib/DeploymentState.js +87 -0
  86. package/lib/DeploymentState.js.map +1 -0
  87. package/lib/Encrypt.d.ts +50 -0
  88. package/lib/Encrypt.d.ts.map +1 -0
  89. package/lib/Encrypt.js +3 -0
  90. package/lib/Encrypt.js.map +1 -0
  91. package/lib/EncryptHttp.d.ts +22 -0
  92. package/lib/EncryptHttp.d.ts.map +1 -0
  93. package/lib/EncryptHttp.js +39 -0
  94. package/lib/EncryptHttp.js.map +1 -0
  95. package/lib/Environment.d.ts +45 -0
  96. package/lib/Environment.d.ts.map +1 -0
  97. package/lib/Environment.js +43 -0
  98. package/lib/Environment.js.map +1 -0
  99. package/lib/Errors.d.ts +18 -0
  100. package/lib/Errors.d.ts.map +1 -0
  101. package/lib/Errors.js +13 -0
  102. package/lib/Errors.js.map +1 -0
  103. package/lib/Exec.d.ts +41 -0
  104. package/lib/Exec.d.ts.map +1 -0
  105. package/lib/Exec.js +3 -0
  106. package/lib/Exec.js.map +1 -0
  107. package/lib/ExecHttp.d.ts +22 -0
  108. package/lib/ExecHttp.d.ts.map +1 -0
  109. package/lib/ExecHttp.js +39 -0
  110. package/lib/ExecHttp.js.map +1 -0
  111. package/lib/GetObject.d.ts +34 -0
  112. package/lib/GetObject.d.ts.map +1 -0
  113. package/lib/GetObject.js +3 -0
  114. package/lib/GetObject.js.map +1 -0
  115. package/lib/GetObjectHttp.d.ts +12 -0
  116. package/lib/GetObjectHttp.d.ts.map +1 -0
  117. package/lib/GetObjectHttp.js +17 -0
  118. package/lib/GetObjectHttp.js.map +1 -0
  119. package/lib/GetSecret.d.ts +44 -0
  120. package/lib/GetSecret.d.ts.map +1 -0
  121. package/lib/GetSecret.js +3 -0
  122. package/lib/GetSecret.js.map +1 -0
  123. package/lib/GetSecretHttp.d.ts +22 -0
  124. package/lib/GetSecretHttp.d.ts.map +1 -0
  125. package/lib/GetSecretHttp.js +50 -0
  126. package/lib/GetSecretHttp.js.map +1 -0
  127. package/lib/HeadObject.d.ts +29 -0
  128. package/lib/HeadObject.d.ts.map +1 -0
  129. package/lib/HeadObject.js +3 -0
  130. package/lib/HeadObject.js.map +1 -0
  131. package/lib/HeadObjectHttp.d.ts +12 -0
  132. package/lib/HeadObjectHttp.d.ts.map +1 -0
  133. package/lib/HeadObjectHttp.js +17 -0
  134. package/lib/HeadObjectHttp.js.map +1 -0
  135. package/lib/IpAssignment.d.ts +258 -0
  136. package/lib/IpAssignment.d.ts.map +1 -0
  137. package/lib/IpAssignment.js +376 -0
  138. package/lib/IpAssignment.js.map +1 -0
  139. package/lib/ListObjectsV2.d.ts +29 -0
  140. package/lib/ListObjectsV2.d.ts.map +1 -0
  141. package/lib/ListObjectsV2.js +3 -0
  142. package/lib/ListObjectsV2.js.map +1 -0
  143. package/lib/ListObjectsV2Http.d.ts +12 -0
  144. package/lib/ListObjectsV2Http.d.ts.map +1 -0
  145. package/lib/ListObjectsV2Http.js +17 -0
  146. package/lib/ListObjectsV2Http.js.map +1 -0
  147. package/lib/ListSecrets.d.ts +53 -0
  148. package/lib/ListSecrets.d.ts.map +1 -0
  149. package/lib/ListSecrets.js +3 -0
  150. package/lib/ListSecrets.js.map +1 -0
  151. package/lib/ListSecretsHttp.d.ts +22 -0
  152. package/lib/ListSecretsHttp.d.ts.map +1 -0
  153. package/lib/ListSecretsHttp.js +35 -0
  154. package/lib/ListSecretsHttp.js.map +1 -0
  155. package/lib/Machine.d.ts +802 -0
  156. package/lib/Machine.d.ts.map +1 -0
  157. package/lib/Machine.js +773 -0
  158. package/lib/Machine.js.map +1 -0
  159. package/lib/MachineContainers.d.ts +44 -0
  160. package/lib/MachineContainers.d.ts.map +1 -0
  161. package/lib/MachineContainers.js +115 -0
  162. package/lib/MachineContainers.js.map +1 -0
  163. package/lib/Metadata.d.ts +109 -0
  164. package/lib/Metadata.d.ts.map +1 -0
  165. package/lib/Metadata.js +159 -0
  166. package/lib/Metadata.js.map +1 -0
  167. package/lib/MountVolume.d.ts +295 -0
  168. package/lib/MountVolume.d.ts.map +1 -0
  169. package/lib/MountVolume.js +20 -0
  170. package/lib/MountVolume.js.map +1 -0
  171. package/lib/Postgres.d.ts +298 -0
  172. package/lib/Postgres.d.ts.map +1 -0
  173. package/lib/Postgres.js +508 -0
  174. package/lib/Postgres.js.map +1 -0
  175. package/lib/PostgresMigrations.d.ts +20 -0
  176. package/lib/PostgresMigrations.d.ts.map +1 -0
  177. package/lib/PostgresMigrations.js +58 -0
  178. package/lib/PostgresMigrations.js.map +1 -0
  179. package/lib/Providers.d.ts +38 -0
  180. package/lib/Providers.d.ts.map +1 -0
  181. package/lib/Providers.js +95 -0
  182. package/lib/Providers.js.map +1 -0
  183. package/lib/PutObject.d.ts +35 -0
  184. package/lib/PutObject.d.ts.map +1 -0
  185. package/lib/PutObject.js +3 -0
  186. package/lib/PutObject.js.map +1 -0
  187. package/lib/PutObjectHttp.d.ts +12 -0
  188. package/lib/PutObjectHttp.d.ts.map +1 -0
  189. package/lib/PutObjectHttp.js +17 -0
  190. package/lib/PutObjectHttp.js.map +1 -0
  191. package/lib/ReadRedis.d.ts +26 -0
  192. package/lib/ReadRedis.d.ts.map +1 -0
  193. package/lib/ReadRedis.js +3 -0
  194. package/lib/ReadRedis.js.map +1 -0
  195. package/lib/ReadRedisHttp.d.ts +11 -0
  196. package/lib/ReadRedisHttp.d.ts.map +1 -0
  197. package/lib/ReadRedisHttp.js +15 -0
  198. package/lib/ReadRedisHttp.js.map +1 -0
  199. package/lib/ReadWriteRedis.d.ts +29 -0
  200. package/lib/ReadWriteRedis.d.ts.map +1 -0
  201. package/lib/ReadWriteRedis.js +3 -0
  202. package/lib/ReadWriteRedis.js.map +1 -0
  203. package/lib/ReadWriteRedisHttp.d.ts +11 -0
  204. package/lib/ReadWriteRedisHttp.d.ts.map +1 -0
  205. package/lib/ReadWriteRedisHttp.js +15 -0
  206. package/lib/ReadWriteRedisHttp.js.map +1 -0
  207. package/lib/Redis.d.ts +252 -0
  208. package/lib/Redis.d.ts.map +1 -0
  209. package/lib/Redis.js +611 -0
  210. package/lib/Redis.js.map +1 -0
  211. package/lib/RedisBinding.d.ts +7 -0
  212. package/lib/RedisBinding.d.ts.map +1 -0
  213. package/lib/RedisBinding.js +53 -0
  214. package/lib/RedisBinding.js.map +1 -0
  215. package/lib/RedisHttp.d.ts +8 -0
  216. package/lib/RedisHttp.d.ts.map +1 -0
  217. package/lib/RedisHttp.js +11 -0
  218. package/lib/RedisHttp.js.map +1 -0
  219. package/lib/Region.d.ts +16 -0
  220. package/lib/Region.d.ts.map +1 -0
  221. package/lib/Region.js +13 -0
  222. package/lib/Region.js.map +1 -0
  223. package/lib/Secret.d.ts +190 -0
  224. package/lib/Secret.d.ts.map +1 -0
  225. package/lib/Secret.js +310 -0
  226. package/lib/Secret.js.map +1 -0
  227. package/lib/SecretHttp.d.ts +54 -0
  228. package/lib/SecretHttp.d.ts.map +1 -0
  229. package/lib/SecretHttp.js +66 -0
  230. package/lib/SecretHttp.js.map +1 -0
  231. package/lib/SecretKey.d.ts +164 -0
  232. package/lib/SecretKey.d.ts.map +1 -0
  233. package/lib/SecretKey.js +277 -0
  234. package/lib/SecretKey.js.map +1 -0
  235. package/lib/SecretKeyHttp.d.ts +14 -0
  236. package/lib/SecretKeyHttp.d.ts.map +1 -0
  237. package/lib/SecretKeyHttp.js +5 -0
  238. package/lib/SecretKeyHttp.js.map +1 -0
  239. package/lib/Service.d.ts +1017 -0
  240. package/lib/Service.d.ts.map +1 -0
  241. package/lib/Service.js +1430 -0
  242. package/lib/Service.js.map +1 -0
  243. package/lib/Sign.d.ts +36 -0
  244. package/lib/Sign.d.ts.map +1 -0
  245. package/lib/Sign.js +3 -0
  246. package/lib/Sign.js.map +1 -0
  247. package/lib/SignHttp.d.ts +22 -0
  248. package/lib/SignHttp.d.ts.map +1 -0
  249. package/lib/SignHttp.js +36 -0
  250. package/lib/SignHttp.js.map +1 -0
  251. package/lib/Sprite.d.ts +283 -0
  252. package/lib/Sprite.d.ts.map +1 -0
  253. package/lib/Sprite.js +471 -0
  254. package/lib/Sprite.js.map +1 -0
  255. package/lib/SpriteHttp.d.ts +25 -0
  256. package/lib/SpriteHttp.d.ts.map +1 -0
  257. package/lib/SpriteHttp.js +33 -0
  258. package/lib/SpriteHttp.js.map +1 -0
  259. package/lib/Verify.d.ts +37 -0
  260. package/lib/Verify.d.ts.map +1 -0
  261. package/lib/Verify.js +3 -0
  262. package/lib/Verify.js.map +1 -0
  263. package/lib/VerifyHttp.d.ts +22 -0
  264. package/lib/VerifyHttp.d.ts.map +1 -0
  265. package/lib/VerifyHttp.js +38 -0
  266. package/lib/VerifyHttp.js.map +1 -0
  267. package/lib/Volume.d.ts +53 -0
  268. package/lib/Volume.d.ts.map +1 -0
  269. package/lib/Volume.js +188 -0
  270. package/lib/Volume.js.map +1 -0
  271. package/lib/VolumeSnapshot.d.ts +135 -0
  272. package/lib/VolumeSnapshot.d.ts.map +1 -0
  273. package/lib/VolumeSnapshot.js +213 -0
  274. package/lib/VolumeSnapshot.js.map +1 -0
  275. package/lib/Website/AssetDeployment.d.ts +43 -0
  276. package/lib/Website/AssetDeployment.d.ts.map +1 -0
  277. package/lib/Website/AssetDeployment.js +162 -0
  278. package/lib/Website/AssetDeployment.js.map +1 -0
  279. package/lib/Website/Astro.d.ts +89 -0
  280. package/lib/Website/Astro.d.ts.map +1 -0
  281. package/lib/Website/Astro.js +54 -0
  282. package/lib/Website/Astro.js.map +1 -0
  283. package/lib/Website/Foldkit.d.ts +52 -0
  284. package/lib/Website/Foldkit.d.ts.map +1 -0
  285. package/lib/Website/Foldkit.js +45 -0
  286. package/lib/Website/Foldkit.js.map +1 -0
  287. package/lib/Website/FrameworkSite.d.ts +212 -0
  288. package/lib/Website/FrameworkSite.d.ts.map +1 -0
  289. package/lib/Website/FrameworkSite.js +205 -0
  290. package/lib/Website/FrameworkSite.js.map +1 -0
  291. package/lib/Website/Nextjs.d.ts +54 -0
  292. package/lib/Website/Nextjs.d.ts.map +1 -0
  293. package/lib/Website/Nextjs.js +46 -0
  294. package/lib/Website/Nextjs.js.map +1 -0
  295. package/lib/Website/Nuxt.d.ts +51 -0
  296. package/lib/Website/Nuxt.d.ts.map +1 -0
  297. package/lib/Website/Nuxt.js +36 -0
  298. package/lib/Website/Nuxt.js.map +1 -0
  299. package/lib/Website/Octane.d.ts +49 -0
  300. package/lib/Website/Octane.d.ts.map +1 -0
  301. package/lib/Website/Octane.js +39 -0
  302. package/lib/Website/Octane.js.map +1 -0
  303. package/lib/Website/ReactRouter.d.ts +80 -0
  304. package/lib/Website/ReactRouter.d.ts.map +1 -0
  305. package/lib/Website/ReactRouter.js +70 -0
  306. package/lib/Website/ReactRouter.js.map +1 -0
  307. package/lib/Website/SolidStart.d.ts +93 -0
  308. package/lib/Website/SolidStart.d.ts.map +1 -0
  309. package/lib/Website/SolidStart.js +71 -0
  310. package/lib/Website/SolidStart.js.map +1 -0
  311. package/lib/Website/StaticSite.d.ts +162 -0
  312. package/lib/Website/StaticSite.d.ts.map +1 -0
  313. package/lib/Website/StaticSite.js +180 -0
  314. package/lib/Website/StaticSite.js.map +1 -0
  315. package/lib/Website/SvelteKit.d.ts +52 -0
  316. package/lib/Website/SvelteKit.d.ts.map +1 -0
  317. package/lib/Website/SvelteKit.js +37 -0
  318. package/lib/Website/SvelteKit.js.map +1 -0
  319. package/lib/Website/TanStackStart.d.ts +76 -0
  320. package/lib/Website/TanStackStart.d.ts.map +1 -0
  321. package/lib/Website/TanStackStart.js +66 -0
  322. package/lib/Website/TanStackStart.js.map +1 -0
  323. package/lib/Website/Vinext.d.ts +73 -0
  324. package/lib/Website/Vinext.d.ts.map +1 -0
  325. package/lib/Website/Vinext.js +67 -0
  326. package/lib/Website/Vinext.js.map +1 -0
  327. package/lib/Website/Vite.d.ts +112 -0
  328. package/lib/Website/Vite.d.ts.map +1 -0
  329. package/lib/Website/Vite.js +100 -0
  330. package/lib/Website/Vite.js.map +1 -0
  331. package/lib/Website/Vocs.d.ts +52 -0
  332. package/lib/Website/Vocs.d.ts.map +1 -0
  333. package/lib/Website/Vocs.js +38 -0
  334. package/lib/Website/Vocs.js.map +1 -0
  335. package/lib/Website/Waku.d.ts +64 -0
  336. package/lib/Website/Waku.d.ts.map +1 -0
  337. package/lib/Website/Waku.js +39 -0
  338. package/lib/Website/Waku.js.map +1 -0
  339. package/lib/Website/index.d.ts +17 -0
  340. package/lib/Website/index.d.ts.map +1 -0
  341. package/lib/Website/index.js +17 -0
  342. package/lib/Website/index.js.map +1 -0
  343. package/lib/WriteCertificates.d.ts +63 -0
  344. package/lib/WriteCertificates.d.ts.map +1 -0
  345. package/lib/WriteCertificates.js +3 -0
  346. package/lib/WriteCertificates.js.map +1 -0
  347. package/lib/WriteCertificatesHttp.d.ts +25 -0
  348. package/lib/WriteCertificatesHttp.d.ts.map +1 -0
  349. package/lib/WriteCertificatesHttp.js +67 -0
  350. package/lib/WriteCertificatesHttp.js.map +1 -0
  351. package/lib/WriteRedis.d.ts +26 -0
  352. package/lib/WriteRedis.d.ts.map +1 -0
  353. package/lib/WriteRedis.js +3 -0
  354. package/lib/WriteRedis.js.map +1 -0
  355. package/lib/WriteRedisHttp.d.ts +11 -0
  356. package/lib/WriteRedisHttp.d.ts.map +1 -0
  357. package/lib/WriteRedisHttp.js +15 -0
  358. package/lib/WriteRedisHttp.js.map +1 -0
  359. package/lib/WriteSecret.d.ts +68 -0
  360. package/lib/WriteSecret.d.ts.map +1 -0
  361. package/lib/WriteSecret.js +4 -0
  362. package/lib/WriteSecret.js.map +1 -0
  363. package/lib/WriteSecretHttp.d.ts +26 -0
  364. package/lib/WriteSecretHttp.d.ts.map +1 -0
  365. package/lib/WriteSecretHttp.js +54 -0
  366. package/lib/WriteSecretHttp.js.map +1 -0
  367. package/lib/bluegreen.d.ts +36 -0
  368. package/lib/bluegreen.d.ts.map +1 -0
  369. package/lib/bluegreen.js +460 -0
  370. package/lib/bluegreen.js.map +1 -0
  371. package/lib/hosted.d.ts +171 -0
  372. package/lib/hosted.d.ts.map +1 -0
  373. package/lib/hosted.js +458 -0
  374. package/lib/hosted.js.map +1 -0
  375. package/lib/index.d.ts +65 -0
  376. package/lib/index.d.ts.map +1 -0
  377. package/lib/index.js +63 -0
  378. package/lib/index.js.map +1 -0
  379. package/lib/internal/RemoteBuilder.d.ts +28 -0
  380. package/lib/internal/RemoteBuilder.d.ts.map +1 -0
  381. package/lib/internal/RemoteBuilder.js +158 -0
  382. package/lib/internal/RemoteBuilder.js.map +1 -0
  383. package/lib/leases.d.ts +53 -0
  384. package/lib/leases.d.ts.map +1 -0
  385. package/lib/leases.js +279 -0
  386. package/lib/leases.js.map +1 -0
  387. package/lib/ports.d.ts +51 -0
  388. package/lib/ports.d.ts.map +1 -0
  389. package/lib/ports.js +123 -0
  390. package/lib/ports.js.map +1 -0
  391. package/lib/replicas.d.ts +270 -0
  392. package/lib/replicas.d.ts.map +1 -0
  393. package/lib/replicas.js +969 -0
  394. package/lib/replicas.js.map +1 -0
  395. package/lib/rpc.d.ts +35 -0
  396. package/lib/rpc.d.ts.map +1 -0
  397. package/lib/rpc.js +113 -0
  398. package/lib/rpc.js.map +1 -0
  399. package/package.json +83 -3
  400. package/src/App.ts +514 -0
  401. package/src/AuthProvider.ts +68 -0
  402. package/src/BindService.ts +303 -0
  403. package/src/Bootstrap.ts +66 -0
  404. package/src/Bucket.ts +918 -0
  405. package/src/BucketBinding.ts +128 -0
  406. package/src/Catalog.ts +43 -0
  407. package/src/Certificate.ts +548 -0
  408. package/src/Checkpoint.ts +69 -0
  409. package/src/CheckpointHttp.ts +66 -0
  410. package/src/ConnectPostgres.ts +68 -0
  411. package/src/ConnectPostgresHttp.ts +77 -0
  412. package/src/Contributions.ts +9 -0
  413. package/src/Credentials.ts +75 -0
  414. package/src/Decrypt.ts +62 -0
  415. package/src/DecryptHttp.ts +52 -0
  416. package/src/DeleteObject.ts +43 -0
  417. package/src/DeleteObjectHttp.ts +20 -0
  418. package/src/Deployment.ts +121 -0
  419. package/src/DeploymentImages.ts +84 -0
  420. package/src/DeploymentState.ts +104 -0
  421. package/src/Encrypt.ts +60 -0
  422. package/src/EncryptHttp.ts +48 -0
  423. package/src/Environment.ts +81 -0
  424. package/src/Errors.ts +14 -0
  425. package/src/Exec.ts +50 -0
  426. package/src/ExecHttp.ts +47 -0
  427. package/src/GetObject.ts +48 -0
  428. package/src/GetObjectHttp.ts +20 -0
  429. package/src/GetSecret.ts +48 -0
  430. package/src/GetSecretHttp.ts +60 -0
  431. package/src/HeadObject.ts +43 -0
  432. package/src/HeadObjectHttp.ts +20 -0
  433. package/src/IpAssignment.ts +522 -0
  434. package/src/ListObjectsV2.ts +43 -0
  435. package/src/ListObjectsV2Http.ts +20 -0
  436. package/src/ListSecrets.ts +57 -0
  437. package/src/ListSecretsHttp.ts +43 -0
  438. package/src/Machine.ts +1270 -0
  439. package/src/MachineContainers.ts +152 -0
  440. package/src/Metadata.ts +195 -0
  441. package/src/MountVolume.ts +315 -0
  442. package/src/Postgres.ts +777 -0
  443. package/src/PostgresMigrations.ts +93 -0
  444. package/src/Providers.ts +155 -0
  445. package/src/PutObject.ts +49 -0
  446. package/src/PutObjectHttp.ts +20 -0
  447. package/src/ReadRedis.ts +31 -0
  448. package/src/ReadRedisHttp.ts +18 -0
  449. package/src/ReadWriteRedis.ts +33 -0
  450. package/src/ReadWriteRedisHttp.ts +18 -0
  451. package/src/Redis.ts +823 -0
  452. package/src/RedisBinding.ts +64 -0
  453. package/src/RedisHttp.ts +14 -0
  454. package/src/Region.ts +44 -0
  455. package/src/Secret.ts +405 -0
  456. package/src/SecretHttp.ts +149 -0
  457. package/src/SecretKey.ts +389 -0
  458. package/src/SecretKeyHttp.ts +23 -0
  459. package/src/Service.ts +1968 -0
  460. package/src/Sign.ts +46 -0
  461. package/src/SignHttp.ts +44 -0
  462. package/src/Sprite.ts +673 -0
  463. package/src/SpriteHttp.ts +50 -0
  464. package/src/Verify.ts +47 -0
  465. package/src/VerifyHttp.ts +46 -0
  466. package/src/Volume.ts +264 -0
  467. package/src/VolumeSnapshot.ts +321 -0
  468. package/src/Website/AssetDeployment.ts +292 -0
  469. package/src/Website/Astro.ts +92 -0
  470. package/src/Website/Foldkit.ts +54 -0
  471. package/src/Website/FrameworkSite.ts +449 -0
  472. package/src/Website/Nextjs.ts +50 -0
  473. package/src/Website/Nuxt.ts +48 -0
  474. package/src/Website/Octane.ts +44 -0
  475. package/src/Website/ReactRouter.ts +76 -0
  476. package/src/Website/SolidStart.ts +90 -0
  477. package/src/Website/StaticSite.ts +295 -0
  478. package/src/Website/SvelteKit.ts +49 -0
  479. package/src/Website/TanStackStart.ts +72 -0
  480. package/src/Website/Vinext.ts +79 -0
  481. package/src/Website/Vite.ts +121 -0
  482. package/src/Website/Vocs.ts +50 -0
  483. package/src/Website/Waku.ts +65 -0
  484. package/src/Website/index.ts +16 -0
  485. package/src/WriteCertificates.ts +90 -0
  486. package/src/WriteCertificatesHttp.ts +93 -0
  487. package/src/WriteRedis.ts +31 -0
  488. package/src/WriteRedisHttp.ts +18 -0
  489. package/src/WriteSecret.ts +86 -0
  490. package/src/WriteSecretHttp.ts +71 -0
  491. package/src/bluegreen.ts +711 -0
  492. package/src/globals.d.ts +2 -0
  493. package/src/hosted.ts +667 -0
  494. package/src/index.ts +64 -0
  495. package/src/internal/RemoteBuilder.ts +242 -0
  496. package/src/leases.ts +437 -0
  497. package/src/ports.ts +177 -0
  498. package/src/replicas.ts +1480 -0
  499. package/src/rpc.ts +136 -0
package/src/App.ts ADDED
@@ -0,0 +1,514 @@
1
+ import type { App as FlyApp } from "@distilled.cloud/fly-io/machines";
2
+ import * as machines from "@distilled.cloud/fly-io/machines";
3
+ import * as Retry from "@distilled.cloud/fly-io/Retry";
4
+ import { Unowned } from "alchemy/AdoptPolicy";
5
+ import { isResolved } from "alchemy/Diff";
6
+ import * as Provider from "alchemy/Provider";
7
+ import { Resource, type ResourceBinding } from "alchemy/Resource";
8
+ import * as Data from "effect/Data";
9
+ import * as Effect from "effect/Effect";
10
+ import * as FetchHttpClient from "effect/http/FetchHttpClient";
11
+ import * as HttpClient from "effect/http/HttpClient";
12
+ import * as HttpClientRequest from "effect/http/HttpClientRequest";
13
+ import * as Option from "effect/Option";
14
+ import * as Schedule from "effect/Schedule";
15
+ import { resolveOrgSlug } from "./Environment.ts";
16
+ import type { MachineService } from "./Machine.ts";
17
+ import {
18
+ createFlyAppName,
19
+ isAlchemyOwnedMetadata,
20
+ matchesAlchemyPhysicalName,
21
+ sanitizeFlyAppName,
22
+ } from "./Metadata.ts";
23
+ import { findPortConflict, portsOfProps, withBindingPort } from "./ports.ts";
24
+ import type { Providers } from "./Providers.ts";
25
+ import { DEFAULT_BINDING_PORT } from "./rpc.ts";
26
+
27
+ export class AppDeletionAmbiguous extends Data.TaggedError("Fly.AppDeletionAmbiguous")<{
28
+ appName: string;
29
+ evidence: string;
30
+ }> {
31
+ get message() {
32
+ return `Deletion of ${this.appName} is uncertain (${this.evidence}); reconcile the App before retrying or recreating its name. Machine leases cannot fence App deletion.`;
33
+ }
34
+ }
35
+
36
+ export interface AppProps {
37
+ /**
38
+ * Fly App name. Globally unique, DNS-compatible (lowercase letters,
39
+ * digits, hyphens), must start with a letter, max 30 characters. If
40
+ * omitted, a unique name is generated from the stack, stage and logical
41
+ * ID. Changing it replaces the App.
42
+ */
43
+ name?: string;
44
+ /**
45
+ * Organization slug. Defaults to the current token's org
46
+ * (`getCurrentToken`). Changing it replaces the App.
47
+ */
48
+ orgSlug?: string;
49
+ /**
50
+ * Isolated network name. Immutable after create — changing it replaces
51
+ * the App.
52
+ */
53
+ network?: string;
54
+ /**
55
+ * Enable `*.{name}.fly.dev` subdomains. Create-only; ignored on update
56
+ * (Fly has no App update API).
57
+ */
58
+ enableSubdomains?: boolean;
59
+ }
60
+
61
+ export type App = Resource<
62
+ "Fly.App",
63
+ AppProps,
64
+ {
65
+ /** Fly App id. */
66
+ appId: string;
67
+ /** Physical Fly App name. */
68
+ appName: string;
69
+ /** Fly internal numeric id, if the API returned one. */
70
+ internalNumericId: number | undefined;
71
+ /** Isolated network name, if set. */
72
+ network: string | undefined;
73
+ /** Observed status (e.g. `deployed`, `pending`). */
74
+ status: string | undefined;
75
+ /** Organization slug. */
76
+ orgSlug: string | undefined;
77
+ /** Observed machine count. */
78
+ machineCount: number | undefined;
79
+ /** Observed volume count. */
80
+ volumeCount: number | undefined;
81
+ /** Public `https://{appName}.fly.dev` URL. */
82
+ url: string;
83
+ },
84
+ AppBinding,
85
+ Providers
86
+ >;
87
+
88
+ /**
89
+ * Binding contract accepted by {@link App}. Each {@link Service} placed in
90
+ * the App (`app` prop) reports the ports it publishes, so the App can
91
+ * reject two Services on the same port before either one is deployed.
92
+ */
93
+ export interface AppBinding {
94
+ /** Logical id of the Service. */
95
+ service: string;
96
+ /** The Service's `services` prop; `undefined` for the default ports. */
97
+ services: MachineService[] | undefined;
98
+ /** The Service's `bindingPort` prop. */
99
+ bindingPort: number | undefined;
100
+ }
101
+
102
+ /**
103
+ * A Fly.App is a global namespace in your account. It contains Machines,
104
+ * Secrets, IPs, and certificates. A {@link Service} creates its own App,
105
+ * so declare an App yourself for {@link Machine}s, or to group Services
106
+ * that share Secrets or a custom domain (the Service `app` prop).
107
+ *
108
+ * @see https://fly.io/docs/machines/api/apps-resource/
109
+ *
110
+ * ### Create an App
111
+ * Alchemy generates a unique name unless you pass one. `url` is
112
+ * `https://{appName}.fly.dev`. Nothing answers there until a
113
+ * {@link Machine} (or a Service with `app`) publishes a proxy service and
114
+ * the App has an {@link IpAssignment}.
115
+ *
116
+ * **Example:** Generated name
117
+ * ```typescript
118
+ * const site = yield* Fly.App("Site");
119
+ * ```
120
+ *
121
+ * :::note
122
+ * Prefer omitting `name` in tests and CI so names stay unique and
123
+ * reclaimable.
124
+ * :::
125
+ *
126
+ * ### A stable hostname
127
+ * Pass `name` when you need a stable `fly.dev` hostname.
128
+ *
129
+ * **Example:** Explicit name
130
+ * ```typescript
131
+ * const site = yield* Fly.App("Site", {
132
+ * name: "my-site",
133
+ * });
134
+ * ```
135
+ *
136
+ * :::caution[Changing `name` replaces the App]
137
+ * Fly cannot have two Apps with the same name. Alchemy deletes the
138
+ * old App first, then creates the new one.
139
+ * :::
140
+ *
141
+ * ### Organization
142
+ * Org defaults to the current token. Pass `orgSlug` to pin it.
143
+ *
144
+ * **Example:** Pin an org
145
+ * ```typescript
146
+ * const site = yield* Fly.App("Site", {
147
+ * name: "my-site",
148
+ * orgSlug: "my-org",
149
+ * });
150
+ * ```
151
+ *
152
+ * :::caution[Changing `orgSlug` replaces the App]
153
+ * The App is created in the new org. The old App is deleted.
154
+ * :::
155
+ *
156
+ * ### Subdomains
157
+ * `enableSubdomains: true` turns on `*.{appName}.fly.dev`.
158
+ *
159
+ * **Example:** Enable subdomains
160
+ * ```typescript
161
+ * const site = yield* Fly.App("Site", {
162
+ * name: "my-site",
163
+ * enableSubdomains: true,
164
+ * });
165
+ * ```
166
+ *
167
+ * :::note[Create-only]
168
+ * Flipping `enableSubdomains` later is ignored.
169
+ * :::
170
+ *
171
+ * ### Isolated network
172
+ * `network` is an optional 6PN name.
173
+ *
174
+ * **Example:** Custom network
175
+ * ```typescript
176
+ * const site = yield* Fly.App("Site", {
177
+ * name: "my-site",
178
+ * network: "private",
179
+ * });
180
+ * ```
181
+ *
182
+ * :::caution[Changing `network` replaces the App]
183
+ * The App is recreated on the new network.
184
+ * :::
185
+ *
186
+ * ### Module-scope declarations
187
+ * Declare the App once. Pass it into every child. Resource-valued props
188
+ * accept the resource or an Effect producing it. Do not unwrap it just
189
+ * to pass it along.
190
+ *
191
+ * **Example:** Module-scope App
192
+ * ```typescript
193
+ * // src/app.ts
194
+ * import * as Fly from "@alchemy.run/fly";
195
+ *
196
+ * export const Site = Fly.App("Site");
197
+ * ```
198
+ *
199
+ * @resource
200
+ * @product App
201
+ */
202
+ export const App = Resource<App>("Fly.App");
203
+
204
+ export class AppNotCreated extends Data.TaggedError("Fly.AppNotCreated")<{
205
+ resourceName: string;
206
+ /** Fly's rejection of the create request, when there was one. */
207
+ reason?: string;
208
+ }> {
209
+ get message() {
210
+ return `Fly App ${this.resourceName} was not created${this.reason ? `: ${this.reason}` : ""}`;
211
+ }
212
+ }
213
+
214
+ const toAttrs = (app: FlyApp, fallbackName?: string): App["Attributes"] => {
215
+ const appName = app.name ?? fallbackName ?? "";
216
+ return {
217
+ appId: app.id ?? appName,
218
+ appName,
219
+ internalNumericId: app.internal_numeric_id,
220
+ network: app.network,
221
+ status: app.status,
222
+ orgSlug: app.organization?.slug,
223
+ machineCount: app.machine_count,
224
+ volumeCount: app.volume_count,
225
+ url: `https://${appName}.fly.dev`,
226
+ };
227
+ };
228
+
229
+ const resolveAppName = (id: string, name: string | undefined, existing?: string) =>
230
+ Effect.gen(function* () {
231
+ if (name !== undefined) return sanitizeFlyAppName(name);
232
+ if (existing !== undefined) return existing;
233
+ return yield* createFlyAppName(id);
234
+ });
235
+
236
+ const getByName = (appName: string) =>
237
+ machines.getApp({ app_name: appName }).pipe(Effect.catchTag("NotFound", () => Effect.undefined));
238
+
239
+ const hasAlchemyMachines = (appName: string) =>
240
+ machines.listMachines({ app_name: appName }).pipe(
241
+ Effect.map((machines) =>
242
+ machines.some((machine) => isAlchemyOwnedMetadata(machine.config?.metadata)),
243
+ ),
244
+ Effect.catchTag(["NotFound", "Forbidden"], () => Effect.succeed(false)),
245
+ );
246
+
247
+ const hasAlchemyNamed = (names: Array<string | undefined>) =>
248
+ names.some((name) => matchesAlchemyPhysicalName(name));
249
+
250
+ const hasAlchemyVolumes = (appName: string) =>
251
+ machines.listVolumes({ app_name: appName }).pipe(
252
+ Effect.map((volumes) => hasAlchemyNamed(volumes.map((volume) => volume.name))),
253
+ Effect.catchTag(["NotFound", "Forbidden"], () => Effect.succeed(false)),
254
+ );
255
+
256
+ const hasAlchemySecrets = (appName: string) =>
257
+ machines.listSecrets({ app_name: appName }).pipe(
258
+ Effect.map((res) => hasAlchemyNamed((res.secrets ?? []).map((secret) => secret.name))),
259
+ Effect.catchTag(["NotFound", "Forbidden"], () => Effect.succeed(false)),
260
+ );
261
+
262
+ const hasAlchemySecretKeys = (appName: string) =>
263
+ machines.listSecretKeys({ app_name: appName }).pipe(
264
+ Effect.map((res) => hasAlchemyNamed((res.secret_keys ?? []).map((key) => key.name))),
265
+ Effect.catchTag(["NotFound", "Forbidden"], () => Effect.succeed(false)),
266
+ );
267
+
268
+ const isOwnedApp = (app: FlyApp) =>
269
+ Effect.gen(function* () {
270
+ if (matchesAlchemyPhysicalName(app.name)) return true;
271
+ const appName = app.name;
272
+ if (appName === undefined || appName.length === 0) return false;
273
+ const flags = yield* Effect.all(
274
+ [
275
+ hasAlchemyMachines(appName),
276
+ hasAlchemyVolumes(appName),
277
+ hasAlchemySecrets(appName),
278
+ hasAlchemySecretKeys(appName),
279
+ ],
280
+ { concurrency: 4 },
281
+ );
282
+ return flags.some(Boolean);
283
+ });
284
+
285
+ /**
286
+ * Apps in the current token's org that Alchemy owns. Used by {@link App}
287
+ * `list()` and by child resources (Machine / Volume / Secret) so nuke
288
+ * never enumerates the whole org unfiltered.
289
+ */
290
+ export const listOwnedApps = Effect.fn(function* () {
291
+ const orgSlug = yield* resolveOrgSlug();
292
+ const { apps } = yield* machines.listApps({ org_slug: orgSlug });
293
+ const flagged = yield* Effect.forEach(
294
+ apps ?? [],
295
+ (app) => isOwnedApp(app).pipe(Effect.map((owned) => (owned ? toAttrs(app) : undefined))),
296
+ { concurrency: 8 },
297
+ );
298
+ return flagged.filter((attrs) => attrs !== undefined);
299
+ });
300
+
301
+ /**
302
+ * Observe an App by name and create it when missing. Shared by
303
+ * {@link App} and by Services that own their App.
304
+ */
305
+ export const ensureApp = Effect.fn(function* (input: {
306
+ name: string;
307
+ orgSlug?: string;
308
+ network?: string;
309
+ enableSubdomains?: boolean;
310
+ /** Physical name from a previous reconcile, observed first. */
311
+ previousName?: string;
312
+ }) {
313
+ let current = input.previousName !== undefined ? yield* getByName(input.previousName) : undefined;
314
+ if (current === undefined && input.previousName !== input.name) {
315
+ current = yield* getByName(input.name);
316
+ }
317
+ if (current === undefined) {
318
+ const orgSlug = input.orgSlug ?? (yield* resolveOrgSlug());
319
+ // A name race surfaces as Conflict or UnprocessableEntity; the lookup
320
+ // decides whether the App now exists. Apps created at the same time on
321
+ // a network that does not exist yet race to create it, and the losers
322
+ // are rejected with "uniqueness constraint violated", so retry them.
323
+ const create = machines
324
+ .createApp({
325
+ name: input.name,
326
+ org_slug: orgSlug,
327
+ network: input.network,
328
+ enable_subdomains: input.enableSubdomains,
329
+ })
330
+ .pipe(
331
+ Effect.as(undefined),
332
+ Effect.catchTag(["Conflict", "UnprocessableEntity"], (error) => Effect.succeed(error)),
333
+ );
334
+ // A new App can take a moment to become readable.
335
+ const observe = getByName(input.name).pipe(
336
+ Effect.repeat({
337
+ schedule: Schedule.spaced("1 second"),
338
+ until: (app) => app !== undefined,
339
+ times: 5,
340
+ }),
341
+ );
342
+ let rejection: string | undefined;
343
+ for (let attempt = 0; attempt < 5 && current === undefined; attempt++) {
344
+ if (attempt > 0) yield* Effect.sleep(`${attempt * 2} seconds`);
345
+ rejection = (yield* create)?.message;
346
+ current = yield* observe;
347
+ }
348
+ if (current === undefined) {
349
+ return yield* new AppNotCreated({ resourceName: input.name, reason: rejection });
350
+ }
351
+ }
352
+ if (current === undefined) {
353
+ return yield* new AppNotCreated({ resourceName: input.name });
354
+ }
355
+ return current;
356
+ });
357
+
358
+ /**
359
+ * Delete an App and the Alchemy-owned Volumes in it. Idempotent: a missing
360
+ * App is not an error. Fly deletes the App's Machines, addresses, secrets,
361
+ * and certificates with it.
362
+ */
363
+ export const deleteApp = Effect.fn(function* (appName: string) {
364
+ if (appName.length === 0) return;
365
+ const volumes = yield* machines
366
+ .listVolumes({ app_name: appName })
367
+ .pipe(Effect.catchTag(["NotFound", "Forbidden"], () => Effect.succeed([])));
368
+ yield* Effect.forEach(
369
+ volumes,
370
+ (volume) => {
371
+ const volumeId = volume.id;
372
+ if (
373
+ volumeId === undefined ||
374
+ volumeId.length === 0 ||
375
+ !matchesAlchemyPhysicalName(volume.name)
376
+ ) {
377
+ return Effect.void;
378
+ }
379
+ return machines.deleteVolume({ app_name: appName, volume_id: volumeId }).pipe(
380
+ Effect.asVoid,
381
+ Effect.catchTag(["NotFound", "Conflict"], () => Effect.void),
382
+ );
383
+ },
384
+ { concurrency: 4 },
385
+ );
386
+ const http = yield* HttpClient.HttpClient;
387
+ const fetchOptions = yield* Effect.serviceOption(FetchHttpClient.RequestInit);
388
+ yield* machines.deleteApp({ app_name: appName }).pipe(
389
+ Retry.none,
390
+ // Bun can replay DELETE on a reused socket below the SDK retry policy.
391
+ Effect.provideService(
392
+ HttpClient.HttpClient,
393
+ HttpClient.mapRequest(http, HttpClientRequest.setHeader("connection", "close")),
394
+ ),
395
+ Effect.provideService(FetchHttpClient.RequestInit, {
396
+ ...Option.getOrUndefined(fetchOptions),
397
+ keepalive: false,
398
+ redirect: "error",
399
+ }),
400
+ Effect.timeout("30 seconds"),
401
+ Effect.catchTag("NotFound", () => Effect.void),
402
+ Effect.catchTag(
403
+ [
404
+ "HttpClientError",
405
+ "TimeoutError",
406
+ "InternalServerError",
407
+ "BadGateway",
408
+ "ServiceUnavailable",
409
+ "GatewayTimeout",
410
+ ],
411
+ (error) => Effect.fail(new AppDeletionAmbiguous({ appName, evidence: error._tag })),
412
+ ),
413
+ );
414
+ const gone = yield* getByName(appName).pipe(
415
+ Effect.map((app) => app === undefined),
416
+ Effect.repeat({ schedule: Schedule.spaced("1 second"), until: (gone) => gone, times: 8 }),
417
+ Effect.timeout("30 seconds"),
418
+ Effect.mapError(
419
+ (error) =>
420
+ new AppDeletionAmbiguous({
421
+ appName,
422
+ evidence: `delete accepted but absence verification failed: ${error._tag}`,
423
+ }),
424
+ ),
425
+ );
426
+ if (!gone)
427
+ return yield* new AppDeletionAmbiguous({
428
+ appName,
429
+ evidence: "delete accepted but absence not observed",
430
+ });
431
+ });
432
+
433
+ /** Fail when two Services placed in the App publish the same port. */
434
+ const validateServicePorts = (
435
+ appName: string,
436
+ bindings: ReadonlyArray<ResourceBinding<AppBinding> & { action?: string }>,
437
+ ) => {
438
+ const conflict = findPortConflict(
439
+ appName,
440
+ bindings
441
+ .filter((binding) => binding.action !== "delete")
442
+ .map((binding) => ({
443
+ id: binding.data.service,
444
+ // A Service in a shared App is public: default ports are 80 and 443.
445
+ ports: withBindingPort(
446
+ portsOfProps(binding.data.services, true),
447
+ binding.data.bindingPort ?? DEFAULT_BINDING_PORT,
448
+ ),
449
+ })),
450
+ );
451
+ return conflict === undefined ? Effect.void : Effect.fail(conflict);
452
+ };
453
+
454
+ export const AppProvider = () =>
455
+ Provider.succeed(App, {
456
+ stables: ["appId", "appName", "orgSlug", "network", "internalNumericId"],
457
+
458
+ diff: Effect.fn(function* ({ id, news, output, newBindings }) {
459
+ // At plan time, including for an App created in the same deploy.
460
+ if (isResolved(newBindings)) {
461
+ yield* validateServicePorts(
462
+ output?.appName ?? (isResolved(news) ? news?.name : undefined) ?? id,
463
+ newBindings,
464
+ );
465
+ }
466
+ if (news === undefined || !isResolved(news)) return undefined;
467
+ if (output === undefined) return undefined;
468
+ const desiredName = news.name !== undefined ? sanitizeFlyAppName(news.name) : output.appName;
469
+ const nameChanged = desiredName !== output.appName;
470
+ const orgChanged = news.orgSlug !== undefined && news.orgSlug !== output.orgSlug;
471
+ const networkChanged = news.network !== undefined && news.network !== output.network;
472
+ if (nameChanged || orgChanged || networkChanged) {
473
+ return {
474
+ action: "replace" as const,
475
+ // Same physical name cannot exist twice — delete the old App first.
476
+ deleteFirst: !nameChanged,
477
+ };
478
+ }
479
+ return undefined;
480
+ }),
481
+
482
+ read: Effect.fn(function* ({ id, olds, output }) {
483
+ const name = yield* resolveAppName(id, olds?.name, output?.appName);
484
+ const found =
485
+ (output?.appName !== undefined ? yield* getByName(output.appName) : undefined) ??
486
+ (yield* getByName(name));
487
+ if (found === undefined) return undefined;
488
+ const attrs = toAttrs(found, name);
489
+ if (output !== undefined) return attrs;
490
+ return (yield* isOwnedApp(found)) ? attrs : Unowned(attrs);
491
+ }),
492
+
493
+ list: listOwnedApps,
494
+
495
+ reconcile: Effect.fn(function* ({ id, news, output, bindings }) {
496
+ const props = news ?? {};
497
+ const name = yield* resolveAppName(id, props.name, output?.appName);
498
+ // Before creating anything, so a conflict leaves the App untouched.
499
+ yield* validateServicePorts(name, bindings);
500
+ const current = yield* ensureApp({
501
+ name,
502
+ orgSlug: props.orgSlug,
503
+ network: props.network,
504
+ enableSubdomains: props.enableSubdomains,
505
+ previousName: output?.appName,
506
+ });
507
+ // No update API. enableSubdomains is create-only.
508
+ return toAttrs(current, name);
509
+ }),
510
+
511
+ delete: Effect.fn(function* ({ output }) {
512
+ yield* deleteApp(output.appName);
513
+ }),
514
+ });
@@ -0,0 +1,68 @@
1
+ import { DEFAULT_API_BASE_URL, normalizeApiBaseUrl } from "@distilled.cloud/fly-io";
2
+ import { getEnv, getEnvRedactedRequired } from "alchemy/Auth/Env";
3
+ import {
4
+ makeStoredAuthProvider,
5
+ storedSecret,
6
+ storedValueText,
7
+ type StoredAuthConfig,
8
+ } from "alchemy/Auth/StoredAuthProvider";
9
+ import * as Effect from "effect/Effect";
10
+ import * as Redacted from "effect/Redacted";
11
+
12
+ export const FLY_AUTH_PROVIDER_NAME = "Fly";
13
+ export const FLY_API_TOKEN_ENV = "FLY_API_TOKEN";
14
+ export const FLY_API_HOSTNAME_ENV = "FLY_API_HOSTNAME";
15
+
16
+ export type FlyAuthConfig = StoredAuthConfig;
17
+
18
+ export type FlyResolvedCredentials = {
19
+ type: "token";
20
+ apiKey: Redacted.Redacted<string>;
21
+ apiBaseUrl: string;
22
+ source: { type: FlyAuthConfig["method"] | "env"; details?: string };
23
+ };
24
+
25
+ const resolveApiBaseUrl = (explicit?: string) =>
26
+ getEnv(FLY_API_HOSTNAME_ENV).pipe(
27
+ Effect.map((fromEnv) => normalizeApiBaseUrl(explicit ?? fromEnv)),
28
+ );
29
+
30
+ const flyAuth = makeStoredAuthProvider<FlyResolvedCredentials>({
31
+ provider: FLY_AUTH_PROVIDER_NAME,
32
+ fields: [
33
+ { name: "apiKey", label: "Fly.io API Token", secret: true },
34
+ {
35
+ name: "apiBaseUrl",
36
+ label: "Fly API hostname",
37
+ placeholder: DEFAULT_API_BASE_URL,
38
+ optional: true,
39
+ },
40
+ ],
41
+ toResolved: (values) => ({
42
+ type: "token",
43
+ apiKey: storedSecret(values.apiKey) ?? Redacted.make(""),
44
+ apiBaseUrl: normalizeApiBaseUrl(storedValueText(values.apiBaseUrl)),
45
+ source: { type: "stored" },
46
+ }),
47
+ readEnvironment: Effect.gen(function* () {
48
+ const apiKey = yield* getEnvRedactedRequired(FLY_API_TOKEN_ENV);
49
+ const apiBaseUrl = yield* resolveApiBaseUrl();
50
+ return {
51
+ type: "token" as const,
52
+ apiKey,
53
+ apiBaseUrl,
54
+ source: { type: "env" as const, details: FLY_API_TOKEN_ENV },
55
+ };
56
+ }),
57
+ environment: [
58
+ { name: FLY_API_TOKEN_ENV, required: true, secret: true },
59
+ { name: FLY_API_HOSTNAME_ENV, required: false },
60
+ ],
61
+ });
62
+
63
+ /**
64
+ * Layer that registers the Fly {@link AuthProvider} into the
65
+ * {@link AuthProviders} registry. Fly uses a stored API token locally and
66
+ * `FLY_API_TOKEN` in CI; `FLY_API_HOSTNAME` optionally overrides the API root.
67
+ */
68
+ export const FlyAuth = flyAuth.layer;