1import type { ReadSecretClient } from "@/Cloudflare/SecretsStore/ReadSecret.ts";
2import * as Effect from "effect/Effect";
3import * as Redacted from "effect/Redacted";
4import * as HttpServerResponse from "effect/http/HttpServerResponse";
5
6/**
7 * Shared route that drives every shape of the {@link ReadSecretClient} so both
8 * invocation-style fixtures (effect-worker via `ReadSecret`, async-worker via
9 * the `env` async binding) exercise the same client surface over `fetch`:
10 *
11 * - `yield* client` — the client is itself an `Effect` resolving to the value
12 * - `client.get()` — the explicit callable
13 * - `client.raw` — the underlying `SecretsStoreSecret` binding
14 *
15 * Returns `undefined` for unmatched paths so the worker shell can 404.
16 */
17export const secretRoutes = (client: ReadSecretClient, url: URL) =>
18 Effect.gen(function* () {
19 if (url.pathname === "/secret") {
20 // The client is an Effect that resolves to the redacted value.
21 const direct = yield* client.pipe(Effect.orDie);
22 const viaGet = yield* client.get().pipe(Effect.orDie);
23 const raw = yield* client.raw.pipe(Effect.orDie);
24 const viaRaw = yield* Effect.promise(() => raw.get());
25 return yield* HttpServerResponse.json({
26 value: Redacted.value(direct),
27 viaGet: Redacted.value(viaGet),
28 viaRaw,
29 });
30 }
31 return undefined;
32 });