import axios from 'axios'; export const API_URL = (window.location.hostname === 'localhost' || window.location.hostname === '127.0.0.1') ? "http://127.0.0.1:8787" : ""; export function resolveMediaUrl(value?: string | null): string { if (!value) return ''; return value.startsWith('/api/media/') ? API_URL + value : value; } function resolveMediaUrls(value: unknown): unknown { if (typeof value === 'string') return resolveMediaUrl(value); if (Array.isArray(value)) return value.map(resolveMediaUrls); if (value && typeof value === 'object') { return Object.fromEntries( Object.entries(value as Record).map(([key, nested]) => [key, resolveMediaUrls(nested)]) ); } return value; } export const api = axios.create({ baseURL: API_URL }); export const adminApi = axios.create({ baseURL: API_URL }); api.interceptors.request.use((config) => { // Force the /api prefix on all internal API calls that forgot it if (config.url && !config.url.startsWith('/api') && !config.url.startsWith('http')) { config.url = `/api${config.url.startsWith('/') ? '' : '/'}${config.url}`; } const token = localStorage.getItem('user_auth_token'); if (token) { config.headers.Authorization = `Bearer ${token}`; } if (typeof FormData !== 'undefined' && config.data instanceof FormData) { config.headers['Content-Type'] = undefined; } const currentOrigin = localStorage.getItem('mworld_origin') || window.location.origin; config.headers['x-mworld-origin'] = currentOrigin; return config; }); api.interceptors.response.use( (response) => { response.data = resolveMediaUrls(response.data); return response; }, (error) => { if (error.response?.status === 401) { // Prevent infinite page reloads on check-in failures const isCheckIn = error.config?.url?.includes('/user/check-in'); if (!isCheckIn) { const hadToken = localStorage.getItem('user_auth_token'); localStorage.removeItem('user_auth_token'); localStorage.removeItem('auth_user'); if (hadToken) window.location.reload(); } } return Promise.reject(error); } ); adminApi.interceptors.request.use((config) => { if (config.url && !config.url.startsWith('http')) { if (config.url.startsWith('/api/admin')) { // Already namespaced. } else if (config.url.startsWith('/api/')) { config.url = `/api/admin${config.url.slice('/api'.length)}`; } else { config.url = `/api/admin${config.url.startsWith('/') ? '' : '/'}${config.url}`; } } const token = sessionStorage.getItem('admin_auth_token'); if (token) config.headers.Authorization = `Bearer ${token}`; if (typeof FormData !== 'undefined' && config.data instanceof FormData) { config.headers['Content-Type'] = undefined; } config.headers['x-mworld-origin'] = window.location.origin; return config; }); adminApi.interceptors.response.use( (response) => { response.data = resolveMediaUrls(response.data); return response; }, (error) => Promise.reject(error) ); export default api;