@alchemy.run/fly 2.0.0-beta.84 → 2.0.0-beta.86
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/lib/App.d.ts +27 -5
- package/lib/App.d.ts.map +1 -1
- package/lib/App.js +29 -8
- package/lib/App.js.map +1 -1
- package/lib/AuthProvider.d.ts +1 -1
- package/lib/AuthProvider.d.ts.map +1 -1
- package/lib/AuthProvider.js.map +1 -1
- package/lib/BindService.d.ts +7 -7
- package/lib/BindService.d.ts.map +1 -1
- package/lib/BindService.js +21 -28
- package/lib/BindService.js.map +1 -1
- package/lib/Bootstrap.d.ts.map +1 -1
- package/lib/Bootstrap.js +2 -1
- package/lib/Bootstrap.js.map +1 -1
- package/lib/Bucket.d.ts +38 -4
- package/lib/Bucket.d.ts.map +1 -1
- package/lib/Bucket.js +190 -37
- package/lib/Bucket.js.map +1 -1
- package/lib/BucketBinding.d.ts.map +1 -1
- package/lib/BucketBinding.js +1 -1
- package/lib/BucketBinding.js.map +1 -1
- package/lib/Catalog.d.ts.map +1 -1
- package/lib/Catalog.js.map +1 -1
- package/lib/Certificate.d.ts +25 -1
- package/lib/Certificate.d.ts.map +1 -1
- package/lib/Certificate.js +22 -4
- package/lib/Certificate.js.map +1 -1
- package/lib/Checkpoint.d.ts.map +1 -1
- package/lib/Checkpoint.js.map +1 -1
- package/lib/CheckpointHttp.d.ts.map +1 -1
- package/lib/CheckpointHttp.js.map +1 -1
- package/lib/ConnectPostgres.d.ts +1 -1
- package/lib/ConnectPostgres.d.ts.map +1 -1
- package/lib/ConnectPostgres.js.map +1 -1
- package/lib/ConnectPostgresHttp.d.ts.map +1 -1
- package/lib/ConnectPostgresHttp.js +1 -1
- package/lib/ConnectPostgresHttp.js.map +1 -1
- package/lib/Contributions.d.ts +1 -1
- package/lib/Contributions.d.ts.map +1 -1
- package/lib/Contributions.js.map +1 -1
- package/lib/Credentials.d.ts +5 -4
- package/lib/Credentials.d.ts.map +1 -1
- package/lib/Credentials.js +18 -18
- package/lib/Credentials.js.map +1 -1
- package/lib/Decrypt.d.ts.map +1 -1
- package/lib/Decrypt.js.map +1 -1
- package/lib/DecryptHttp.d.ts.map +1 -1
- package/lib/DecryptHttp.js.map +1 -1
- package/lib/DeleteObject.d.ts.map +1 -1
- package/lib/DeleteObject.js.map +1 -1
- package/lib/DeleteObjectHttp.d.ts.map +1 -1
- package/lib/DeleteObjectHttp.js.map +1 -1
- package/lib/Deployment.d.ts.map +1 -1
- package/lib/Deployment.js.map +1 -1
- package/lib/DeploymentImages.d.ts.map +1 -1
- package/lib/DeploymentImages.js +1 -1
- package/lib/DeploymentImages.js.map +1 -1
- package/lib/DeploymentState.d.ts.map +1 -1
- package/lib/DeploymentState.js.map +1 -1
- package/lib/Encrypt.d.ts.map +1 -1
- package/lib/Encrypt.js.map +1 -1
- package/lib/EncryptHttp.d.ts.map +1 -1
- package/lib/EncryptHttp.js.map +1 -1
- package/lib/Environment.d.ts.map +1 -1
- package/lib/Environment.js.map +1 -1
- package/lib/Errors.d.ts +1 -1
- package/lib/Errors.d.ts.map +1 -1
- package/lib/Errors.js.map +1 -1
- package/lib/Exec.d.ts.map +1 -1
- package/lib/Exec.js.map +1 -1
- package/lib/ExecHttp.d.ts.map +1 -1
- package/lib/ExecHttp.js.map +1 -1
- package/lib/GetObject.d.ts.map +1 -1
- package/lib/GetObject.js.map +1 -1
- package/lib/GetObjectHttp.d.ts.map +1 -1
- package/lib/GetObjectHttp.js.map +1 -1
- package/lib/GetSecret.d.ts.map +1 -1
- package/lib/GetSecret.js.map +1 -1
- package/lib/GetSecretHttp.d.ts.map +1 -1
- package/lib/GetSecretHttp.js.map +1 -1
- package/lib/HeadObject.d.ts.map +1 -1
- package/lib/HeadObject.js.map +1 -1
- package/lib/HeadObjectHttp.d.ts.map +1 -1
- package/lib/HeadObjectHttp.js.map +1 -1
- package/lib/IpAssignment.d.ts +24 -1
- package/lib/IpAssignment.d.ts.map +1 -1
- package/lib/IpAssignment.js +21 -4
- package/lib/IpAssignment.js.map +1 -1
- package/lib/ListObjectsV2.d.ts.map +1 -1
- package/lib/ListObjectsV2.js.map +1 -1
- package/lib/ListObjectsV2Http.d.ts.map +1 -1
- package/lib/ListObjectsV2Http.js.map +1 -1
- package/lib/ListSecrets.d.ts.map +1 -1
- package/lib/ListSecrets.js.map +1 -1
- package/lib/ListSecretsHttp.d.ts.map +1 -1
- package/lib/ListSecretsHttp.js.map +1 -1
- package/lib/Machine.d.ts +27 -2
- package/lib/Machine.d.ts.map +1 -1
- package/lib/Machine.js +18 -3
- package/lib/Machine.js.map +1 -1
- package/lib/MachineContainers.d.ts.map +1 -1
- package/lib/MachineContainers.js.map +1 -1
- package/lib/Metadata.d.ts.map +1 -1
- package/lib/Metadata.js.map +1 -1
- package/lib/MountVolume.d.ts +7 -2
- package/lib/MountVolume.d.ts.map +1 -1
- package/lib/MountVolume.js.map +1 -1
- package/lib/Postgres.d.ts +34 -2
- package/lib/Postgres.d.ts.map +1 -1
- package/lib/Postgres.js +26 -6
- package/lib/Postgres.js.map +1 -1
- package/lib/PostgresMigrations.d.ts +7 -22
- package/lib/PostgresMigrations.d.ts.map +1 -1
- package/lib/PostgresMigrations.js +37 -89
- package/lib/PostgresMigrations.js.map +1 -1
- package/lib/Providers.d.ts +1 -1
- package/lib/Providers.d.ts.map +1 -1
- package/lib/Providers.js.map +1 -1
- package/lib/PutObject.d.ts.map +1 -1
- package/lib/PutObject.js.map +1 -1
- package/lib/PutObjectHttp.d.ts.map +1 -1
- package/lib/PutObjectHttp.js.map +1 -1
- package/lib/ReadRedis.d.ts.map +1 -1
- package/lib/ReadRedis.js.map +1 -1
- package/lib/ReadRedisHttp.d.ts.map +1 -1
- package/lib/ReadRedisHttp.js.map +1 -1
- package/lib/ReadWriteRedis.d.ts.map +1 -1
- package/lib/ReadWriteRedis.js.map +1 -1
- package/lib/ReadWriteRedisHttp.d.ts.map +1 -1
- package/lib/ReadWriteRedisHttp.js.map +1 -1
- package/lib/Redis.d.ts +23 -3
- package/lib/Redis.d.ts.map +1 -1
- package/lib/Redis.js +37 -6
- package/lib/Redis.js.map +1 -1
- package/lib/RedisBinding.d.ts.map +1 -1
- package/lib/RedisBinding.js +1 -1
- package/lib/RedisBinding.js.map +1 -1
- package/lib/RedisHttp.d.ts +1 -1
- package/lib/RedisHttp.d.ts.map +1 -1
- package/lib/RedisHttp.js +4 -1
- package/lib/RedisHttp.js.map +1 -1
- package/lib/Region.d.ts.map +1 -1
- package/lib/Region.js.map +1 -1
- package/lib/Secret.d.ts +23 -2
- package/lib/Secret.d.ts.map +1 -1
- package/lib/Secret.js +17 -2
- package/lib/Secret.js.map +1 -1
- package/lib/SecretHttp.d.ts.map +1 -1
- package/lib/SecretHttp.js.map +1 -1
- package/lib/SecretKey.d.ts +23 -2
- package/lib/SecretKey.d.ts.map +1 -1
- package/lib/SecretKey.js +17 -2
- package/lib/SecretKey.js.map +1 -1
- package/lib/SecretKeyHttp.d.ts.map +1 -1
- package/lib/SecretKeyHttp.js.map +1 -1
- package/lib/Service.d.ts +104 -34
- package/lib/Service.d.ts.map +1 -1
- package/lib/Service.js +301 -54
- package/lib/Service.js.map +1 -1
- package/lib/Sign.d.ts.map +1 -1
- package/lib/Sign.js.map +1 -1
- package/lib/SignHttp.d.ts.map +1 -1
- package/lib/SignHttp.js.map +1 -1
- package/lib/Sprite.d.ts +24 -5
- package/lib/Sprite.d.ts.map +1 -1
- package/lib/Sprite.js +22 -5
- package/lib/Sprite.js.map +1 -1
- package/lib/SpriteHttp.d.ts.map +1 -1
- package/lib/SpriteHttp.js.map +1 -1
- package/lib/Verify.d.ts.map +1 -1
- package/lib/Verify.js.map +1 -1
- package/lib/VerifyHttp.d.ts.map +1 -1
- package/lib/VerifyHttp.js.map +1 -1
- package/lib/Volume.d.ts +4 -4
- package/lib/Volume.d.ts.map +1 -1
- package/lib/Volume.js +21 -5
- package/lib/Volume.js.map +1 -1
- package/lib/VolumeSnapshot.d.ts +32 -1
- package/lib/VolumeSnapshot.d.ts.map +1 -1
- package/lib/VolumeSnapshot.js +24 -1
- package/lib/VolumeSnapshot.js.map +1 -1
- package/lib/Website/AssetDeployment.d.ts.map +1 -1
- package/lib/Website/AssetDeployment.js +9 -9
- package/lib/Website/AssetDeployment.js.map +1 -1
- package/lib/Website/Astro.d.ts +8 -6
- package/lib/Website/Astro.d.ts.map +1 -1
- package/lib/Website/Astro.js +12 -13
- package/lib/Website/Astro.js.map +1 -1
- package/lib/Website/Foldkit.d.ts.map +1 -1
- package/lib/Website/Foldkit.js.map +1 -1
- package/lib/Website/FrameworkSite.d.ts +39 -2
- package/lib/Website/FrameworkSite.d.ts.map +1 -1
- package/lib/Website/FrameworkSite.js +46 -3
- package/lib/Website/FrameworkSite.js.map +1 -1
- package/lib/Website/Nextjs.d.ts.map +1 -1
- package/lib/Website/Nextjs.js.map +1 -1
- package/lib/Website/Nuxt.d.ts.map +1 -1
- package/lib/Website/Nuxt.js.map +1 -1
- package/lib/Website/Octane.d.ts.map +1 -1
- package/lib/Website/Octane.js.map +1 -1
- package/lib/Website/ReactRouter.d.ts.map +1 -1
- package/lib/Website/ReactRouter.js.map +1 -1
- package/lib/Website/SolidStart.d.ts.map +1 -1
- package/lib/Website/SolidStart.js.map +1 -1
- package/lib/Website/StaticSite.d.ts +10 -3
- package/lib/Website/StaticSite.d.ts.map +1 -1
- package/lib/Website/StaticSite.js +16 -4
- package/lib/Website/StaticSite.js.map +1 -1
- package/lib/Website/SvelteKit.d.ts.map +1 -1
- package/lib/Website/SvelteKit.js.map +1 -1
- package/lib/Website/TanStackStart.d.ts.map +1 -1
- package/lib/Website/TanStackStart.js.map +1 -1
- package/lib/Website/Vinext.d.ts.map +1 -1
- package/lib/Website/Vinext.js.map +1 -1
- package/lib/Website/Vite.d.ts +9 -0
- package/lib/Website/Vite.d.ts.map +1 -1
- package/lib/Website/Vite.js +9 -0
- package/lib/Website/Vite.js.map +1 -1
- package/lib/Website/Vocs.d.ts.map +1 -1
- package/lib/Website/Vocs.js.map +1 -1
- package/lib/Website/Waku.d.ts.map +1 -1
- package/lib/Website/Waku.js.map +1 -1
- package/lib/Website/index.d.ts.map +1 -1
- package/lib/Website/index.js.map +1 -1
- package/lib/WriteCertificates.d.ts.map +1 -1
- package/lib/WriteCertificates.js.map +1 -1
- package/lib/WriteCertificatesHttp.d.ts.map +1 -1
- package/lib/WriteCertificatesHttp.js +2 -2
- package/lib/WriteCertificatesHttp.js.map +1 -1
- package/lib/WriteRedis.d.ts.map +1 -1
- package/lib/WriteRedis.js.map +1 -1
- package/lib/WriteRedisHttp.d.ts.map +1 -1
- package/lib/WriteRedisHttp.js.map +1 -1
- package/lib/WriteSecret.d.ts.map +1 -1
- package/lib/WriteSecret.js.map +1 -1
- package/lib/WriteSecretHttp.d.ts.map +1 -1
- package/lib/WriteSecretHttp.js.map +1 -1
- package/lib/bluegreen.d.ts +5 -4
- package/lib/bluegreen.d.ts.map +1 -1
- package/lib/bluegreen.js +7 -5
- package/lib/bluegreen.js.map +1 -1
- package/lib/hosted.d.ts +19 -4
- package/lib/hosted.d.ts.map +1 -1
- package/lib/hosted.js +101 -11
- package/lib/hosted.js.map +1 -1
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js.map +1 -1
- package/lib/internal/Oidc.d.ts +15 -0
- package/lib/internal/Oidc.d.ts.map +1 -0
- package/lib/internal/Oidc.js +73 -0
- package/lib/internal/Oidc.js.map +1 -0
- package/lib/internal/RemoteBuilder.d.ts.map +1 -1
- package/lib/internal/RemoteBuilder.js +21 -8
- package/lib/internal/RemoteBuilder.js.map +1 -1
- package/lib/leases.d.ts +6 -2
- package/lib/leases.d.ts.map +1 -1
- package/lib/leases.js +25 -5
- package/lib/leases.js.map +1 -1
- package/lib/ports.d.ts.map +1 -1
- package/lib/ports.js.map +1 -1
- package/lib/replicas.d.ts +39 -27
- package/lib/replicas.d.ts.map +1 -1
- package/lib/replicas.js +63 -8
- package/lib/replicas.js.map +1 -1
- package/lib/rpc.d.ts +14 -12
- package/lib/rpc.d.ts.map +1 -1
- package/lib/rpc.js +38 -40
- package/lib/rpc.js.map +1 -1
- package/package.json +15 -15
- package/src/App.ts +41 -10
- package/src/BindService.ts +28 -36
- package/src/Bootstrap.ts +2 -0
- package/src/Bucket.ts +278 -45
- package/src/BucketBinding.ts +1 -1
- package/src/Certificate.ts +36 -5
- package/src/ConnectPostgres.ts +1 -1
- package/src/ConnectPostgresHttp.ts +1 -1
- package/src/Credentials.ts +18 -41
- package/src/DeploymentImages.ts +1 -1
- package/src/Errors.ts +1 -1
- package/src/IpAssignment.ts +35 -5
- package/src/Machine.ts +39 -4
- package/src/MountVolume.ts +5 -2
- package/src/Postgres.ts +50 -8
- package/src/PostgresMigrations.ts +39 -99
- package/src/Redis.ts +54 -9
- package/src/RedisBinding.ts +1 -1
- package/src/RedisHttp.ts +4 -1
- package/src/Secret.ts +32 -4
- package/src/SecretKey.ts +32 -4
- package/src/Service.ts +441 -88
- package/src/Sprite.ts +45 -17
- package/src/Volume.ts +30 -6
- package/src/VolumeSnapshot.ts +40 -2
- package/src/Website/AssetDeployment.ts +13 -15
- package/src/Website/Astro.ts +20 -15
- package/src/Website/FrameworkSite.ts +92 -6
- package/src/Website/StaticSite.ts +27 -7
- package/src/Website/Vite.ts +9 -0
- package/src/WriteCertificatesHttp.ts +2 -2
- package/src/bluegreen.ts +11 -5
- package/src/hosted.ts +121 -17
- package/src/internal/Oidc.ts +99 -0
- package/src/internal/RemoteBuilder.ts +37 -19
- package/src/leases.ts +35 -7
- package/src/replicas.ts +70 -9
- package/src/rpc.ts +37 -40
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@alchemy.run/fly",
|
|
3
|
-
"version": "2.0.0-beta.
|
|
3
|
+
"version": "2.0.0-beta.86",
|
|
4
4
|
"description": "Fly.io apps, machines and Postgres for Alchemy.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"alchemy",
|
|
@@ -57,27 +57,27 @@
|
|
|
57
57
|
"access": "public"
|
|
58
58
|
},
|
|
59
59
|
"dependencies": {
|
|
60
|
-
"@alchemy.run/docker": "2.0.0-beta.
|
|
61
|
-
"@alchemy.run/redis": "2.0.0-beta.
|
|
62
|
-
"@alchemy.run/sql": "2.0.0-beta.
|
|
63
|
-
"@distilled.cloud/aws": "1.0.0-rc.
|
|
64
|
-
"@distilled.cloud/core": "1.0.0-rc.
|
|
65
|
-
"@distilled.cloud/fly-io": "1.0.0-rc.
|
|
66
|
-
"rolldown": "1.2.
|
|
60
|
+
"@alchemy.run/docker": "2.0.0-beta.86",
|
|
61
|
+
"@alchemy.run/redis": "2.0.0-beta.86",
|
|
62
|
+
"@alchemy.run/sql": "2.0.0-beta.86",
|
|
63
|
+
"@distilled.cloud/aws": "1.0.0-rc.19",
|
|
64
|
+
"@distilled.cloud/core": "1.0.0-rc.19",
|
|
65
|
+
"@distilled.cloud/fly-io": "1.0.0-rc.19",
|
|
66
|
+
"rolldown": "1.2.16"
|
|
67
67
|
},
|
|
68
68
|
"devDependencies": {
|
|
69
|
-
"@effect/platform-node": "^4.
|
|
69
|
+
"@effect/platform-node": "^4.1.4",
|
|
70
70
|
"@types/bun": "1.4.3",
|
|
71
71
|
"@types/pg": "^8.20.0",
|
|
72
|
-
"alchemy": "2.0.0-beta.
|
|
73
|
-
"effect": "^4.
|
|
72
|
+
"alchemy": "2.0.0-beta.86",
|
|
73
|
+
"effect": "^4.1.4",
|
|
74
74
|
"pg": "^8.22.0",
|
|
75
|
-
"typescript": "^7.0.
|
|
75
|
+
"typescript": "^7.1.0-dev.20261105.1"
|
|
76
76
|
},
|
|
77
77
|
"peerDependencies": {
|
|
78
|
-
"@effect/platform-node": "^4.
|
|
79
|
-
"alchemy": "2.0.0-beta.
|
|
80
|
-
"effect": "^4.
|
|
78
|
+
"@effect/platform-node": "^4.1.4",
|
|
79
|
+
"alchemy": "2.0.0-beta.86",
|
|
80
|
+
"effect": "^4.1.4",
|
|
81
81
|
"pg": "^8.22.0"
|
|
82
82
|
},
|
|
83
83
|
"peerDependenciesMeta": {
|
package/src/App.ts
CHANGED
|
@@ -82,9 +82,19 @@ export type App = Resource<
|
|
|
82
82
|
url: string;
|
|
83
83
|
},
|
|
84
84
|
AppBinding,
|
|
85
|
-
Providers
|
|
85
|
+
Providers,
|
|
86
|
+
AppLookup
|
|
86
87
|
>;
|
|
87
88
|
|
|
89
|
+
/**
|
|
90
|
+
* Props for {@link App.lookup}: find an App this stack doesn't manage by
|
|
91
|
+
* its name.
|
|
92
|
+
*/
|
|
93
|
+
export interface AppLookup {
|
|
94
|
+
/** Fly App name. */
|
|
95
|
+
name: string;
|
|
96
|
+
}
|
|
97
|
+
|
|
88
98
|
/**
|
|
89
99
|
* Binding contract accepted by {@link App}. Each {@link Service} placed in
|
|
90
100
|
* the App (`app` prop) reports the ports it publishes, so the App can
|
|
@@ -196,18 +206,32 @@ export interface AppBinding {
|
|
|
196
206
|
* export const Site = Fly.App("Site");
|
|
197
207
|
* ```
|
|
198
208
|
*
|
|
209
|
+
* ### Looking up an existing App
|
|
210
|
+
* `App.lookup` references an App Alchemy doesn't manage (created with
|
|
211
|
+
* `fly launch` or by another stack). It is read during plan/deploy, never
|
|
212
|
+
* created, updated or deleted, and works anywhere a declared App does.
|
|
213
|
+
*
|
|
214
|
+
* **Example:** Reference an existing App
|
|
215
|
+
* ```typescript
|
|
216
|
+
* const site = Fly.App.lookup({ name: "my-site" });
|
|
217
|
+
* const db = yield* Fly.Secret("DatabaseUrl", {
|
|
218
|
+
* app: site,
|
|
219
|
+
* value: Redacted.make("postgres://…"),
|
|
220
|
+
* });
|
|
221
|
+
* ```
|
|
222
|
+
*
|
|
199
223
|
* @resource
|
|
200
224
|
* @product App
|
|
201
225
|
*/
|
|
202
226
|
export const App = Resource<App>("Fly.App");
|
|
203
227
|
|
|
204
228
|
export class AppNotCreated extends Data.TaggedError("Fly.AppNotCreated")<{
|
|
205
|
-
|
|
229
|
+
resourceName: string;
|
|
206
230
|
/** Fly's rejection of the create request, when there was one. */
|
|
207
231
|
reason?: string;
|
|
208
232
|
}> {
|
|
209
233
|
get message() {
|
|
210
|
-
return `Fly App ${this.
|
|
234
|
+
return `Fly App ${this.resourceName} was not created${this.reason ? `: ${this.reason}` : ""}`;
|
|
211
235
|
}
|
|
212
236
|
}
|
|
213
237
|
|
|
@@ -234,9 +258,7 @@ const resolveAppName = (id: string, name: string | undefined, existing?: string)
|
|
|
234
258
|
});
|
|
235
259
|
|
|
236
260
|
const getByName = (appName: string) =>
|
|
237
|
-
machines
|
|
238
|
-
.getApp({ app_name: appName })
|
|
239
|
-
.pipe(Effect.catchTag("NotFound", () => Effect.succeed(undefined)));
|
|
261
|
+
machines.getApp({ app_name: appName }).pipe(Effect.catchTag("NotFound", () => Effect.undefined));
|
|
240
262
|
|
|
241
263
|
const hasAlchemyMachines = (appName: string) =>
|
|
242
264
|
machines.listMachines({ app_name: appName }).pipe(
|
|
@@ -348,11 +370,11 @@ export const ensureApp = Effect.fn(function* (input: {
|
|
|
348
370
|
current = yield* observe;
|
|
349
371
|
}
|
|
350
372
|
if (current === undefined) {
|
|
351
|
-
return yield* new AppNotCreated({
|
|
373
|
+
return yield* new AppNotCreated({ resourceName: input.name, reason: rejection });
|
|
352
374
|
}
|
|
353
375
|
}
|
|
354
376
|
if (current === undefined) {
|
|
355
|
-
return yield* new AppNotCreated({
|
|
377
|
+
return yield* new AppNotCreated({ resourceName: input.name });
|
|
356
378
|
}
|
|
357
379
|
return current;
|
|
358
380
|
});
|
|
@@ -387,7 +409,7 @@ export const deleteApp = Effect.fn(function* (appName: string) {
|
|
|
387
409
|
);
|
|
388
410
|
const http = yield* HttpClient.HttpClient;
|
|
389
411
|
const fetchOptions = yield* Effect.serviceOption(FetchHttpClient.RequestInit);
|
|
390
|
-
yield* machines.deleteApp({ app_name: appName }).pipe(
|
|
412
|
+
const accepted = yield* machines.deleteApp({ app_name: appName }).pipe(
|
|
391
413
|
Retry.none,
|
|
392
414
|
// Bun can replay DELETE on a reused socket below the SDK retry policy.
|
|
393
415
|
Effect.provideService(
|
|
@@ -400,7 +422,10 @@ export const deleteApp = Effect.fn(function* (appName: string) {
|
|
|
400
422
|
redirect: "error",
|
|
401
423
|
}),
|
|
402
424
|
Effect.timeout("30 seconds"),
|
|
403
|
-
Effect.
|
|
425
|
+
Effect.as(true),
|
|
426
|
+
// Fly's DELETE is authoritative for absence: its GET can keep serving a
|
|
427
|
+
// deleted App as `pending` long after DELETE answers 404.
|
|
428
|
+
Effect.catchTag("NotFound", () => Effect.succeed(false)),
|
|
404
429
|
Effect.catchTag(
|
|
405
430
|
[
|
|
406
431
|
"HttpClientError",
|
|
@@ -413,6 +438,7 @@ export const deleteApp = Effect.fn(function* (appName: string) {
|
|
|
413
438
|
(error) => Effect.fail(new AppDeletionAmbiguous({ appName, evidence: error._tag })),
|
|
414
439
|
),
|
|
415
440
|
);
|
|
441
|
+
if (!accepted) return;
|
|
416
442
|
const gone = yield* getByName(appName).pipe(
|
|
417
443
|
Effect.map((app) => app === undefined),
|
|
418
444
|
Effect.repeat({ schedule: Schedule.spaced("1 second"), until: (gone) => gone, times: 8 }),
|
|
@@ -481,6 +507,11 @@ export const AppProvider = () =>
|
|
|
481
507
|
return undefined;
|
|
482
508
|
}),
|
|
483
509
|
|
|
510
|
+
lookup: Effect.fn(function* ({ name }) {
|
|
511
|
+
const found = yield* getByName(name);
|
|
512
|
+
return found === undefined ? undefined : toAttrs(found, name);
|
|
513
|
+
}),
|
|
514
|
+
|
|
484
515
|
read: Effect.fn(function* ({ id, olds, output }) {
|
|
485
516
|
const name = yield* resolveAppName(id, olds?.name, output?.appName);
|
|
486
517
|
const found =
|
package/src/BindService.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as Binding from "alchemy/Binding";
|
|
2
2
|
import type { Resource } from "alchemy/Resource";
|
|
3
|
-
import { makeFetchRpcStub,
|
|
3
|
+
import { makeFetchRpcStub, type Rpc } from "alchemy/Rpc";
|
|
4
4
|
import { CurrentRuntimeContext, type RuntimeContext, sanitizeKey } from "alchemy/RuntimeContext";
|
|
5
5
|
import { isYieldableEffectLike } from "alchemy/Util/effect";
|
|
6
6
|
import * as Data from "effect/Data";
|
|
@@ -9,9 +9,7 @@ import * as HttpClient from "effect/http/HttpClient";
|
|
|
9
9
|
import type * as HttpClientError from "effect/http/HttpClientError";
|
|
10
10
|
import * as HttpClientRequest from "effect/http/HttpClientRequest";
|
|
11
11
|
import type * as HttpClientResponse from "effect/http/HttpClientResponse";
|
|
12
|
-
import * as Redacted from "effect/Redacted";
|
|
13
12
|
import type { BoundTarget, ServiceBinding } from "./MountVolume.ts";
|
|
14
|
-
import { RPC_TOKEN_HEADER } from "./rpc.ts";
|
|
15
13
|
import type { Service } from "./Service.ts";
|
|
16
14
|
|
|
17
15
|
/** The deployed caller has no address for the bound Service. */
|
|
@@ -75,12 +73,13 @@ const logicalIdOf = (target: unknown): string => {
|
|
|
75
73
|
export const boundTargetEnvKeys = (id: string) => ({
|
|
76
74
|
appName: sanitizeKey(`FLY_BIND_${id}_APP`),
|
|
77
75
|
url: sanitizeKey(`FLY_BIND_${id}_URL`),
|
|
78
|
-
token: sanitizeKey(`FLY_BIND_${id}_TOKEN`),
|
|
79
76
|
});
|
|
80
77
|
|
|
81
78
|
/**
|
|
82
79
|
* Record the binding on the caller and transport the target's private
|
|
83
|
-
* address
|
|
80
|
+
* address as Outputs. For {@link bindService}, also record the caller's
|
|
81
|
+
* App on the target, which serves its methods only to the Apps recorded
|
|
82
|
+
* there. Returns runtime accessors for the address.
|
|
84
83
|
*/
|
|
85
84
|
const bindTarget = Effect.fn(function* <Shape, Req>(
|
|
86
85
|
target: Target<Shape> | Effect.Effect<Target<Shape>, never, Req>,
|
|
@@ -105,17 +104,27 @@ const bindTarget = Effect.fn(function* <Shape, Req>(
|
|
|
105
104
|
appName: service.appName,
|
|
106
105
|
network: service.network,
|
|
107
106
|
privateUrl: service.privateUrl,
|
|
108
|
-
rpcToken: service.rpcToken,
|
|
109
107
|
port,
|
|
110
108
|
endpoints: service.endpoints,
|
|
111
109
|
} as unknown as BoundTarget,
|
|
112
110
|
});
|
|
111
|
+
if (port === undefined) {
|
|
112
|
+
// Fly signs each request's calling App (`Fly-Src`), so the target
|
|
113
|
+
// authorizes callers by App: no key to hand out.
|
|
114
|
+
yield* (
|
|
115
|
+
service as unknown as {
|
|
116
|
+
bind: (
|
|
117
|
+
label: TemplateStringsArray,
|
|
118
|
+
...args: unknown[]
|
|
119
|
+
) => (data: ServiceBinding) => Effect.Effect<void>;
|
|
120
|
+
}
|
|
121
|
+
).bind`Caller(${host})`({ caller: { appName: host.appName as unknown as string } });
|
|
122
|
+
}
|
|
113
123
|
}
|
|
114
124
|
}
|
|
115
125
|
// Captured at bind time: the host's runtime context reads the values
|
|
116
126
|
// transported onto the Machine.
|
|
117
|
-
const read = (key: string) =>
|
|
118
|
-
ctx === undefined ? Effect.succeed(undefined) : ctx.get<unknown>(key);
|
|
127
|
+
const read = (key: string) => (ctx === undefined ? Effect.undefined : ctx.get<unknown>(key));
|
|
119
128
|
const required = (key: string) =>
|
|
120
129
|
read(key).pipe(
|
|
121
130
|
Effect.flatMap((value) =>
|
|
@@ -127,15 +136,6 @@ const bindTarget = Effect.fn(function* <Shape, Req>(
|
|
|
127
136
|
return {
|
|
128
137
|
appName: required(keys.appName),
|
|
129
138
|
url: required(keys.url),
|
|
130
|
-
token: read(keys.token).pipe(
|
|
131
|
-
Effect.map((value) =>
|
|
132
|
-
Redacted.isRedacted(value)
|
|
133
|
-
? String(Redacted.value(value))
|
|
134
|
-
: typeof value === "string"
|
|
135
|
-
? value
|
|
136
|
-
: "",
|
|
137
|
-
),
|
|
138
|
-
),
|
|
139
139
|
};
|
|
140
140
|
});
|
|
141
141
|
|
|
@@ -151,12 +151,13 @@ const withBase = (base: string, url: string) => {
|
|
|
151
151
|
* `fetch` and `run`) and forwards `fetch` requests, over Fly's private
|
|
152
152
|
* network.
|
|
153
153
|
*
|
|
154
|
-
* Binding makes the caller deploy after the Service
|
|
155
|
-
* Service's private address and
|
|
156
|
-
*
|
|
157
|
-
*
|
|
158
|
-
*
|
|
159
|
-
*
|
|
154
|
+
* Binding makes the caller deploy after the Service, hands it the
|
|
155
|
+
* Service's private address, and records the caller's App on the Service.
|
|
156
|
+
* Fly's proxy signs every call with the calling App (`Fly-Src`), and the
|
|
157
|
+
* Service answers methods only for the Apps recorded on it, so neither
|
|
158
|
+
* other Services on the network nor the public internet can call them,
|
|
159
|
+
* and no key is involved. Calls are plain HTTP inside Fly's
|
|
160
|
+
* WireGuard-encrypted network.
|
|
160
161
|
*
|
|
161
162
|
* ### Call a private Service
|
|
162
163
|
* **Example:** Methods on the target
|
|
@@ -251,24 +252,15 @@ export const bindService = <Shape, Req = never>(
|
|
|
251
252
|
Effect.gen(function* () {
|
|
252
253
|
const http = yield* HttpClient.HttpClient;
|
|
253
254
|
const bound = yield* bindTarget(target, undefined);
|
|
254
|
-
const send = (request: HttpClientRequest.HttpClientRequest
|
|
255
|
+
const send = (request: HttpClientRequest.HttpClientRequest) =>
|
|
255
256
|
Effect.gen(function* () {
|
|
256
257
|
const base = yield* bound.url;
|
|
257
|
-
|
|
258
|
-
if (isRpc) {
|
|
259
|
-
next = HttpClientRequest.setHeader(next, RPC_TOKEN_HEADER, yield* bound.token);
|
|
260
|
-
}
|
|
261
|
-
return yield* http.execute(next);
|
|
258
|
+
return yield* http.execute(HttpClientRequest.setUrl(request, withBase(base, request.url)));
|
|
262
259
|
});
|
|
263
260
|
return makeFetchRpcStub<ServiceClient<Shape>>({
|
|
264
261
|
fetch: (request) =>
|
|
265
|
-
send(request
|
|
266
|
-
|
|
267
|
-
unknown
|
|
268
|
-
>,
|
|
269
|
-
base: {
|
|
270
|
-
fetch: (request: HttpClientRequest.HttpClientRequest) => send(request, false),
|
|
271
|
-
},
|
|
262
|
+
send(request) as Effect.Effect<HttpClientResponse.HttpClientResponse, unknown>,
|
|
263
|
+
base: { fetch: send },
|
|
272
264
|
});
|
|
273
265
|
});
|
|
274
266
|
|
package/src/Bootstrap.ts
CHANGED
|
@@ -14,6 +14,7 @@ import {
|
|
|
14
14
|
} from "alchemy/Runtime/Bootstrap";
|
|
15
15
|
import { ManagedHttpShutdown } from "alchemy/Runtime/ManagedHttpShutdown";
|
|
16
16
|
import * as ConfigProvider from "effect/ConfigProvider";
|
|
17
|
+
import * as SecureRandom from "effect/crypto/SecureRandom";
|
|
17
18
|
import * as Effect from "effect/Effect";
|
|
18
19
|
import * as FetchHttpClient from "effect/http/FetchHttpClient";
|
|
19
20
|
import * as Layer from "effect/Layer";
|
|
@@ -31,6 +32,7 @@ export const bootstrap = (entrypoint: unknown): Promise<void> => {
|
|
|
31
32
|
const platform = Layer.mergeAll(
|
|
32
33
|
NodeServices.layer,
|
|
33
34
|
FetchHttpClient.layer,
|
|
35
|
+
SecureRandom.layerWebCrypto,
|
|
34
36
|
Logger.layer([Logger.consolePretty()]),
|
|
35
37
|
);
|
|
36
38
|
|