1import * as Effect from "effect/Effect";
2import type { RuntimeContext } from "../../RuntimeContext.ts";
3import type { WorkerExecutionContextAccess } from "../Workers/WorkerAccess.ts";
4import { WorkerExecutionContext } from "../Workers/Worker.ts";
5
6/**
7 * One-yield accessor for the current request's Cloudflare Access context
8 * (`ctx.access`) — sugar over `WorkerExecutionContext`:
9 *
10 * ```typescript
11 * fetch: Effect.gen(function* () {
12 * const access = yield* Cloudflare.Access.Context;
13 * if (access === undefined) {
14 * return HttpServerResponse.text("Access required", { status: 403 });
15 * }
16 * const identity = yield* access.getIdentity();
17 * return yield* HttpServerResponse.json({
18 * aud: access.aud,
19 * email: identity?.email,
20 * });
21 * }),
22 * ```
23 *
24 * `undefined` when the request did not pass through Cloudflare Access (see
25 * `Cloudflare.Access.Application` with `worker` / `all_workers`
26 * destinations for turning enforcement on). Colored with
27 * {@link RuntimeContext}: it can be closed over during init but only *run*
28 * inside a request handler. Under `alchemy dev` the Worker's `dev.access`
29 * config simulates the authenticated state.
30 */
31export const Context: Effect.Effect<
32 WorkerExecutionContextAccess | undefined,
33 never,
34 RuntimeContext | WorkerExecutionContext
35> = WorkerExecutionContext.pipe(Effect.flatMap((ctx) => ctx.access));