@alchemy.run/fly 0.0.0-stage → 2.0.0-beta.84
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +201 -0
- package/README.md +61 -2
- package/lib/App.d.ts +230 -0
- package/lib/App.d.ts.map +1 -0
- package/lib/App.js +340 -0
- package/lib/App.js.map +1 -0
- package/lib/AuthProvider.d.ts +22 -0
- package/lib/AuthProvider.d.ts.map +1 -0
- package/lib/AuthProvider.js +48 -0
- package/lib/AuthProvider.js.map +1 -0
- package/lib/BindService.d.ts +159 -0
- package/lib/BindService.d.ts.map +1 -0
- package/lib/BindService.js +222 -0
- package/lib/BindService.js.map +1 -0
- package/lib/Bootstrap.d.ts +8 -0
- package/lib/Bootstrap.d.ts.map +1 -0
- package/lib/Bootstrap.js +41 -0
- package/lib/Bootstrap.js.map +1 -0
- package/lib/Bucket.d.ts +278 -0
- package/lib/Bucket.d.ts.map +1 -0
- package/lib/Bucket.js +658 -0
- package/lib/Bucket.js.map +1 -0
- package/lib/BucketBinding.d.ts +33 -0
- package/lib/BucketBinding.d.ts.map +1 -0
- package/lib/BucketBinding.js +70 -0
- package/lib/BucketBinding.js.map +1 -0
- package/lib/Catalog.d.ts +28 -0
- package/lib/Catalog.d.ts.map +1 -0
- package/lib/Catalog.js +31 -0
- package/lib/Catalog.js.map +1 -0
- package/lib/Certificate.d.ts +189 -0
- package/lib/Certificate.d.ts.map +1 -0
- package/lib/Certificate.js +380 -0
- package/lib/Certificate.js.map +1 -0
- package/lib/Checkpoint.d.ts +55 -0
- package/lib/Checkpoint.d.ts.map +1 -0
- package/lib/Checkpoint.js +3 -0
- package/lib/Checkpoint.js.map +1 -0
- package/lib/CheckpointHttp.d.ts +22 -0
- package/lib/CheckpointHttp.d.ts.map +1 -0
- package/lib/CheckpointHttp.js +53 -0
- package/lib/CheckpointHttp.js.map +1 -0
- package/lib/ConnectPostgres.d.ts +58 -0
- package/lib/ConnectPostgres.d.ts.map +1 -0
- package/lib/ConnectPostgres.js +13 -0
- package/lib/ConnectPostgres.js.map +1 -0
- package/lib/ConnectPostgresHttp.d.ts +26 -0
- package/lib/ConnectPostgresHttp.d.ts.map +1 -0
- package/lib/ConnectPostgresHttp.js +57 -0
- package/lib/ConnectPostgresHttp.js.map +1 -0
- package/lib/Contributions.d.ts +7 -0
- package/lib/Contributions.d.ts.map +1 -0
- package/lib/Contributions.js +6 -0
- package/lib/Contributions.js.map +1 -0
- package/lib/Credentials.d.ts +33 -0
- package/lib/Credentials.d.ts.map +1 -0
- package/lib/Credentials.js +59 -0
- package/lib/Credentials.js.map +1 -0
- package/lib/Decrypt.d.ts +52 -0
- package/lib/Decrypt.d.ts.map +1 -0
- package/lib/Decrypt.js +3 -0
- package/lib/Decrypt.js.map +1 -0
- package/lib/DecryptHttp.d.ts +22 -0
- package/lib/DecryptHttp.d.ts.map +1 -0
- package/lib/DecryptHttp.js +43 -0
- package/lib/DecryptHttp.js.map +1 -0
- package/lib/DeleteObject.d.ts +29 -0
- package/lib/DeleteObject.d.ts.map +1 -0
- package/lib/DeleteObject.js +3 -0
- package/lib/DeleteObject.js.map +1 -0
- package/lib/DeleteObjectHttp.d.ts +12 -0
- package/lib/DeleteObjectHttp.d.ts.map +1 -0
- package/lib/DeleteObjectHttp.js +17 -0
- package/lib/DeleteObjectHttp.js.map +1 -0
- package/lib/Deployment.d.ts +51 -0
- package/lib/Deployment.d.ts.map +1 -0
- package/lib/Deployment.js +62 -0
- package/lib/Deployment.js.map +1 -0
- package/lib/DeploymentImages.d.ts +18 -0
- package/lib/DeploymentImages.d.ts.map +1 -0
- package/lib/DeploymentImages.js +61 -0
- package/lib/DeploymentImages.js.map +1 -0
- package/lib/DeploymentState.d.ts +17 -0
- package/lib/DeploymentState.d.ts.map +1 -0
- package/lib/DeploymentState.js +87 -0
- package/lib/DeploymentState.js.map +1 -0
- package/lib/Encrypt.d.ts +50 -0
- package/lib/Encrypt.d.ts.map +1 -0
- package/lib/Encrypt.js +3 -0
- package/lib/Encrypt.js.map +1 -0
- package/lib/EncryptHttp.d.ts +22 -0
- package/lib/EncryptHttp.d.ts.map +1 -0
- package/lib/EncryptHttp.js +39 -0
- package/lib/EncryptHttp.js.map +1 -0
- package/lib/Environment.d.ts +45 -0
- package/lib/Environment.d.ts.map +1 -0
- package/lib/Environment.js +43 -0
- package/lib/Environment.js.map +1 -0
- package/lib/Errors.d.ts +18 -0
- package/lib/Errors.d.ts.map +1 -0
- package/lib/Errors.js +13 -0
- package/lib/Errors.js.map +1 -0
- package/lib/Exec.d.ts +41 -0
- package/lib/Exec.d.ts.map +1 -0
- package/lib/Exec.js +3 -0
- package/lib/Exec.js.map +1 -0
- package/lib/ExecHttp.d.ts +22 -0
- package/lib/ExecHttp.d.ts.map +1 -0
- package/lib/ExecHttp.js +39 -0
- package/lib/ExecHttp.js.map +1 -0
- package/lib/GetObject.d.ts +34 -0
- package/lib/GetObject.d.ts.map +1 -0
- package/lib/GetObject.js +3 -0
- package/lib/GetObject.js.map +1 -0
- package/lib/GetObjectHttp.d.ts +12 -0
- package/lib/GetObjectHttp.d.ts.map +1 -0
- package/lib/GetObjectHttp.js +17 -0
- package/lib/GetObjectHttp.js.map +1 -0
- package/lib/GetSecret.d.ts +44 -0
- package/lib/GetSecret.d.ts.map +1 -0
- package/lib/GetSecret.js +3 -0
- package/lib/GetSecret.js.map +1 -0
- package/lib/GetSecretHttp.d.ts +22 -0
- package/lib/GetSecretHttp.d.ts.map +1 -0
- package/lib/GetSecretHttp.js +50 -0
- package/lib/GetSecretHttp.js.map +1 -0
- package/lib/HeadObject.d.ts +29 -0
- package/lib/HeadObject.d.ts.map +1 -0
- package/lib/HeadObject.js +3 -0
- package/lib/HeadObject.js.map +1 -0
- package/lib/HeadObjectHttp.d.ts +12 -0
- package/lib/HeadObjectHttp.d.ts.map +1 -0
- package/lib/HeadObjectHttp.js +17 -0
- package/lib/HeadObjectHttp.js.map +1 -0
- package/lib/IpAssignment.d.ts +258 -0
- package/lib/IpAssignment.d.ts.map +1 -0
- package/lib/IpAssignment.js +376 -0
- package/lib/IpAssignment.js.map +1 -0
- package/lib/ListObjectsV2.d.ts +29 -0
- package/lib/ListObjectsV2.d.ts.map +1 -0
- package/lib/ListObjectsV2.js +3 -0
- package/lib/ListObjectsV2.js.map +1 -0
- package/lib/ListObjectsV2Http.d.ts +12 -0
- package/lib/ListObjectsV2Http.d.ts.map +1 -0
- package/lib/ListObjectsV2Http.js +17 -0
- package/lib/ListObjectsV2Http.js.map +1 -0
- package/lib/ListSecrets.d.ts +53 -0
- package/lib/ListSecrets.d.ts.map +1 -0
- package/lib/ListSecrets.js +3 -0
- package/lib/ListSecrets.js.map +1 -0
- package/lib/ListSecretsHttp.d.ts +22 -0
- package/lib/ListSecretsHttp.d.ts.map +1 -0
- package/lib/ListSecretsHttp.js +35 -0
- package/lib/ListSecretsHttp.js.map +1 -0
- package/lib/Machine.d.ts +802 -0
- package/lib/Machine.d.ts.map +1 -0
- package/lib/Machine.js +773 -0
- package/lib/Machine.js.map +1 -0
- package/lib/MachineContainers.d.ts +44 -0
- package/lib/MachineContainers.d.ts.map +1 -0
- package/lib/MachineContainers.js +115 -0
- package/lib/MachineContainers.js.map +1 -0
- package/lib/Metadata.d.ts +109 -0
- package/lib/Metadata.d.ts.map +1 -0
- package/lib/Metadata.js +159 -0
- package/lib/Metadata.js.map +1 -0
- package/lib/MountVolume.d.ts +295 -0
- package/lib/MountVolume.d.ts.map +1 -0
- package/lib/MountVolume.js +20 -0
- package/lib/MountVolume.js.map +1 -0
- package/lib/Postgres.d.ts +298 -0
- package/lib/Postgres.d.ts.map +1 -0
- package/lib/Postgres.js +508 -0
- package/lib/Postgres.js.map +1 -0
- package/lib/PostgresMigrations.d.ts +35 -0
- package/lib/PostgresMigrations.d.ts.map +1 -0
- package/lib/PostgresMigrations.js +110 -0
- package/lib/PostgresMigrations.js.map +1 -0
- package/lib/Providers.d.ts +38 -0
- package/lib/Providers.d.ts.map +1 -0
- package/lib/Providers.js +95 -0
- package/lib/Providers.js.map +1 -0
- package/lib/PutObject.d.ts +35 -0
- package/lib/PutObject.d.ts.map +1 -0
- package/lib/PutObject.js +3 -0
- package/lib/PutObject.js.map +1 -0
- package/lib/PutObjectHttp.d.ts +12 -0
- package/lib/PutObjectHttp.d.ts.map +1 -0
- package/lib/PutObjectHttp.js +17 -0
- package/lib/PutObjectHttp.js.map +1 -0
- package/lib/ReadRedis.d.ts +26 -0
- package/lib/ReadRedis.d.ts.map +1 -0
- package/lib/ReadRedis.js +3 -0
- package/lib/ReadRedis.js.map +1 -0
- package/lib/ReadRedisHttp.d.ts +11 -0
- package/lib/ReadRedisHttp.d.ts.map +1 -0
- package/lib/ReadRedisHttp.js +15 -0
- package/lib/ReadRedisHttp.js.map +1 -0
- package/lib/ReadWriteRedis.d.ts +29 -0
- package/lib/ReadWriteRedis.d.ts.map +1 -0
- package/lib/ReadWriteRedis.js +3 -0
- package/lib/ReadWriteRedis.js.map +1 -0
- package/lib/ReadWriteRedisHttp.d.ts +11 -0
- package/lib/ReadWriteRedisHttp.d.ts.map +1 -0
- package/lib/ReadWriteRedisHttp.js +15 -0
- package/lib/ReadWriteRedisHttp.js.map +1 -0
- package/lib/Redis.d.ts +252 -0
- package/lib/Redis.d.ts.map +1 -0
- package/lib/Redis.js +608 -0
- package/lib/Redis.js.map +1 -0
- package/lib/RedisBinding.d.ts +7 -0
- package/lib/RedisBinding.d.ts.map +1 -0
- package/lib/RedisBinding.js +53 -0
- package/lib/RedisBinding.js.map +1 -0
- package/lib/RedisHttp.d.ts +8 -0
- package/lib/RedisHttp.d.ts.map +1 -0
- package/lib/RedisHttp.js +8 -0
- package/lib/RedisHttp.js.map +1 -0
- package/lib/Region.d.ts +16 -0
- package/lib/Region.d.ts.map +1 -0
- package/lib/Region.js +13 -0
- package/lib/Region.js.map +1 -0
- package/lib/Secret.d.ts +190 -0
- package/lib/Secret.d.ts.map +1 -0
- package/lib/Secret.js +310 -0
- package/lib/Secret.js.map +1 -0
- package/lib/SecretHttp.d.ts +54 -0
- package/lib/SecretHttp.d.ts.map +1 -0
- package/lib/SecretHttp.js +66 -0
- package/lib/SecretHttp.js.map +1 -0
- package/lib/SecretKey.d.ts +164 -0
- package/lib/SecretKey.d.ts.map +1 -0
- package/lib/SecretKey.js +277 -0
- package/lib/SecretKey.js.map +1 -0
- package/lib/SecretKeyHttp.d.ts +14 -0
- package/lib/SecretKeyHttp.d.ts.map +1 -0
- package/lib/SecretKeyHttp.js +5 -0
- package/lib/SecretKeyHttp.js.map +1 -0
- package/lib/Service.d.ts +1022 -0
- package/lib/Service.d.ts.map +1 -0
- package/lib/Service.js +1397 -0
- package/lib/Service.js.map +1 -0
- package/lib/Sign.d.ts +36 -0
- package/lib/Sign.d.ts.map +1 -0
- package/lib/Sign.js +3 -0
- package/lib/Sign.js.map +1 -0
- package/lib/SignHttp.d.ts +22 -0
- package/lib/SignHttp.d.ts.map +1 -0
- package/lib/SignHttp.js +36 -0
- package/lib/SignHttp.js.map +1 -0
- package/lib/Sprite.d.ts +283 -0
- package/lib/Sprite.d.ts.map +1 -0
- package/lib/Sprite.js +469 -0
- package/lib/Sprite.js.map +1 -0
- package/lib/SpriteHttp.d.ts +25 -0
- package/lib/SpriteHttp.d.ts.map +1 -0
- package/lib/SpriteHttp.js +33 -0
- package/lib/SpriteHttp.js.map +1 -0
- package/lib/Verify.d.ts +37 -0
- package/lib/Verify.d.ts.map +1 -0
- package/lib/Verify.js +3 -0
- package/lib/Verify.js.map +1 -0
- package/lib/VerifyHttp.d.ts +22 -0
- package/lib/VerifyHttp.d.ts.map +1 -0
- package/lib/VerifyHttp.js +38 -0
- package/lib/VerifyHttp.js.map +1 -0
- package/lib/Volume.d.ts +53 -0
- package/lib/Volume.d.ts.map +1 -0
- package/lib/Volume.js +188 -0
- package/lib/Volume.js.map +1 -0
- package/lib/VolumeSnapshot.d.ts +135 -0
- package/lib/VolumeSnapshot.d.ts.map +1 -0
- package/lib/VolumeSnapshot.js +213 -0
- package/lib/VolumeSnapshot.js.map +1 -0
- package/lib/Website/AssetDeployment.d.ts +43 -0
- package/lib/Website/AssetDeployment.d.ts.map +1 -0
- package/lib/Website/AssetDeployment.js +162 -0
- package/lib/Website/AssetDeployment.js.map +1 -0
- package/lib/Website/Astro.d.ts +87 -0
- package/lib/Website/Astro.d.ts.map +1 -0
- package/lib/Website/Astro.js +55 -0
- package/lib/Website/Astro.js.map +1 -0
- package/lib/Website/Foldkit.d.ts +52 -0
- package/lib/Website/Foldkit.d.ts.map +1 -0
- package/lib/Website/Foldkit.js +45 -0
- package/lib/Website/Foldkit.js.map +1 -0
- package/lib/Website/FrameworkSite.d.ts +175 -0
- package/lib/Website/FrameworkSite.d.ts.map +1 -0
- package/lib/Website/FrameworkSite.js +162 -0
- package/lib/Website/FrameworkSite.js.map +1 -0
- package/lib/Website/Nextjs.d.ts +54 -0
- package/lib/Website/Nextjs.d.ts.map +1 -0
- package/lib/Website/Nextjs.js +46 -0
- package/lib/Website/Nextjs.js.map +1 -0
- package/lib/Website/Nuxt.d.ts +51 -0
- package/lib/Website/Nuxt.d.ts.map +1 -0
- package/lib/Website/Nuxt.js +36 -0
- package/lib/Website/Nuxt.js.map +1 -0
- package/lib/Website/Octane.d.ts +49 -0
- package/lib/Website/Octane.d.ts.map +1 -0
- package/lib/Website/Octane.js +39 -0
- package/lib/Website/Octane.js.map +1 -0
- package/lib/Website/ReactRouter.d.ts +80 -0
- package/lib/Website/ReactRouter.d.ts.map +1 -0
- package/lib/Website/ReactRouter.js +70 -0
- package/lib/Website/ReactRouter.js.map +1 -0
- package/lib/Website/SolidStart.d.ts +93 -0
- package/lib/Website/SolidStart.d.ts.map +1 -0
- package/lib/Website/SolidStart.js +71 -0
- package/lib/Website/SolidStart.js.map +1 -0
- package/lib/Website/StaticSite.d.ts +155 -0
- package/lib/Website/StaticSite.d.ts.map +1 -0
- package/lib/Website/StaticSite.js +168 -0
- package/lib/Website/StaticSite.js.map +1 -0
- package/lib/Website/SvelteKit.d.ts +52 -0
- package/lib/Website/SvelteKit.d.ts.map +1 -0
- package/lib/Website/SvelteKit.js +37 -0
- package/lib/Website/SvelteKit.js.map +1 -0
- package/lib/Website/TanStackStart.d.ts +76 -0
- package/lib/Website/TanStackStart.d.ts.map +1 -0
- package/lib/Website/TanStackStart.js +66 -0
- package/lib/Website/TanStackStart.js.map +1 -0
- package/lib/Website/Vinext.d.ts +73 -0
- package/lib/Website/Vinext.d.ts.map +1 -0
- package/lib/Website/Vinext.js +67 -0
- package/lib/Website/Vinext.js.map +1 -0
- package/lib/Website/Vite.d.ts +103 -0
- package/lib/Website/Vite.d.ts.map +1 -0
- package/lib/Website/Vite.js +91 -0
- package/lib/Website/Vite.js.map +1 -0
- package/lib/Website/Vocs.d.ts +52 -0
- package/lib/Website/Vocs.d.ts.map +1 -0
- package/lib/Website/Vocs.js +38 -0
- package/lib/Website/Vocs.js.map +1 -0
- package/lib/Website/Waku.d.ts +64 -0
- package/lib/Website/Waku.d.ts.map +1 -0
- package/lib/Website/Waku.js +39 -0
- package/lib/Website/Waku.js.map +1 -0
- package/lib/Website/index.d.ts +17 -0
- package/lib/Website/index.d.ts.map +1 -0
- package/lib/Website/index.js +17 -0
- package/lib/Website/index.js.map +1 -0
- package/lib/WriteCertificates.d.ts +63 -0
- package/lib/WriteCertificates.d.ts.map +1 -0
- package/lib/WriteCertificates.js +3 -0
- package/lib/WriteCertificates.js.map +1 -0
- package/lib/WriteCertificatesHttp.d.ts +25 -0
- package/lib/WriteCertificatesHttp.d.ts.map +1 -0
- package/lib/WriteCertificatesHttp.js +67 -0
- package/lib/WriteCertificatesHttp.js.map +1 -0
- package/lib/WriteRedis.d.ts +26 -0
- package/lib/WriteRedis.d.ts.map +1 -0
- package/lib/WriteRedis.js +3 -0
- package/lib/WriteRedis.js.map +1 -0
- package/lib/WriteRedisHttp.d.ts +11 -0
- package/lib/WriteRedisHttp.d.ts.map +1 -0
- package/lib/WriteRedisHttp.js +15 -0
- package/lib/WriteRedisHttp.js.map +1 -0
- package/lib/WriteSecret.d.ts +68 -0
- package/lib/WriteSecret.d.ts.map +1 -0
- package/lib/WriteSecret.js +4 -0
- package/lib/WriteSecret.js.map +1 -0
- package/lib/WriteSecretHttp.d.ts +26 -0
- package/lib/WriteSecretHttp.d.ts.map +1 -0
- package/lib/WriteSecretHttp.js +54 -0
- package/lib/WriteSecretHttp.js.map +1 -0
- package/lib/bluegreen.d.ts +36 -0
- package/lib/bluegreen.d.ts.map +1 -0
- package/lib/bluegreen.js +458 -0
- package/lib/bluegreen.js.map +1 -0
- package/lib/hosted.d.ts +172 -0
- package/lib/hosted.d.ts.map +1 -0
- package/lib/hosted.js +458 -0
- package/lib/hosted.js.map +1 -0
- package/lib/index.d.ts +65 -0
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +63 -0
- package/lib/index.js.map +1 -0
- package/lib/internal/RemoteBuilder.d.ts +28 -0
- package/lib/internal/RemoteBuilder.d.ts.map +1 -0
- package/lib/internal/RemoteBuilder.js +145 -0
- package/lib/internal/RemoteBuilder.js.map +1 -0
- package/lib/leases.d.ts +53 -0
- package/lib/leases.d.ts.map +1 -0
- package/lib/leases.js +279 -0
- package/lib/leases.js.map +1 -0
- package/lib/ports.d.ts +51 -0
- package/lib/ports.d.ts.map +1 -0
- package/lib/ports.js +123 -0
- package/lib/ports.js.map +1 -0
- package/lib/replicas.d.ts +270 -0
- package/lib/replicas.d.ts.map +1 -0
- package/lib/replicas.js +969 -0
- package/lib/replicas.js.map +1 -0
- package/lib/rpc.d.ts +35 -0
- package/lib/rpc.d.ts.map +1 -0
- package/lib/rpc.js +113 -0
- package/lib/rpc.js.map +1 -0
- package/package.json +97 -3
- package/src/App.ts +516 -0
- package/src/AuthProvider.ts +68 -0
- package/src/BindService.ts +304 -0
- package/src/Bootstrap.ts +66 -0
- package/src/Bucket.ts +916 -0
- package/src/BucketBinding.ts +128 -0
- package/src/Catalog.ts +43 -0
- package/src/Certificate.ts +548 -0
- package/src/Checkpoint.ts +69 -0
- package/src/CheckpointHttp.ts +66 -0
- package/src/ConnectPostgres.ts +68 -0
- package/src/ConnectPostgresHttp.ts +77 -0
- package/src/Contributions.ts +9 -0
- package/src/Credentials.ts +102 -0
- package/src/Decrypt.ts +62 -0
- package/src/DecryptHttp.ts +52 -0
- package/src/DeleteObject.ts +43 -0
- package/src/DeleteObjectHttp.ts +20 -0
- package/src/Deployment.ts +121 -0
- package/src/DeploymentImages.ts +84 -0
- package/src/DeploymentState.ts +104 -0
- package/src/Encrypt.ts +60 -0
- package/src/EncryptHttp.ts +48 -0
- package/src/Environment.ts +81 -0
- package/src/Errors.ts +14 -0
- package/src/Exec.ts +50 -0
- package/src/ExecHttp.ts +47 -0
- package/src/GetObject.ts +48 -0
- package/src/GetObjectHttp.ts +20 -0
- package/src/GetSecret.ts +48 -0
- package/src/GetSecretHttp.ts +60 -0
- package/src/HeadObject.ts +43 -0
- package/src/HeadObjectHttp.ts +20 -0
- package/src/IpAssignment.ts +522 -0
- package/src/ListObjectsV2.ts +43 -0
- package/src/ListObjectsV2Http.ts +20 -0
- package/src/ListSecrets.ts +57 -0
- package/src/ListSecretsHttp.ts +43 -0
- package/src/Machine.ts +1268 -0
- package/src/MachineContainers.ts +152 -0
- package/src/Metadata.ts +195 -0
- package/src/MountVolume.ts +315 -0
- package/src/Postgres.ts +777 -0
- package/src/PostgresMigrations.ts +153 -0
- package/src/Providers.ts +155 -0
- package/src/PutObject.ts +49 -0
- package/src/PutObjectHttp.ts +20 -0
- package/src/ReadRedis.ts +31 -0
- package/src/ReadRedisHttp.ts +18 -0
- package/src/ReadWriteRedis.ts +33 -0
- package/src/ReadWriteRedisHttp.ts +18 -0
- package/src/Redis.ts +820 -0
- package/src/RedisBinding.ts +64 -0
- package/src/RedisHttp.ts +11 -0
- package/src/Region.ts +44 -0
- package/src/Secret.ts +405 -0
- package/src/SecretHttp.ts +149 -0
- package/src/SecretKey.ts +389 -0
- package/src/SecretKeyHttp.ts +23 -0
- package/src/Service.ts +1934 -0
- package/src/Sign.ts +46 -0
- package/src/SignHttp.ts +44 -0
- package/src/Sprite.ts +671 -0
- package/src/SpriteHttp.ts +50 -0
- package/src/Verify.ts +47 -0
- package/src/VerifyHttp.ts +46 -0
- package/src/Volume.ts +264 -0
- package/src/VolumeSnapshot.ts +321 -0
- package/src/Website/AssetDeployment.ts +294 -0
- package/src/Website/Astro.ts +87 -0
- package/src/Website/Foldkit.ts +54 -0
- package/src/Website/FrameworkSite.ts +363 -0
- package/src/Website/Nextjs.ts +50 -0
- package/src/Website/Nuxt.ts +48 -0
- package/src/Website/Octane.ts +44 -0
- package/src/Website/ReactRouter.ts +76 -0
- package/src/Website/SolidStart.ts +90 -0
- package/src/Website/StaticSite.ts +275 -0
- package/src/Website/SvelteKit.ts +49 -0
- package/src/Website/TanStackStart.ts +72 -0
- package/src/Website/Vinext.ts +79 -0
- package/src/Website/Vite.ts +112 -0
- package/src/Website/Vocs.ts +50 -0
- package/src/Website/Waku.ts +65 -0
- package/src/Website/index.ts +16 -0
- package/src/WriteCertificates.ts +90 -0
- package/src/WriteCertificatesHttp.ts +93 -0
- package/src/WriteRedis.ts +31 -0
- package/src/WriteRedisHttp.ts +18 -0
- package/src/WriteSecret.ts +86 -0
- package/src/WriteSecretHttp.ts +71 -0
- package/src/bluegreen.ts +708 -0
- package/src/globals.d.ts +2 -0
- package/src/hosted.ts +668 -0
- package/src/index.ts +64 -0
- package/src/internal/RemoteBuilder.ts +224 -0
- package/src/leases.ts +437 -0
- package/src/ports.ts +177 -0
- package/src/replicas.ts +1480 -0
- package/src/rpc.ts +136 -0
|
@@ -0,0 +1,522 @@
|
|
|
1
|
+
import type { IPAssignment as FlyIPAssignment } from "@distilled.cloud/fly-io/machines";
|
|
2
|
+
import * as machines from "@distilled.cloud/fly-io/machines";
|
|
3
|
+
import { isResolved } from "alchemy/Diff";
|
|
4
|
+
import * as Provider from "alchemy/Provider";
|
|
5
|
+
import { Resource } from "alchemy/Resource";
|
|
6
|
+
import * as Data from "effect/Data";
|
|
7
|
+
import * as Effect from "effect/Effect";
|
|
8
|
+
import * as Schedule from "effect/Schedule";
|
|
9
|
+
import { listOwnedApps } from "./App.ts";
|
|
10
|
+
import type { App } from "./App.ts";
|
|
11
|
+
import type { Providers } from "./Providers.ts";
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* A resource-valued prop: the resource itself, or an Effect that produces
|
|
15
|
+
* it (so `yield* App(...)` and `App(...)` both type-check).
|
|
16
|
+
*/
|
|
17
|
+
type Ref<T> = T | Effect.Effect<T, never, Providers>;
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Fly IP family allocated onto an App. Dedicated `v4` is billed and may
|
|
21
|
+
* be rejected when the org has no IPv4 quota. Prefer `v6` (free) or
|
|
22
|
+
* `shared_v4` (free) in tests. `private_v6` is a Flycast address: it is
|
|
23
|
+
* reachable only from the organization's private network.
|
|
24
|
+
*/
|
|
25
|
+
export type IpAssignmentType = "v4" | "v6" | "shared_v4" | "private_v6";
|
|
26
|
+
|
|
27
|
+
export interface IpAssignmentProps {
|
|
28
|
+
/**
|
|
29
|
+
* Parent Fly App. Accepts a `Fly.App` resource or an Effect that
|
|
30
|
+
* produces one. Changing the App replaces the assignment.
|
|
31
|
+
*/
|
|
32
|
+
app: Ref<App>;
|
|
33
|
+
/**
|
|
34
|
+
* Address family to allocate. `v6` is a dedicated IPv6 (free).
|
|
35
|
+
* `shared_v4` is a shared Anycast IPv4 (free). `v4` is a dedicated
|
|
36
|
+
* IPv4 (billed; may 400 when the org is over quota). `private_v6` is
|
|
37
|
+
* a Flycast IPv6 (free) that Fly's proxy serves only inside the
|
|
38
|
+
* private network. Changing type replaces the assignment.
|
|
39
|
+
*/
|
|
40
|
+
type: IpAssignmentType;
|
|
41
|
+
/**
|
|
42
|
+
* Region for a dedicated address. Changing it replaces the assignment.
|
|
43
|
+
*/
|
|
44
|
+
region?: string;
|
|
45
|
+
/**
|
|
46
|
+
* Private network a `private_v6` address is reachable from. Defaults
|
|
47
|
+
* to the organization's network. Create-only; changing it replaces.
|
|
48
|
+
*/
|
|
49
|
+
network?: string;
|
|
50
|
+
/**
|
|
51
|
+
* Organization slug. Defaults to the current token's org. Not a
|
|
52
|
+
* replacement key.
|
|
53
|
+
*/
|
|
54
|
+
orgSlug?: string;
|
|
55
|
+
/**
|
|
56
|
+
* Fly proxy service this address is bound to. Changing it replaces
|
|
57
|
+
* the assignment.
|
|
58
|
+
*/
|
|
59
|
+
serviceName?: string;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export type IpAssignment = Resource<
|
|
63
|
+
"Fly.IpAssignment",
|
|
64
|
+
IpAssignmentProps,
|
|
65
|
+
{
|
|
66
|
+
/** Physical Fly App name the address is assigned to. */
|
|
67
|
+
appName: string;
|
|
68
|
+
/** Allocated address. Identity of the assignment. */
|
|
69
|
+
ip: string;
|
|
70
|
+
/** Observed address family. */
|
|
71
|
+
type: IpAssignmentType;
|
|
72
|
+
/** Region for a dedicated address, if set. */
|
|
73
|
+
region: string | undefined;
|
|
74
|
+
/** Fly proxy service this address is bound to, if set. */
|
|
75
|
+
serviceName: string | undefined;
|
|
76
|
+
/** Whether the address is a shared Anycast IPv4. */
|
|
77
|
+
shared: boolean;
|
|
78
|
+
/**
|
|
79
|
+
* Named private network a `private_v6` address is reachable from.
|
|
80
|
+
* `undefined` for the organization's default network and for public
|
|
81
|
+
* addresses.
|
|
82
|
+
*/
|
|
83
|
+
network: string | undefined;
|
|
84
|
+
/** RFC3339 creation timestamp, if the API returned one. */
|
|
85
|
+
createdAt: string | undefined;
|
|
86
|
+
},
|
|
87
|
+
never,
|
|
88
|
+
Providers
|
|
89
|
+
>;
|
|
90
|
+
|
|
91
|
+
const resolveIpAssignmentProps = (
|
|
92
|
+
props: IpAssignmentProps | Effect.Effect<IpAssignmentProps, never, Providers>,
|
|
93
|
+
): Effect.Effect<IpAssignmentProps, never, Providers> =>
|
|
94
|
+
Effect.gen(function* () {
|
|
95
|
+
const resolved = Effect.isEffect(props) ? yield* props : props;
|
|
96
|
+
if (globalThis.__ALCHEMY_RUNTIME__) return resolved;
|
|
97
|
+
const app = Effect.isEffect(resolved.app)
|
|
98
|
+
? yield* resolved.app as Effect.Effect<App, never, Providers>
|
|
99
|
+
: resolved.app;
|
|
100
|
+
return { ...resolved, app };
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
const IpAssignmentResource = Resource<IpAssignment>("Fly.IpAssignment");
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* A Fly.IpAssignment is an address on an {@link App}. A {@link Service}
|
|
107
|
+
* publishes ports. Fly's proxy load-balances `{app}.fly.dev` across
|
|
108
|
+
* Machines that publish a proxy service.
|
|
109
|
+
*
|
|
110
|
+
* Identity is the allocated `ip`. There is no in-place update.
|
|
111
|
+
*
|
|
112
|
+
* @see https://fly.io/docs/networking/services/
|
|
113
|
+
*
|
|
114
|
+
* ### Shared IPv4
|
|
115
|
+
* `shared_v4` is a shared Anycast IPv4. It is free. This is what you
|
|
116
|
+
* want for fly.dev over IPv4. Yield it next to the Service.
|
|
117
|
+
*
|
|
118
|
+
* **Example:** Allocate shared_v4
|
|
119
|
+
* ```typescript
|
|
120
|
+
* export const PublicIp = Fly.IpAssignment("Shared", {
|
|
121
|
+
* app: Site,
|
|
122
|
+
* type: "shared_v4",
|
|
123
|
+
* });
|
|
124
|
+
* ```
|
|
125
|
+
*
|
|
126
|
+
* :::caution[Changing `type` or `app` replaces the assignment]
|
|
127
|
+
* A new address is allocated. The old one is released.
|
|
128
|
+
* :::
|
|
129
|
+
*
|
|
130
|
+
* ### Dedicated IPv6
|
|
131
|
+
* `v6` is a dedicated IPv6. It is free.
|
|
132
|
+
*
|
|
133
|
+
* **Example:** Allocate v6
|
|
134
|
+
* ```typescript
|
|
135
|
+
* export const V6 = Fly.IpAssignment("V6", {
|
|
136
|
+
* app: Site,
|
|
137
|
+
* type: "v6",
|
|
138
|
+
* });
|
|
139
|
+
* ```
|
|
140
|
+
*
|
|
141
|
+
* ### Dedicated IPv4
|
|
142
|
+
* `v4` is a billed dedicated IPv4. It may 400 if the org has no
|
|
143
|
+
* quota. Prefer `shared_v4` or `v6` in tests.
|
|
144
|
+
*
|
|
145
|
+
* **Example:** Allocate v4
|
|
146
|
+
* ```typescript
|
|
147
|
+
* export const Dedicated = Fly.IpAssignment("Dedicated", {
|
|
148
|
+
* app: Site,
|
|
149
|
+
* type: "v4",
|
|
150
|
+
* });
|
|
151
|
+
* ```
|
|
152
|
+
*
|
|
153
|
+
* ### Flycast (private IPv6)
|
|
154
|
+
* `private_v6` is a Flycast address. Fly's proxy serves it only inside
|
|
155
|
+
* the organization's private network, at `{app}.flycast`. It is free.
|
|
156
|
+
* Use it for a backend that another App calls and the internet must
|
|
157
|
+
* not reach. Requests still go through the proxy, so blue/green
|
|
158
|
+
* cordoning, `autostart`, and `autostop` keep working. Allocate no
|
|
159
|
+
* public address on the same App.
|
|
160
|
+
*
|
|
161
|
+
* **Example:** Allocate private_v6
|
|
162
|
+
* ```typescript
|
|
163
|
+
* export const Private = Fly.IpAssignment("Private", {
|
|
164
|
+
* app: Backend,
|
|
165
|
+
* type: "private_v6",
|
|
166
|
+
* });
|
|
167
|
+
* ```
|
|
168
|
+
*
|
|
169
|
+
* ### Region
|
|
170
|
+
* `region` pins a dedicated address. Shared Anycast ignores it. See
|
|
171
|
+
* [Regions](/fly/compute/regions) for the list of codes.
|
|
172
|
+
*
|
|
173
|
+
* **Example:** Dedicated IPv4 in iad
|
|
174
|
+
* ```typescript
|
|
175
|
+
* export const Dedicated = Fly.IpAssignment("Dedicated", {
|
|
176
|
+
* app: Site,
|
|
177
|
+
* type: "v4",
|
|
178
|
+
* region: "iad",
|
|
179
|
+
* });
|
|
180
|
+
* ```
|
|
181
|
+
*
|
|
182
|
+
* :::caution[Changing `region` replaces the assignment]
|
|
183
|
+
* A new address is allocated in the new region.
|
|
184
|
+
* :::
|
|
185
|
+
*
|
|
186
|
+
* ### Service name
|
|
187
|
+
* `serviceName` binds the address to a Fly proxy service. Changing it
|
|
188
|
+
* replaces the assignment.
|
|
189
|
+
*
|
|
190
|
+
* **Example:** Bind to a named service
|
|
191
|
+
* ```typescript
|
|
192
|
+
* export const PublicIp = Fly.IpAssignment("Shared", {
|
|
193
|
+
* app: Site,
|
|
194
|
+
* type: "shared_v4",
|
|
195
|
+
* serviceName: "http",
|
|
196
|
+
* });
|
|
197
|
+
* ```
|
|
198
|
+
*
|
|
199
|
+
* :::caution[Changing `serviceName` replaces the assignment]
|
|
200
|
+
* A new address is allocated bound to the new service.
|
|
201
|
+
* :::
|
|
202
|
+
*
|
|
203
|
+
* ### Isolated network
|
|
204
|
+
* `network` names the private network a `private_v6` address is
|
|
205
|
+
* reachable from. Create-only.
|
|
206
|
+
*
|
|
207
|
+
* **Example:** Custom network
|
|
208
|
+
* ```typescript
|
|
209
|
+
* export const Private = Fly.IpAssignment("Private", {
|
|
210
|
+
* app: Backend,
|
|
211
|
+
* type: "private_v6",
|
|
212
|
+
* network: "tenant-a",
|
|
213
|
+
* });
|
|
214
|
+
* ```
|
|
215
|
+
*
|
|
216
|
+
* :::caution[Changing `network` replaces the assignment]
|
|
217
|
+
* A new address is allocated on the new network.
|
|
218
|
+
* :::
|
|
219
|
+
*
|
|
220
|
+
* ### Organization
|
|
221
|
+
* `orgSlug` defaults to the current token's org. It is not a
|
|
222
|
+
* replacement key.
|
|
223
|
+
*
|
|
224
|
+
* **Example:** Pin an org
|
|
225
|
+
* ```typescript
|
|
226
|
+
* export const PublicIp = Fly.IpAssignment("Shared", {
|
|
227
|
+
* app: Site,
|
|
228
|
+
* type: "shared_v4",
|
|
229
|
+
* orgSlug: "my-org",
|
|
230
|
+
* });
|
|
231
|
+
* ```
|
|
232
|
+
*
|
|
233
|
+
* ### Yield with a Service
|
|
234
|
+
* Allocate the address on the same App as the Service. `api.url` is
|
|
235
|
+
* `https://{appName}.fly.dev`.
|
|
236
|
+
*
|
|
237
|
+
* **Example:** Stack outputs
|
|
238
|
+
* ```typescript
|
|
239
|
+
* export default Alchemy.Stack(
|
|
240
|
+
* "MyApp",
|
|
241
|
+
* { providers: Fly.providers(), state: Alchemy.localState() },
|
|
242
|
+
* Effect.gen(function* () {
|
|
243
|
+
* const api = yield* Api;
|
|
244
|
+
* const ip = yield* PublicIp;
|
|
245
|
+
* return { url: api.url, ip: ip.ip };
|
|
246
|
+
* }),
|
|
247
|
+
* );
|
|
248
|
+
* ```
|
|
249
|
+
*
|
|
250
|
+
* @resource
|
|
251
|
+
* @product App
|
|
252
|
+
*/
|
|
253
|
+
export const IpAssignment: typeof IpAssignmentResource = Object.assign(
|
|
254
|
+
(id: string, props: IpAssignmentProps | Effect.Effect<IpAssignmentProps, never, Providers>) =>
|
|
255
|
+
IpAssignmentResource(id, resolveIpAssignmentProps(props)),
|
|
256
|
+
IpAssignmentResource,
|
|
257
|
+
);
|
|
258
|
+
|
|
259
|
+
export class IpAssignmentNotCreated extends Data.TaggedError("Fly.IpAssignmentNotCreated")<{
|
|
260
|
+
appName: string;
|
|
261
|
+
type: IpAssignmentType;
|
|
262
|
+
}> {}
|
|
263
|
+
|
|
264
|
+
export class IpAssignmentAppMissing extends Data.TaggedError("Fly.IpAssignmentAppMissing")<{
|
|
265
|
+
type: IpAssignmentType;
|
|
266
|
+
}> {}
|
|
267
|
+
|
|
268
|
+
const appNameOf = (value: unknown): string | undefined => {
|
|
269
|
+
if (value === null || typeof value !== "object") return undefined;
|
|
270
|
+
const rec = value as { appName?: unknown; name?: unknown };
|
|
271
|
+
if (typeof rec.appName === "string" && rec.appName.length > 0) {
|
|
272
|
+
return rec.appName;
|
|
273
|
+
}
|
|
274
|
+
if (typeof rec.name === "string" && rec.name.length > 0) {
|
|
275
|
+
return rec.name;
|
|
276
|
+
}
|
|
277
|
+
return undefined;
|
|
278
|
+
};
|
|
279
|
+
|
|
280
|
+
const asType = (value: string | undefined): IpAssignmentType | undefined =>
|
|
281
|
+
value === "v4" || value === "v6" || value === "shared_v4" || value === "private_v6"
|
|
282
|
+
? value
|
|
283
|
+
: undefined;
|
|
284
|
+
|
|
285
|
+
/**
|
|
286
|
+
* Fly omits `type` from IP assignment responses. Only Flycast addresses carry
|
|
287
|
+
* a `network` (its name is empty for the organization's default network).
|
|
288
|
+
*/
|
|
289
|
+
const isFlycast = (assignment: FlyIPAssignment) =>
|
|
290
|
+
assignment.network !== undefined && assignment.network !== null;
|
|
291
|
+
|
|
292
|
+
const networkOf = (assignment: FlyIPAssignment) => assignment.network?.name || undefined;
|
|
293
|
+
|
|
294
|
+
const inferType = (assignment: FlyIPAssignment, fallback?: IpAssignmentType): IpAssignmentType => {
|
|
295
|
+
const wire = asType(assignment.type);
|
|
296
|
+
if (wire !== undefined) return wire;
|
|
297
|
+
if (assignment.shared === true) return "shared_v4";
|
|
298
|
+
if (isFlycast(assignment)) return "private_v6";
|
|
299
|
+
const ip = assignment.ip ?? "";
|
|
300
|
+
if (ip.includes(":")) return "v6";
|
|
301
|
+
if (fallback !== undefined) return fallback;
|
|
302
|
+
return ip.length > 0 ? "v4" : (fallback ?? "v4");
|
|
303
|
+
};
|
|
304
|
+
|
|
305
|
+
const toAttrs = (
|
|
306
|
+
appName: string,
|
|
307
|
+
assignment: FlyIPAssignment,
|
|
308
|
+
fallbackType?: IpAssignmentType,
|
|
309
|
+
): IpAssignment["Attributes"] => {
|
|
310
|
+
const type = inferType(assignment, fallbackType);
|
|
311
|
+
return {
|
|
312
|
+
appName,
|
|
313
|
+
ip: assignment.ip ?? "",
|
|
314
|
+
type,
|
|
315
|
+
region: assignment.region,
|
|
316
|
+
serviceName: assignment.service_name,
|
|
317
|
+
shared: type === "shared_v4" || assignment.shared === true,
|
|
318
|
+
network: networkOf(assignment),
|
|
319
|
+
createdAt: assignment.created_at,
|
|
320
|
+
};
|
|
321
|
+
};
|
|
322
|
+
|
|
323
|
+
const matchesDesired = (
|
|
324
|
+
assignment: FlyIPAssignment,
|
|
325
|
+
news: Pick<IpAssignmentProps, "type" | "region" | "serviceName" | "network">,
|
|
326
|
+
): boolean => {
|
|
327
|
+
if (inferType(assignment, news.type) !== news.type) return false;
|
|
328
|
+
if (news.type === "private_v6" && networkOf(assignment) !== news.network) return false;
|
|
329
|
+
if (news.region !== undefined && assignment.region !== news.region) {
|
|
330
|
+
return false;
|
|
331
|
+
}
|
|
332
|
+
if (news.serviceName !== undefined && assignment.service_name !== news.serviceName) {
|
|
333
|
+
return false;
|
|
334
|
+
}
|
|
335
|
+
return true;
|
|
336
|
+
};
|
|
337
|
+
|
|
338
|
+
const listAssignments = (appName: string) =>
|
|
339
|
+
machines.listAppIPAssignments({ app_name: appName }).pipe(
|
|
340
|
+
Effect.map((res) => res.ips ?? []),
|
|
341
|
+
Effect.catchTag(["NotFound", "Forbidden"], () => Effect.succeed([] as FlyIPAssignment[])),
|
|
342
|
+
);
|
|
343
|
+
|
|
344
|
+
const findByIp = (appName: string, ip: string) =>
|
|
345
|
+
listAssignments(appName).pipe(Effect.map((ips) => ips.find((item) => item.ip === ip)));
|
|
346
|
+
|
|
347
|
+
const findMatching = (
|
|
348
|
+
appName: string,
|
|
349
|
+
news: Pick<IpAssignmentProps, "type" | "region" | "serviceName" | "network">,
|
|
350
|
+
) =>
|
|
351
|
+
listAssignments(appName).pipe(
|
|
352
|
+
Effect.map((ips) => ips.find((item) => matchesDesired(item, news))),
|
|
353
|
+
);
|
|
354
|
+
|
|
355
|
+
const waitUntilGone = (appName: string, ip: string) =>
|
|
356
|
+
findByIp(appName, ip).pipe(
|
|
357
|
+
Effect.map((found) => found === undefined),
|
|
358
|
+
Effect.repeat({ schedule: Schedule.spaced("1 second"), until: (gone) => gone, times: 8 }),
|
|
359
|
+
);
|
|
360
|
+
|
|
361
|
+
/** Whether the App has any address reachable from the internet. */
|
|
362
|
+
export const hasPublicAddress = (appName: string) =>
|
|
363
|
+
listAssignments(appName).pipe(
|
|
364
|
+
Effect.map((ips) => ips.some((item) => inferType(item) !== "private_v6")),
|
|
365
|
+
);
|
|
366
|
+
|
|
367
|
+
/**
|
|
368
|
+
* Converge the addresses of an App a {@link Service} owns. Every owned App
|
|
369
|
+
* gets a Flycast address on its private network (the organization's
|
|
370
|
+
* default network when `network` is omitted). A public App also gets a
|
|
371
|
+
* shared IPv4 and an IPv6; a private one has every public address
|
|
372
|
+
* released. All three types are free.
|
|
373
|
+
*/
|
|
374
|
+
export const syncOwnedAppAddresses = Effect.fn(function* (
|
|
375
|
+
appName: string,
|
|
376
|
+
isPublic: boolean,
|
|
377
|
+
network?: string,
|
|
378
|
+
) {
|
|
379
|
+
const observed = yield* listAssignments(appName);
|
|
380
|
+
const isDesiredFlycast = (item: FlyIPAssignment) =>
|
|
381
|
+
inferType(item) === "private_v6" && networkOf(item) === network;
|
|
382
|
+
if (!observed.some(isDesiredFlycast)) {
|
|
383
|
+
yield* machines
|
|
384
|
+
.createAppIPAssignment({ app_name: appName, type: "private_v6", network })
|
|
385
|
+
.pipe(Effect.catchTag("Conflict", () => Effect.succeed(undefined)));
|
|
386
|
+
}
|
|
387
|
+
if (isPublic) {
|
|
388
|
+
for (const type of ["shared_v4", "v6"] as const) {
|
|
389
|
+
if (observed.some((item) => inferType(item) === type)) continue;
|
|
390
|
+
yield* machines
|
|
391
|
+
.createAppIPAssignment({ app_name: appName, type })
|
|
392
|
+
.pipe(Effect.catchTag("Conflict", () => Effect.succeed(undefined)));
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
// Release public addresses of a private Service and Flycast addresses
|
|
396
|
+
// on any other network.
|
|
397
|
+
for (const item of observed) {
|
|
398
|
+
if (item.ip === undefined || isDesiredFlycast(item)) continue;
|
|
399
|
+
if (isPublic && inferType(item) !== "private_v6") continue;
|
|
400
|
+
yield* machines
|
|
401
|
+
.deleteAppIPAssignment({ app_name: appName, ip: item.ip })
|
|
402
|
+
.pipe(Effect.catchTag("NotFound", () => Effect.void));
|
|
403
|
+
yield* waitUntilGone(appName, item.ip);
|
|
404
|
+
}
|
|
405
|
+
});
|
|
406
|
+
|
|
407
|
+
/**
|
|
408
|
+
* Add a Flycast address on `network` to an App a {@link Service} shares,
|
|
409
|
+
* so bound callers can reach it. Only ever adds; the address is removed
|
|
410
|
+
* with the App.
|
|
411
|
+
*/
|
|
412
|
+
export const ensureFlycastAddress = Effect.fn(function* (appName: string, network?: string) {
|
|
413
|
+
const observed = yield* listAssignments(appName);
|
|
414
|
+
if (observed.some((item) => inferType(item) === "private_v6" && networkOf(item) === network))
|
|
415
|
+
return;
|
|
416
|
+
yield* machines
|
|
417
|
+
.createAppIPAssignment({ app_name: appName, type: "private_v6", network })
|
|
418
|
+
.pipe(Effect.catchTag("Conflict", () => Effect.succeed(undefined)));
|
|
419
|
+
});
|
|
420
|
+
|
|
421
|
+
export const IpAssignmentProvider = () =>
|
|
422
|
+
Provider.succeed(IpAssignment, {
|
|
423
|
+
stables: ["ip", "appName", "type", "region"],
|
|
424
|
+
nuke: { dependsOn: ["Fly.App"] },
|
|
425
|
+
|
|
426
|
+
diff: Effect.fn(function* ({ news, olds, output }) {
|
|
427
|
+
if (news === undefined || !isResolved(news)) return undefined;
|
|
428
|
+
if (output === undefined) return undefined;
|
|
429
|
+
const appName = appNameOf(news.app);
|
|
430
|
+
const appChanged = appName !== undefined && appName !== output.appName;
|
|
431
|
+
const typeChanged = news.type !== output.type;
|
|
432
|
+
const regionChanged = news.region !== undefined && news.region !== output.region;
|
|
433
|
+
const serviceChanged =
|
|
434
|
+
news.serviceName !== undefined && news.serviceName !== output.serviceName;
|
|
435
|
+
const networkChanged = news.network !== (olds !== undefined ? olds.network : output.network);
|
|
436
|
+
if (appChanged || typeChanged || regionChanged || serviceChanged || networkChanged) {
|
|
437
|
+
return { action: "replace" as const };
|
|
438
|
+
}
|
|
439
|
+
return undefined;
|
|
440
|
+
}),
|
|
441
|
+
|
|
442
|
+
read: Effect.fn(function* ({ olds, output }) {
|
|
443
|
+
const appName = output?.appName ?? appNameOf(olds?.app);
|
|
444
|
+
if (appName === undefined) return undefined;
|
|
445
|
+
const found =
|
|
446
|
+
output?.ip !== undefined && output.ip.length > 0
|
|
447
|
+
? yield* findByIp(appName, output.ip)
|
|
448
|
+
: olds !== undefined
|
|
449
|
+
? yield* findMatching(appName, olds)
|
|
450
|
+
: undefined;
|
|
451
|
+
if (found === undefined || found.ip === undefined) return undefined;
|
|
452
|
+
return toAttrs(appName, found, output?.type ?? olds?.type);
|
|
453
|
+
}),
|
|
454
|
+
|
|
455
|
+
list: Effect.fn(function* () {
|
|
456
|
+
const apps = yield* listOwnedApps();
|
|
457
|
+
const rows = yield* Effect.forEach(
|
|
458
|
+
apps,
|
|
459
|
+
(app) =>
|
|
460
|
+
listAssignments(app.appName).pipe(
|
|
461
|
+
Effect.map((ips) =>
|
|
462
|
+
ips
|
|
463
|
+
.filter((item) => item.ip !== undefined && item.ip.length > 0)
|
|
464
|
+
.map((item) => toAttrs(app.appName, item)),
|
|
465
|
+
),
|
|
466
|
+
),
|
|
467
|
+
{ concurrency: 8 },
|
|
468
|
+
);
|
|
469
|
+
return rows.flat();
|
|
470
|
+
}),
|
|
471
|
+
|
|
472
|
+
reconcile: Effect.fn(function* ({ news, output }) {
|
|
473
|
+
const props = news ?? ({} as IpAssignmentProps);
|
|
474
|
+
const appName = appNameOf(props.app) ?? output?.appName;
|
|
475
|
+
if (appName === undefined) {
|
|
476
|
+
return yield* new IpAssignmentAppMissing({ type: props.type });
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
// Observe by cached ip, then by desired type/region/service.
|
|
480
|
+
let current =
|
|
481
|
+
output?.ip !== undefined && output.ip.length > 0
|
|
482
|
+
? yield* findByIp(appName, output.ip)
|
|
483
|
+
: undefined;
|
|
484
|
+
if (current === undefined) {
|
|
485
|
+
current = yield* findMatching(appName, props);
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
if (current === undefined) {
|
|
489
|
+
const created = yield* machines
|
|
490
|
+
.createAppIPAssignment({
|
|
491
|
+
app_name: appName,
|
|
492
|
+
type: props.type,
|
|
493
|
+
region: props.region,
|
|
494
|
+
network: props.network,
|
|
495
|
+
org_slug: props.orgSlug,
|
|
496
|
+
service_name: props.serviceName,
|
|
497
|
+
})
|
|
498
|
+
.pipe(Effect.catchTag("Conflict", () => Effect.succeed(undefined)));
|
|
499
|
+
if (created !== undefined && created.ip !== undefined) {
|
|
500
|
+
current = created;
|
|
501
|
+
} else {
|
|
502
|
+
current = yield* findMatching(appName, props);
|
|
503
|
+
}
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
if (current === undefined || current.ip === undefined) {
|
|
507
|
+
return yield* new IpAssignmentNotCreated({ appName, type: props.type });
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
return toAttrs(appName, current, props.type);
|
|
511
|
+
}),
|
|
512
|
+
|
|
513
|
+
delete: Effect.fn(function* ({ output }) {
|
|
514
|
+
const appName = output.appName;
|
|
515
|
+
const ip = output.ip;
|
|
516
|
+
if (appName.length === 0 || ip.length === 0) return;
|
|
517
|
+
yield* machines
|
|
518
|
+
.deleteAppIPAssignment({ app_name: appName, ip })
|
|
519
|
+
.pipe(Effect.catchTag("NotFound", () => Effect.void));
|
|
520
|
+
yield* waitUntilGone(appName, ip);
|
|
521
|
+
}),
|
|
522
|
+
});
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import type * as S3 from "@distilled.cloud/aws/s3";
|
|
2
|
+
import * as Binding from "alchemy/Binding";
|
|
3
|
+
import type { RuntimeContext } from "alchemy/RuntimeContext";
|
|
4
|
+
import type * as Effect from "effect/Effect";
|
|
5
|
+
import type { Bucket } from "./Bucket.ts";
|
|
6
|
+
import type { TigrisCredentialsMissing } from "./Errors.ts";
|
|
7
|
+
|
|
8
|
+
export interface ListObjectsV2Request extends Omit<S3.ListObjectsV2Request, "Bucket"> {}
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Runtime binding for Tigris `ListObjectsV2` over the S3 API.
|
|
12
|
+
*
|
|
13
|
+
* Bind this operation to a {@link Bucket} in Service init. Provide
|
|
14
|
+
* {@link ListObjectsV2Http}.
|
|
15
|
+
*
|
|
16
|
+
*
|
|
17
|
+
* ### Listing Objects
|
|
18
|
+
* **Example:** List Objects Under a Prefix
|
|
19
|
+
* ```typescript
|
|
20
|
+
* const listObjects = yield* Fly.ListObjectsV2(Data);
|
|
21
|
+
* const result = yield* listObjects({ Prefix: "jobs/", MaxKeys: 100 });
|
|
22
|
+
* ```
|
|
23
|
+
*
|
|
24
|
+
* @binding
|
|
25
|
+
* @product Bucket
|
|
26
|
+
*/
|
|
27
|
+
export interface ListObjectsV2 extends Binding.Service<
|
|
28
|
+
ListObjectsV2,
|
|
29
|
+
"Fly.ListObjectsV2",
|
|
30
|
+
(
|
|
31
|
+
bucket: Bucket,
|
|
32
|
+
) => Effect.Effect<
|
|
33
|
+
(
|
|
34
|
+
request?: ListObjectsV2Request,
|
|
35
|
+
) => Effect.Effect<
|
|
36
|
+
S3.ListObjectsV2Output,
|
|
37
|
+
S3.ListObjectsV2Error | TigrisCredentialsMissing,
|
|
38
|
+
RuntimeContext
|
|
39
|
+
>
|
|
40
|
+
>
|
|
41
|
+
> {}
|
|
42
|
+
|
|
43
|
+
export const ListObjectsV2 = Binding.Service<ListObjectsV2>("Fly.ListObjectsV2");
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import * as S3 from "@distilled.cloud/aws/s3";
|
|
2
|
+
import * as Layer from "effect/Layer";
|
|
3
|
+
import { makeTigrisS3Binding } from "./BucketBinding.ts";
|
|
4
|
+
import { ListObjectsV2 } from "./ListObjectsV2.ts";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* HTTP implementation of {@link ListObjectsV2}. Calls distilled S3
|
|
8
|
+
* `listObjectsV2` against the Tigris endpoint with the bucket's credentials.
|
|
9
|
+
*
|
|
10
|
+
* @layer
|
|
11
|
+
* @product Bucket
|
|
12
|
+
* @provides Fly.ListObjectsV2
|
|
13
|
+
*/
|
|
14
|
+
export const ListObjectsV2Http = Layer.effect(
|
|
15
|
+
ListObjectsV2,
|
|
16
|
+
makeTigrisS3Binding({
|
|
17
|
+
tag: "Fly.ListObjectsV2",
|
|
18
|
+
operation: S3.listObjectsV2,
|
|
19
|
+
}),
|
|
20
|
+
);
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import type { AppSecrets, ListSecretsError } from "@distilled.cloud/fly-io/machines";
|
|
2
|
+
import * as Binding from "alchemy/Binding";
|
|
3
|
+
import type { RuntimeContext } from "alchemy/RuntimeContext";
|
|
4
|
+
import type * as Effect from "effect/Effect";
|
|
5
|
+
import type { App } from "./App.ts";
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* List Fly.io App secrets. Scoped to an {@link App}. Fly's list API
|
|
9
|
+
* is `GET /apps/{app}/secrets`, not a single Secret.
|
|
10
|
+
*
|
|
11
|
+
*
|
|
12
|
+
* ### List this App
|
|
13
|
+
* The App is fixed by `ListSecrets(app)`. Calls take no `app_name`.
|
|
14
|
+
* Provide {@link ListSecretsHttp}.
|
|
15
|
+
*
|
|
16
|
+
* Plaintext is only returned from inside a Machine in the same App.
|
|
17
|
+
* From a deploy-time Action you get metadata (name, digest,
|
|
18
|
+
* timestamps).
|
|
19
|
+
*
|
|
20
|
+
* **Example:** ListSecrets
|
|
21
|
+
* ```typescript
|
|
22
|
+
* const list = yield* Fly.ListSecrets(Site);
|
|
23
|
+
* const { secrets } = yield* list();
|
|
24
|
+
* ```
|
|
25
|
+
*
|
|
26
|
+
* ### List another App
|
|
27
|
+
* From an Action, the org `FLY_API_TOKEN` can list any App in the
|
|
28
|
+
* org. `ListSecrets(other)` is how you reach across Apps.
|
|
29
|
+
*
|
|
30
|
+
* From a Machine, deploy tokens are per-App. Mixing Apps on one host
|
|
31
|
+
* shares one `FLY_API_TOKEN` and is not supported.
|
|
32
|
+
*
|
|
33
|
+
* **Example:** Cross-app from an Action
|
|
34
|
+
* ```typescript
|
|
35
|
+
* const Seed = Alchemy.Action(
|
|
36
|
+
* "Seed",
|
|
37
|
+
* Effect.gen(function* () {
|
|
38
|
+
* const list = yield* Fly.ListSecrets(Other);
|
|
39
|
+
*
|
|
40
|
+
* return Effect.fn(function* () {
|
|
41
|
+
* const { secrets } = yield* list();
|
|
42
|
+
* return secrets;
|
|
43
|
+
* });
|
|
44
|
+
* }).pipe(Effect.provide(Fly.ListSecretsHttp)),
|
|
45
|
+
* );
|
|
46
|
+
* ```
|
|
47
|
+
*
|
|
48
|
+
* @binding
|
|
49
|
+
* @product Secret
|
|
50
|
+
*/
|
|
51
|
+
export interface ListSecrets extends Binding.Service<
|
|
52
|
+
ListSecrets,
|
|
53
|
+
"Fly.ListSecrets",
|
|
54
|
+
(app: App) => Effect.Effect<() => Effect.Effect<AppSecrets, ListSecretsError, RuntimeContext>>
|
|
55
|
+
> {}
|
|
56
|
+
|
|
57
|
+
export const ListSecrets = Binding.Service<ListSecrets>("Fly.ListSecrets");
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import * as machines from "@distilled.cloud/fly-io/machines";
|
|
2
|
+
import * as Effect from "effect/Effect";
|
|
3
|
+
import * as FetchHttpClient from "effect/http/FetchHttpClient";
|
|
4
|
+
import * as Layer from "effect/Layer";
|
|
5
|
+
import { CredentialsFromAmbientOrEnv } from "./Credentials.ts";
|
|
6
|
+
import { ListSecrets } from "./ListSecrets.ts";
|
|
7
|
+
import { makeHttpAppBinding } from "./SecretHttp.ts";
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* HTTP implementation of {@link ListSecrets}. Provide it on the
|
|
11
|
+
* {@link Service} or Action Effect.
|
|
12
|
+
*
|
|
13
|
+
*
|
|
14
|
+
* ### Provide the layer
|
|
15
|
+
* **Example:** On an Action
|
|
16
|
+
* ```typescript
|
|
17
|
+
* Effect.gen(function* () {
|
|
18
|
+
* const list = yield* Fly.ListSecrets(Site);
|
|
19
|
+
* // ...
|
|
20
|
+
* }).pipe(Effect.provide(Fly.ListSecretsHttp))
|
|
21
|
+
* ```
|
|
22
|
+
*
|
|
23
|
+
* @layer
|
|
24
|
+
* @product Secret
|
|
25
|
+
* @provides Fly.ListSecrets
|
|
26
|
+
*/
|
|
27
|
+
export const ListSecretsHttp = Layer.effect(
|
|
28
|
+
ListSecrets,
|
|
29
|
+
Effect.suspend(() =>
|
|
30
|
+
makeHttpAppBinding({
|
|
31
|
+
makeClient: (auth, appName) =>
|
|
32
|
+
Effect.fn("Fly.ListSecrets")(function* () {
|
|
33
|
+
return yield* auth.authorize(
|
|
34
|
+
machines.listSecrets({
|
|
35
|
+
app_name: yield* appName,
|
|
36
|
+
// Names are enough for the binding; plaintext is env-injected.
|
|
37
|
+
show_secrets: false,
|
|
38
|
+
}),
|
|
39
|
+
);
|
|
40
|
+
}),
|
|
41
|
+
}),
|
|
42
|
+
),
|
|
43
|
+
).pipe(Layer.provide(FetchHttpClient.layer), Layer.provide(CredentialsFromAmbientOrEnv));
|