98 lines
3.0 KiB
TypeScript
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;
|