@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,321 @@
1
+ import type { VolumeSnapshot as FlyVolumeSnapshot } from "@distilled.cloud/fly-io/machines";
2
+ import * as machines from "@distilled.cloud/fly-io/machines";
3
+ import { isResolved } from "alchemy/Diff";
4
+ import * as Provider from "alchemy/Provider";
5
+ import { Resource } from "alchemy/Resource";
6
+ import * as Data from "effect/Data";
7
+ import * as Duration from "effect/Duration";
8
+ import * as Effect from "effect/Effect";
9
+ import * as Schedule from "effect/Schedule";
10
+ import type { App } from "./App.ts";
11
+ import type { Providers } from "./Providers.ts";
12
+ import { listOwnedVolumes } from "./Volume.ts";
13
+
14
+ /**
15
+ * A resource-valued prop: the resource itself, or an Effect that produces
16
+ * it (so `yield* App(...)` and `App(...)` both type-check).
17
+ */
18
+ type Ref<T> = T | Effect.Effect<T, never, Providers>;
19
+
20
+ export interface VolumeSnapshotProps {
21
+ /**
22
+ * Parent Fly App. Changing it replaces the snapshot (a new snapshot is
23
+ * created on the new App's Volume). There is no delete API for the old
24
+ * snapshot — it follows Volume `snapshot_retention`.
25
+ */
26
+ app: Ref<App>;
27
+ /**
28
+ * Fly Volume id to snapshot (`vol_…`). Changing it replaces the
29
+ * snapshot. Identity is the snapshot `id` returned by a subsequent
30
+ * `listVolumeSnapshots`.
31
+ */
32
+ volumeId: string;
33
+ }
34
+
35
+ export type VolumeSnapshot = Resource<
36
+ "Fly.VolumeSnapshot",
37
+ VolumeSnapshotProps,
38
+ {
39
+ /** Parent Fly App name. */
40
+ appName: string;
41
+ /** Fly Volume id this snapshot belongs to. */
42
+ volumeId: string;
43
+ /** Fly snapshot id (`vs_…`). Identity of the resource. */
44
+ snapshotId: string;
45
+ /** Observed snapshot status, if the API returned one. */
46
+ status: string | undefined;
47
+ /** Content digest of the snapshot. */
48
+ digest: string | undefined;
49
+ /** Snapshot size in bytes, if the API returned one. */
50
+ size: number | undefined;
51
+ /** Source volume size in GB at snapshot time. */
52
+ volumeSize: number | undefined;
53
+ /** Retention in days. */
54
+ retentionDays: number | undefined;
55
+ /** RFC3339 creation timestamp. */
56
+ createdAt: string | undefined;
57
+ },
58
+ never,
59
+ Providers
60
+ >;
61
+
62
+ /**
63
+ * A Fly.VolumeSnapshot is an on-demand snapshot of a mounted disk.
64
+ *
65
+ * Create is fire-and-forget. Identity is the snapshot id from a
66
+ * subsequent list. Destroy is a no-op. Snapshots follow Volume
67
+ * retention. `nuke` skips this type.
68
+ *
69
+ * @see https://fly.io/docs/machines/api/volumes-resource/
70
+ *
71
+ * ### Create a snapshot
72
+ * Point it at a Volume id from the parent {@link Machine} or
73
+ * {@link Service} (`mounts[0].volumeId`).
74
+ *
75
+ * **Example:** Snapshot a mounted disk
76
+ * ```typescript
77
+ * const box = yield* Fly.Machine("Box", {
78
+ * app: Site,
79
+ * region: "iad",
80
+ * image: "nginx:alpine",
81
+ * mounts: [{ path: "/data", sizeGb: 1 }],
82
+ * });
83
+ *
84
+ * export const Nightly = Fly.VolumeSnapshot("Nightly", {
85
+ * app: Site,
86
+ * volumeId: box.mounts[0].volumeId,
87
+ * });
88
+ * ```
89
+ *
90
+ * :::caution[Changing `app` or `volumeId` replaces the snapshot]
91
+ * A new snapshot is created. There is no delete API for the old one.
92
+ * It follows Volume `snapshot_retention`.
93
+ * :::
94
+ *
95
+ * ### Restore
96
+ * Restore into a new disk with `snapshotId` on the mount. Create-only.
97
+ * The new Machine gets a copy. The original Volume is unchanged.
98
+ *
99
+ * **Example:** Restore onto a Machine
100
+ * ```typescript
101
+ * const restored = yield* Fly.Machine("Restored", {
102
+ * app: Site,
103
+ * region: "iad",
104
+ * image: "nginx:alpine",
105
+ * mounts: [{ path: "/data", sizeGb: 1, snapshotId: Nightly.snapshotId }],
106
+ * });
107
+ * ```
108
+ *
109
+ * ### Restore into a Service
110
+ * Pass `snapshotId` on {@link MountVolume}. Same create-only rule.
111
+ *
112
+ * **Example:** Restore onto a Service
113
+ * ```typescript
114
+ * export default class Api extends Fly.Service<Api>()(
115
+ * "Api",
116
+ * { app: Site, main: import.meta.url, region: "iad", port: 3000 },
117
+ * Effect.gen(function* () {
118
+ * const disk = yield* Fly.MountVolume({
119
+ * path: "/data",
120
+ * sizeGb: 1,
121
+ * snapshotId: Nightly.snapshotId,
122
+ * });
123
+ * return {
124
+ * fetch: Effect.succeed(HttpServerResponse.text(disk.path)),
125
+ * };
126
+ * }).pipe(Effect.provide(Fly.MountVolumeLive)),
127
+ * ) {}
128
+ * ```
129
+ *
130
+ * @resource
131
+ * @product Volume
132
+ */
133
+ export const VolumeSnapshot = Resource<VolumeSnapshot>("Fly.VolumeSnapshot");
134
+
135
+ export class VolumeSnapshotNotCreated extends Data.TaggedError("Fly.VolumeSnapshotNotCreated")<{
136
+ appName: string;
137
+ volumeId: string;
138
+ }> {}
139
+
140
+ export class VolumeSnapshotRefsMissing extends Data.TaggedError("Fly.VolumeSnapshotRefsMissing")<{
141
+ message: string;
142
+ }> {}
143
+
144
+ class VolumeSnapshotPending extends Data.TaggedError("Fly.VolumeSnapshotPending")<{
145
+ volumeId: string;
146
+ }> {}
147
+
148
+ const backoff = Schedule.min([
149
+ Schedule.exponential(Duration.millis(500), 1.5),
150
+ Schedule.spaced(Duration.seconds(5)),
151
+ ]);
152
+
153
+ const appNameOf = (value: unknown): string | undefined => {
154
+ if (value == null || typeof value !== "object") return undefined;
155
+ const name = (value as { appName?: unknown }).appName;
156
+ return typeof name === "string" && name.length > 0 ? name : undefined;
157
+ };
158
+
159
+ const volumeIdOf = (value: unknown): string | undefined => {
160
+ if (typeof value === "string" && value.length > 0) return value;
161
+ if (value == null || typeof value !== "object") return undefined;
162
+ const id = (value as { volumeId?: unknown }).volumeId;
163
+ return typeof id === "string" && id.length > 0 ? id : undefined;
164
+ };
165
+
166
+ const toAttrs = (
167
+ appName: string,
168
+ volumeId: string,
169
+ snapshot: FlyVolumeSnapshot,
170
+ ): VolumeSnapshot["Attributes"] => ({
171
+ appName,
172
+ volumeId,
173
+ snapshotId: snapshot.id ?? "",
174
+ status: snapshot.status,
175
+ digest: snapshot.digest,
176
+ size: snapshot.size,
177
+ volumeSize: snapshot.volume_size,
178
+ retentionDays: snapshot.retention_days,
179
+ createdAt: snapshot.created_at,
180
+ });
181
+
182
+ const listSnapshots = (appName: string, volumeId: string) =>
183
+ machines
184
+ .listVolumeSnapshots({
185
+ app_name: appName,
186
+ volume_id: volumeId,
187
+ })
188
+ .pipe(
189
+ Effect.catchTag(["NotFound", "Forbidden"], () => Effect.succeed([] as FlyVolumeSnapshot[])),
190
+ );
191
+
192
+ const findById = (appName: string, volumeId: string, snapshotId: string) =>
193
+ listSnapshots(appName, volumeId).pipe(
194
+ Effect.map((snapshots) => snapshots.find((snapshot) => snapshot.id === snapshotId)),
195
+ );
196
+
197
+ const newestFirst = (left: FlyVolumeSnapshot, right: FlyVolumeSnapshot) =>
198
+ Date.parse(right.created_at ?? "") - Date.parse(left.created_at ?? "");
199
+
200
+ const pickNewest = (snapshots: FlyVolumeSnapshot[]): FlyVolumeSnapshot | undefined =>
201
+ snapshots.filter((snapshot) => (snapshot.id ?? "").length > 0).sort(newestFirst)[0];
202
+
203
+ const waitForNewSnapshot = (appName: string, volumeId: string, knownIds: ReadonlySet<string>) =>
204
+ listSnapshots(appName, volumeId).pipe(
205
+ Effect.flatMap((snapshots) => {
206
+ const next = pickNewest(
207
+ snapshots.filter((snapshot) => snapshot.id !== undefined && !knownIds.has(snapshot.id)),
208
+ );
209
+ if (next !== undefined) return Effect.succeed(next);
210
+ return Effect.fail(new VolumeSnapshotPending({ volumeId }));
211
+ }),
212
+ Effect.retry({
213
+ while: (e) => e._tag === "Fly.VolumeSnapshotPending",
214
+ times: 8,
215
+ schedule: backoff,
216
+ }),
217
+ Effect.catchTag("Fly.VolumeSnapshotPending", () => Effect.succeed(undefined)),
218
+ );
219
+
220
+ export const VolumeSnapshotProvider = () =>
221
+ Provider.succeed(VolumeSnapshot, {
222
+ stables: ["snapshotId", "volumeId", "appName"],
223
+ nuke: { skip: true },
224
+
225
+ diff: Effect.fn(function* ({ news, output }) {
226
+ if (news === undefined || !isResolved(news)) return undefined;
227
+ if (output === undefined) return undefined;
228
+ const desiredApp = appNameOf(news.app);
229
+ const appChanged = desiredApp !== undefined && desiredApp !== output.appName;
230
+ const desiredVolume = volumeIdOf(news.volumeId);
231
+ const volumeChanged = desiredVolume !== undefined && desiredVolume !== output.volumeId;
232
+ if (appChanged || volumeChanged) {
233
+ return { action: "replace" as const };
234
+ }
235
+ return undefined;
236
+ }),
237
+
238
+ read: Effect.fn(function* ({ olds, output }) {
239
+ const appName = output?.appName ?? appNameOf(olds?.app);
240
+ const volumeId = output?.volumeId ?? volumeIdOf(olds?.volumeId);
241
+ if (appName === undefined || volumeId === undefined) return undefined;
242
+ const snapshotId = output?.snapshotId;
243
+ if (snapshotId === undefined || snapshotId.length === 0) {
244
+ return undefined;
245
+ }
246
+ const found = yield* findById(appName, volumeId, snapshotId);
247
+ if (found === undefined) return undefined;
248
+ return toAttrs(appName, volumeId, found);
249
+ }),
250
+
251
+ list: Effect.fn(function* () {
252
+ const volumes = yield* listOwnedVolumes();
253
+ const groups = yield* Effect.forEach(
254
+ volumes,
255
+ ({ appName, volumeId }) =>
256
+ listSnapshots(appName, volumeId).pipe(
257
+ Effect.map((snapshots) =>
258
+ snapshots
259
+ .filter((snapshot) => snapshot.id !== undefined && snapshot.id.length > 0)
260
+ .map((snapshot) => toAttrs(appName, volumeId, snapshot)),
261
+ ),
262
+ ),
263
+ { concurrency: 8 },
264
+ );
265
+ return groups.flat();
266
+ }),
267
+
268
+ reconcile: Effect.fn(function* ({ news, output }) {
269
+ const props = news ?? ({} as VolumeSnapshotProps);
270
+ const appName = appNameOf(props.app) ?? output?.appName;
271
+ const volumeId = volumeIdOf(props.volumeId) ?? output?.volumeId;
272
+ if (appName === undefined || volumeId === undefined) {
273
+ return yield* new VolumeSnapshotRefsMissing({
274
+ message: "Fly.VolumeSnapshot requires a resolved App with appName and a volumeId.",
275
+ });
276
+ }
277
+
278
+ // Observe by cached snapshot id on the target volume.
279
+ const observed = yield* listSnapshots(appName, volumeId);
280
+ let current =
281
+ output?.snapshotId !== undefined && output.snapshotId.length > 0
282
+ ? observed.find((snapshot) => snapshot.id === output.snapshotId)
283
+ : undefined;
284
+
285
+ if (current === undefined) {
286
+ const knownIds = new Set(
287
+ observed.flatMap((snapshot) =>
288
+ snapshot.id !== undefined && snapshot.id.length > 0 ? [snapshot.id] : [],
289
+ ),
290
+ );
291
+ yield* machines
292
+ .createVolumeSnapshot({
293
+ app_name: appName,
294
+ volume_id: volumeId,
295
+ })
296
+ .pipe(
297
+ Effect.asVoid,
298
+ Effect.catchTag("Conflict", () => Effect.void),
299
+ Effect.retry({
300
+ while: (e) =>
301
+ e._tag === "NotFound" ||
302
+ (e._tag === "BadRequest" && e.message.includes("uninitialized volume")),
303
+ times: 8,
304
+ schedule: backoff,
305
+ }),
306
+ );
307
+ current = yield* waitForNewSnapshot(appName, volumeId, knownIds);
308
+ }
309
+
310
+ if (current === undefined || current.id === undefined) {
311
+ return yield* new VolumeSnapshotNotCreated({ appName, volumeId });
312
+ }
313
+
314
+ return toAttrs(appName, volumeId, current);
315
+ }),
316
+
317
+ delete: Effect.fn(function* () {
318
+ // Fly has no snapshot delete API. Snapshots expire with Volume
319
+ // snapshot_retention or when the Volume is deleted.
320
+ }),
321
+ });
@@ -0,0 +1,294 @@
1
+ import { createHash } from "node:crypto";
2
+ import { Credentials, fromCredentials } from "@distilled.cloud/aws/Credentials";
3
+ import * as AwsEndpoint from "@distilled.cloud/aws/Endpoint";
4
+ import type { RegionName } from "@distilled.cloud/aws/Region";
5
+ import * as s3 from "@distilled.cloud/aws/s3";
6
+ import * as Provider from "alchemy/Provider";
7
+ import { Resource } from "alchemy/Resource";
8
+ import { initialCwd } from "alchemy/Util/Node";
9
+ import { cacheControlOf, contentTypeOf } from "alchemy/Website/assets";
10
+ import * as Effect from "effect/Effect";
11
+ import * as FileSystem from "effect/FileSystem";
12
+ import * as FetchHttpClient from "effect/http/FetchHttpClient";
13
+ import type * as HttpClient from "effect/http/HttpClient";
14
+ import * as Layer from "effect/Layer";
15
+ import * as Path from "effect/Path";
16
+ import * as Redacted from "effect/Redacted";
17
+ import * as Stream from "effect/Stream";
18
+ import type { Bucket } from "../Bucket.ts";
19
+ import { TigrisCredentialsMissing } from "../Errors.ts";
20
+ import type { Providers } from "../Providers.ts";
21
+
22
+ const s3Concurrency = 16;
23
+
24
+ /**
25
+ * Unwrap Tigris {@link Bucket} attrs for the S3 client. Credentials and
26
+ * the endpoint are `Redacted<string>`; names are plain strings. This is
27
+ * Fly Bucket plumbing, not website MIME — it stays here because this
28
+ * resource is the only Website helper that speaks Tigris.
29
+ */
30
+ const asPlain = (value: unknown): string | undefined => {
31
+ if (typeof value === "string" && value.length > 0) return value;
32
+ if (Redacted.isRedacted(value)) {
33
+ const inner = Redacted.value(value);
34
+ return typeof inner === "string" && inner.length > 0 ? inner : undefined;
35
+ }
36
+ return undefined;
37
+ };
38
+
39
+ export interface AssetDeploymentProps {
40
+ /**
41
+ * Destination Tigris bucket (a {@link Bucket} resource).
42
+ */
43
+ bucket: Bucket;
44
+ /**
45
+ * Local directory to upload (framework `clientDirectory`).
46
+ */
47
+ sourcePath: string;
48
+ /**
49
+ * Optional key prefix within the bucket.
50
+ */
51
+ prefix?: string;
52
+ /**
53
+ * Delete observed keys under the prefix that are not in this deploy.
54
+ * @default true
55
+ */
56
+ purge?: boolean;
57
+ }
58
+
59
+ export interface AssetDeployment extends Resource<
60
+ "Fly.Website.AssetDeployment",
61
+ AssetDeploymentProps,
62
+ {
63
+ bucketName: string;
64
+ prefix: string;
65
+ version: string;
66
+ fileCount: number;
67
+ files: string[];
68
+ },
69
+ never,
70
+ Providers
71
+ > {}
72
+
73
+ /**
74
+ * Upload a local directory into a public Tigris bucket for Fly Website
75
+ * statics. HTML is never cached; everything else is immutable.
76
+ *
77
+ * @resource
78
+ */
79
+ export const AssetDeployment = Resource<AssetDeployment>("Fly.Website.AssetDeployment");
80
+
81
+ const normalizePrefix = (prefix: string | undefined) =>
82
+ prefix ? prefix.replace(/^\/+|\/+$/g, "") : "";
83
+
84
+ const scopeOf = (bucket: Bucket) =>
85
+ Effect.gen(function* () {
86
+ const bucketName = asPlain(bucket.bucketName) ?? asPlain(bucket.name);
87
+ const accessKeyId = asPlain(bucket.accessKeyId);
88
+ const secretAccessKey = asPlain(bucket.secretAccessKey);
89
+ const endpoint = asPlain(bucket.endpoint);
90
+ const region = (asPlain(bucket.region) ?? "auto") as RegionName;
91
+ if (
92
+ bucketName === undefined ||
93
+ accessKeyId === undefined ||
94
+ secretAccessKey === undefined ||
95
+ endpoint === undefined
96
+ ) {
97
+ return yield* new TigrisCredentialsMissing({
98
+ name: bucketName ?? bucket.LogicalId,
99
+ });
100
+ }
101
+ return { bucketName, accessKeyId, secretAccessKey, endpoint, region };
102
+ });
103
+
104
+ const withTigris = <A, E>(
105
+ scope: {
106
+ accessKeyId: string;
107
+ secretAccessKey: string;
108
+ endpoint: string;
109
+ region: RegionName;
110
+ },
111
+ operation: Effect.Effect<A, E, Credentials | HttpClient.HttpClient>,
112
+ ) =>
113
+ operation.pipe(
114
+ Effect.provide(
115
+ Layer.mergeAll(
116
+ fromCredentials(
117
+ {
118
+ accessKeyId: Redacted.make(scope.accessKeyId),
119
+ secretAccessKey: Redacted.make(scope.secretAccessKey),
120
+ },
121
+ scope.region,
122
+ ),
123
+ AwsEndpoint.of(scope.endpoint),
124
+ FetchHttpClient.layer,
125
+ ),
126
+ ),
127
+ );
128
+
129
+ const walkFiles = Effect.fn(function* (root: string) {
130
+ const fs = yield* FileSystem.FileSystem;
131
+ const path = yield* Path.Path;
132
+ if (!(yield* fs.exists(root))) return [] as string[];
133
+ const names = yield* fs.readDirectory(root, { recursive: true });
134
+ const files = yield* Effect.all(
135
+ names.map((name) =>
136
+ Effect.gen(function* () {
137
+ const full = path.join(root, name);
138
+ const stat = yield* fs.stat(full);
139
+ return stat.type === "File" ? name.replaceAll("\\", "/") : undefined;
140
+ }),
141
+ ),
142
+ { concurrency: "unbounded" },
143
+ );
144
+ return files
145
+ .filter((name): name is string => name !== undefined)
146
+ .sort((a, b) => a.localeCompare(b));
147
+ });
148
+
149
+ const listObserved = (
150
+ scope: {
151
+ bucketName: string;
152
+ accessKeyId: string;
153
+ secretAccessKey: string;
154
+ endpoint: string;
155
+ region: RegionName;
156
+ },
157
+ prefix: string,
158
+ ) =>
159
+ withTigris(
160
+ scope,
161
+ s3.listObjectsV2
162
+ .pages({
163
+ Bucket: scope.bucketName,
164
+ Prefix: prefix.length > 0 ? `${prefix}/` : undefined,
165
+ })
166
+ .pipe(
167
+ Stream.flatMap((page) => Stream.fromIterable(page.Contents ?? [])),
168
+ Stream.runFold(
169
+ () => new Map<string, string | undefined>(),
170
+ (observed, object) => {
171
+ if (object.Key !== undefined) {
172
+ observed.set(object.Key, object.ETag);
173
+ }
174
+ return observed;
175
+ },
176
+ ),
177
+ ),
178
+ );
179
+
180
+ const deleteObject = (
181
+ scope: {
182
+ bucketName: string;
183
+ accessKeyId: string;
184
+ secretAccessKey: string;
185
+ endpoint: string;
186
+ region: RegionName;
187
+ },
188
+ key: string,
189
+ ) =>
190
+ withTigris(
191
+ scope,
192
+ s3.deleteObject({
193
+ Bucket: scope.bucketName,
194
+ Key: key,
195
+ }),
196
+ ).pipe(Effect.catchTag("NoSuchKey", () => Effect.void));
197
+
198
+ export const AssetDeploymentProvider = () =>
199
+ Provider.effect(
200
+ AssetDeployment,
201
+ Effect.succeed({
202
+ list: () => Effect.succeed([]),
203
+ read: Effect.fn(function* ({ output }) {
204
+ return output;
205
+ }),
206
+ reconcile: Effect.fn(function* ({ news, session }) {
207
+ const fs = yield* FileSystem.FileSystem;
208
+ const path = yield* Path.Path;
209
+ const scope = yield* scopeOf(news.bucket);
210
+ const prefix = normalizePrefix(news.prefix);
211
+ const root = path.isAbsolute(news.sourcePath)
212
+ ? news.sourcePath
213
+ : path.resolve(initialCwd, news.sourcePath);
214
+ const files = yield* walkFiles(root);
215
+ const observed = yield* listObserved(scope, prefix);
216
+ const prepared = yield* Effect.all(
217
+ files.map((relative) =>
218
+ Effect.gen(function* () {
219
+ const body = yield* fs.readFile(path.join(root, relative));
220
+ const key = prefix.length > 0 ? `${prefix}/${relative}` : relative;
221
+ const contentType = contentTypeOf(relative);
222
+ const cacheControl = cacheControlOf(relative);
223
+ return { relative, key, body, contentType, cacheControl };
224
+ }),
225
+ ),
226
+ { concurrency: "unbounded" },
227
+ );
228
+ const version = yield* Effect.sync(() => {
229
+ const hash = createHash("sha256");
230
+ for (const file of prepared) {
231
+ hash.update(file.relative);
232
+ hash.update(file.body);
233
+ hash.update(file.contentType);
234
+ hash.update(file.cacheControl);
235
+ }
236
+ return hash.digest("hex");
237
+ });
238
+ const desired = new Set(prepared.map((file) => file.key));
239
+ yield* Effect.all(
240
+ prepared.flatMap((file) => {
241
+ const expected = createHash("md5").update(file.body).digest("hex");
242
+ const etag = observed.get(file.key)?.replace(/^"|"$/g, "");
243
+ if (etag === expected) return [];
244
+ return [
245
+ withTigris(
246
+ scope,
247
+ s3.putObject({
248
+ Bucket: scope.bucketName,
249
+ Key: file.key,
250
+ Body: file.body,
251
+ ContentType: file.contentType,
252
+ CacheControl: file.cacheControl,
253
+ }),
254
+ ),
255
+ ];
256
+ }),
257
+ { concurrency: s3Concurrency },
258
+ );
259
+
260
+ if (news.purge ?? true) {
261
+ yield* Effect.all(
262
+ [...observed.keys()]
263
+ .filter((key) => !desired.has(key))
264
+ .map((key) => deleteObject(scope, key)),
265
+ { concurrency: s3Concurrency },
266
+ );
267
+ }
268
+
269
+ const output = {
270
+ bucketName: scope.bucketName,
271
+ prefix,
272
+ version,
273
+ fileCount: files.length,
274
+ files: prepared.map((file) => file.relative),
275
+ };
276
+ yield* session.note(
277
+ `Uploaded ${output.fileCount} file(s) to tigris://${output.bucketName}/${output.prefix}`,
278
+ );
279
+ return output;
280
+ }),
281
+ delete: Effect.fn(
282
+ function* ({ olds, output }) {
283
+ if (!(olds.purge ?? true)) return;
284
+ const scope = yield* scopeOf(olds.bucket);
285
+ const observed = yield* listObserved(scope, output.prefix);
286
+ yield* Effect.all(
287
+ [...observed.keys()].map((key) => deleteObject(scope, key)),
288
+ { concurrency: s3Concurrency },
289
+ );
290
+ },
291
+ Effect.catchTag("NoSuchBucket", () => Effect.void),
292
+ ),
293
+ }),
294
+ );
@@ -0,0 +1,87 @@
1
+ import { frameworkSite, staticConfigFromAssets, type FrameworkSiteProps } from "./FrameworkSite.ts";
2
+
3
+ /** The framework-integration package that drives the Astro build. */
4
+ export const ASTRO_FRAMEWORK_SPECIFIER = "@alchemy.run/frontend-frameworks/astro";
5
+
6
+ /** The Node container deploy target for the Astro build. */
7
+ export const ASTRO_NODE_TARGET_SPECIFIER = "@alchemy.run/frontend-frameworks/astro/node";
8
+
9
+ export interface AstroProps extends FrameworkSiteProps {
10
+ /**
11
+ * Serializable Astro config merged OVER the project's own
12
+ * `astro.config.*` (which loads natively). `adapter` is owned by the Node
13
+ * deploy target and may not be set here.
14
+ */
15
+ astro?: {
16
+ /** The full URL the site deploys to (`Astro.site`). */
17
+ site?: string;
18
+ /** Base path the site deploys under. */
19
+ base?: string;
20
+ /**
21
+ * Astro output target. `"server"` renders pages on demand; individual
22
+ * pages opt into prerendering with `export const prerender = true`.
23
+ * `"static"` prerenders every page at build time and deploys
24
+ * assets-only (no SSR server).
25
+ * @default "server"
26
+ */
27
+ output?: "server" | "static";
28
+ /** Source directory, relative to `rootDir`. @default "./src" */
29
+ srcDir?: string;
30
+ /** Public (static passthrough) directory. @default "./public" */
31
+ publicDir?: string;
32
+ /** Build output directory. @default "./dist" */
33
+ outDir?: string;
34
+ /** Trailing-slash handling for routes. */
35
+ trailingSlash?: "always" | "never" | "ignore";
36
+ };
37
+ }
38
+
39
+ /**
40
+ * Deploy an [Astro](https://astro.build) application to Fly: a Service
41
+ * running the Node adapter's serve entry (static files first, then the
42
+ * framework handler) on port 3000.
43
+ *
44
+ * Pages render on demand by default (`output: "server"`). With
45
+ * `astro: { output: "static" }` every page is prerendered and the deploy
46
+ * is assets-only.
47
+ *
48
+ *
49
+ * ### Creating Astro Sites
50
+ * **Example:** Basic Astro App
51
+ * ```typescript
52
+ * const site = yield* Fly.Website.Astro("Web", {
53
+ * rootDir: "./app",
54
+ * });
55
+ * ```
56
+ *
57
+ * **Example:** Custom Domain
58
+ * ```typescript
59
+ * const site = yield* Fly.Website.Astro("Web", {
60
+ * rootDir: "./app",
61
+ * domain: "app.example.com",
62
+ * });
63
+ * ```
64
+ *
65
+ * ### Static Sites
66
+ * **Example:** Fully Static Astro Site
67
+ * ```typescript
68
+ * const site = yield* Fly.Website.Astro("Docs", {
69
+ * rootDir: "./docs",
70
+ * astro: { output: "static" },
71
+ * assets: { notFoundHandling: "404-page" },
72
+ * });
73
+ * ```
74
+ *
75
+ * @resource
76
+ * @product Website
77
+ */
78
+ export const Astro = (id: string, props: AstroProps = {}) => {
79
+ const output = props.astro?.output ?? "server";
80
+ return frameworkSite(id, props, {
81
+ name: "Astro",
82
+ framework: ASTRO_FRAMEWORK_SPECIFIER,
83
+ target: ASTRO_NODE_TARGET_SPECIFIER,
84
+ options: { astro: { ...props.astro, output } },
85
+ static: output === "static" ? staticConfigFromAssets(props.assets) : undefined,
86
+ });
87
+ };