@alchemy.run/fly 0.0.0-stage → 2.0.0-beta.84

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 +61 -2
  3. package/lib/App.d.ts +230 -0
  4. package/lib/App.d.ts.map +1 -0
  5. package/lib/App.js +340 -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 +59 -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 +35 -0
  176. package/lib/PostgresMigrations.d.ts.map +1 -0
  177. package/lib/PostgresMigrations.js +110 -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 +608 -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 +8 -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 +1022 -0
  240. package/lib/Service.d.ts.map +1 -0
  241. package/lib/Service.js +1397 -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 +469 -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 +87 -0
  280. package/lib/Website/Astro.d.ts.map +1 -0
  281. package/lib/Website/Astro.js +55 -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 +175 -0
  288. package/lib/Website/FrameworkSite.d.ts.map +1 -0
  289. package/lib/Website/FrameworkSite.js +162 -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 +155 -0
  312. package/lib/Website/StaticSite.d.ts.map +1 -0
  313. package/lib/Website/StaticSite.js +168 -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 +103 -0
  328. package/lib/Website/Vite.d.ts.map +1 -0
  329. package/lib/Website/Vite.js +91 -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 +458 -0
  370. package/lib/bluegreen.js.map +1 -0
  371. package/lib/hosted.d.ts +172 -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 +145 -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 +97 -3
  400. package/src/App.ts +516 -0
  401. package/src/AuthProvider.ts +68 -0
  402. package/src/BindService.ts +304 -0
  403. package/src/Bootstrap.ts +66 -0
  404. package/src/Bucket.ts +916 -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 +102 -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 +1268 -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 +153 -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 +820 -0
  452. package/src/RedisBinding.ts +64 -0
  453. package/src/RedisHttp.ts +11 -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 +1934 -0
  460. package/src/Sign.ts +46 -0
  461. package/src/SignHttp.ts +44 -0
  462. package/src/Sprite.ts +671 -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 +294 -0
  469. package/src/Website/Astro.ts +87 -0
  470. package/src/Website/Foldkit.ts +54 -0
  471. package/src/Website/FrameworkSite.ts +363 -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 +275 -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 +112 -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 +708 -0
  492. package/src/globals.d.ts +2 -0
  493. package/src/hosted.ts +668 -0
  494. package/src/index.ts +64 -0
  495. package/src/internal/RemoteBuilder.ts +224 -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
@@ -0,0 +1,2 @@
1
+ // `globalThis.__ALCHEMY_RUNTIME__`, declared by alchemy's Phase module.
2
+ import type {} from "alchemy/Phase";
package/src/hosted.ts ADDED
@@ -0,0 +1,668 @@
1
+ import type { Docker } from "@alchemy.run/docker/Docker";
2
+ import type { FlyMachineService } from "@distilled.cloud/fly-io/machines";
3
+ import * as machines from "@distilled.cloud/fly-io/machines";
4
+ import * as Bundle from "alchemy/Bundle/Bundle";
5
+ import {
6
+ matchesPackageRoot,
7
+ normalizeInstallTargets,
8
+ resolvePackageInstallIdentity,
9
+ type PackageInstall,
10
+ } from "alchemy/Bundle/InstalledPackages";
11
+ import { findCwdForBundle, getStableContextDir, resolveMainPath } from "alchemy/Bundle/TempRoot";
12
+ import { safeHttpEffect } from "alchemy/Http";
13
+ import type { ResourceBinding } from "alchemy/Resource";
14
+ import { createContainerRuntimeContext, type HostRuntimeContext } from "alchemy/Runtime/Process";
15
+ import {
16
+ copyExtraFiles,
17
+ contextRootOf,
18
+ extraFileDestination,
19
+ hashExtraFiles,
20
+ isContextRootDest,
21
+ posixRelUnder,
22
+ resolveExtraSource,
23
+ type ExtraFile,
24
+ } from "alchemy/Util/extraFiles";
25
+ import { sha256, sha256Object } from "alchemy/Util/sha256";
26
+ import * as Data from "effect/Data";
27
+ import * as Effect from "effect/Effect";
28
+ import * as FileSystem from "effect/FileSystem";
29
+ import * as Path from "effect/Path";
30
+ import * as Redacted from "effect/Redacted";
31
+ import * as Schedule from "effect/Schedule";
32
+ import type * as rolldown from "rolldown";
33
+ import { buildOnRemoteBuilder } from "./internal/RemoteBuilder.ts";
34
+ import type { BoundTarget, DiskSpec, ServiceBinding } from "./MountVolume.ts";
35
+ import { rpcMethodsOf, serveFlyRpc } from "./rpc.ts";
36
+
37
+ export type FlyHostRuntimeContext = HostRuntimeContext;
38
+
39
+ /**
40
+ * Container runtime context for Fly hosts. It also serves the program's RPC
41
+ * methods to bound callers (see {@link serveFlyRpc}) and boots the HTTP
42
+ * server for a program that exposes methods but no `fetch`.
43
+ */
44
+ export const createFlyHostRuntimeContext =
45
+ (type: string) =>
46
+ (id: string): HostRuntimeContext => {
47
+ const base = createContainerRuntimeContext(type)(id);
48
+ const serveBase = base.serve;
49
+ const serve: HostRuntimeContext["serve"] = (handler, options) => {
50
+ const shape = options?.shape;
51
+ const methods = rpcMethodsOf(shape);
52
+ // `safeHttpEffect` also resolves a `fetch` given as an Effect that
53
+ // builds the handler.
54
+ const wrapped = serveFlyRpc(methods, safeHttpEffect(handler));
55
+ const boots =
56
+ shape === undefined || shape.fetch !== undefined || Object.keys(methods).length > 0;
57
+ return serveBase(
58
+ wrapped,
59
+ boots ? { shape: { ...shape, fetch: shape?.fetch ?? wrapped } } : options,
60
+ ) as Effect.Effect<void, never, any>;
61
+ };
62
+ return Object.assign(base, { serve });
63
+ };
64
+
65
+ export const FLY_REGISTRY = "registry.fly.io";
66
+ export const DEFAULT_BASE_IMAGE = "node:26-slim";
67
+ export const DEFAULT_PORT = 3000;
68
+ export const MACHINE_PLATFORM = "linux/amd64";
69
+
70
+ export interface FlyBuildOptions extends Bundle.BundleConfig {
71
+ /**
72
+ * Native or Node-only packages to install into the Machine image with
73
+ * `npm install` instead of bundling them. `pg` is CommonJS: Rolldown's
74
+ * interop turns `Client` into a namespace (`The superclass is not a
75
+ * constructor`). Same `build.install` shape as Lambda.
76
+ *
77
+ * @example
78
+ * ```typescript
79
+ * build: { install: ["pg"] }
80
+ * ```
81
+ */
82
+ readonly install?: PackageInstall;
83
+ /**
84
+ * Build the image on Fly's remote builders (Depot), as `fly deploy` does,
85
+ * instead of with the local Docker engine. Only the build context is
86
+ * uploaded; the builder pulls the base image and pushes the result to
87
+ * `registry.fly.io` next to it. Set `false` to build and push locally.
88
+ * Either way, the local `docker buildx` client drives the build.
89
+ *
90
+ * @default true
91
+ */
92
+ readonly remote?: boolean;
93
+ }
94
+
95
+ export type { ExtraFile };
96
+
97
+ export interface HostedProgramProps {
98
+ main: string;
99
+ handler?: string;
100
+ port?: number;
101
+ image?: string;
102
+ env?: Record<string, any>;
103
+ isExternal?: boolean;
104
+ build?: FlyBuildOptions;
105
+ /**
106
+ * Extra host directories baked into the image (framework client
107
+ * assets, Next.js `.next`, …). Hashed into `code.hash` so asset
108
+ * changes rebuild the image.
109
+ */
110
+ extraFiles?: ReadonlyArray<ExtraFile>;
111
+ }
112
+
113
+ export { extraFileDestination };
114
+
115
+ const matchesConfiguredExternal = (
116
+ external: rolldown.InputOptions["external"],
117
+ moduleId: string,
118
+ parentId: string | undefined,
119
+ isResolved: boolean,
120
+ ): boolean => {
121
+ if (external === undefined) return false;
122
+ if (typeof external === "function") {
123
+ return external(moduleId, parentId, isResolved) === true;
124
+ }
125
+ const matchers = Array.isArray(external) ? external : [external];
126
+ return matchers.some((matcher) =>
127
+ typeof matcher === "string" ? matcher === moduleId : matcher.test(moduleId),
128
+ );
129
+ };
130
+
131
+ export class DeployTokenMissing extends Data.TaggedError("Fly.DeployTokenMissing")<{
132
+ appName: string;
133
+ }> {}
134
+
135
+ /**
136
+ * The generated entry for `Fly.Service` / `Fly.Sprite` machines: a shim
137
+ * importing only `@alchemy.run/fly/Bootstrap` plus the user's `main` —
138
+ * see that module for why the entry never imports alchemy's own
139
+ * dependencies. The runtime flag is raised BEFORE the user's module is
140
+ * evaluated (hence the dynamic import) so its module-scope code sees it.
141
+ */
142
+ const makeBunBootstrap =
143
+ (handler: string) =>
144
+ (importPath: string): string =>
145
+ `
146
+ import { bootstrap } from "@alchemy.run/fly/Bootstrap";
147
+
148
+ globalThis.__ALCHEMY_RUNTIME__ = true;
149
+ const { ${handler}: entrypoint } = await import(${JSON.stringify(importPath)});
150
+
151
+ await bootstrap(entrypoint);
152
+ `;
153
+
154
+ /** Unwrap env inputs while preserving serialized RuntimeContext markers. */
155
+ export const plainEnvValue = (value: unknown): string | undefined => {
156
+ if (value === undefined || value === null) return undefined;
157
+ if (Redacted.isRedacted(value)) return value.pipe(Redacted.value, plainEnvValue);
158
+ if (typeof value === "string") {
159
+ return value.length > 0 ? value : undefined;
160
+ }
161
+ if (typeof value === "number" || typeof value === "boolean") {
162
+ return String(value);
163
+ }
164
+ return undefined;
165
+ };
166
+
167
+ export const toEnvRecord = (env: Record<string, any> | undefined): Record<string, string> =>
168
+ Object.fromEntries(
169
+ Object.entries(env ?? {}).flatMap(([key, value]) => {
170
+ const raw = plainEnvValue(value);
171
+ return raw === undefined ? [] : [[key, raw]];
172
+ }),
173
+ );
174
+
175
+ const coerceBindingName = (value: unknown): string | undefined => {
176
+ const direct = plainEnvValue(value);
177
+ if (direct !== undefined) return direct;
178
+ if (value != null && typeof value === "object") {
179
+ const record = value as { name?: unknown; id?: unknown; addOnId?: unknown };
180
+ return (
181
+ coerceBindingName(record.name) ??
182
+ coerceBindingName(record.id) ??
183
+ coerceBindingName(record.addOnId)
184
+ );
185
+ }
186
+ return undefined;
187
+ };
188
+
189
+ export const collectBindingState = (bindings: readonly ResourceBinding<ServiceBinding>[]) => {
190
+ const active = bindings.filter(
191
+ (binding: ResourceBinding<ServiceBinding> & { action?: string }) => binding.action !== "delete",
192
+ );
193
+ const env = toEnvRecord(
194
+ active
195
+ .map((binding) => binding?.data?.env)
196
+ .reduce<Record<string, any>>((acc, value) => ({ ...acc, ...value }), {}),
197
+ );
198
+ const mounts: DiskSpec[] = [];
199
+ const seen = new Set<string>();
200
+ const redis: { name: string; id?: string }[] = [];
201
+ const buckets: { name: string; id?: string; values?: Record<string, string> }[] = [];
202
+ const postgres: { clusterId: string; variableName?: string }[] = [];
203
+ const targets: BoundTarget[] = [];
204
+ for (const binding of active) {
205
+ const target = binding?.data?.target;
206
+ if (target !== undefined) targets.push(target);
207
+ for (const mount of binding?.data?.mounts ?? []) {
208
+ if (seen.has(mount.path)) continue;
209
+ seen.add(mount.path);
210
+ mounts.push(mount);
211
+ }
212
+ const attached = binding?.data?.redis;
213
+ const redisName = coerceBindingName(attached?.name);
214
+ const redisId = coerceBindingName(attached?.id);
215
+ if (redisName !== undefined || redisId !== undefined) {
216
+ redis.push({ name: redisName ?? "", id: redisId });
217
+ }
218
+ const bucket = binding?.data?.bucket as
219
+ | {
220
+ name?: unknown;
221
+ id?: unknown;
222
+ addOnId?: unknown;
223
+ bucketName?: unknown;
224
+ accessKeyId?: unknown;
225
+ secretAccessKey?: unknown;
226
+ endpoint?: unknown;
227
+ region?: unknown;
228
+ }
229
+ | undefined;
230
+ const bucketName = coerceBindingName(bucket?.name);
231
+ const bucketId = coerceBindingName(bucket?.id) ?? coerceBindingName(bucket?.addOnId);
232
+ if (bucketName !== undefined || bucketId !== undefined) {
233
+ // The bound Bucket's attributes carry the create-time Tigris
234
+ // credentials, which Fly's add-on lookup often returns empty.
235
+ const values: Record<string, string> = {};
236
+ for (const [key, value] of [
237
+ ["BUCKET_NAME", bucket?.bucketName],
238
+ ["AWS_ACCESS_KEY_ID", bucket?.accessKeyId],
239
+ ["AWS_SECRET_ACCESS_KEY", bucket?.secretAccessKey],
240
+ ["AWS_ENDPOINT_URL_S3", bucket?.endpoint],
241
+ ["AWS_REGION", bucket?.region],
242
+ ] as const) {
243
+ const plain = plainEnvValue(value);
244
+ if (plain !== undefined) values[key] = plain;
245
+ }
246
+ buckets.push({ name: bucketName ?? "", id: bucketId, values });
247
+ }
248
+ const pg = binding?.data?.postgres;
249
+ const clusterId = coerceBindingName(pg?.clusterId);
250
+ if (clusterId !== undefined) {
251
+ postgres.push({
252
+ clusterId,
253
+ variableName:
254
+ typeof pg?.variableName === "string" && pg.variableName.length > 0
255
+ ? pg.variableName
256
+ : undefined,
257
+ });
258
+ }
259
+ }
260
+ return { env, mounts, redis, buckets, postgres, targets };
261
+ };
262
+
263
+ /**
264
+ * HTTP 80 → HTTPS redirect plus HTTPS 443 for public Services. Private
265
+ * (Flycast-only) Services publish plain HTTP on 80: Fly issues no
266
+ * certificate for `.flycast`, so a redirect to HTTPS would break callers.
267
+ */
268
+ export const defaultHttpServices = (
269
+ port: number,
270
+ count = 1,
271
+ isPublic = true,
272
+ ): FlyMachineService[] => [
273
+ {
274
+ protocol: "tcp",
275
+ internal_port: port,
276
+ autostart: true,
277
+ autostop: "off",
278
+ min_machines_running: count,
279
+ ports: isPublic
280
+ ? [
281
+ { port: 80, handlers: ["http"], force_https: true },
282
+ { port: 443, handlers: ["tls", "http"] },
283
+ ]
284
+ : [{ port: 80, handlers: ["http"] }],
285
+ // Wait until the process is listening before the proxy sends traffic.
286
+ // Without this, fly.dev hangs (status 0) while Node is still booting.
287
+ checks: [{ type: "tcp", port, interval: "10s", timeout: "2s", grace_period: "30s" }],
288
+ },
289
+ ];
290
+
291
+ const sanitizeImageRepo = (id: string): string => {
292
+ const lowered = id
293
+ .toLowerCase()
294
+ .replace(/[^a-z0-9_.-]+/g, "-")
295
+ .replace(/^-+|-+$/g, "");
296
+ return lowered.length === 0 ? "service" : lowered;
297
+ };
298
+
299
+ const generateDockerfile = (
300
+ props: HostedProgramProps,
301
+ hasChunks: boolean,
302
+ install?: Record<string, string>,
303
+ entryRel?: string,
304
+ ) => {
305
+ const port = props.port ?? DEFAULT_PORT;
306
+ const lines = [`FROM ${props.image ?? DEFAULT_BASE_IMAGE}`, `WORKDIR /app`];
307
+ if (install !== undefined && Object.keys(install).length > 0) {
308
+ lines.push(
309
+ `COPY package.json /app/package.json`,
310
+ `RUN npm install --omit=dev --no-fund --no-audit`,
311
+ );
312
+ }
313
+ if (props.isExternal === true) {
314
+ lines.push(`COPY . /app`);
315
+ const entry = entryRel !== undefined && entryRel.length > 0 ? entryRel : "serve-node.mjs";
316
+ lines.push(
317
+ `ENV PORT=${String(port)}`,
318
+ `ENV HOST=0.0.0.0`,
319
+ `EXPOSE ${String(port)}`,
320
+ `ENTRYPOINT ["node", ${JSON.stringify(`/app/${entry}`)}]`,
321
+ );
322
+ return `${lines.join("\n")}\n`;
323
+ }
324
+ lines.push(`COPY index.mjs /app/index.mjs`);
325
+ if (hasChunks) {
326
+ lines.push(`COPY *.js /app/`);
327
+ }
328
+ const seen = new Set<string>();
329
+ for (const extra of props.extraFiles ?? []) {
330
+ const dest = extraFileDestination(extra.dest);
331
+ if (isContextRootDest(dest) || seen.has(dest)) continue;
332
+ seen.add(dest);
333
+ lines.push(`COPY ${dest} /app/${dest}`);
334
+ }
335
+ lines.push(
336
+ `ENV PORT=${String(port)}`,
337
+ `ENV HOST=0.0.0.0`,
338
+ `EXPOSE ${String(port)}`,
339
+ `ENTRYPOINT ["node", "/app/index.mjs"]`,
340
+ );
341
+ return `${lines.join("\n")}\n`;
342
+ };
343
+
344
+ const installManifest = (dependencies: Record<string, string>) =>
345
+ `${JSON.stringify({ private: true, type: "module", dependencies }, null, 2)}\n`;
346
+
347
+ export const createFlyHostedSupport = ({
348
+ stackName,
349
+ stage,
350
+ virtualEntryPlugin,
351
+ docker,
352
+ dotAlchemy,
353
+ }: {
354
+ stackName: string;
355
+ stage: string;
356
+ virtualEntryPlugin: (content: (importPath: string) => string) => rolldown.Plugin;
357
+ docker: Docker["Service"];
358
+ dotAlchemy: string;
359
+ }) => {
360
+ const alchemyEnv = {
361
+ ALCHEMY_STACK_NAME: stackName,
362
+ ALCHEMY_STAGE: stage,
363
+ ALCHEMY_PHASE: "runtime",
364
+ HOST: "0.0.0.0",
365
+ };
366
+
367
+ const bundleProgram = Effect.fn(function* (props: HostedProgramProps) {
368
+ const handler = props.handler ?? "default";
369
+ const realMain = yield* resolveMainPath(props.main);
370
+ const cwd = yield* findCwdForBundle(realMain);
371
+ const bootstrap = makeBunBootstrap(handler);
372
+ const requested = yield* normalizeInstallTargets(props.build?.install);
373
+ const installRoots = new Set(Object.keys(requested));
374
+ const configuredExternal = props.build?.input?.external;
375
+
376
+ const buildBundle = Effect.fn(function* (
377
+ entry: string,
378
+ plugins?: rolldown.RolldownPluginOption,
379
+ ) {
380
+ return yield* Bundle.build(
381
+ {
382
+ ...props.build?.input,
383
+ input: entry,
384
+ cwd,
385
+ platform: "node",
386
+ external: (moduleId, parentId, isResolved) => {
387
+ if (moduleId === "bun" || moduleId.startsWith("bun:")) return true;
388
+ for (const root of installRoots) {
389
+ if (matchesPackageRoot(moduleId, root)) return true;
390
+ }
391
+ return matchesConfiguredExternal(configuredExternal, moduleId, parentId, isResolved);
392
+ },
393
+ resolve: {
394
+ conditionNames: [...Bundle.NODE_CONDITION_NAMES],
395
+ ...props.build?.input?.resolve,
396
+ },
397
+ plugins: [props.build?.input?.plugins, plugins],
398
+ },
399
+ {
400
+ ...props.build?.output,
401
+ format: "esm",
402
+ sourcemap: props.build?.output?.sourcemap ?? false,
403
+ entryFileNames: "index.mjs",
404
+ strictExecutionOrder: true,
405
+ keepNames: true,
406
+ },
407
+ props.build,
408
+ );
409
+ });
410
+
411
+ if (props.isExternal === true) {
412
+ const fs = yield* FileSystem.FileSystem;
413
+ const path = yield* Path.Path;
414
+ const bytes = yield* fs.readFile(realMain);
415
+ const hash = yield* sha256(bytes);
416
+ return { files: [{ path: path.basename(realMain), content: bytes }], hash };
417
+ }
418
+
419
+ const bundleOutput = yield* buildBundle(realMain, virtualEntryPlugin(bootstrap));
420
+
421
+ const files = bundleOutput.files.map((file) => ({
422
+ path: file.path,
423
+ content:
424
+ typeof file.content === "string" ? new TextEncoder().encode(file.content) : file.content,
425
+ }));
426
+
427
+ return { files, hash: bundleOutput.hash };
428
+ });
429
+
430
+ const computeCodeHash = Effect.fn(function* (props: HostedProgramProps) {
431
+ const bundled = yield* bundleProgram(props);
432
+ const realMain = yield* resolveMainPath(props.main);
433
+ const cwd = yield* findCwdForBundle(realMain);
434
+ const path = yield* Path.Path;
435
+ const requested = yield* normalizeInstallTargets(props.build?.install);
436
+ const identity =
437
+ Object.keys(requested).length > 0
438
+ ? yield* resolvePackageInstallIdentity({ cwd, requested })
439
+ : undefined;
440
+ const install =
441
+ identity !== undefined && Object.keys(identity.resolved).length > 0
442
+ ? identity.resolved
443
+ : undefined;
444
+ const packageJson = install === undefined ? undefined : installManifest(install);
445
+ const extras = (props.extraFiles ?? []).map((file) => ({
446
+ source: file.source,
447
+ dest: file.dest,
448
+ }));
449
+ const root = contextRootOf(realMain, extras, path, (source) =>
450
+ resolveExtraSource(source, path),
451
+ );
452
+ const entryRel =
453
+ props.isExternal === true
454
+ ? (posixRelUnder(root, realMain, path) ?? path.basename(realMain))
455
+ : undefined;
456
+ const dockerfile = generateDockerfile(props, bundled.files.length > 1, install, entryRel);
457
+ const extraFiles = yield* hashExtraFiles(props.extraFiles);
458
+ const codeHash = (yield* sha256Object({
459
+ bundleHash: bundled.hash,
460
+ dockerfile,
461
+ packageJson,
462
+ extraFiles,
463
+ extraFilesIncludesNodeModules: true,
464
+ })).slice(0, 16);
465
+ return { bundled, dockerfile, codeHash, packageJson, entryRel };
466
+ });
467
+
468
+ const imageExists = (imageRef: string) =>
469
+ docker.image.inspect(imageRef).pipe(
470
+ Effect.map(() => true),
471
+ Effect.catchReason("PlatformError", "NotFound", () => Effect.succeed(false)),
472
+ );
473
+
474
+ const pushBackoff = Schedule.exponential("2 seconds");
475
+
476
+ /**
477
+ * Bundle `main`, content-hash the image, build it when missing, and
478
+ * push to `registry.fly.io/{appName}:{logicalId}-{hash}` using an
479
+ * app deploy token. When `previousHash` matches, skip build and push.
480
+ *
481
+ * Fly's registry is app-scoped (`/v2/{app}/...`). A nested
482
+ * `{app}/{image}` repository 404s on blob upload.
483
+ */
484
+ const resolveImage = Effect.fn(function* (input: {
485
+ id: string;
486
+ appName: string;
487
+ props: HostedProgramProps;
488
+ previousHash?: string;
489
+ session?: { note: (message: string) => Effect.Effect<void> };
490
+ }) {
491
+ const note = input.session?.note ?? ((_message: string) => Effect.void);
492
+ yield* note(`Bundling ${input.id} program...`);
493
+ const { bundled, dockerfile, codeHash, packageJson } = yield* computeCodeHash(input.props);
494
+ yield* note(`Hashed ${input.id} (${codeHash})`);
495
+ const repo = sanitizeImageRepo(input.id);
496
+ const imageRef = `${FLY_REGISTRY}/${input.appName}:${repo}-${codeHash}`;
497
+
498
+ if (input.previousHash === codeHash) {
499
+ return { imageRef, codeHash };
500
+ }
501
+
502
+ const minted = yield* machines.createAppDeployToken({ app_name: input.appName });
503
+ const token =
504
+ minted.token === undefined || Redacted.isRedacted(minted.token)
505
+ ? minted.token
506
+ : Redacted.make(minted.token);
507
+ if (token === undefined || Redacted.value(token).length === 0) {
508
+ return yield* new DeployTokenMissing({ appName: input.appName });
509
+ }
510
+ const registry = { server: FLY_REGISTRY, username: "x", password: token };
511
+
512
+ const materialize = Effect.gen(function* () {
513
+ const realMain = yield* resolveMainPath(input.props.main);
514
+ const contextDir = yield* getStableContextDir(realMain, dotAlchemy, `${input.id}-image`);
515
+ const fs = yield* FileSystem.FileSystem;
516
+ const path = yield* Path.Path;
517
+ const files =
518
+ input.props.isExternal === true
519
+ ? packageJson !== undefined
520
+ ? [{ path: "package.json", content: new TextEncoder().encode(packageJson) }]
521
+ : []
522
+ : [
523
+ ...bundled.files.map((file, index) => ({
524
+ path: index === 0 ? "index.mjs" : file.path,
525
+ content: file.content,
526
+ })),
527
+ ...(packageJson !== undefined
528
+ ? [{ path: "package.json", content: new TextEncoder().encode(packageJson) }]
529
+ : []),
530
+ ];
531
+ yield* docker.materialize({ context: contextDir, dockerfile, files });
532
+ yield* copyExtraFiles(contextDir, input.props.extraFiles);
533
+ if (input.props.isExternal === true) {
534
+ const extras = (input.props.extraFiles ?? []).map((file) => ({
535
+ source: file.source,
536
+ dest: file.dest,
537
+ }));
538
+ const root = contextRootOf(realMain, extras, path, (source) =>
539
+ resolveExtraSource(source, path),
540
+ );
541
+ const entryRel = posixRelUnder(root, realMain, path) ?? path.basename(realMain);
542
+ const dest = path.join(contextDir, entryRel);
543
+ if (!(yield* fs.exists(dest).pipe(Effect.orElseSucceed(() => false)))) {
544
+ yield* fs.makeDirectory(path.dirname(dest), { recursive: true });
545
+ yield* fs.copy(realMain, dest, { overwrite: true });
546
+ }
547
+ }
548
+ return contextDir;
549
+ });
550
+
551
+ if (input.props.build?.remote !== false) {
552
+ const contextDir = yield* materialize;
553
+ yield* note(`Building ${imageRef} on a Fly remote builder...`);
554
+ yield* buildOnRemoteBuilder({
555
+ docker,
556
+ appName: input.appName,
557
+ contextDir,
558
+ imageRef,
559
+ platform: MACHINE_PLATFORM,
560
+ registry,
561
+ note,
562
+ });
563
+ yield* note(`Pushed ${imageRef}`);
564
+ return { imageRef, codeHash };
565
+ }
566
+
567
+ if (!(yield* imageExists(imageRef))) {
568
+ const contextDir = yield* materialize;
569
+ yield* note(`Building container image ${imageRef}...`);
570
+ yield* docker.image.build({ context: contextDir, tag: imageRef, platform: MACHINE_PLATFORM });
571
+ yield* note(`Built ${imageRef}`);
572
+ }
573
+
574
+ yield* note(`Pushing ${imageRef}...`);
575
+ yield* docker.image
576
+ .push(imageRef, registry)
577
+ .pipe(Effect.retry({ times: 3, schedule: pushBackoff }));
578
+ yield* note(`Pushed ${imageRef}`);
579
+ return { imageRef, codeHash };
580
+ });
581
+
582
+ const hash = Effect.fn(function* (props: HostedProgramProps) {
583
+ const { codeHash } = yield* computeCodeHash(props);
584
+ return codeHash;
585
+ });
586
+
587
+ return { alchemyEnv, bundleProgram, computeCodeHash, resolveImage, hash };
588
+ };
589
+
590
+ /**
591
+ * Bundle a Sprite program the same way {@link createFlyHostedSupport}
592
+ * bundles a Service — rolldown + Node bootstrap — without building a
593
+ * Docker image. The provider writes the files onto the Sprite.
594
+ */
595
+ export const createSpriteHostedSupport = ({
596
+ stackName,
597
+ stage,
598
+ virtualEntryPlugin,
599
+ }: {
600
+ stackName: string;
601
+ stage: string;
602
+ virtualEntryPlugin: (content: (importPath: string) => string) => rolldown.Plugin;
603
+ }) => {
604
+ const alchemyEnv = {
605
+ ALCHEMY_STACK_NAME: stackName,
606
+ ALCHEMY_STAGE: stage,
607
+ ALCHEMY_PHASE: "runtime",
608
+ HOST: "0.0.0.0",
609
+ };
610
+
611
+ const bundleProgram = Effect.fn(function* (props: HostedProgramProps) {
612
+ const handler = props.handler ?? "default";
613
+ const realMain = yield* resolveMainPath(props.main);
614
+ const cwd = yield* findCwdForBundle(realMain);
615
+ const bootstrap = makeBunBootstrap(handler);
616
+
617
+ const buildBundle = Effect.fn(function* (
618
+ entry: string,
619
+ plugins?: rolldown.RolldownPluginOption,
620
+ ) {
621
+ return yield* Bundle.build(
622
+ {
623
+ ...props.build?.input,
624
+ input: entry,
625
+ cwd,
626
+ platform: "node",
627
+ external: [
628
+ "bun",
629
+ "bun:*",
630
+ ...((props.build?.input?.external as string[] | undefined) ?? []),
631
+ ],
632
+ resolve: {
633
+ conditionNames: [...Bundle.NODE_CONDITION_NAMES],
634
+ ...props.build?.input?.resolve,
635
+ },
636
+ plugins: [props.build?.input?.plugins, plugins],
637
+ },
638
+ {
639
+ ...props.build?.output,
640
+ format: "esm",
641
+ sourcemap: props.build?.output?.sourcemap ?? false,
642
+ minify: props.build?.output?.minify ?? false,
643
+ entryFileNames: "index.mjs",
644
+ },
645
+ props.build,
646
+ );
647
+ });
648
+
649
+ const bundleOutput = props.isExternal
650
+ ? yield* buildBundle(realMain)
651
+ : yield* buildBundle(realMain, virtualEntryPlugin(bootstrap));
652
+
653
+ const files = bundleOutput.files.map((file) => ({
654
+ path: file.path,
655
+ content:
656
+ typeof file.content === "string" ? new TextEncoder().encode(file.content) : file.content,
657
+ }));
658
+
659
+ return { files, hash: bundleOutput.hash };
660
+ });
661
+
662
+ const hash = Effect.fn(function* (props: HostedProgramProps) {
663
+ const bundled = yield* bundleProgram(props);
664
+ return (yield* sha256Object({ bundleHash: bundled.hash })).slice(0, 16);
665
+ });
666
+
667
+ return { alchemyEnv, bundleProgram, hash };
668
+ };