mirror of
https://github.com/fabro-sh/fabro.git
synced 2026-10-11 03:40:05 +00:00
Features like session_sandboxes and retros are server-level capability flags, not user settings. Expose them on GET /system/info where they belong alongside other server metadata. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
97 lines
2.6 KiB
TypeScript
97 lines
2.6 KiB
TypeScript
export interface ApiOptions {
|
|
init?: RequestInit;
|
|
request?: Request;
|
|
}
|
|
|
|
export async function apiFetch(path: string, options?: ApiOptions): Promise<Response> {
|
|
const { init } = options ?? {};
|
|
const response = await fetch(`/api/v1${path}`, {
|
|
...init,
|
|
credentials: "include",
|
|
headers: init?.headers,
|
|
});
|
|
|
|
if (response.status === 401) {
|
|
window.location.href = "/login";
|
|
throw new Error("Unauthorized");
|
|
}
|
|
|
|
return response;
|
|
}
|
|
|
|
export async function apiJson<T>(path: string, options?: ApiOptions): Promise<T> {
|
|
const response = await apiFetch(path, options);
|
|
if (!response.ok) {
|
|
throw new Response(null, { status: response.status, statusText: response.statusText });
|
|
}
|
|
return response.json() as Promise<T>;
|
|
}
|
|
|
|
export function isNotAvailable(status: number): boolean {
|
|
return status === 404 || status === 501;
|
|
}
|
|
|
|
export async function apiJsonOrNull<T>(
|
|
path: string,
|
|
options?: ApiOptions,
|
|
): Promise<T | null> {
|
|
const response = await apiFetch(path, options);
|
|
if (isNotAvailable(response.status)) {
|
|
return null;
|
|
}
|
|
if (!response.ok) {
|
|
throw new Response(null, {
|
|
status: response.status,
|
|
statusText: response.statusText,
|
|
});
|
|
}
|
|
return response.json() as Promise<T>;
|
|
}
|
|
|
|
export async function getAuthConfig(): Promise<{ methods: string[] }> {
|
|
const response = await fetch("/api/v1/auth/config", { credentials: "include" });
|
|
if (!response.ok) {
|
|
throw new Response(null, { status: response.status, statusText: response.statusText });
|
|
}
|
|
return response.json();
|
|
}
|
|
|
|
export async function loginDevToken(token: string): Promise<{ ok: boolean }> {
|
|
const response = await fetch("/auth/login/dev-token", {
|
|
method: "POST",
|
|
credentials: "include",
|
|
headers: { "Content-Type": "application/json" },
|
|
body: JSON.stringify({ token }),
|
|
});
|
|
if (!response.ok) {
|
|
throw new Response(null, { status: response.status, statusText: response.statusText });
|
|
}
|
|
return response.json();
|
|
}
|
|
|
|
export async function getAuthMe(): Promise<{
|
|
user: {
|
|
login: string;
|
|
name: string;
|
|
email: string;
|
|
avatarUrl: string;
|
|
userUrl: string;
|
|
};
|
|
provider: string;
|
|
demoMode: boolean;
|
|
}> {
|
|
const response = await fetch("/api/v1/auth/me", { credentials: "include" });
|
|
if (response.status === 401) {
|
|
throw new Response(null, { status: 401, statusText: "Unauthorized" });
|
|
}
|
|
if (!response.ok) {
|
|
throw new Response(null, { status: response.status, statusText: response.statusText });
|
|
}
|
|
return response.json();
|
|
}
|
|
|
|
export async function getSystemInfo(): Promise<{
|
|
features: { session_sandboxes: boolean; retros: boolean };
|
|
}> {
|
|
return apiJson("/system/info");
|
|
}
|