t3-code-android-nightly/.repos/alchemy-effect/packages/alchemy/test/Prisma/fixtures/write-routes.ts
Julius Marminge 6f9cea00ae
chore(refs): sync Effect and Alchemy references to 4.0.1 and beta.80 (#16170)
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-05 13:22:30 -07:00

71 lines
3 KiB
TypeScript

import type { WriteBucketClient } from "@/Prisma/WriteBucket.ts";
import * as Effect from "effect/Effect";
import type * as HttpServerRequest from "effect/http/HttpServerRequest";
import * as HttpServerResponse from "effect/http/HttpServerResponse";
/**
* Shared write-side routes so every method of {@link WriteBucketClient} is
* driven over `fetch`:
*
* - `PUT /put?key=` — `put(key, body)` (returns the object key to prove the
* call resolved a `BucketObject`). `contentType`, `metaKey` and `metaValue`
* travel as query params and are passed through as `PutOptions`, so the
* read side can observe them.
* - `DELETE /del?key=` — `delete(key)` (single).
* - `DELETE /del-many?keys=a,b,c` — `delete(keys)` (batch). Keys travel as a
* comma-separated query param rather than a request body because DELETE
* bodies are unreliable across `fetch`.
* - `GET /presign-put?key=` — `presignPut(key)`.
*
* Returns `undefined` when the path is not a write route so the caller can
* fall through (used by the read-write fixtures).
*/
export const writeRoutes = (
store: WriteBucketClient,
request: HttpServerRequest.HttpServerRequest,
url: URL,
) =>
Effect.gen(function* () {
if (request.method === "PUT" && url.pathname === "/put") {
const key = url.searchParams.get("key") ?? "";
const metaKey = url.searchParams.get("metaKey");
const body = yield* request.text;
const object = yield* store
.put(key, body, {
contentType: url.searchParams.get("contentType") ?? undefined,
metadata: metaKey
? { [metaKey]: url.searchParams.get("metaValue") ?? "" }
: undefined,
})
.pipe(Effect.orDie);
return yield* HttpServerResponse.json({ ok: true, key: object.key });
}
if (request.method === "DELETE" && url.pathname === "/del") {
const key = url.searchParams.get("key") ?? "";
yield* store.delete(key).pipe(Effect.orDie);
return yield* HttpServerResponse.json({ ok: true });
}
if (request.method === "DELETE" && url.pathname === "/del-many") {
const keys = (url.searchParams.get("keys") ?? "")
.split(",")
.filter((k) => k.length > 0);
yield* store.delete(keys).pipe(Effect.orDie);
return yield* HttpServerResponse.json({ ok: true });
}
// The app mints the URL from its bound credentials and hands it back; the
// test then uploads to that URL directly, carrying no credentials of its
// own.
if (request.method === "GET" && url.pathname === "/presign-put") {
const key = url.searchParams.get("key") ?? "";
const expiresIn = url.searchParams.get("expiresIn");
const contentType = url.searchParams.get("contentType");
const presigned = yield* store
.presignPut(key, {
expiresIn: expiresIn ? Number(expiresIn) : undefined,
contentType: contentType ?? undefined,
})
.pipe(Effect.orDie);
return yield* HttpServerResponse.json({ url: presigned });
}
return undefined;
});