import axios from 'axios'; import { API_URLS, BASE_URL } from './URLs'; import { getToken } from '@/hooks/storage.native'; import AsyncStorage from '@react-native-async-storage/async-storage'; import { router } from 'expo-router'; const httpClient = axios.create({ baseURL: BASE_URL, timeout: 60000, }); httpClient.interceptors.request.use(async (config) => { const token = await getToken(); const lang = await AsyncStorage.getItem('lang'); config.headers['Accept-Language'] = lang; if (token) { config.headers.Authorization = `Bearer ${token}`; } return config; }); let isRefreshing = false; let failedQueue: Array<{ resolve: (value: any) => void; reject: (reason?: any) => void }> = []; const processQueue = (error: any = null) => { failedQueue.forEach((prom) => { if (error) { prom.reject(error); } else { prom.resolve(null); } }); failedQueue = []; }; httpClient.interceptors.response.use( (response) => response, async (error) => { const originalRequest = error.config; // Agar 401 bo'lsa va bu refresh so'rovi bo'lmasa if (error.response?.status === 401 && !originalRequest._retry) { if (isRefreshing) { // Agar allaqachon refresh ketayotgan bo'lsa → kutamiz return new Promise((resolve, reject) => { failedQueue.push({ resolve, reject }); }) .then(() => httpClient(originalRequest)) .catch((err) => Promise.reject(err)); } originalRequest._retry = true; isRefreshing = true; try { const refresh = await AsyncStorage.getItem('refresh_token'); if (!refresh) { throw new Error('Refresh token mavjud emas'); } // Refresh token so'rovi const { data } = await axios.post(`${BASE_URL}${API_URLS.REFRESH}`, { refresh, // backend odatda { refresh } body kutadi }); // Yangi tokenlarni saqlaymiz await AsyncStorage.setItem('access_token', data.access); await AsyncStorage.setItem('refresh_token', data.refresh || refresh); // agar yangi refresh kelmasa, eskisini saqlab qolamiz // Headerni yangilaymiz originalRequest.headers.Authorization = `Bearer ${data.access}`; // Kutgan so'rovlarni qayta yuboramiz processQueue(); // Original so'rovni qayta yuboramiz return httpClient(originalRequest); } catch (refreshError) { console.error('Refresh token xatosi:', refreshError); // Refresh muvaffaqiyatsiz bo'lsa processQueue(refreshError); // Tokenlarni o'chirib, logout qilamiz await AsyncStorage.removeItem('access_token'); await AsyncStorage.removeItem('refresh_token'); // Foydalanuvchini login sahifasiga yo'naltiramiz router.replace('/'); } finally { isRefreshing = false; } } // Boshqa xatolar uchun oddiy reject return Promise.reject(error); } ); export default httpClient;