67 lines · 2.7 KB · TypeScript
RawDownload
import assert from "node:assert/strict"; import { Effect, Layer } from "effect";import { HttpApiClient } from "effect/unstable/httpapi";import { FetchHttpClient } from "effect/unstable/http"; import { AdminHttpApi } from "../admin/api";import { type InviteRole } from "../auth/invites"; // Test helper: mint an invite code through the TYPED admin HttpApi client, the// same surface the web app calls — no raw request building, no direct DB poke.// The one unavoidable raw call is the bootstrap admin's Better Auth sign-in (an// auth boundary, not an HttpApi surface); everything after is the typed client. type Handler = (request: Request) => Promise<Response>; const BASE = "http://localhost:4788/api"; const signInToken = async (handler: Handler, email: string, password: string): Promise<string> => {  const response = await handler(    new Request("http://localhost:4788/api/auth/sign-in/email", {      method: "POST",      headers: { "content-type": "application/json" },      body: JSON.stringify({ email, password }),    }),  );  const token = response.headers.get("set-auth-token");  assert(response.ok && token, `Test admin sign-in failed (${response.status}).`);  return token;}; // A FetchHttpClient backed by the in-process handler, carrying the admin bearer.const clientLayer = (handler: Handler, token: string) =>  FetchHttpClient.layer.pipe(    Layer.provide(      Layer.succeed(FetchHttpClient.Fetch)(((input: RequestInfo | URL, init?: RequestInit) => {        const base = input instanceof Request ? input : new Request(input, init);        const request = new Request(base, {          headers: { ...Object.fromEntries(base.headers), authorization: `Bearer ${token}` },        });        return handler(request);      }) as typeof globalThis.fetch),    ),  ); /** Sign in once and mint each invitation through the authenticated admin API. */export const createInviteMinter = async (  handler: Handler,): Promise<(role?: InviteRole) => Promise<string>> => {  const token = await signInToken(    handler,    process.env.EXECUTOR_BOOTSTRAP_ADMIN_EMAIL!,    process.env.EXECUTOR_BOOTSTRAP_ADMIN_PASSWORD!,  );  return (role = "member") =>    Effect.gen(function* () {      const client = yield* HttpApiClient.make(AdminHttpApi, { baseUrl: BASE });      const invite = yield* client.admin.createInvite({ payload: { role } });      return invite.code;    }).pipe(Effect.provide(clientLayer(handler, token)), Effect.runPromise);}; /** Mint one invitation with a fresh authenticated admin session. */export const mintInviteCode = async (  handler: Handler,  role: InviteRole = "member",): Promise<string> => (await createInviteMinter(handler))(role);