@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.
- package/LICENSE +201 -0
- package/README.md +61 -2
- package/lib/App.d.ts +230 -0
- package/lib/App.d.ts.map +1 -0
- package/lib/App.js +340 -0
- package/lib/App.js.map +1 -0
- package/lib/AuthProvider.d.ts +22 -0
- package/lib/AuthProvider.d.ts.map +1 -0
- package/lib/AuthProvider.js +48 -0
- package/lib/AuthProvider.js.map +1 -0
- package/lib/BindService.d.ts +159 -0
- package/lib/BindService.d.ts.map +1 -0
- package/lib/BindService.js +222 -0
- package/lib/BindService.js.map +1 -0
- package/lib/Bootstrap.d.ts +8 -0
- package/lib/Bootstrap.d.ts.map +1 -0
- package/lib/Bootstrap.js +41 -0
- package/lib/Bootstrap.js.map +1 -0
- package/lib/Bucket.d.ts +278 -0
- package/lib/Bucket.d.ts.map +1 -0
- package/lib/Bucket.js +658 -0
- package/lib/Bucket.js.map +1 -0
- package/lib/BucketBinding.d.ts +33 -0
- package/lib/BucketBinding.d.ts.map +1 -0
- package/lib/BucketBinding.js +70 -0
- package/lib/BucketBinding.js.map +1 -0
- package/lib/Catalog.d.ts +28 -0
- package/lib/Catalog.d.ts.map +1 -0
- package/lib/Catalog.js +31 -0
- package/lib/Catalog.js.map +1 -0
- package/lib/Certificate.d.ts +189 -0
- package/lib/Certificate.d.ts.map +1 -0
- package/lib/Certificate.js +380 -0
- package/lib/Certificate.js.map +1 -0
- package/lib/Checkpoint.d.ts +55 -0
- package/lib/Checkpoint.d.ts.map +1 -0
- package/lib/Checkpoint.js +3 -0
- package/lib/Checkpoint.js.map +1 -0
- package/lib/CheckpointHttp.d.ts +22 -0
- package/lib/CheckpointHttp.d.ts.map +1 -0
- package/lib/CheckpointHttp.js +53 -0
- package/lib/CheckpointHttp.js.map +1 -0
- package/lib/ConnectPostgres.d.ts +58 -0
- package/lib/ConnectPostgres.d.ts.map +1 -0
- package/lib/ConnectPostgres.js +13 -0
- package/lib/ConnectPostgres.js.map +1 -0
- package/lib/ConnectPostgresHttp.d.ts +26 -0
- package/lib/ConnectPostgresHttp.d.ts.map +1 -0
- package/lib/ConnectPostgresHttp.js +57 -0
- package/lib/ConnectPostgresHttp.js.map +1 -0
- package/lib/Contributions.d.ts +7 -0
- package/lib/Contributions.d.ts.map +1 -0
- package/lib/Contributions.js +6 -0
- package/lib/Contributions.js.map +1 -0
- package/lib/Credentials.d.ts +33 -0
- package/lib/Credentials.d.ts.map +1 -0
- package/lib/Credentials.js +59 -0
- package/lib/Credentials.js.map +1 -0
- package/lib/Decrypt.d.ts +52 -0
- package/lib/Decrypt.d.ts.map +1 -0
- package/lib/Decrypt.js +3 -0
- package/lib/Decrypt.js.map +1 -0
- package/lib/DecryptHttp.d.ts +22 -0
- package/lib/DecryptHttp.d.ts.map +1 -0
- package/lib/DecryptHttp.js +43 -0
- package/lib/DecryptHttp.js.map +1 -0
- package/lib/DeleteObject.d.ts +29 -0
- package/lib/DeleteObject.d.ts.map +1 -0
- package/lib/DeleteObject.js +3 -0
- package/lib/DeleteObject.js.map +1 -0
- package/lib/DeleteObjectHttp.d.ts +12 -0
- package/lib/DeleteObjectHttp.d.ts.map +1 -0
- package/lib/DeleteObjectHttp.js +17 -0
- package/lib/DeleteObjectHttp.js.map +1 -0
- package/lib/Deployment.d.ts +51 -0
- package/lib/Deployment.d.ts.map +1 -0
- package/lib/Deployment.js +62 -0
- package/lib/Deployment.js.map +1 -0
- package/lib/DeploymentImages.d.ts +18 -0
- package/lib/DeploymentImages.d.ts.map +1 -0
- package/lib/DeploymentImages.js +61 -0
- package/lib/DeploymentImages.js.map +1 -0
- package/lib/DeploymentState.d.ts +17 -0
- package/lib/DeploymentState.d.ts.map +1 -0
- package/lib/DeploymentState.js +87 -0
- package/lib/DeploymentState.js.map +1 -0
- package/lib/Encrypt.d.ts +50 -0
- package/lib/Encrypt.d.ts.map +1 -0
- package/lib/Encrypt.js +3 -0
- package/lib/Encrypt.js.map +1 -0
- package/lib/EncryptHttp.d.ts +22 -0
- package/lib/EncryptHttp.d.ts.map +1 -0
- package/lib/EncryptHttp.js +39 -0
- package/lib/EncryptHttp.js.map +1 -0
- package/lib/Environment.d.ts +45 -0
- package/lib/Environment.d.ts.map +1 -0
- package/lib/Environment.js +43 -0
- package/lib/Environment.js.map +1 -0
- package/lib/Errors.d.ts +18 -0
- package/lib/Errors.d.ts.map +1 -0
- package/lib/Errors.js +13 -0
- package/lib/Errors.js.map +1 -0
- package/lib/Exec.d.ts +41 -0
- package/lib/Exec.d.ts.map +1 -0
- package/lib/Exec.js +3 -0
- package/lib/Exec.js.map +1 -0
- package/lib/ExecHttp.d.ts +22 -0
- package/lib/ExecHttp.d.ts.map +1 -0
- package/lib/ExecHttp.js +39 -0
- package/lib/ExecHttp.js.map +1 -0
- package/lib/GetObject.d.ts +34 -0
- package/lib/GetObject.d.ts.map +1 -0
- package/lib/GetObject.js +3 -0
- package/lib/GetObject.js.map +1 -0
- package/lib/GetObjectHttp.d.ts +12 -0
- package/lib/GetObjectHttp.d.ts.map +1 -0
- package/lib/GetObjectHttp.js +17 -0
- package/lib/GetObjectHttp.js.map +1 -0
- package/lib/GetSecret.d.ts +44 -0
- package/lib/GetSecret.d.ts.map +1 -0
- package/lib/GetSecret.js +3 -0
- package/lib/GetSecret.js.map +1 -0
- package/lib/GetSecretHttp.d.ts +22 -0
- package/lib/GetSecretHttp.d.ts.map +1 -0
- package/lib/GetSecretHttp.js +50 -0
- package/lib/GetSecretHttp.js.map +1 -0
- package/lib/HeadObject.d.ts +29 -0
- package/lib/HeadObject.d.ts.map +1 -0
- package/lib/HeadObject.js +3 -0
- package/lib/HeadObject.js.map +1 -0
- package/lib/HeadObjectHttp.d.ts +12 -0
- package/lib/HeadObjectHttp.d.ts.map +1 -0
- package/lib/HeadObjectHttp.js +17 -0
- package/lib/HeadObjectHttp.js.map +1 -0
- package/lib/IpAssignment.d.ts +258 -0
- package/lib/IpAssignment.d.ts.map +1 -0
- package/lib/IpAssignment.js +376 -0
- package/lib/IpAssignment.js.map +1 -0
- package/lib/ListObjectsV2.d.ts +29 -0
- package/lib/ListObjectsV2.d.ts.map +1 -0
- package/lib/ListObjectsV2.js +3 -0
- package/lib/ListObjectsV2.js.map +1 -0
- package/lib/ListObjectsV2Http.d.ts +12 -0
- package/lib/ListObjectsV2Http.d.ts.map +1 -0
- package/lib/ListObjectsV2Http.js +17 -0
- package/lib/ListObjectsV2Http.js.map +1 -0
- package/lib/ListSecrets.d.ts +53 -0
- package/lib/ListSecrets.d.ts.map +1 -0
- package/lib/ListSecrets.js +3 -0
- package/lib/ListSecrets.js.map +1 -0
- package/lib/ListSecretsHttp.d.ts +22 -0
- package/lib/ListSecretsHttp.d.ts.map +1 -0
- package/lib/ListSecretsHttp.js +35 -0
- package/lib/ListSecretsHttp.js.map +1 -0
- package/lib/Machine.d.ts +802 -0
- package/lib/Machine.d.ts.map +1 -0
- package/lib/Machine.js +773 -0
- package/lib/Machine.js.map +1 -0
- package/lib/MachineContainers.d.ts +44 -0
- package/lib/MachineContainers.d.ts.map +1 -0
- package/lib/MachineContainers.js +115 -0
- package/lib/MachineContainers.js.map +1 -0
- package/lib/Metadata.d.ts +109 -0
- package/lib/Metadata.d.ts.map +1 -0
- package/lib/Metadata.js +159 -0
- package/lib/Metadata.js.map +1 -0
- package/lib/MountVolume.d.ts +295 -0
- package/lib/MountVolume.d.ts.map +1 -0
- package/lib/MountVolume.js +20 -0
- package/lib/MountVolume.js.map +1 -0
- package/lib/Postgres.d.ts +298 -0
- package/lib/Postgres.d.ts.map +1 -0
- package/lib/Postgres.js +508 -0
- package/lib/Postgres.js.map +1 -0
- package/lib/PostgresMigrations.d.ts +35 -0
- package/lib/PostgresMigrations.d.ts.map +1 -0
- package/lib/PostgresMigrations.js +110 -0
- package/lib/PostgresMigrations.js.map +1 -0
- package/lib/Providers.d.ts +38 -0
- package/lib/Providers.d.ts.map +1 -0
- package/lib/Providers.js +95 -0
- package/lib/Providers.js.map +1 -0
- package/lib/PutObject.d.ts +35 -0
- package/lib/PutObject.d.ts.map +1 -0
- package/lib/PutObject.js +3 -0
- package/lib/PutObject.js.map +1 -0
- package/lib/PutObjectHttp.d.ts +12 -0
- package/lib/PutObjectHttp.d.ts.map +1 -0
- package/lib/PutObjectHttp.js +17 -0
- package/lib/PutObjectHttp.js.map +1 -0
- package/lib/ReadRedis.d.ts +26 -0
- package/lib/ReadRedis.d.ts.map +1 -0
- package/lib/ReadRedis.js +3 -0
- package/lib/ReadRedis.js.map +1 -0
- package/lib/ReadRedisHttp.d.ts +11 -0
- package/lib/ReadRedisHttp.d.ts.map +1 -0
- package/lib/ReadRedisHttp.js +15 -0
- package/lib/ReadRedisHttp.js.map +1 -0
- package/lib/ReadWriteRedis.d.ts +29 -0
- package/lib/ReadWriteRedis.d.ts.map +1 -0
- package/lib/ReadWriteRedis.js +3 -0
- package/lib/ReadWriteRedis.js.map +1 -0
- package/lib/ReadWriteRedisHttp.d.ts +11 -0
- package/lib/ReadWriteRedisHttp.d.ts.map +1 -0
- package/lib/ReadWriteRedisHttp.js +15 -0
- package/lib/ReadWriteRedisHttp.js.map +1 -0
- package/lib/Redis.d.ts +252 -0
- package/lib/Redis.d.ts.map +1 -0
- package/lib/Redis.js +608 -0
- package/lib/Redis.js.map +1 -0
- package/lib/RedisBinding.d.ts +7 -0
- package/lib/RedisBinding.d.ts.map +1 -0
- package/lib/RedisBinding.js +53 -0
- package/lib/RedisBinding.js.map +1 -0
- package/lib/RedisHttp.d.ts +8 -0
- package/lib/RedisHttp.d.ts.map +1 -0
- package/lib/RedisHttp.js +8 -0
- package/lib/RedisHttp.js.map +1 -0
- package/lib/Region.d.ts +16 -0
- package/lib/Region.d.ts.map +1 -0
- package/lib/Region.js +13 -0
- package/lib/Region.js.map +1 -0
- package/lib/Secret.d.ts +190 -0
- package/lib/Secret.d.ts.map +1 -0
- package/lib/Secret.js +310 -0
- package/lib/Secret.js.map +1 -0
- package/lib/SecretHttp.d.ts +54 -0
- package/lib/SecretHttp.d.ts.map +1 -0
- package/lib/SecretHttp.js +66 -0
- package/lib/SecretHttp.js.map +1 -0
- package/lib/SecretKey.d.ts +164 -0
- package/lib/SecretKey.d.ts.map +1 -0
- package/lib/SecretKey.js +277 -0
- package/lib/SecretKey.js.map +1 -0
- package/lib/SecretKeyHttp.d.ts +14 -0
- package/lib/SecretKeyHttp.d.ts.map +1 -0
- package/lib/SecretKeyHttp.js +5 -0
- package/lib/SecretKeyHttp.js.map +1 -0
- package/lib/Service.d.ts +1022 -0
- package/lib/Service.d.ts.map +1 -0
- package/lib/Service.js +1397 -0
- package/lib/Service.js.map +1 -0
- package/lib/Sign.d.ts +36 -0
- package/lib/Sign.d.ts.map +1 -0
- package/lib/Sign.js +3 -0
- package/lib/Sign.js.map +1 -0
- package/lib/SignHttp.d.ts +22 -0
- package/lib/SignHttp.d.ts.map +1 -0
- package/lib/SignHttp.js +36 -0
- package/lib/SignHttp.js.map +1 -0
- package/lib/Sprite.d.ts +283 -0
- package/lib/Sprite.d.ts.map +1 -0
- package/lib/Sprite.js +469 -0
- package/lib/Sprite.js.map +1 -0
- package/lib/SpriteHttp.d.ts +25 -0
- package/lib/SpriteHttp.d.ts.map +1 -0
- package/lib/SpriteHttp.js +33 -0
- package/lib/SpriteHttp.js.map +1 -0
- package/lib/Verify.d.ts +37 -0
- package/lib/Verify.d.ts.map +1 -0
- package/lib/Verify.js +3 -0
- package/lib/Verify.js.map +1 -0
- package/lib/VerifyHttp.d.ts +22 -0
- package/lib/VerifyHttp.d.ts.map +1 -0
- package/lib/VerifyHttp.js +38 -0
- package/lib/VerifyHttp.js.map +1 -0
- package/lib/Volume.d.ts +53 -0
- package/lib/Volume.d.ts.map +1 -0
- package/lib/Volume.js +188 -0
- package/lib/Volume.js.map +1 -0
- package/lib/VolumeSnapshot.d.ts +135 -0
- package/lib/VolumeSnapshot.d.ts.map +1 -0
- package/lib/VolumeSnapshot.js +213 -0
- package/lib/VolumeSnapshot.js.map +1 -0
- package/lib/Website/AssetDeployment.d.ts +43 -0
- package/lib/Website/AssetDeployment.d.ts.map +1 -0
- package/lib/Website/AssetDeployment.js +162 -0
- package/lib/Website/AssetDeployment.js.map +1 -0
- package/lib/Website/Astro.d.ts +87 -0
- package/lib/Website/Astro.d.ts.map +1 -0
- package/lib/Website/Astro.js +55 -0
- package/lib/Website/Astro.js.map +1 -0
- package/lib/Website/Foldkit.d.ts +52 -0
- package/lib/Website/Foldkit.d.ts.map +1 -0
- package/lib/Website/Foldkit.js +45 -0
- package/lib/Website/Foldkit.js.map +1 -0
- package/lib/Website/FrameworkSite.d.ts +175 -0
- package/lib/Website/FrameworkSite.d.ts.map +1 -0
- package/lib/Website/FrameworkSite.js +162 -0
- package/lib/Website/FrameworkSite.js.map +1 -0
- package/lib/Website/Nextjs.d.ts +54 -0
- package/lib/Website/Nextjs.d.ts.map +1 -0
- package/lib/Website/Nextjs.js +46 -0
- package/lib/Website/Nextjs.js.map +1 -0
- package/lib/Website/Nuxt.d.ts +51 -0
- package/lib/Website/Nuxt.d.ts.map +1 -0
- package/lib/Website/Nuxt.js +36 -0
- package/lib/Website/Nuxt.js.map +1 -0
- package/lib/Website/Octane.d.ts +49 -0
- package/lib/Website/Octane.d.ts.map +1 -0
- package/lib/Website/Octane.js +39 -0
- package/lib/Website/Octane.js.map +1 -0
- package/lib/Website/ReactRouter.d.ts +80 -0
- package/lib/Website/ReactRouter.d.ts.map +1 -0
- package/lib/Website/ReactRouter.js +70 -0
- package/lib/Website/ReactRouter.js.map +1 -0
- package/lib/Website/SolidStart.d.ts +93 -0
- package/lib/Website/SolidStart.d.ts.map +1 -0
- package/lib/Website/SolidStart.js +71 -0
- package/lib/Website/SolidStart.js.map +1 -0
- package/lib/Website/StaticSite.d.ts +155 -0
- package/lib/Website/StaticSite.d.ts.map +1 -0
- package/lib/Website/StaticSite.js +168 -0
- package/lib/Website/StaticSite.js.map +1 -0
- package/lib/Website/SvelteKit.d.ts +52 -0
- package/lib/Website/SvelteKit.d.ts.map +1 -0
- package/lib/Website/SvelteKit.js +37 -0
- package/lib/Website/SvelteKit.js.map +1 -0
- package/lib/Website/TanStackStart.d.ts +76 -0
- package/lib/Website/TanStackStart.d.ts.map +1 -0
- package/lib/Website/TanStackStart.js +66 -0
- package/lib/Website/TanStackStart.js.map +1 -0
- package/lib/Website/Vinext.d.ts +73 -0
- package/lib/Website/Vinext.d.ts.map +1 -0
- package/lib/Website/Vinext.js +67 -0
- package/lib/Website/Vinext.js.map +1 -0
- package/lib/Website/Vite.d.ts +103 -0
- package/lib/Website/Vite.d.ts.map +1 -0
- package/lib/Website/Vite.js +91 -0
- package/lib/Website/Vite.js.map +1 -0
- package/lib/Website/Vocs.d.ts +52 -0
- package/lib/Website/Vocs.d.ts.map +1 -0
- package/lib/Website/Vocs.js +38 -0
- package/lib/Website/Vocs.js.map +1 -0
- package/lib/Website/Waku.d.ts +64 -0
- package/lib/Website/Waku.d.ts.map +1 -0
- package/lib/Website/Waku.js +39 -0
- package/lib/Website/Waku.js.map +1 -0
- package/lib/Website/index.d.ts +17 -0
- package/lib/Website/index.d.ts.map +1 -0
- package/lib/Website/index.js +17 -0
- package/lib/Website/index.js.map +1 -0
- package/lib/WriteCertificates.d.ts +63 -0
- package/lib/WriteCertificates.d.ts.map +1 -0
- package/lib/WriteCertificates.js +3 -0
- package/lib/WriteCertificates.js.map +1 -0
- package/lib/WriteCertificatesHttp.d.ts +25 -0
- package/lib/WriteCertificatesHttp.d.ts.map +1 -0
- package/lib/WriteCertificatesHttp.js +67 -0
- package/lib/WriteCertificatesHttp.js.map +1 -0
- package/lib/WriteRedis.d.ts +26 -0
- package/lib/WriteRedis.d.ts.map +1 -0
- package/lib/WriteRedis.js +3 -0
- package/lib/WriteRedis.js.map +1 -0
- package/lib/WriteRedisHttp.d.ts +11 -0
- package/lib/WriteRedisHttp.d.ts.map +1 -0
- package/lib/WriteRedisHttp.js +15 -0
- package/lib/WriteRedisHttp.js.map +1 -0
- package/lib/WriteSecret.d.ts +68 -0
- package/lib/WriteSecret.d.ts.map +1 -0
- package/lib/WriteSecret.js +4 -0
- package/lib/WriteSecret.js.map +1 -0
- package/lib/WriteSecretHttp.d.ts +26 -0
- package/lib/WriteSecretHttp.d.ts.map +1 -0
- package/lib/WriteSecretHttp.js +54 -0
- package/lib/WriteSecretHttp.js.map +1 -0
- package/lib/bluegreen.d.ts +36 -0
- package/lib/bluegreen.d.ts.map +1 -0
- package/lib/bluegreen.js +458 -0
- package/lib/bluegreen.js.map +1 -0
- package/lib/hosted.d.ts +172 -0
- package/lib/hosted.d.ts.map +1 -0
- package/lib/hosted.js +458 -0
- package/lib/hosted.js.map +1 -0
- package/lib/index.d.ts +65 -0
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +63 -0
- package/lib/index.js.map +1 -0
- package/lib/internal/RemoteBuilder.d.ts +28 -0
- package/lib/internal/RemoteBuilder.d.ts.map +1 -0
- package/lib/internal/RemoteBuilder.js +145 -0
- package/lib/internal/RemoteBuilder.js.map +1 -0
- package/lib/leases.d.ts +53 -0
- package/lib/leases.d.ts.map +1 -0
- package/lib/leases.js +279 -0
- package/lib/leases.js.map +1 -0
- package/lib/ports.d.ts +51 -0
- package/lib/ports.d.ts.map +1 -0
- package/lib/ports.js +123 -0
- package/lib/ports.js.map +1 -0
- package/lib/replicas.d.ts +270 -0
- package/lib/replicas.d.ts.map +1 -0
- package/lib/replicas.js +969 -0
- package/lib/replicas.js.map +1 -0
- package/lib/rpc.d.ts +35 -0
- package/lib/rpc.d.ts.map +1 -0
- package/lib/rpc.js +113 -0
- package/lib/rpc.js.map +1 -0
- package/package.json +97 -3
- package/src/App.ts +516 -0
- package/src/AuthProvider.ts +68 -0
- package/src/BindService.ts +304 -0
- package/src/Bootstrap.ts +66 -0
- package/src/Bucket.ts +916 -0
- package/src/BucketBinding.ts +128 -0
- package/src/Catalog.ts +43 -0
- package/src/Certificate.ts +548 -0
- package/src/Checkpoint.ts +69 -0
- package/src/CheckpointHttp.ts +66 -0
- package/src/ConnectPostgres.ts +68 -0
- package/src/ConnectPostgresHttp.ts +77 -0
- package/src/Contributions.ts +9 -0
- package/src/Credentials.ts +102 -0
- package/src/Decrypt.ts +62 -0
- package/src/DecryptHttp.ts +52 -0
- package/src/DeleteObject.ts +43 -0
- package/src/DeleteObjectHttp.ts +20 -0
- package/src/Deployment.ts +121 -0
- package/src/DeploymentImages.ts +84 -0
- package/src/DeploymentState.ts +104 -0
- package/src/Encrypt.ts +60 -0
- package/src/EncryptHttp.ts +48 -0
- package/src/Environment.ts +81 -0
- package/src/Errors.ts +14 -0
- package/src/Exec.ts +50 -0
- package/src/ExecHttp.ts +47 -0
- package/src/GetObject.ts +48 -0
- package/src/GetObjectHttp.ts +20 -0
- package/src/GetSecret.ts +48 -0
- package/src/GetSecretHttp.ts +60 -0
- package/src/HeadObject.ts +43 -0
- package/src/HeadObjectHttp.ts +20 -0
- package/src/IpAssignment.ts +522 -0
- package/src/ListObjectsV2.ts +43 -0
- package/src/ListObjectsV2Http.ts +20 -0
- package/src/ListSecrets.ts +57 -0
- package/src/ListSecretsHttp.ts +43 -0
- package/src/Machine.ts +1268 -0
- package/src/MachineContainers.ts +152 -0
- package/src/Metadata.ts +195 -0
- package/src/MountVolume.ts +315 -0
- package/src/Postgres.ts +777 -0
- package/src/PostgresMigrations.ts +153 -0
- package/src/Providers.ts +155 -0
- package/src/PutObject.ts +49 -0
- package/src/PutObjectHttp.ts +20 -0
- package/src/ReadRedis.ts +31 -0
- package/src/ReadRedisHttp.ts +18 -0
- package/src/ReadWriteRedis.ts +33 -0
- package/src/ReadWriteRedisHttp.ts +18 -0
- package/src/Redis.ts +820 -0
- package/src/RedisBinding.ts +64 -0
- package/src/RedisHttp.ts +11 -0
- package/src/Region.ts +44 -0
- package/src/Secret.ts +405 -0
- package/src/SecretHttp.ts +149 -0
- package/src/SecretKey.ts +389 -0
- package/src/SecretKeyHttp.ts +23 -0
- package/src/Service.ts +1934 -0
- package/src/Sign.ts +46 -0
- package/src/SignHttp.ts +44 -0
- package/src/Sprite.ts +671 -0
- package/src/SpriteHttp.ts +50 -0
- package/src/Verify.ts +47 -0
- package/src/VerifyHttp.ts +46 -0
- package/src/Volume.ts +264 -0
- package/src/VolumeSnapshot.ts +321 -0
- package/src/Website/AssetDeployment.ts +294 -0
- package/src/Website/Astro.ts +87 -0
- package/src/Website/Foldkit.ts +54 -0
- package/src/Website/FrameworkSite.ts +363 -0
- package/src/Website/Nextjs.ts +50 -0
- package/src/Website/Nuxt.ts +48 -0
- package/src/Website/Octane.ts +44 -0
- package/src/Website/ReactRouter.ts +76 -0
- package/src/Website/SolidStart.ts +90 -0
- package/src/Website/StaticSite.ts +275 -0
- package/src/Website/SvelteKit.ts +49 -0
- package/src/Website/TanStackStart.ts +72 -0
- package/src/Website/Vinext.ts +79 -0
- package/src/Website/Vite.ts +112 -0
- package/src/Website/Vocs.ts +50 -0
- package/src/Website/Waku.ts +65 -0
- package/src/Website/index.ts +16 -0
- package/src/WriteCertificates.ts +90 -0
- package/src/WriteCertificatesHttp.ts +93 -0
- package/src/WriteRedis.ts +31 -0
- package/src/WriteRedisHttp.ts +18 -0
- package/src/WriteSecret.ts +86 -0
- package/src/WriteSecretHttp.ts +71 -0
- package/src/bluegreen.ts +708 -0
- package/src/globals.d.ts +2 -0
- package/src/hosted.ts +668 -0
- package/src/index.ts +64 -0
- package/src/internal/RemoteBuilder.ts +224 -0
- package/src/leases.ts +437 -0
- package/src/ports.ts +177 -0
- package/src/replicas.ts +1480 -0
- package/src/rpc.ts +136 -0
package/src/globals.d.ts
ADDED
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
|
+
};
|