68 lines
1.8 KiB
TypeScript
68 lines
1.8 KiB
TypeScript
/**
|
|
* HTTP client for the my.quinn API.
|
|
*/
|
|
|
|
import { getBaseUrl, getToken } from './config';
|
|
|
|
interface ApiResponse<T = unknown> {
|
|
ok: boolean;
|
|
status: number;
|
|
data: T;
|
|
}
|
|
|
|
export async function apiGet<T>(path: string): Promise<ApiResponse<T>> {
|
|
const baseUrl = await getBaseUrl();
|
|
const token = await getToken();
|
|
|
|
const res = await fetch(`${baseUrl}${path}`, {
|
|
method: 'GET',
|
|
headers: {
|
|
'Authorization': `Bearer ${token}`,
|
|
'Accept': 'application/json',
|
|
},
|
|
});
|
|
|
|
const data = await res.json() as T;
|
|
return { ok: res.ok, status: res.status, data };
|
|
}
|
|
|
|
export async function apiMutate<T>(method: string, path: string, body?: unknown): Promise<ApiResponse<T>> {
|
|
const baseUrl = await getBaseUrl();
|
|
const token = await getToken();
|
|
|
|
const headers: Record<string, string> = {
|
|
'Authorization': `Bearer ${token}`,
|
|
'Accept': 'application/json',
|
|
};
|
|
|
|
const init: RequestInit = { method, headers };
|
|
|
|
if (body !== undefined) {
|
|
headers['Content-Type'] = 'application/json';
|
|
init.body = JSON.stringify(body);
|
|
}
|
|
|
|
const res = await fetch(`${baseUrl}${path}`, init);
|
|
const data = await res.json() as T;
|
|
return { ok: res.ok, status: res.status, data };
|
|
}
|
|
|
|
export async function apiLogin(passphrase: string): Promise<{ token: string; expiresAt: string } | null> {
|
|
const baseUrl = await getBaseUrl();
|
|
|
|
try {
|
|
const res = await fetch(`${baseUrl}/auth/login`, {
|
|
method: 'POST',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify({ passphrase }),
|
|
});
|
|
|
|
if (!res.ok) return null;
|
|
|
|
const data = await res.json() as { ok: boolean; token: string; expiresAt: string };
|
|
return data.ok ? { token: data.token, expiresAt: data.expiresAt } : null;
|
|
} catch (err) {
|
|
console.error('Login request failed:', String(err));
|
|
return null;
|
|
}
|
|
}
|