app-uau39m/frontend/src/api.ts
2026-09-28 23:38:56 +05:30

98 lines
3.0 KiB
TypeScript

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<string, unknown>).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;