From 4a67f85dcbf948f5a2c93299a75a92db6d8e02ef Mon Sep 17 00:00:00 2001 From: Mono Mono Date: Sat, 14 Feb 2026 18:20:07 -0500 Subject: [PATCH] #28 refactor(api): using axios instead fetch. --- src/services/django-api.js | 51 +++++--------------------------------- src/services/http.js | 48 +++++++++++++++++++++++++++++++++++ vite.config.mjs | 10 -------- 3 files changed, 54 insertions(+), 55 deletions(-) create mode 100644 src/services/http.js diff --git a/src/services/django-api.js b/src/services/django-api.js index a52cd3b..b302065 100644 --- a/src/services/django-api.js +++ b/src/services/django-api.js @@ -1,36 +1,17 @@ import AuthService from '@/services/auth'; +import http from '@/services/http'; class DjangoApi { constructor() { this.base = import.meta.env.VITE_DJANGO_BASE_URL; } - _authHeaders() { - const token = AuthService.getAccessToken(); - return token ? { Authorization: `Bearer ${token}` } : {}; + getRequest(url) { + return http.get(url).then(r => r.data); } - _handleResponse(response) { - if (!response.ok) { - // Si el token ha expirado (401) intentamos refrescar y re‑intentar - if (response.status === 401) { - return AuthService.refresh().then(newToken => { - // volver a ejecutar la petición original con el nuevo token - const retryHeaders = { - ...response.headers, - Authorization: `Bearer ${newToken}`, - }; - // aquí usamos fetch de nuevo con los mismos parámetros - // (para simplificar, delegamos a getRequest/postRequest) - // En la práctica, extrae la lógica a una función reutilizable. - throw new Error('Retry logic should be implemented here'); - }); - } - return response.json().then(err => { - throw new Error(`Error ${response.status}: ${err.detail || response.statusText}`); - }); - } - return response.json(); + postRequest(url, payload) { + return http.post(url, payload).then(r => r.data); } getCustomers() { @@ -107,26 +88,6 @@ class DjangoApi { const url = this.base + '/don_confiao/api/enviar_ventas_a_tryton'; return this.postRequest(url, {}); } - - getRequest(url) { - return fetch(url, { - headers: { - 'Content-Type': 'application/json', - ...this._authHeaders(), - }, - }).then(this._handleResponse); - } - - postRequest(url, content) { - return fetch(url, { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - ...this._authHeaders(), - }, - body: JSON.stringify(content), - }).then(this._handleResponse); - } } - export default DjangoApi; +export default DjangoApi; diff --git a/src/services/http.js b/src/services/http.js new file mode 100644 index 0000000..27884c7 --- /dev/null +++ b/src/services/http.js @@ -0,0 +1,48 @@ +import axios from 'axios'; +import AuthService from '@/services/auth'; + +const http = axios.create({ + baseURL: import.meta.env.VITE_DJANGO_BASE_URL, // ← raíz del API + headers: { + 'Content-Type': 'application/json', + }, +}); + +http.interceptors.request.use( + config => { + const token = AuthService.getAccessToken(); + if (token) { + config.headers.Authorization = `Bearer ${token}`; + } + return config; + }, + error => Promise.reject(error) +); + +http.interceptors.response.use( + response => response, // paso directo si todo está OK + async error => { + const originalRequest = error.config; + + // Sólo intentamos refrescar una vez + if (error.response?.status === 401 && !originalRequest._retry) { + originalRequest._retry = true; + try { + const newAccess = await AuthService.refresh(); // guarda el nuevo token + // vuelve a colocar el header actualizado + originalRequest.headers.Authorization = `Bearer ${newAccess}`; + return http.request(originalRequest); // re‑intenta la petición + } catch (refreshError) { + // Si el refresh falla, forzamos logout + AuthService.logout(); + // opcional: redirigir al login + window.location.href = '/login'; + return Promise.reject(refreshError); + } + } + + return Promise.reject(error); + } +); + +export default http; diff --git a/vite.config.mjs b/vite.config.mjs index 3d70eca..bfb192d 100644 --- a/vite.config.mjs +++ b/vite.config.mjs @@ -11,16 +11,6 @@ import Vuetify, { transformAssetUrls } from 'vite-plugin-vuetify' import { defineConfig } from 'vite' import { fileURLToPath, URL } from 'node:url' -const aliasMap = { - '@': fileURLToPath(new URL('./src', import.meta.url)), -}; - -console.log('🔧 Alias configurado:'); -console.log(aliasMap); // <-- se muestra en la terminal al iniciar Vite -console.log('Resolución real de "@":', aliasMap['@']); - - - // https://vitejs.dev/config/ export default defineConfig({ plugins: [