@alchemy.run/fly 0.0.0 → 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 +57 -4
- 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 +83 -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
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
import type { FlyContainerConfig, FlyMachineConfig } from "@distilled.cloud/fly-io/machines";
|
|
2
|
+
import { deepEqual } from "alchemy/Diff";
|
|
3
|
+
import * as Data from "effect/Data";
|
|
4
|
+
import * as Effect from "effect/Effect";
|
|
5
|
+
import type { MachineContainer, MachineProps } from "./Machine.ts";
|
|
6
|
+
|
|
7
|
+
export class InvalidMachineContainers extends Data.TaggedError("Fly.InvalidMachineContainers")<{
|
|
8
|
+
message: string;
|
|
9
|
+
}> {}
|
|
10
|
+
|
|
11
|
+
/** Validate resolved inputs before any Machine or Volume is changed. */
|
|
12
|
+
export const validateMachineContainers = (
|
|
13
|
+
props: Pick<MachineProps, "image" | "containers" | "init">,
|
|
14
|
+
) => {
|
|
15
|
+
const image = "image" in props ? props.image : undefined;
|
|
16
|
+
const containers = "containers" in props ? props.containers : undefined;
|
|
17
|
+
if ((image !== undefined) === (containers !== undefined))
|
|
18
|
+
return Effect.fail(
|
|
19
|
+
new InvalidMachineContainers({
|
|
20
|
+
message: "Fly.Machine requires exactly one of image or containers.",
|
|
21
|
+
}),
|
|
22
|
+
);
|
|
23
|
+
if (image !== undefined)
|
|
24
|
+
return typeof image === "string" && image.trim().length > 0
|
|
25
|
+
? Effect.void
|
|
26
|
+
: Effect.fail(new InvalidMachineContainers({ message: "image must be nonempty." }));
|
|
27
|
+
if (!Array.isArray(containers) || containers.length === 0)
|
|
28
|
+
return Effect.fail(
|
|
29
|
+
new InvalidMachineContainers({
|
|
30
|
+
message: "containers must be a nonempty array.",
|
|
31
|
+
}),
|
|
32
|
+
);
|
|
33
|
+
if (props.init !== undefined)
|
|
34
|
+
return Effect.fail(
|
|
35
|
+
new InvalidMachineContainers({
|
|
36
|
+
message: "init is only supported with image.",
|
|
37
|
+
}),
|
|
38
|
+
);
|
|
39
|
+
const names = new Set<string>();
|
|
40
|
+
for (const container of containers) {
|
|
41
|
+
if (
|
|
42
|
+
container == null ||
|
|
43
|
+
typeof container.name !== "string" ||
|
|
44
|
+
!container.name.trim() ||
|
|
45
|
+
typeof container.image !== "string" ||
|
|
46
|
+
!container.image.trim()
|
|
47
|
+
)
|
|
48
|
+
return Effect.fail(
|
|
49
|
+
new InvalidMachineContainers({
|
|
50
|
+
message: "Every container needs a nonempty name and image.",
|
|
51
|
+
}),
|
|
52
|
+
);
|
|
53
|
+
if ("exec" in container && container.exec !== undefined)
|
|
54
|
+
return Effect.fail(
|
|
55
|
+
new InvalidMachineContainers({
|
|
56
|
+
message: `Container ${container.name}: use cmd and entrypoint; native container exec overrides are not supported.`,
|
|
57
|
+
}),
|
|
58
|
+
);
|
|
59
|
+
if (names.has(container.name))
|
|
60
|
+
return Effect.fail(
|
|
61
|
+
new InvalidMachineContainers({
|
|
62
|
+
message: `Duplicate container name: ${container.name}.`,
|
|
63
|
+
}),
|
|
64
|
+
);
|
|
65
|
+
names.add(container.name);
|
|
66
|
+
}
|
|
67
|
+
for (const container of containers)
|
|
68
|
+
for (const dependency of container.dependsOn ?? [])
|
|
69
|
+
if (dependency == null || typeof dependency.name !== "string" || !names.has(dependency.name))
|
|
70
|
+
return Effect.fail(
|
|
71
|
+
new InvalidMachineContainers({
|
|
72
|
+
message: `Container ${container.name} depends on an undeclared container.`,
|
|
73
|
+
}),
|
|
74
|
+
);
|
|
75
|
+
return Effect.void;
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
export const toFlyContainers = (containers: MachineContainer[]): FlyContainerConfig[] =>
|
|
79
|
+
containers.map((container) => ({
|
|
80
|
+
name: container.name,
|
|
81
|
+
image: container.image,
|
|
82
|
+
cmd: container.cmd,
|
|
83
|
+
entrypoint: container.entrypoint,
|
|
84
|
+
env: container.env,
|
|
85
|
+
depends_on: container.dependsOn?.map(({ name, condition }) => ({
|
|
86
|
+
name,
|
|
87
|
+
condition,
|
|
88
|
+
})),
|
|
89
|
+
healthchecks: container.healthChecks?.map((check) => ({
|
|
90
|
+
name: check.name,
|
|
91
|
+
kind: check.kind,
|
|
92
|
+
interval: check.interval,
|
|
93
|
+
timeout: check.timeout,
|
|
94
|
+
grace_period: check.gracePeriod,
|
|
95
|
+
success_threshold: check.successThreshold,
|
|
96
|
+
failure_threshold: check.failureThreshold,
|
|
97
|
+
http: check.http && {
|
|
98
|
+
port: check.http.port,
|
|
99
|
+
path: check.http.path,
|
|
100
|
+
method: check.http.method,
|
|
101
|
+
scheme: check.http.scheme,
|
|
102
|
+
headers: check.http.headers,
|
|
103
|
+
tls_server_name: check.http.tlsServerName,
|
|
104
|
+
tls_skip_verify: check.http.tlsSkipVerify,
|
|
105
|
+
},
|
|
106
|
+
tcp: check.tcp,
|
|
107
|
+
exec: check.exec,
|
|
108
|
+
})),
|
|
109
|
+
}));
|
|
110
|
+
|
|
111
|
+
/** Canonical semantic config shared by drift detection and generation identity. */
|
|
112
|
+
export const canonicalContainers = (containers: FlyContainerConfig[] | undefined) =>
|
|
113
|
+
(containers ?? [])
|
|
114
|
+
.map((container) => ({
|
|
115
|
+
name: container.name,
|
|
116
|
+
image: container.image,
|
|
117
|
+
cmd: container.cmd,
|
|
118
|
+
entrypoint: container.entrypoint,
|
|
119
|
+
env: Object.fromEntries(
|
|
120
|
+
Object.entries(container.env ?? {}).filter(([, value]) => value !== undefined),
|
|
121
|
+
),
|
|
122
|
+
depends_on: [...(container.depends_on ?? [])]
|
|
123
|
+
.map(({ name, condition }) => ({ name, condition }))
|
|
124
|
+
.sort((a, b) => (a.name ?? "").localeCompare(b.name ?? "")),
|
|
125
|
+
healthchecks: (container.healthchecks ?? []).map((check) => ({
|
|
126
|
+
name: check.name,
|
|
127
|
+
kind: check.kind,
|
|
128
|
+
interval: check.interval,
|
|
129
|
+
timeout: check.timeout,
|
|
130
|
+
grace_period: check.grace_period,
|
|
131
|
+
success_threshold: check.success_threshold,
|
|
132
|
+
failure_threshold: check.failure_threshold,
|
|
133
|
+
http: check.http,
|
|
134
|
+
tcp: check.tcp,
|
|
135
|
+
exec: check.exec,
|
|
136
|
+
})),
|
|
137
|
+
}))
|
|
138
|
+
.sort((a, b) => (a.name ?? "").localeCompare(b.name ?? ""));
|
|
139
|
+
|
|
140
|
+
export const sameContainers = (
|
|
141
|
+
observed: FlyContainerConfig[] | undefined,
|
|
142
|
+
desired: FlyContainerConfig[] | undefined,
|
|
143
|
+
) =>
|
|
144
|
+
deepEqual(canonicalContainers(observed), canonicalContainers(desired), {
|
|
145
|
+
stripNullish: true,
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
/** Fly may synthesize a top-level image from the first container on readback. */
|
|
149
|
+
export const sameContainerWorkload = (
|
|
150
|
+
observed: FlyMachineConfig | undefined,
|
|
151
|
+
desired: FlyContainerConfig[],
|
|
152
|
+
) => sameContainers(observed?.containers, desired);
|
package/src/Metadata.ts
ADDED
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
import { createPhysicalName } from "alchemy/PhysicalName";
|
|
2
|
+
import { createInternalTags, diffTags, hasTags, type Tags } from "alchemy/Tags";
|
|
3
|
+
import * as Effect from "effect/Effect";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Fly App has no labels. Ownership is stamped onto Machine
|
|
7
|
+
* `config.metadata` (and encoded into Volume/Secret names) as
|
|
8
|
+
* `alchemy.stack` / `alchemy.stage` / `alchemy.id`.
|
|
9
|
+
*
|
|
10
|
+
* Names here are Fly-prefixed so `export *` from this module does not
|
|
11
|
+
* collide with Hetzner Labels or `alchemy/src/Ref.ts`.
|
|
12
|
+
*/
|
|
13
|
+
export const ALCHEMY_METADATA_PREFIX = "alchemy.";
|
|
14
|
+
|
|
15
|
+
export const alchemyMetadataKeys = {
|
|
16
|
+
stack: "alchemy.stack",
|
|
17
|
+
stage: "alchemy.stage",
|
|
18
|
+
id: "alchemy.id",
|
|
19
|
+
type: "alchemy.type",
|
|
20
|
+
replica: "alchemy.replica",
|
|
21
|
+
instance: "alchemy.instance",
|
|
22
|
+
fqn: "alchemy.fqn",
|
|
23
|
+
baseName: "alchemy.base-name",
|
|
24
|
+
generation: "alchemy.generation",
|
|
25
|
+
workload: "alchemy.workload",
|
|
26
|
+
sequence: "alchemy.sequence",
|
|
27
|
+
count: "alchemy.count",
|
|
28
|
+
image: "alchemy.image",
|
|
29
|
+
containerImageSet: "alchemy.container-image-set",
|
|
30
|
+
phase: "alchemy.phase",
|
|
31
|
+
protocol: "alchemy.deployment-protocol",
|
|
32
|
+
roles: "alchemy.readiness-roles",
|
|
33
|
+
role: "alchemy.readiness-role",
|
|
34
|
+
predecessors: "alchemy.predecessors",
|
|
35
|
+
restored: "alchemy.idle-policy-restored",
|
|
36
|
+
checkedInstance: "alchemy.checked-instance",
|
|
37
|
+
secretsVersion: "alchemy.min-secrets-version",
|
|
38
|
+
} as const;
|
|
39
|
+
|
|
40
|
+
export type FlyAlchemyType = "Fly.Machine" | "Fly.Service";
|
|
41
|
+
|
|
42
|
+
const TAG_PREFIX = "alchemy::";
|
|
43
|
+
|
|
44
|
+
export const toMetadataKey = (tagKey: string): string =>
|
|
45
|
+
tagKey.startsWith(TAG_PREFIX)
|
|
46
|
+
? `${ALCHEMY_METADATA_PREFIX}${tagKey.slice(TAG_PREFIX.length)}`
|
|
47
|
+
: tagKey;
|
|
48
|
+
|
|
49
|
+
export const toTagKeyFromMetadata = (metadataKey: string): string =>
|
|
50
|
+
metadataKey.startsWith(ALCHEMY_METADATA_PREFIX)
|
|
51
|
+
? `${TAG_PREFIX}${metadataKey.slice(ALCHEMY_METADATA_PREFIX.length)}`
|
|
52
|
+
: metadataKey;
|
|
53
|
+
|
|
54
|
+
export const toMachineMetadata = (
|
|
55
|
+
tags: Record<string, string> | null | undefined,
|
|
56
|
+
): Record<string, string> =>
|
|
57
|
+
Object.fromEntries(Object.entries(tags ?? {}).map(([key, value]) => [toMetadataKey(key), value]));
|
|
58
|
+
|
|
59
|
+
export const fromMachineMetadata = (
|
|
60
|
+
metadata: Record<string, string> | null | undefined,
|
|
61
|
+
): Record<string, string> =>
|
|
62
|
+
Object.fromEntries(
|
|
63
|
+
Object.entries(metadata ?? {}).map(([key, value]) => [toTagKeyFromMetadata(key), value]),
|
|
64
|
+
);
|
|
65
|
+
|
|
66
|
+
export const createInternalMetadata = Effect.fn(function* (id: string) {
|
|
67
|
+
return toMachineMetadata(yield* createInternalTags(id));
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Stamp alchemy ownership plus `alchemy.type` onto Machine config.metadata.
|
|
72
|
+
*/
|
|
73
|
+
export const createMachineMetadata = Effect.fn(function* (id: string, type: FlyAlchemyType) {
|
|
74
|
+
return {
|
|
75
|
+
...(yield* createInternalMetadata(id)),
|
|
76
|
+
[alchemyMetadataKeys.type]: type,
|
|
77
|
+
};
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
export const stripInternalMetadata = (
|
|
81
|
+
metadata: Record<string, string> | null | undefined,
|
|
82
|
+
): Record<string, string> =>
|
|
83
|
+
Object.fromEntries(
|
|
84
|
+
Object.entries(metadata ?? {}).filter(([key]) => !key.startsWith(ALCHEMY_METADATA_PREFIX)),
|
|
85
|
+
);
|
|
86
|
+
|
|
87
|
+
export const hasAlchemyMetadata = Effect.fn(function* (id: string, metadata: Tags | undefined) {
|
|
88
|
+
const expected = yield* createInternalMetadata(id);
|
|
89
|
+
return hasTags(expected, metadata);
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
/** True when observed Machine metadata was stamped by Alchemy. */
|
|
93
|
+
export const isAlchemyOwnedMetadata = (
|
|
94
|
+
metadata: Record<string, string | undefined> | null | undefined,
|
|
95
|
+
): boolean => {
|
|
96
|
+
const stack = metadata?.[alchemyMetadataKeys.stack];
|
|
97
|
+
return stack !== undefined && stack.length > 0;
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Diff observed Machine metadata against desired. Always pass **observed**
|
|
102
|
+
* cloud metadata as `oldMetadata` — never `olds.metadata` or
|
|
103
|
+
* `output.metadata` — so adoption converges.
|
|
104
|
+
*/
|
|
105
|
+
export const diffMachineMetadata = diffTags;
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Fly App names: `createPhysicalName({ lowercase: true, maxLength: 30 })`,
|
|
109
|
+
* then force a leading letter (`f` prefix if needed). Globally unique.
|
|
110
|
+
*/
|
|
111
|
+
export const createFlyAppName = Effect.fn(function* (id: string) {
|
|
112
|
+
const raw = yield* createPhysicalName({
|
|
113
|
+
id,
|
|
114
|
+
lowercase: true,
|
|
115
|
+
maxLength: 30,
|
|
116
|
+
});
|
|
117
|
+
return /^[a-z]/.test(raw) ? raw : `f${raw}`.slice(0, 30);
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Volume / Secret / SecretKey physical names use the same shape as App
|
|
122
|
+
* names so `list()` can recognize alchemy-owned rows without labels.
|
|
123
|
+
*
|
|
124
|
+
* Fly Volume names reject hyphens (`[a-z0-9_]`, max 30). Use
|
|
125
|
+
* {@link createFlyVolumeName} for Volumes.
|
|
126
|
+
*/
|
|
127
|
+
export const createFlyResourceName = createFlyAppName;
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* Fly Volume names: same physical-name shape as App, but underscore
|
|
131
|
+
* delimited. Fly rejects hyphens (`[a-z0-9_]`, max 30).
|
|
132
|
+
*/
|
|
133
|
+
export const createFlyVolumeName = Effect.fn(function* (id: string) {
|
|
134
|
+
const raw = yield* createPhysicalName({
|
|
135
|
+
id,
|
|
136
|
+
lowercase: true,
|
|
137
|
+
maxLength: 30,
|
|
138
|
+
delimiter: "_",
|
|
139
|
+
});
|
|
140
|
+
// createPhysicalName keeps hyphens in the stack/stage prefix; Fly
|
|
141
|
+
// Volume names only allow [a-z0-9_].
|
|
142
|
+
return sanitizeFlyVolumeName(raw);
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* Sanitize a user-supplied Fly App / Volume / Secret name: lowercase,
|
|
147
|
+
* DNS-compatible (`[a-z0-9-]`), force a leading letter, max 30 chars.
|
|
148
|
+
*/
|
|
149
|
+
export const sanitizeFlyAppName = (name: string): string => {
|
|
150
|
+
const lowered = name
|
|
151
|
+
.toLowerCase()
|
|
152
|
+
.replace(/[^a-z0-9-]+/g, "-")
|
|
153
|
+
.replace(/-+/g, "-")
|
|
154
|
+
.replace(/^-+|-+$/g, "");
|
|
155
|
+
const clipped = lowered.length > 30 ? lowered.slice(0, 30).replace(/-+$/g, "") : lowered;
|
|
156
|
+
const raw = clipped.length === 0 ? "f" : clipped;
|
|
157
|
+
return /^[a-z]/.test(raw) ? raw : `f${raw}`.slice(0, 30);
|
|
158
|
+
};
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* Sanitize a user-supplied Fly Volume name: lowercase alphanumeric and
|
|
162
|
+
* underscores only, force a leading letter, max 30 chars.
|
|
163
|
+
*/
|
|
164
|
+
export const sanitizeFlyVolumeName = (name: string): string => {
|
|
165
|
+
const lowered = name
|
|
166
|
+
.toLowerCase()
|
|
167
|
+
.replace(/[^a-z0-9_]+/g, "_")
|
|
168
|
+
.replace(/_+/g, "_")
|
|
169
|
+
.replace(/^_+|_+$/g, "");
|
|
170
|
+
const clipped = lowered.length > 30 ? lowered.slice(0, 30).replace(/_+$/g, "") : lowered;
|
|
171
|
+
const raw = clipped.length === 0 ? "f" : clipped;
|
|
172
|
+
return /^[a-z]/.test(raw) ? raw : `f${raw}`.slice(0, 30);
|
|
173
|
+
};
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* True when `name` matches the `createPhysicalName` + leading-letter shape
|
|
177
|
+
* used for alchemy-owned Fly Apps / Volumes / Secrets / SecretKeys.
|
|
178
|
+
*
|
|
179
|
+
* Untruncated names end with a hyphen (App) or underscore (Volume) plus
|
|
180
|
+
* an 8–16 char RFC4648 base32 instance suffix. Truncated 30-char names
|
|
181
|
+
* keep that suffix (the human prefix is what gets cut).
|
|
182
|
+
*/
|
|
183
|
+
export const matchesAlchemyPhysicalName = (name: string | undefined): boolean => {
|
|
184
|
+
if (name === undefined || name.length === 0 || name.length > 30) {
|
|
185
|
+
return false;
|
|
186
|
+
}
|
|
187
|
+
if (!/^[a-z][a-z0-9_-]*$/.test(name)) return false;
|
|
188
|
+
const parts = name.split(/[-_]/);
|
|
189
|
+
const last = parts.at(-1) ?? "";
|
|
190
|
+
if (parts.length >= 2 && last.length >= 8 && last.length <= 16 && /^[a-z2-7]+$/.test(last)) {
|
|
191
|
+
return true;
|
|
192
|
+
}
|
|
193
|
+
const compact = name.replaceAll("-", "").replaceAll("_", "");
|
|
194
|
+
return name.length === 30 && /[a-z2-7]{16}$/.test(compact);
|
|
195
|
+
};
|
|
@@ -0,0 +1,315 @@
|
|
|
1
|
+
import * as Binding from "alchemy/Binding";
|
|
2
|
+
import type { Resource } from "alchemy/Resource";
|
|
3
|
+
import * as Effect from "effect/Effect";
|
|
4
|
+
import * as Layer from "effect/Layer";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Spec for a per-replica Fly disk. Fly Volumes cannot be shared —
|
|
8
|
+
* `count` Machines get `count` Volumes in one name-group.
|
|
9
|
+
*/
|
|
10
|
+
export interface DiskSpec {
|
|
11
|
+
/**
|
|
12
|
+
* Absolute path inside the Machine the disk is mounted at
|
|
13
|
+
* (e.g. `/data`).
|
|
14
|
+
*/
|
|
15
|
+
path: string;
|
|
16
|
+
/**
|
|
17
|
+
* Size in GB. Fly minimum is 1. Increasing size updates in place
|
|
18
|
+
* via `extendVolume`. Fly cannot shrink a Volume.
|
|
19
|
+
*/
|
|
20
|
+
sizeGb: number;
|
|
21
|
+
/**
|
|
22
|
+
* Encrypt the Volume at rest. Create-only.
|
|
23
|
+
*/
|
|
24
|
+
encrypted?: boolean;
|
|
25
|
+
/**
|
|
26
|
+
* Filesystem type (`ext4`, …). Create-only.
|
|
27
|
+
*/
|
|
28
|
+
fstype?: string;
|
|
29
|
+
/**
|
|
30
|
+
* Enable scheduled automatic snapshots.
|
|
31
|
+
*
|
|
32
|
+
* @default true
|
|
33
|
+
*/
|
|
34
|
+
autoBackupEnabled?: boolean;
|
|
35
|
+
/**
|
|
36
|
+
* Snapshot retention in days. Updated in place via `updateVolume`.
|
|
37
|
+
*/
|
|
38
|
+
snapshotRetention?: number;
|
|
39
|
+
/**
|
|
40
|
+
* Restore from an existing snapshot. Create-only.
|
|
41
|
+
*/
|
|
42
|
+
snapshotId?: string;
|
|
43
|
+
/**
|
|
44
|
+
* Fork from an existing volume. Create-only.
|
|
45
|
+
*/
|
|
46
|
+
sourceVolumeId?: string;
|
|
47
|
+
/**
|
|
48
|
+
* Require the Volume to land in a unique zone. Create-only.
|
|
49
|
+
*/
|
|
50
|
+
requireUniqueZone?: boolean;
|
|
51
|
+
/**
|
|
52
|
+
* Fly volume-group name. If omitted, a unique name is generated
|
|
53
|
+
* from the host's logical ID and {@link path}.
|
|
54
|
+
*/
|
|
55
|
+
name?: string;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export interface MountVolumeOptions extends DiskSpec {}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Runtime view of a disk mounted into a {@link Service}: the path
|
|
62
|
+
* inside the Machine.
|
|
63
|
+
*/
|
|
64
|
+
export interface MountedVolume {
|
|
65
|
+
/** Mount path inside the Machine (same value as {@link DiskSpec.path}). */
|
|
66
|
+
path: string;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Observed disk attached to a Machine / Service replica.
|
|
71
|
+
*/
|
|
72
|
+
export interface MountedDisk {
|
|
73
|
+
/** Mount path inside the Machine. */
|
|
74
|
+
path: string;
|
|
75
|
+
/** Fly Volume id. */
|
|
76
|
+
volumeId: string;
|
|
77
|
+
/** Size in GB. */
|
|
78
|
+
sizeGb: number;
|
|
79
|
+
/** Fly volume-group name. */
|
|
80
|
+
name: string;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
const isBindHost = (value: unknown): value is Resource<string, any, any, ServiceBinding> =>
|
|
84
|
+
typeof value === "object" &&
|
|
85
|
+
value !== null &&
|
|
86
|
+
((value as { Type?: string }).Type === "Fly.Service" ||
|
|
87
|
+
(value as { Type?: string }).Type === "Fly.Machine");
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Binding contract accepted by {@link Service} (and Machine) for mounted
|
|
91
|
+
* disks and injected env.
|
|
92
|
+
*/
|
|
93
|
+
export interface ServiceBinding {
|
|
94
|
+
env?: Record<string, any>;
|
|
95
|
+
mounts?: DiskSpec[];
|
|
96
|
+
/**
|
|
97
|
+
* Upstash Redis add-on to attach. Redis HTTP bindings write
|
|
98
|
+
* `REDIS_URL` as an App secret during Service reconcile.
|
|
99
|
+
*/
|
|
100
|
+
redis?: { name: string; id?: string };
|
|
101
|
+
/**
|
|
102
|
+
* Tigris bucket to attach. Object HTTP bindings write `AWS_*` /
|
|
103
|
+
* `BUCKET_NAME` as App secrets during Service reconcile.
|
|
104
|
+
*/
|
|
105
|
+
bucket?: { name: string; id?: string };
|
|
106
|
+
/**
|
|
107
|
+
* Managed Postgres cluster to attach. `Fly.ConnectPostgres` records
|
|
108
|
+
* the MPG attachment during Service reconcile. Connection URIs travel
|
|
109
|
+
* as Outputs (`yield* postgres.connectionUri`), not bind env.
|
|
110
|
+
*/
|
|
111
|
+
postgres?: { clusterId: string; variableName?: string };
|
|
112
|
+
/**
|
|
113
|
+
* Another Service this one calls, recorded by `Fly.bindService` and
|
|
114
|
+
* `Fly.bindEndpoint`. Service reconcile checks the target is reachable
|
|
115
|
+
* from this Service's network and, for an endpoint, that the port is
|
|
116
|
+
* published.
|
|
117
|
+
*/
|
|
118
|
+
target?: BoundTarget;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/** A Service bound by `Fly.bindService` or `Fly.bindEndpoint`. */
|
|
122
|
+
export interface BoundTarget {
|
|
123
|
+
/** Logical id of the bound Service. */
|
|
124
|
+
service: string;
|
|
125
|
+
/** Fly App the bound Service runs in. */
|
|
126
|
+
appName: string;
|
|
127
|
+
/** Private network of that App. `undefined` for the default network. */
|
|
128
|
+
network: string | undefined;
|
|
129
|
+
/** The bound Service's private address; `undefined` when it publishes nothing. */
|
|
130
|
+
privateUrl: string | undefined;
|
|
131
|
+
/** The bound Service's caller token. */
|
|
132
|
+
rpcToken?: import("effect/Redacted").Redacted<string>;
|
|
133
|
+
/** Port `Fly.bindEndpoint` targets; the binding port for `bindService`. */
|
|
134
|
+
port?: number;
|
|
135
|
+
/** Ports the bound Service publishes, for `Fly.bindEndpoint`. */
|
|
136
|
+
endpoints?: Array<{ port: number; handlers: string[] }>;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* Create a per-replica Fly Volume and mount it into a {@link Service}.
|
|
141
|
+
*
|
|
142
|
+
* There is no standalone Volume resource. From a {@link Machine}, pass
|
|
143
|
+
* `mounts: [{ path, sizeGb }]` instead.
|
|
144
|
+
*
|
|
145
|
+
*
|
|
146
|
+
* ### Mount into a Service
|
|
147
|
+
* Yield `MountVolume` inside init. App and region come from the
|
|
148
|
+
* parent Service. Provide {@link MountVolumeLive}. At runtime you get
|
|
149
|
+
* `disk.path`.
|
|
150
|
+
*
|
|
151
|
+
* A Volume attaches to one Machine. `count: 3` creates three Volumes
|
|
152
|
+
* in one name-group, one per replica.
|
|
153
|
+
*
|
|
154
|
+
* **Example:** Bind a path
|
|
155
|
+
* ```typescript
|
|
156
|
+
* export default class Api extends Fly.Service<Api>()(
|
|
157
|
+
* "Api",
|
|
158
|
+
* { app: Site, main: import.meta.url, region: "iad", count: 3, port: 3000 },
|
|
159
|
+
* Effect.gen(function* () {
|
|
160
|
+
* const disk = yield* Fly.MountVolume({ path: "/data", sizeGb: 1 });
|
|
161
|
+
* const fs = yield* FileSystem.FileSystem;
|
|
162
|
+
* return {
|
|
163
|
+
* fetch: Effect.gen(function* () {
|
|
164
|
+
* const text = yield* fs.readFileString(`${disk.path}/hello.txt`);
|
|
165
|
+
* return HttpServerResponse.text(text);
|
|
166
|
+
* }),
|
|
167
|
+
* };
|
|
168
|
+
* }).pipe(Effect.provide(Fly.MountVolumeLive)),
|
|
169
|
+
* ) {}
|
|
170
|
+
* ```
|
|
171
|
+
*
|
|
172
|
+
* ### Grow a disk
|
|
173
|
+
* `sizeGb` can grow in place via `extendVolume`. Fly cannot shrink a
|
|
174
|
+
* Volume. Minimum size is 1 GB.
|
|
175
|
+
*
|
|
176
|
+
* **Example:** 10 GB
|
|
177
|
+
* ```typescript
|
|
178
|
+
* const disk = yield* Fly.MountVolume({ path: "/data", sizeGb: 10 });
|
|
179
|
+
* ```
|
|
180
|
+
*
|
|
181
|
+
* ### Encryption
|
|
182
|
+
* `encrypted` encrypts the Volume at rest.
|
|
183
|
+
*
|
|
184
|
+
* **Example:** Encrypted
|
|
185
|
+
* ```typescript
|
|
186
|
+
* const disk = yield* Fly.MountVolume({
|
|
187
|
+
* path: "/data",
|
|
188
|
+
* sizeGb: 1,
|
|
189
|
+
* encrypted: true,
|
|
190
|
+
* });
|
|
191
|
+
* ```
|
|
192
|
+
*
|
|
193
|
+
* :::note[Create-only]
|
|
194
|
+
* Flipping `encrypted` later is ignored.
|
|
195
|
+
* :::
|
|
196
|
+
*
|
|
197
|
+
* ### Filesystem
|
|
198
|
+
* `fstype` is the filesystem (`ext4`, …).
|
|
199
|
+
*
|
|
200
|
+
* **Example:** ext4
|
|
201
|
+
* ```typescript
|
|
202
|
+
* const disk = yield* Fly.MountVolume({
|
|
203
|
+
* path: "/data",
|
|
204
|
+
* sizeGb: 1,
|
|
205
|
+
* fstype: "ext4",
|
|
206
|
+
* });
|
|
207
|
+
* ```
|
|
208
|
+
*
|
|
209
|
+
* :::note[Create-only]
|
|
210
|
+
* Flipping `fstype` later is ignored.
|
|
211
|
+
* :::
|
|
212
|
+
*
|
|
213
|
+
* ### Scheduled snapshots
|
|
214
|
+
* Scheduled snapshots default on (`autoBackupEnabled`).
|
|
215
|
+
* `snapshotRetention` is days and updates in place. An on-demand
|
|
216
|
+
* snapshot is {@link VolumeSnapshot}.
|
|
217
|
+
*
|
|
218
|
+
* **Example:** Retention
|
|
219
|
+
* ```typescript
|
|
220
|
+
* const disk = yield* Fly.MountVolume({
|
|
221
|
+
* path: "/data",
|
|
222
|
+
* sizeGb: 1,
|
|
223
|
+
* autoBackupEnabled: true,
|
|
224
|
+
* snapshotRetention: 5,
|
|
225
|
+
* });
|
|
226
|
+
* ```
|
|
227
|
+
*
|
|
228
|
+
* ### Restore from a snapshot
|
|
229
|
+
* `snapshotId` restores into a new disk.
|
|
230
|
+
*
|
|
231
|
+
* **Example:** snapshotId
|
|
232
|
+
* ```typescript
|
|
233
|
+
* const disk = yield* Fly.MountVolume({
|
|
234
|
+
* path: "/data",
|
|
235
|
+
* sizeGb: 1,
|
|
236
|
+
* snapshotId: Nightly.snapshotId,
|
|
237
|
+
* });
|
|
238
|
+
* ```
|
|
239
|
+
*
|
|
240
|
+
* :::note[Create-only]
|
|
241
|
+
* Changing `snapshotId` later is ignored.
|
|
242
|
+
* :::
|
|
243
|
+
*
|
|
244
|
+
* ### Fork a volume
|
|
245
|
+
* `sourceVolumeId` forks from an existing Volume.
|
|
246
|
+
*
|
|
247
|
+
* **Example:** sourceVolumeId
|
|
248
|
+
* ```typescript
|
|
249
|
+
* const disk = yield* Fly.MountVolume({
|
|
250
|
+
* path: "/data",
|
|
251
|
+
* sizeGb: 1,
|
|
252
|
+
* sourceVolumeId: box.mounts[0].volumeId,
|
|
253
|
+
* });
|
|
254
|
+
* ```
|
|
255
|
+
*
|
|
256
|
+
* :::note[Create-only]
|
|
257
|
+
* Changing `sourceVolumeId` later is ignored.
|
|
258
|
+
* :::
|
|
259
|
+
*
|
|
260
|
+
* ### Unique zone
|
|
261
|
+
* `requireUniqueZone` asks Fly to land the Volume in a unique zone.
|
|
262
|
+
*
|
|
263
|
+
* **Example:** Unique zone
|
|
264
|
+
* ```typescript
|
|
265
|
+
* const disk = yield* Fly.MountVolume({
|
|
266
|
+
* path: "/data",
|
|
267
|
+
* sizeGb: 1,
|
|
268
|
+
* requireUniqueZone: true,
|
|
269
|
+
* });
|
|
270
|
+
* ```
|
|
271
|
+
*
|
|
272
|
+
* :::note[Create-only]
|
|
273
|
+
* Flipping `requireUniqueZone` later is ignored.
|
|
274
|
+
* :::
|
|
275
|
+
*
|
|
276
|
+
* ### Volume name
|
|
277
|
+
* `name` is the Fly volume-group name. If omitted, a unique name is
|
|
278
|
+
* generated from the host's logical ID and `path`.
|
|
279
|
+
*
|
|
280
|
+
* **Example:** Named group
|
|
281
|
+
* ```typescript
|
|
282
|
+
* const disk = yield* Fly.MountVolume({
|
|
283
|
+
* path: "/data",
|
|
284
|
+
* sizeGb: 1,
|
|
285
|
+
* name: "api_data",
|
|
286
|
+
* });
|
|
287
|
+
* ```
|
|
288
|
+
*
|
|
289
|
+
* @binding
|
|
290
|
+
* @product Volume
|
|
291
|
+
*/
|
|
292
|
+
export interface MountVolume extends Binding.Service<
|
|
293
|
+
MountVolume,
|
|
294
|
+
"Fly.MountVolume",
|
|
295
|
+
(options: MountVolumeOptions) => Effect.Effect<MountedVolume>
|
|
296
|
+
> {}
|
|
297
|
+
|
|
298
|
+
export const MountVolume = Binding.Service<MountVolume>("Fly.MountVolume");
|
|
299
|
+
|
|
300
|
+
export const MountVolumeLive = Layer.effect(
|
|
301
|
+
MountVolume,
|
|
302
|
+
Effect.succeed(
|
|
303
|
+
Effect.fn(function* (options: MountVolumeOptions) {
|
|
304
|
+
if (!globalThis.__ALCHEMY_RUNTIME__) {
|
|
305
|
+
const host = yield* Binding.Host;
|
|
306
|
+
if (isBindHost(host)) {
|
|
307
|
+
yield* host.bind`Fly.MountVolume(${options.path})`({
|
|
308
|
+
mounts: [options],
|
|
309
|
+
});
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
return { path: options.path };
|
|
313
|
+
}),
|
|
314
|
+
),
|
|
315
|
+
);
|