54 lines
1.9 KiB
TypeScript
54 lines
1.9 KiB
TypeScript
/**
|
|
* Browser-side client for the user's roaming reading preferences.
|
|
*
|
|
* The BFF stores prefs as opaque JSONB keyed off the user. This module
|
|
* just round-trips that blob — it makes no claim about its shape (that
|
|
* contract is owned by components/reading-settings.tsx). All calls run
|
|
* with `credentials: "include"` so the auth cookie comes along.
|
|
*/
|
|
|
|
const BFF_BASE =
|
|
process.env.NEXT_PUBLIC_BFF_URL || "http://localhost:8080";
|
|
|
|
type Envelope<T> = {
|
|
success?: boolean;
|
|
data?: T;
|
|
error?: { code: number; message: string };
|
|
};
|
|
|
|
async function call<T>(path: string, init?: RequestInit): Promise<T | null> {
|
|
const res = await fetch(`${BFF_BASE}/api/v1${path}`, {
|
|
credentials: "include",
|
|
headers: { "Content-Type": "application/json", ...(init?.headers ?? {}) },
|
|
...init,
|
|
});
|
|
if (res.status === 401 || res.status === 403) return null;
|
|
if (!res.ok) {
|
|
throw new Error(`reading-prefs ${path}: ${res.status}`);
|
|
}
|
|
const body = (await res.json().catch(() => ({}))) as Envelope<T>;
|
|
return (body.data ?? null) as T | null;
|
|
}
|
|
|
|
export const readingPrefsApi = {
|
|
/** Fetches the caller's reading prefs blob. Returns `null` if the
|
|
* request is unauthenticated (treat as "no remote prefs"). The blob
|
|
* is the raw JSON object the frontend wrote last; an empty object
|
|
* on first load. */
|
|
async get(): Promise<Record<string, unknown> | null> {
|
|
const data = await call<Record<string, unknown>>("/users/me/reading-prefs");
|
|
return data ?? null;
|
|
},
|
|
|
|
/** Overwrites the caller's reading prefs blob. The server stores the
|
|
* payload verbatim (after canonicalising via re-marshal) — schema is
|
|
* client-owned. Errors are swallowed by the caller; reading prefs
|
|
* should never block a UI interaction. */
|
|
async put(prefs: Record<string, unknown>): Promise<void> {
|
|
await call<Record<string, unknown>>("/users/me/reading-prefs", {
|
|
method: "PUT",
|
|
body: JSON.stringify(prefs),
|
|
});
|
|
},
|
|
};
|