export const getApiBase = () => process.env.NEXT_PUBLIC_API_BASE ?? '/api' export const getToken = () => { if (typeof window === 'undefined') return null return window.localStorage.getItem('magent_token') } export const setToken = (token: string) => { if (typeof window === 'undefined') return window.localStorage.setItem('magent_token', token) } export const clearToken = () => { if (typeof window === 'undefined') return window.localStorage.removeItem('magent_token') } export const authFetch = (input: RequestInfo | URL, init?: RequestInit) => { const token = getToken() const headers = new Headers(init?.headers || {}) if (token) { headers.set('Authorization', `Bearer ${token}`) } return fetch(input, { ...init, headers }) } export class UnauthorizedError extends Error { constructor() { super('Unauthorized') this.name = 'UnauthorizedError' } } export class ForbiddenError extends Error { constructor() { super('Forbidden') this.name = 'ForbiddenError' } } export const authFetchOrThrow = async (input: RequestInfo | URL, init?: RequestInit) => { const response = await authFetch(input, init) if (response.status === 401) { clearToken() throw new UnauthorizedError() } if (response.status === 403) { throw new ForbiddenError() } return response } export const readResponseText = async (response: Response) => { try { return (await response.text()).trim() } catch { return '' } }