| 1 | import type { ConnectClient } from "@/Cloudflare/Hyperdrive/Connect.ts"; |
| 2 | import * as Effect from "effect/Effect"; |
| 3 | import * as Redacted from "effect/Redacted"; |
| 4 | import * as HttpServerResponse from "effect/http/HttpServerResponse"; |
| 5 | |
| 6 | /** |
| 7 | * Shared routes exercised by the effect-worker fixture so every member of |
| 8 | * {@link ConnectClient} (`host`, `port`, `user`, `database`, |
| 9 | * `connectionString`, `raw`) is driven over `fetch`. Returns `undefined` |
| 10 | * when the path is not a known route so the caller can fall through. |
| 11 | * |
| 12 | * The runtime password / connection string are valid only within the |
| 13 | * current Worker invocation, so the route reports their *shape* |
| 14 | * (non-empty, parseable URL) rather than echoing secret material. |
| 15 | */ |
| 16 | export const connectionRoutes = (hd: ConnectClient, url: URL) => |
| 17 | Effect.gen(function* () { |
| 18 | if (url.pathname === "/meta") { |
| 19 | const host = yield* hd.host; |
| 20 | const port = yield* hd.port; |
| 21 | const user = yield* hd.user; |
| 22 | const database = yield* hd.database; |
| 23 | const connectionString = Redacted.value(yield* hd.connectionString); |
| 24 | const password = Redacted.value(yield* hd.password); |
| 25 | // Parse the connection string so we prove it is a real, well-formed |
| 26 | // URI rather than echoing the secret back to the test. |
| 27 | const parsed = new URL(connectionString); |
| 28 | return yield* HttpServerResponse.json({ |
| 29 | host, |
| 30 | port, |
| 31 | user, |
| 32 | database, |
| 33 | // Booleans only — never leak the runtime secret over the wire. |
| 34 | hasConnectionString: connectionString.length > 0, |
| 35 | hasPassword: password.length > 0, |
| 36 | connectionStringProtocol: parsed.protocol, |
| 37 | connectionStringHost: parsed.hostname, |
| 38 | }); |
| 39 | } |
| 40 | if (url.pathname === "/raw") { |
| 41 | // `raw` is the escape hatch driver libraries use. Prove it resolves |
| 42 | // to the runtime Hyperdrive object exposing the same host. |
| 43 | const raw = yield* hd.raw; |
| 44 | return yield* HttpServerResponse.json({ |
| 45 | host: raw.host, |
| 46 | port: raw.port, |
| 47 | user: raw.user, |
| 48 | database: raw.database, |
| 49 | }); |
| 50 | } |
| 51 | return undefined; |
| 52 | }); |