const API_BASE = '/api' async function parseResponse(response) { if (response.status === 204) { return null } const data = await response.json().catch(() => null) if (!response.ok) { const message = data?.message || data?.['hydra:description'] || response.statusText throw new Error(message) } return data } export async function apiFetch(path, options = {}) { const token = localStorage.getItem('speedbb_token') const headers = { Accept: 'application/json', ...(options.headers || {}), } if (!(options.body instanceof FormData)) { headers['Content-Type'] = 'application/json' } if (token) { headers.Authorization = `Bearer ${token}` } const response = await fetch(`${API_BASE}${path}`, { ...options, headers, }) return parseResponse(response) } export async function getCollection(path) { const data = await apiFetch(path) return data?.['hydra:member'] || [] } export async function login(email, password) { return apiFetch('/login', { method: 'POST', body: JSON.stringify({ email, password }), }) } export async function registerUser({ email, username, plainPassword }) { return apiFetch('/users', { method: 'POST', body: JSON.stringify({ email, username, plainPassword }), }) } export async function listRootForums() { return getCollection('/forums?parent[exists]=false') } export async function listForumsByParent(parentId) { return getCollection(`/forums?parent=/api/forums/${parentId}`) } export async function getForum(id) { return apiFetch(`/forums/${id}`) } export async function listThreadsByForum(forumId) { return getCollection(`/threads?forum=/api/forums/${forumId}`) } export async function getThread(id) { return apiFetch(`/threads/${id}`) } export async function listPostsByThread(threadId) { return getCollection(`/posts?thread=/api/threads/${threadId}`) } export async function createThread({ title, body, forumId }) { return apiFetch('/threads', { method: 'POST', body: JSON.stringify({ title, body, forum: `/api/forums/${forumId}`, }), }) } export async function createPost({ body, threadId }) { return apiFetch('/posts', { method: 'POST', body: JSON.stringify({ body, thread: `/api/threads/${threadId}`, }), }) }