init
This commit is contained in:
@@ -0,0 +1,37 @@
|
||||
import { env } from '$env/dynamic/public';
|
||||
|
||||
const BASE = env.PUBLIC_API_BASE || 'http://localhost:8080';
|
||||
|
||||
export class ApiError extends Error {
|
||||
status: number;
|
||||
constructor(status: number, message: string) {
|
||||
super(message);
|
||||
this.status = status;
|
||||
}
|
||||
}
|
||||
|
||||
async function request<T>(path: string, opts: RequestInit = {}): Promise<T> {
|
||||
const res = await fetch(`${BASE}/api${path}`, {
|
||||
credentials: 'include',
|
||||
headers: { 'Content-Type': 'application/json', ...(opts.headers ?? {}) },
|
||||
...opts
|
||||
});
|
||||
|
||||
if (res.status === 204) return undefined as T;
|
||||
|
||||
const text = await res.text();
|
||||
const data = text ? JSON.parse(text) : null;
|
||||
|
||||
if (!res.ok) {
|
||||
throw new ApiError(res.status, data?.error ?? res.statusText);
|
||||
}
|
||||
return data as T;
|
||||
}
|
||||
|
||||
export const api = {
|
||||
get: <T>(p: string) => request<T>(p),
|
||||
post: <T>(p: string, body?: unknown) =>
|
||||
request<T>(p, { method: 'POST', body: body ? JSON.stringify(body) : undefined }),
|
||||
patch: <T>(p: string, body?: unknown) =>
|
||||
request<T>(p, { method: 'PATCH', body: body ? JSON.stringify(body) : undefined })
|
||||
};
|
||||
@@ -0,0 +1,53 @@
|
||||
import { api } from './api';
|
||||
|
||||
export type User = {
|
||||
id: string;
|
||||
email: string;
|
||||
display_name: string | null;
|
||||
email_verified: boolean;
|
||||
};
|
||||
|
||||
export type Settings = {
|
||||
locale: string;
|
||||
currency: string;
|
||||
theme: string;
|
||||
notify_email: boolean;
|
||||
};
|
||||
|
||||
type Me = { user: User; settings: Settings };
|
||||
|
||||
class AuthStore {
|
||||
user = $state<User | null>(null);
|
||||
settings = $state<Settings | null>(null);
|
||||
loaded = $state(false);
|
||||
|
||||
async refresh() {
|
||||
try {
|
||||
const me = await api.get<Me>('/auth/me');
|
||||
this.user = me.user;
|
||||
this.settings = me.settings;
|
||||
} catch {
|
||||
this.user = null;
|
||||
this.settings = null;
|
||||
} finally {
|
||||
this.loaded = true;
|
||||
}
|
||||
}
|
||||
|
||||
set(me: Me) {
|
||||
this.user = me.user;
|
||||
this.settings = me.settings;
|
||||
this.loaded = true;
|
||||
}
|
||||
|
||||
async logout() {
|
||||
try {
|
||||
await api.post('/auth/logout');
|
||||
} finally {
|
||||
this.user = null;
|
||||
this.settings = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export const auth = new AuthStore();
|
||||
Reference in New Issue
Block a user