new version with admin

This commit is contained in:
user committed 2025-09-26 12:21:27 +03:00
1 parent 0f983eb34d
commit d08a02b6e7
10 files changed
+2357 -186

No files matched your search

+93 -8
View File
@@ -1,17 +1,102 @@
import axios from 'axios';
import axios, { AxiosError, InternalAxiosRequestConfig } from 'axios';
export const APP_API_BASE_URL = import.meta.env.VITE_API_BASE_URL;
import { getAdminAuthSnapshot } from '~/shared/libs/admin-auth';
export const request = axios.create({
baseURL: APP_API_BASE_URL,
const API_BASE_PATH = '/api/v1';
const API_ENDPOINTS = [
'https://my-public-node-8.projscale.dev',
'http://localhost:3000',
] as const;
const API_BASE_URLS = API_ENDPOINTS.map((endpoint) => {
return `${endpoint.replace(/\/$/, '')}${API_BASE_PATH}`;
});
request.interceptors.request.use((config) => {
const auth_v1_token = localStorage.getItem('auth_v1_token');
const ENDPOINT_INDEX_KEY = '__apiEndpointIndex__';
if (auth_v1_token) {
config.headers.Authorization = auth_v1_token;
const isBrowser = typeof window !== 'undefined';
const readStorage = (key: string) => {
if (!isBrowser) {
return null;
}
try {
return window.localStorage.getItem(key);
} catch (error) {
console.error('Failed to access localStorage', error);
return null;
}
};
type RequestConfig = InternalAxiosRequestConfig & {
[ENDPOINT_INDEX_KEY]?: number;
};
export const request = axios.create({ withCredentials: true });
request.interceptors.request.use((config: RequestConfig) => {
config.headers = config.headers ?? {};
const headers = config.headers as Record<string, any>;
const authToken = readStorage('auth_v1_token');
if (authToken && !headers.Authorization) {
headers.Authorization = authToken;
}
const urlPath = config.url ?? '';
if (urlPath.startsWith('/admin')) {
const { token, headerName } = getAdminAuthSnapshot();
if (token) {
const headerKey = headerName || 'X-Admin-Token';
if (!headers[headerKey]) {
headers[headerKey] = token;
}
}
}
const hasCustomBaseUrl = Boolean(config.baseURL && !API_BASE_URLS.includes(config.baseURL));
if (hasCustomBaseUrl) {
return config;
}
const attempt = typeof config[ENDPOINT_INDEX_KEY] === 'number' ? (config[ENDPOINT_INDEX_KEY] as number) : 0;
config[ENDPOINT_INDEX_KEY] = attempt;
config.baseURL = API_BASE_URLS[attempt] ?? API_BASE_URLS[0];
return config;
});
request.interceptors.response.use(
(response) => response,
async (error: AxiosError) => {
const config = error.config as RequestConfig | undefined;
if (!config) {
return Promise.reject(error);
}
const hasCustomBaseUrl = Boolean(config.baseURL && !API_BASE_URLS.includes(config.baseURL));
if (hasCustomBaseUrl) {
return Promise.reject(error);
}
const isAbortError = error.code === 'ERR_CANCELED' || error.message === 'canceled';
const isNetworkError = !error.response && !isAbortError;
if (!isNetworkError) {
return Promise.reject(error);
}
const currentIndex = typeof config[ENDPOINT_INDEX_KEY] === 'number' ? (config[ENDPOINT_INDEX_KEY] as number) : 0;
const nextIndex = currentIndex + 1;
if (nextIndex >= API_BASE_URLS.length) {
return Promise.reject(error);
}
config[ENDPOINT_INDEX_KEY] = nextIndex;
config.baseURL = API_BASE_URLS[nextIndex];
return request(config);
},
);