@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
package/lib/Bucket.js
ADDED
|
@@ -0,0 +1,658 @@
|
|
|
1
|
+
import * as addons from "@distilled.cloud/fly-io/addons";
|
|
2
|
+
import * as machines from "@distilled.cloud/fly-io/machines";
|
|
3
|
+
import { Unowned } from "alchemy/AdoptPolicy";
|
|
4
|
+
import { deepEqual, isResolved } from "alchemy/Diff";
|
|
5
|
+
import * as Provider from "alchemy/Provider";
|
|
6
|
+
import { Resource } from "alchemy/Resource";
|
|
7
|
+
import { createInternalTags } from "alchemy/Tags";
|
|
8
|
+
import * as Data from "effect/Data";
|
|
9
|
+
import * as Duration from "effect/Duration";
|
|
10
|
+
import * as Effect from "effect/Effect";
|
|
11
|
+
import * as Redacted from "effect/Redacted";
|
|
12
|
+
import * as Result from "effect/Result";
|
|
13
|
+
import * as Schedule from "effect/Schedule";
|
|
14
|
+
import { resolveOrgSlug } from "./Environment.js";
|
|
15
|
+
import { TigrisCredentialsMissing } from "./Errors.js";
|
|
16
|
+
import { createFlyAppName, matchesAlchemyPhysicalName } from "./Metadata.js";
|
|
17
|
+
/** Env-var names Tigris HTTP bindings write onto an App (same as `fly storage create`). */
|
|
18
|
+
export const BUCKET_SECRET_NAMES = [
|
|
19
|
+
"AWS_ACCESS_KEY_ID",
|
|
20
|
+
"AWS_SECRET_ACCESS_KEY",
|
|
21
|
+
"AWS_ENDPOINT_URL_S3",
|
|
22
|
+
"AWS_REGION",
|
|
23
|
+
"BUCKET_NAME",
|
|
24
|
+
];
|
|
25
|
+
/**
|
|
26
|
+
* A Fly.Bucket is Tigris S3-compatible object storage, billed through
|
|
27
|
+
* Fly. It is an org-scoped GraphQL add-on (`AddOnType` `tigris`).
|
|
28
|
+
*
|
|
29
|
+
* @see https://fly.io/docs/tigris/
|
|
30
|
+
*
|
|
31
|
+
* ### Create a Bucket
|
|
32
|
+
* Alchemy generates a unique name unless you pass one.
|
|
33
|
+
*
|
|
34
|
+
* **Example:** Generated name
|
|
35
|
+
* ```typescript
|
|
36
|
+
* const data = yield* Fly.Bucket("Data");
|
|
37
|
+
* ```
|
|
38
|
+
*
|
|
39
|
+
* ### A stable name
|
|
40
|
+
* Pass `name` when you need a stable Tigris bucket name.
|
|
41
|
+
*
|
|
42
|
+
* **Example:** Explicit name
|
|
43
|
+
* ```typescript
|
|
44
|
+
* const data = yield* Fly.Bucket("Data", {
|
|
45
|
+
* name: "my-bucket",
|
|
46
|
+
* });
|
|
47
|
+
* ```
|
|
48
|
+
*
|
|
49
|
+
* :::caution[Changing `name` replaces the Bucket]
|
|
50
|
+
* Tigris cannot rename a bucket. Alchemy creates the new name, then
|
|
51
|
+
* deletes the old one.
|
|
52
|
+
* :::
|
|
53
|
+
*
|
|
54
|
+
* ### Organization
|
|
55
|
+
* Org defaults to the current token. Pass `orgSlug` to pin it.
|
|
56
|
+
*
|
|
57
|
+
* **Example:** Pin an org
|
|
58
|
+
* ```typescript
|
|
59
|
+
* const data = yield* Fly.Bucket("Data", {
|
|
60
|
+
* orgSlug: "my-org",
|
|
61
|
+
* });
|
|
62
|
+
* ```
|
|
63
|
+
*
|
|
64
|
+
* :::caution[Changing `orgSlug` replaces the Bucket]
|
|
65
|
+
* The bucket is created in the new org. The old bucket is deleted.
|
|
66
|
+
* :::
|
|
67
|
+
*
|
|
68
|
+
* ### Public access
|
|
69
|
+
* Buckets are private by default. `public: true` serves objects
|
|
70
|
+
* without credentials.
|
|
71
|
+
*
|
|
72
|
+
* **Example:** Public bucket
|
|
73
|
+
* ```typescript
|
|
74
|
+
* const assets = yield* Fly.Bucket("Assets", {
|
|
75
|
+
* public: true,
|
|
76
|
+
* });
|
|
77
|
+
* ```
|
|
78
|
+
*
|
|
79
|
+
* ### Custom domain
|
|
80
|
+
* `domainName` sets `website.domain_name` on the add-on. Point a
|
|
81
|
+
* CNAME at `{name}.t3.tigrisbucket.io`.
|
|
82
|
+
*
|
|
83
|
+
* **Example:** Custom domain
|
|
84
|
+
* ```typescript
|
|
85
|
+
* const assets = yield* Fly.Bucket("Assets", {
|
|
86
|
+
* public: true,
|
|
87
|
+
* domainName: "assets.example.com",
|
|
88
|
+
* });
|
|
89
|
+
* ```
|
|
90
|
+
*
|
|
91
|
+
* ### Put and get objects
|
|
92
|
+
* Tigris speaks the S3 API. Bind {@link PutObject} / {@link GetObject}
|
|
93
|
+
* (and the other S3 object ops) in Service init. Alchemy injects the
|
|
94
|
+
* Tigris endpoint and credentials; you never read `AWS_*` yourself.
|
|
95
|
+
*
|
|
96
|
+
* **Example:** Put an object from a Service
|
|
97
|
+
* ```typescript
|
|
98
|
+
* import * as HttpServerResponse from "effect/http/HttpServerResponse";
|
|
99
|
+
*
|
|
100
|
+
* export default class Api extends Fly.Service<Api>()(
|
|
101
|
+
* "Api",
|
|
102
|
+
* { app: Site, main: import.meta.url, port: 3000 },
|
|
103
|
+
* Effect.gen(function* () {
|
|
104
|
+
* const putObject = yield* Fly.PutObject(Data);
|
|
105
|
+
* const getObject = yield* Fly.GetObject(Data);
|
|
106
|
+
*
|
|
107
|
+
* return {
|
|
108
|
+
* fetch: Effect.gen(function* () {
|
|
109
|
+
* yield* putObject({
|
|
110
|
+
* Key: "hello.txt",
|
|
111
|
+
* Body: "hello",
|
|
112
|
+
* ContentType: "text/plain",
|
|
113
|
+
* });
|
|
114
|
+
* const obj = yield* getObject({ Key: "hello.txt" });
|
|
115
|
+
* return HttpServerResponse.json({ ok: obj.ETag !== undefined });
|
|
116
|
+
* }),
|
|
117
|
+
* };
|
|
118
|
+
* }).pipe(Effect.provide([Fly.PutObjectHttp, Fly.GetObjectHttp])),
|
|
119
|
+
* ) {}
|
|
120
|
+
* ```
|
|
121
|
+
*
|
|
122
|
+
* ### Fly.Secret
|
|
123
|
+
* You can also set each key yourself with {@link Secret}.
|
|
124
|
+
*
|
|
125
|
+
* **Example:** Manual secrets
|
|
126
|
+
* ```typescript
|
|
127
|
+
* yield* Fly.Secret("BucketName", {
|
|
128
|
+
* app: Site,
|
|
129
|
+
* name: "BUCKET_NAME",
|
|
130
|
+
* value: Data.bucketName,
|
|
131
|
+
* });
|
|
132
|
+
* ```
|
|
133
|
+
*
|
|
134
|
+
* @resource
|
|
135
|
+
* @product Bucket
|
|
136
|
+
*/
|
|
137
|
+
export const Bucket = Resource("Fly.Bucket");
|
|
138
|
+
export class BucketNotCreated extends Data.TaggedError("Fly.BucketNotCreated") {
|
|
139
|
+
}
|
|
140
|
+
export class BucketOrgMissing extends Data.TaggedError("Fly.BucketOrgMissing") {
|
|
141
|
+
}
|
|
142
|
+
export class BucketProvisionFailed extends Data.TaggedError("Fly.BucketProvisionFailed") {
|
|
143
|
+
}
|
|
144
|
+
class BucketPending extends Data.TaggedError("Fly.BucketPending") {
|
|
145
|
+
}
|
|
146
|
+
const TIGRIS = "tigris";
|
|
147
|
+
const backoff = Schedule.min([
|
|
148
|
+
Schedule.exponential(Duration.millis(500), 1.5),
|
|
149
|
+
Schedule.spaced(Duration.seconds(5)),
|
|
150
|
+
]);
|
|
151
|
+
const sanitizeFlyBucketName = (name) => {
|
|
152
|
+
const lowered = name
|
|
153
|
+
.toLowerCase()
|
|
154
|
+
.replace(/[^a-z0-9-]+/g, "-")
|
|
155
|
+
.replace(/-+/g, "-")
|
|
156
|
+
.replace(/^-+|-+$/g, "");
|
|
157
|
+
const clipped = lowered.length > 63 ? lowered.slice(0, 63).replace(/-+$/g, "") : lowered;
|
|
158
|
+
const raw = clipped.length === 0 ? "f" : clipped;
|
|
159
|
+
return /^[a-z]/.test(raw) ? raw : `f${raw}`.slice(0, 63);
|
|
160
|
+
};
|
|
161
|
+
const resolveBucketName = (id, name, existing) => Effect.gen(function* () {
|
|
162
|
+
if (name !== undefined)
|
|
163
|
+
return sanitizeFlyBucketName(name);
|
|
164
|
+
if (existing !== undefined)
|
|
165
|
+
return existing;
|
|
166
|
+
return yield* createFlyAppName(id);
|
|
167
|
+
});
|
|
168
|
+
const asRecord = (value) => {
|
|
169
|
+
if (Redacted.isRedacted(value)) {
|
|
170
|
+
return value.pipe(Redacted.value, asRecord);
|
|
171
|
+
}
|
|
172
|
+
if (typeof value === "string") {
|
|
173
|
+
try {
|
|
174
|
+
return asRecord(JSON.parse(value));
|
|
175
|
+
}
|
|
176
|
+
catch {
|
|
177
|
+
return {};
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
if (value !== null && typeof value === "object" && !Array.isArray(value)) {
|
|
181
|
+
return value;
|
|
182
|
+
}
|
|
183
|
+
return {};
|
|
184
|
+
};
|
|
185
|
+
const asString = (value) => {
|
|
186
|
+
if (typeof value === "string") {
|
|
187
|
+
return value.length > 0 ? value : undefined;
|
|
188
|
+
}
|
|
189
|
+
if (Redacted.isRedacted(value)) {
|
|
190
|
+
return value.pipe(Redacted.value, asString);
|
|
191
|
+
}
|
|
192
|
+
return undefined;
|
|
193
|
+
};
|
|
194
|
+
const redact = (value) => value !== undefined && value.length > 0 ? Redacted.make(value) : undefined;
|
|
195
|
+
const keepSecret = (next, previous) => next ?? previous;
|
|
196
|
+
const envString = (env, key) => asString(env[key]);
|
|
197
|
+
const unwrapSecret = (value) => Redacted.isRedacted(value) ? Redacted.value(value) : value;
|
|
198
|
+
const desiredOptions = (props) => {
|
|
199
|
+
const options = {
|
|
200
|
+
public: props.public ?? false,
|
|
201
|
+
accelerate: props.accelerate ?? false,
|
|
202
|
+
website: { domain_name: props.domainName ?? "" },
|
|
203
|
+
};
|
|
204
|
+
if (props.shadowBucket !== undefined) {
|
|
205
|
+
options.shadow_bucket = {
|
|
206
|
+
access_key: props.shadowBucket.accessKey,
|
|
207
|
+
secret_key: unwrapSecret(props.shadowBucket.secretKey),
|
|
208
|
+
region: props.shadowBucket.region,
|
|
209
|
+
name: props.shadowBucket.name,
|
|
210
|
+
endpoint: props.shadowBucket.endpoint,
|
|
211
|
+
write_through: props.shadowBucket.writeThrough ?? false,
|
|
212
|
+
};
|
|
213
|
+
}
|
|
214
|
+
return options;
|
|
215
|
+
};
|
|
216
|
+
const websiteDomain = (options) => {
|
|
217
|
+
const website = asRecord(options.website);
|
|
218
|
+
return asString(website.domain_name);
|
|
219
|
+
};
|
|
220
|
+
const toAttrs = (addOn, previous, fallback) => {
|
|
221
|
+
const options = asRecord(addOn.options);
|
|
222
|
+
const env = asRecord(addOn.environment);
|
|
223
|
+
const name = addOn.name ?? fallback?.name ?? previous?.name ?? "";
|
|
224
|
+
const orgSlug = asString(addOn.organization?.slug) ??
|
|
225
|
+
asString(addOn.organization?.rawSlug) ??
|
|
226
|
+
fallback?.orgSlug ??
|
|
227
|
+
previous?.orgSlug;
|
|
228
|
+
return {
|
|
229
|
+
addOnId: addOn.id,
|
|
230
|
+
name,
|
|
231
|
+
status: addOn.status ?? undefined,
|
|
232
|
+
orgSlug,
|
|
233
|
+
public: typeof options.public === "boolean" ? options.public : (previous?.public ?? false),
|
|
234
|
+
domainName: websiteDomain(options),
|
|
235
|
+
accelerate: options.accelerate === true,
|
|
236
|
+
ssoLink: addOn.ssoLink ?? undefined,
|
|
237
|
+
createdAt: addOn.createdAt,
|
|
238
|
+
accessKeyId: keepSecret(redact(envString(env, "AWS_ACCESS_KEY_ID")), previous?.accessKeyId),
|
|
239
|
+
secretAccessKey: keepSecret(redact(envString(env, "AWS_SECRET_ACCESS_KEY")), previous?.secretAccessKey),
|
|
240
|
+
endpoint: keepSecret(redact(envString(env, "AWS_ENDPOINT_URL_S3")), previous?.endpoint),
|
|
241
|
+
region: keepSecret(redact(envString(env, "AWS_REGION")), previous?.region),
|
|
242
|
+
bucketName: keepSecret(redact(envString(env, "BUCKET_NAME") ?? name), previous?.bucketName),
|
|
243
|
+
};
|
|
244
|
+
};
|
|
245
|
+
const stringRecordOf = (value) => Object.fromEntries(Object.entries(asRecord(value)).flatMap(([key, item]) => {
|
|
246
|
+
const text = asString(item);
|
|
247
|
+
return text !== undefined ? [[key, text]] : [];
|
|
248
|
+
}));
|
|
249
|
+
const hasAlchemyMetadata = (metadata) => {
|
|
250
|
+
const tags = stringRecordOf(metadata);
|
|
251
|
+
const stack = tags["alchemy::stack"] ?? tags["alchemy.stack"];
|
|
252
|
+
return stack !== undefined && stack.length > 0;
|
|
253
|
+
};
|
|
254
|
+
const isOwnedAddOn = (addOn) => matchesAlchemyPhysicalName(addOn.name ?? undefined) || hasAlchemyMetadata(addOn.metadata);
|
|
255
|
+
export const listTigrisAddOns = Effect.fn(function* () {
|
|
256
|
+
const rows = [];
|
|
257
|
+
let after;
|
|
258
|
+
for (let i = 0; i < 8; i++) {
|
|
259
|
+
const page = yield* addons.addOns({
|
|
260
|
+
type: TIGRIS,
|
|
261
|
+
first: 50,
|
|
262
|
+
after,
|
|
263
|
+
});
|
|
264
|
+
for (const edge of page.edges ?? []) {
|
|
265
|
+
if (edge?.node != null)
|
|
266
|
+
rows.push(edge.node);
|
|
267
|
+
}
|
|
268
|
+
if (!page.pageInfo.hasNextPage)
|
|
269
|
+
break;
|
|
270
|
+
after = page.pageInfo.endCursor ?? undefined;
|
|
271
|
+
if (after === undefined || after.length === 0)
|
|
272
|
+
break;
|
|
273
|
+
}
|
|
274
|
+
return rows;
|
|
275
|
+
});
|
|
276
|
+
const findById = (addOnId) => listTigrisAddOns().pipe(Effect.map((addOns) => addOns.find((addOn) => addOn.id === addOnId)));
|
|
277
|
+
const findByName = (name) => listTigrisAddOns().pipe(Effect.map((addOns) => addOns.find((addOn) => addOn.name === name)));
|
|
278
|
+
const failedStatus = (status) => status === "error" || status === "failed";
|
|
279
|
+
const pendingStatus = (status) => status === "creating" ||
|
|
280
|
+
status === "provisioning" ||
|
|
281
|
+
status === "pending" ||
|
|
282
|
+
status === "pending_create";
|
|
283
|
+
const waitUntilReady = (name, addOnId) => findById(addOnId).pipe(Effect.flatMap((addOn) => {
|
|
284
|
+
if (addOn === undefined) {
|
|
285
|
+
return Effect.fail(new BucketPending({ name, status: "missing" }));
|
|
286
|
+
}
|
|
287
|
+
const status = addOn.status ?? undefined;
|
|
288
|
+
if (failedStatus(status)) {
|
|
289
|
+
return Effect.fail(new BucketProvisionFailed({
|
|
290
|
+
name,
|
|
291
|
+
status,
|
|
292
|
+
errorMessage: addOn.errorMessage ?? undefined,
|
|
293
|
+
}));
|
|
294
|
+
}
|
|
295
|
+
if (pendingStatus(status)) {
|
|
296
|
+
return Effect.fail(new BucketPending({ name, status: status ?? "creating" }));
|
|
297
|
+
}
|
|
298
|
+
return Effect.succeed(addOn);
|
|
299
|
+
}), Effect.retry({
|
|
300
|
+
while: (e) => e._tag === "Fly.BucketPending",
|
|
301
|
+
times: 8,
|
|
302
|
+
schedule: backoff,
|
|
303
|
+
}), Effect.catchTag("Fly.BucketPending", () => findById(addOnId)));
|
|
304
|
+
const waitUntilGone = (addOnId, name) => Effect.gen(function* () {
|
|
305
|
+
// Best-effort: Tigris often answers "The specified bucket does not
|
|
306
|
+
// exist" (untyped UnknownFlyIoError) for a delete that already
|
|
307
|
+
// succeeded. Never fail the wait on that — only on the add-on still
|
|
308
|
+
// showing up in list.
|
|
309
|
+
yield* Effect.result(addons.deleteAddOn({
|
|
310
|
+
input: addOnId.length > 0 ? { addOnId } : { name, provider: TIGRIS },
|
|
311
|
+
}));
|
|
312
|
+
const still = (yield* findById(addOnId)) ?? (name.length > 0 ? yield* findByName(name) : undefined);
|
|
313
|
+
if (still !== undefined) {
|
|
314
|
+
return yield* new BucketPending({
|
|
315
|
+
name,
|
|
316
|
+
status: still.status ?? "deleting",
|
|
317
|
+
});
|
|
318
|
+
}
|
|
319
|
+
}).pipe(Effect.retry({
|
|
320
|
+
while: (e) => e._tag === "Fly.BucketPending",
|
|
321
|
+
schedule: Schedule.spaced("2 seconds"),
|
|
322
|
+
times: 20,
|
|
323
|
+
}));
|
|
324
|
+
const resolveOrganization = (orgSlug) => addons
|
|
325
|
+
.organization({ slug: orgSlug })
|
|
326
|
+
.pipe(Effect.catchTag("FlyIoParseError", () => Effect.succeed(undefined)));
|
|
327
|
+
const ensureTos = (orgSlug, organizationId) => Effect.gen(function* () {
|
|
328
|
+
const agreed = yield* addons.agreedToProviderTos({
|
|
329
|
+
slug: orgSlug,
|
|
330
|
+
providerName: TIGRIS,
|
|
331
|
+
});
|
|
332
|
+
if (agreed === true)
|
|
333
|
+
return;
|
|
334
|
+
const tos = yield* Effect.result(addons.createExtensionTosAgreement({
|
|
335
|
+
input: {
|
|
336
|
+
addOnProviderName: TIGRIS,
|
|
337
|
+
organizationId,
|
|
338
|
+
},
|
|
339
|
+
}));
|
|
340
|
+
if (Result.isFailure(tos))
|
|
341
|
+
return;
|
|
342
|
+
});
|
|
343
|
+
const optionsEqual = (observed, desired) => {
|
|
344
|
+
const observedPublic = observed.public === true;
|
|
345
|
+
const desiredPublic = desired.public === true;
|
|
346
|
+
const observedAccelerate = observed.accelerate === true;
|
|
347
|
+
const desiredAccelerate = desired.accelerate === true;
|
|
348
|
+
const observedDomain = websiteDomain(observed) ?? "";
|
|
349
|
+
const desiredDomain = websiteDomain(desired) ?? "";
|
|
350
|
+
if (observedPublic !== desiredPublic ||
|
|
351
|
+
observedAccelerate !== desiredAccelerate ||
|
|
352
|
+
observedDomain !== desiredDomain) {
|
|
353
|
+
return false;
|
|
354
|
+
}
|
|
355
|
+
if (desired.shadow_bucket !== undefined) {
|
|
356
|
+
return deepEqual(asRecord(observed.shadow_bucket), desired.shadow_bucket);
|
|
357
|
+
}
|
|
358
|
+
return true;
|
|
359
|
+
};
|
|
360
|
+
export const BucketProvider = () => Provider.succeed(Bucket, {
|
|
361
|
+
stables: ["addOnId", "name", "orgSlug"],
|
|
362
|
+
diff: Effect.fn(function* ({ news, output }) {
|
|
363
|
+
if (news === undefined || !isResolved(news))
|
|
364
|
+
return undefined;
|
|
365
|
+
if (output === undefined)
|
|
366
|
+
return undefined;
|
|
367
|
+
const desiredName = news.name !== undefined ? sanitizeFlyBucketName(news.name) : output.name;
|
|
368
|
+
const nameChanged = desiredName !== output.name;
|
|
369
|
+
const orgChanged = news.orgSlug !== undefined && news.orgSlug !== output.orgSlug;
|
|
370
|
+
if (nameChanged || orgChanged) {
|
|
371
|
+
return { action: "replace" };
|
|
372
|
+
}
|
|
373
|
+
return undefined;
|
|
374
|
+
}),
|
|
375
|
+
read: Effect.fn(function* ({ id, olds, output }) {
|
|
376
|
+
const name = yield* resolveBucketName(id, olds?.name, output?.name);
|
|
377
|
+
const found = (output?.addOnId !== undefined && output.addOnId.length > 0
|
|
378
|
+
? yield* findById(output.addOnId)
|
|
379
|
+
: undefined) ?? (yield* findByName(name));
|
|
380
|
+
if (found === undefined)
|
|
381
|
+
return undefined;
|
|
382
|
+
const attrs = toAttrs(found, output, {
|
|
383
|
+
name,
|
|
384
|
+
orgSlug: output?.orgSlug ?? olds?.orgSlug,
|
|
385
|
+
});
|
|
386
|
+
if (output !== undefined)
|
|
387
|
+
return attrs;
|
|
388
|
+
return isOwnedAddOn(found) ? attrs : Unowned(attrs);
|
|
389
|
+
}),
|
|
390
|
+
list: Effect.fn(function* () {
|
|
391
|
+
const addOns = yield* listTigrisAddOns();
|
|
392
|
+
return addOns.flatMap((addOn) => (isOwnedAddOn(addOn) ? [toAttrs(addOn)] : []));
|
|
393
|
+
}),
|
|
394
|
+
reconcile: Effect.fn(function* ({ id, news, output }) {
|
|
395
|
+
const props = news ?? {};
|
|
396
|
+
const name = yield* resolveBucketName(id, props.name, output?.name);
|
|
397
|
+
const orgSlug = props.orgSlug ?? output?.orgSlug ?? (yield* resolveOrgSlug());
|
|
398
|
+
let previous = output;
|
|
399
|
+
// Observe by cached id, then the desired name.
|
|
400
|
+
let current = output?.addOnId !== undefined && output.addOnId.length > 0
|
|
401
|
+
? yield* findById(output.addOnId)
|
|
402
|
+
: undefined;
|
|
403
|
+
if (current === undefined) {
|
|
404
|
+
current = yield* findByName(name);
|
|
405
|
+
}
|
|
406
|
+
const org = yield* resolveOrganization(orgSlug);
|
|
407
|
+
if (org === undefined) {
|
|
408
|
+
return yield* new BucketOrgMissing({ orgSlug });
|
|
409
|
+
}
|
|
410
|
+
if (current === undefined) {
|
|
411
|
+
yield* ensureTos(orgSlug, org.id);
|
|
412
|
+
const created = yield* Effect.result(addons.createAddOn({
|
|
413
|
+
input: {
|
|
414
|
+
type: TIGRIS,
|
|
415
|
+
name,
|
|
416
|
+
organizationId: org.id,
|
|
417
|
+
options: desiredOptions(props),
|
|
418
|
+
},
|
|
419
|
+
}));
|
|
420
|
+
if (Result.isSuccess(created)) {
|
|
421
|
+
current = created.success.addOn;
|
|
422
|
+
}
|
|
423
|
+
else {
|
|
424
|
+
current = yield* findByName(name);
|
|
425
|
+
if (current === undefined) {
|
|
426
|
+
return yield* created.failure;
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
const createdSecrets = current;
|
|
430
|
+
if (current.id.length > 0) {
|
|
431
|
+
current = (yield* waitUntilReady(name, current.id)) ?? current;
|
|
432
|
+
}
|
|
433
|
+
// List/get omit `environment` after create. Keep the create
|
|
434
|
+
// payload as the secrets source for keepSecret below.
|
|
435
|
+
previous = toAttrs(createdSecrets, previous, { name, orgSlug });
|
|
436
|
+
}
|
|
437
|
+
if (current === undefined || current.id.length === 0) {
|
|
438
|
+
return yield* new BucketNotCreated({ name });
|
|
439
|
+
}
|
|
440
|
+
const status = current.status ?? undefined;
|
|
441
|
+
if (failedStatus(status)) {
|
|
442
|
+
return yield* new BucketProvisionFailed({
|
|
443
|
+
name,
|
|
444
|
+
status,
|
|
445
|
+
errorMessage: current.errorMessage ?? undefined,
|
|
446
|
+
});
|
|
447
|
+
}
|
|
448
|
+
const observedOptions = asRecord(current.options);
|
|
449
|
+
const desired = desiredOptions(props);
|
|
450
|
+
const internal = yield* createInternalTags(id);
|
|
451
|
+
const observedMeta = stringRecordOf(current.metadata);
|
|
452
|
+
const nextMeta = { ...observedMeta, ...internal };
|
|
453
|
+
const optionsChanged = !optionsEqual(observedOptions, desired);
|
|
454
|
+
const metaChanged = !deepEqual(observedMeta, nextMeta);
|
|
455
|
+
if (optionsChanged || metaChanged) {
|
|
456
|
+
const nextOptions = {
|
|
457
|
+
...observedOptions,
|
|
458
|
+
...desired,
|
|
459
|
+
};
|
|
460
|
+
const updated = yield* Effect.result(addons.updateAddOn({
|
|
461
|
+
input: {
|
|
462
|
+
addOnId: current.id,
|
|
463
|
+
options: optionsChanged ? nextOptions : undefined,
|
|
464
|
+
metadata: metaChanged ? nextMeta : undefined,
|
|
465
|
+
},
|
|
466
|
+
}));
|
|
467
|
+
if (Result.isSuccess(updated)) {
|
|
468
|
+
current = {
|
|
469
|
+
...current,
|
|
470
|
+
...updated.success.addOn,
|
|
471
|
+
};
|
|
472
|
+
}
|
|
473
|
+
else {
|
|
474
|
+
current = (yield* findById(current.id)) ?? current;
|
|
475
|
+
}
|
|
476
|
+
}
|
|
477
|
+
const latest = (yield* findById(current.id)) ?? current;
|
|
478
|
+
// GraphQL list/get omit `environment` after create. Keep credentials
|
|
479
|
+
// from the create payload (or last persisted attrs) via keepSecret.
|
|
480
|
+
const attrs = toAttrs(latest, toAttrs(current, previous, { name, orgSlug }), {
|
|
481
|
+
name,
|
|
482
|
+
orgSlug,
|
|
483
|
+
});
|
|
484
|
+
const observedPublic = asRecord(latest.options).public;
|
|
485
|
+
return {
|
|
486
|
+
...attrs,
|
|
487
|
+
public: typeof observedPublic === "boolean" ? observedPublic : (props.public ?? attrs.public),
|
|
488
|
+
domainName: websiteDomain(asRecord(latest.options)) ?? props.domainName ?? attrs.domainName,
|
|
489
|
+
accelerate: typeof asRecord(latest.options).accelerate === "boolean"
|
|
490
|
+
? asRecord(latest.options).accelerate
|
|
491
|
+
: (props.accelerate ?? attrs.accelerate),
|
|
492
|
+
};
|
|
493
|
+
}),
|
|
494
|
+
delete: Effect.fn(function* ({ output }) {
|
|
495
|
+
const addOnId = output.addOnId;
|
|
496
|
+
const name = output.name;
|
|
497
|
+
if (addOnId.length === 0 && name.length === 0)
|
|
498
|
+
return;
|
|
499
|
+
// Always wait for the add-on to leave the list. A failed
|
|
500
|
+
// deleteAddOn plus a single list miss is not gone — Tigris
|
|
501
|
+
// list lags, and a bucket still attached to an App is a
|
|
502
|
+
// transient error. waitUntilGone retries delete and only
|
|
503
|
+
// succeeds once list (id and name) is empty.
|
|
504
|
+
yield* waitUntilGone(addOnId, name);
|
|
505
|
+
}),
|
|
506
|
+
});
|
|
507
|
+
class BucketSecretVersionMissing extends Data.TaggedError("Fly.BucketSecretVersionMissing") {
|
|
508
|
+
}
|
|
509
|
+
const bucketSecretVersion = (appName, response) => {
|
|
510
|
+
const version = response.version ?? response.Version;
|
|
511
|
+
return version !== undefined && Number.isSafeInteger(version) && version >= 0
|
|
512
|
+
? Effect.succeed(version)
|
|
513
|
+
: Effect.fail(new BucketSecretVersionMissing({ appName }));
|
|
514
|
+
};
|
|
515
|
+
const requireBucketSecrets = Effect.fn(function* (appName, values) {
|
|
516
|
+
const required = [
|
|
517
|
+
"BUCKET_NAME",
|
|
518
|
+
"AWS_ACCESS_KEY_ID",
|
|
519
|
+
"AWS_SECRET_ACCESS_KEY",
|
|
520
|
+
"AWS_ENDPOINT_URL_S3",
|
|
521
|
+
];
|
|
522
|
+
if (required.some((key) => !values[key]?.trim())) {
|
|
523
|
+
return yield* new TigrisCredentialsMissing({
|
|
524
|
+
name: values.BUCKET_NAME || appName,
|
|
525
|
+
});
|
|
526
|
+
}
|
|
527
|
+
});
|
|
528
|
+
const putSecretValues = (appName, values) => Effect.gen(function* () {
|
|
529
|
+
yield* requireBucketSecrets(appName, values);
|
|
530
|
+
return yield* machines
|
|
531
|
+
.updateSecrets({
|
|
532
|
+
app_name: appName,
|
|
533
|
+
values,
|
|
534
|
+
})
|
|
535
|
+
.pipe(Effect.flatMap((response) => bucketSecretVersion(appName, response)), Effect.catchTag("NotFound", () => Effect.gen(function* () {
|
|
536
|
+
const versions = [];
|
|
537
|
+
for (const [secretName, value] of Object.entries(values)) {
|
|
538
|
+
const version = yield* machines
|
|
539
|
+
.createSecret({
|
|
540
|
+
app_name: appName,
|
|
541
|
+
secret_name: secretName,
|
|
542
|
+
value,
|
|
543
|
+
})
|
|
544
|
+
.pipe(Effect.flatMap((response) => bucketSecretVersion(appName, response)), Effect.catchTag("Conflict", () => machines
|
|
545
|
+
.updateSecrets({
|
|
546
|
+
app_name: appName,
|
|
547
|
+
values: { [secretName]: value },
|
|
548
|
+
})
|
|
549
|
+
.pipe(Effect.flatMap((response) => bucketSecretVersion(appName, response)))));
|
|
550
|
+
versions.push(version);
|
|
551
|
+
}
|
|
552
|
+
return Math.max(...versions);
|
|
553
|
+
})));
|
|
554
|
+
});
|
|
555
|
+
const envValuesOf = (addOn) => {
|
|
556
|
+
const env = asRecord(addOn.environment);
|
|
557
|
+
const values = {};
|
|
558
|
+
for (const key of BUCKET_SECRET_NAMES) {
|
|
559
|
+
const value = envString(env, key);
|
|
560
|
+
if (value !== undefined)
|
|
561
|
+
values[key] = value;
|
|
562
|
+
}
|
|
563
|
+
if (values.BUCKET_NAME === undefined && addOn.name != null) {
|
|
564
|
+
values.BUCKET_NAME = addOn.name;
|
|
565
|
+
}
|
|
566
|
+
if (values.AWS_ENDPOINT_URL === undefined && values.AWS_ENDPOINT_URL_S3 !== undefined) {
|
|
567
|
+
values.AWS_ENDPOINT_URL = values.AWS_ENDPOINT_URL_S3;
|
|
568
|
+
}
|
|
569
|
+
return values;
|
|
570
|
+
};
|
|
571
|
+
const findAttachedBucket = (input) => Effect.gen(function* () {
|
|
572
|
+
const listed = input.id !== undefined && input.id.length > 0
|
|
573
|
+
? ((yield* findById(input.id)) ??
|
|
574
|
+
(input.name.length > 0 ? yield* findByName(input.name) : undefined))
|
|
575
|
+
: input.name.length > 0
|
|
576
|
+
? yield* findByName(input.name)
|
|
577
|
+
: undefined;
|
|
578
|
+
if (listed === undefined) {
|
|
579
|
+
return yield* new BucketPending({
|
|
580
|
+
name: input.name || input.id || "",
|
|
581
|
+
status: "missing",
|
|
582
|
+
});
|
|
583
|
+
}
|
|
584
|
+
const detail = yield* addons
|
|
585
|
+
.addOn({
|
|
586
|
+
id: listed.id,
|
|
587
|
+
name: listed.name ?? input.name,
|
|
588
|
+
provider: TIGRIS,
|
|
589
|
+
})
|
|
590
|
+
.pipe(Effect.catchTag("FlyIoParseError", () => Effect.succeed(undefined)));
|
|
591
|
+
return detail ?? listed;
|
|
592
|
+
});
|
|
593
|
+
const secretsFromBoundEnv = (env) => {
|
|
594
|
+
const values = {};
|
|
595
|
+
for (const key of BUCKET_SECRET_NAMES) {
|
|
596
|
+
const value = env[key];
|
|
597
|
+
if (value !== undefined && value.length > 0)
|
|
598
|
+
values[key] = value;
|
|
599
|
+
}
|
|
600
|
+
if (values.AWS_ENDPOINT_URL === undefined && values.AWS_ENDPOINT_URL_S3 !== undefined) {
|
|
601
|
+
values.AWS_ENDPOINT_URL = values.AWS_ENDPOINT_URL_S3;
|
|
602
|
+
}
|
|
603
|
+
return values;
|
|
604
|
+
};
|
|
605
|
+
/**
|
|
606
|
+
* Write Tigris `AWS_*` / `BUCKET_NAME` secrets onto an App. Called from
|
|
607
|
+
* {@link Service} reconcile so the secrets exist before Machines boot.
|
|
608
|
+
*
|
|
609
|
+
* Looks up the add-on by id/name (retrying while Tigris is still
|
|
610
|
+
* provisioning) and also copies any already-evaluated `AWS_*` /
|
|
611
|
+
* `BUCKET_NAME` values from binding env — GraphQL `environment` is often
|
|
612
|
+
* empty after create. A missing add-on may use bound values only when the
|
|
613
|
+
* bucket name, credential pair, and S3 endpoint are complete. Partial values
|
|
614
|
+
* are never written. Region is optional, as in the Tigris bindings.
|
|
615
|
+
* Without an attachment, only an explicit `BUCKET_NAME` requests this mode;
|
|
616
|
+
* ordinary AWS region or credential settings do not imply a Bucket.
|
|
617
|
+
* Returns the highest accepted secret-version floor, or `undefined` when
|
|
618
|
+
* no Bucket was requested; this is not a vault snapshot.
|
|
619
|
+
*/
|
|
620
|
+
export const attachBucketSecrets = Effect.fn(function* (appName, attached, boundEnv = {}) {
|
|
621
|
+
if (appName.length === 0)
|
|
622
|
+
return undefined;
|
|
623
|
+
if (attached.length === 0 && boundEnv.BUCKET_NAME === undefined) {
|
|
624
|
+
return undefined;
|
|
625
|
+
}
|
|
626
|
+
const fromEnv = secretsFromBoundEnv(boundEnv);
|
|
627
|
+
if (attached.length === 0) {
|
|
628
|
+
return yield* putSecretValues(appName, fromEnv);
|
|
629
|
+
}
|
|
630
|
+
const versions = [];
|
|
631
|
+
for (const item of attached) {
|
|
632
|
+
const name = item.name;
|
|
633
|
+
const id = item.id;
|
|
634
|
+
const fallbackValues = {
|
|
635
|
+
...fromEnv,
|
|
636
|
+
...item.values,
|
|
637
|
+
};
|
|
638
|
+
if (fallbackValues.AWS_ENDPOINT_URL === undefined &&
|
|
639
|
+
fallbackValues.AWS_ENDPOINT_URL_S3 !== undefined) {
|
|
640
|
+
fallbackValues.AWS_ENDPOINT_URL = fallbackValues.AWS_ENDPOINT_URL_S3;
|
|
641
|
+
}
|
|
642
|
+
if (fallbackValues.BUCKET_NAME === undefined && name.length > 0) {
|
|
643
|
+
fallbackValues.BUCKET_NAME = name;
|
|
644
|
+
}
|
|
645
|
+
const row = yield* findAttachedBucket({ id, name }).pipe(Effect.retry({
|
|
646
|
+
while: (error) => error._tag === "Fly.BucketPending",
|
|
647
|
+
times: 8,
|
|
648
|
+
schedule: backoff,
|
|
649
|
+
}), Effect.catchTag("Fly.BucketPending", () => requireBucketSecrets(appName, fallbackValues).pipe(Effect.as(undefined))));
|
|
650
|
+
const values = {
|
|
651
|
+
...fallbackValues,
|
|
652
|
+
...(row === undefined ? {} : envValuesOf(row)),
|
|
653
|
+
};
|
|
654
|
+
versions.push(yield* putSecretValues(appName, values));
|
|
655
|
+
}
|
|
656
|
+
return versions.length > 0 ? Math.max(...versions) : undefined;
|
|
657
|
+
});
|
|
658
|
+
//# sourceMappingURL=Bucket.js.map
|