// Единственная точка выхода вкладок в сеть. Вкладка не создаёт свой axios и не // собирает заголовок авторизации руками — иначе обработка протухшего токена // разъезжается по вкладкам. import axios from 'axios'; // Что делать, когда сервер ответил 401. Ставит оболочка при старте: токен // протух или отозван — надо разлогинить, а не показывать ошибку в снэкбаре. // Само ядро про localStorage не знает — ключ хранения принадлежит приложению. let onUnauthorized: (() => void) | null = null; export function setUnauthorizedHandler(fn: (() => void) | null) { onUnauthorized = fn; } export async function apiFetch(method: string, path: string, token: string, body?: object): Promise { try { const r = await axios({ method, url: path, headers: { Authorization: `Bearer ${token}` }, data: body }); return r.data; } catch (e) { if (axios.isAxiosError(e) && e.response?.status === 401) { onUnauthorized?.(); } throw e; } } // Бэкенды панелей отдают ошибку по-разному: одни как {error}, другие как // {message}. Вкладки читают через этот хелпер, а не разбирают форму ответа // в каждом catch. export function errText(e: unknown, fallback = 'Сервер недоступен'): string { const data = (e as { response?: { data?: { error?: string; message?: string } } })?.response?.data; return data?.error ?? data?.message ?? fallback; }