Add authenticated fetch wrapper for the todos API
This commit is contained in:
56
frontend/src/lib/api.ts
Normal file
56
frontend/src/lib/api.ts
Normal file
@@ -0,0 +1,56 @@
|
||||
import { supabase } from './supabase';
|
||||
|
||||
const API_URL = import.meta.env.VITE_API_URL;
|
||||
if (!API_URL) throw new Error('Missing VITE_API_URL');
|
||||
|
||||
export type Todo = {
|
||||
id: number;
|
||||
title: string;
|
||||
completed: boolean;
|
||||
createdAt: string;
|
||||
};
|
||||
|
||||
async function authedFetch(path: string, init: RequestInit = {}): Promise<Response> {
|
||||
const { data } = await supabase.auth.getSession();
|
||||
const token = data.session?.access_token;
|
||||
if (!token) throw new Error('Not signed in');
|
||||
|
||||
const headers = new Headers(init.headers);
|
||||
headers.set('Authorization', `Bearer ${token}`);
|
||||
if (init.body && !headers.has('Content-Type')) headers.set('Content-Type', 'application/json');
|
||||
|
||||
return fetch(`${API_URL}${path}`, { ...init, headers });
|
||||
}
|
||||
|
||||
async function assertOk(res: Response): Promise<Response> {
|
||||
if (!res.ok) {
|
||||
const text = await res.text().catch(() => '');
|
||||
throw new Error(`API ${res.status}: ${text || res.statusText}`);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
export const api = {
|
||||
async list(): Promise<Todo[]> {
|
||||
const res = await assertOk(await authedFetch('/api/todos'));
|
||||
return res.json();
|
||||
},
|
||||
async create(title: string): Promise<Todo> {
|
||||
const res = await assertOk(
|
||||
await authedFetch('/api/todos', { method: 'POST', body: JSON.stringify({ title }) })
|
||||
);
|
||||
return res.json();
|
||||
},
|
||||
async setCompleted(id: number, completed: boolean): Promise<Todo> {
|
||||
const res = await assertOk(
|
||||
await authedFetch(`/api/todos/${id}`, {
|
||||
method: 'PATCH',
|
||||
body: JSON.stringify({ completed })
|
||||
})
|
||||
);
|
||||
return res.json();
|
||||
},
|
||||
async remove(id: number): Promise<void> {
|
||||
await assertOk(await authedFetch(`/api/todos/${id}`, { method: 'DELETE' }));
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user