| 1 | import * as Effect from "effect/Effect"; |
| 2 | import type * as HttpClient from "effect/http/HttpClient"; |
| 3 | import { CloudflareEnvironment } from "../CloudflareEnvironment.ts"; |
| 4 | import type { Credentials } from "../Credentials.ts"; |
| 5 | import type { TunnelAuth } from "./TunnelBinding.ts"; |
| 6 | |
| 7 | /** |
| 8 | * Shared scaffolding for the `*Local` tunnel services. |
| 9 | * |
| 10 | * Instead of minting a scoped {@link AccountApiToken} (the `*Binding` path), it |
| 11 | * captures the ambient current-credentials context available during stack-eval |
| 12 | * and builds a {@link TunnelAuth} that provides those credentials directly to |
| 13 | * the cfd_tunnel HTTP ops. It then delegates to the same client builders the |
| 14 | * `*Binding` variant uses. |
| 15 | * |
| 16 | * NOT exported from `index.ts` — this is internal scaffolding shared by the |
| 17 | * three access-level Local layers. |
| 18 | */ |
| 19 | export const makeLocalTunnelClient = <Client>( |
| 20 | makeClient: (auth: TunnelAuth) => Client, |
| 21 | ) => |
| 22 | Effect.gen(function* () { |
| 23 | // Account + credentials are ambient during stack-eval (the stack's |
| 24 | // providers layer). Capture the full context so cfd_tunnel HTTP ops can run |
| 25 | // with the current credentials — no `host.bind`, no minted token. |
| 26 | const { accountId } = yield* yield* CloudflareEnvironment; |
| 27 | const context = yield* Effect.context< |
| 28 | Credentials | HttpClient.HttpClient |
| 29 | >(); |
| 30 | |
| 31 | return Effect.fn(function* () { |
| 32 | const auth: TunnelAuth = { |
| 33 | authorize: (eff) => eff.pipe(Effect.provideContext(context)), |
| 34 | accountId: Effect.succeed(accountId), |
| 35 | }; |
| 36 | return makeClient(auth); |
| 37 | }); |
| 38 | }); |