import axios, { AxiosInstance } from "axios" import { IJWTService, JWTToken } from "../domain/JWT.js" import https from "https" // Cambiar por IJWRGeneralService export type JWTProvider = { /** El servidor está solicitando un token nuevo o refrescando el actual*/ isRefreshing: boolean authToken: JWTToken | undefined tryRefreshToken: () => Promise> getAccessToken: () => Promise> } export class HttpClient { public client: AxiosInstance private jwtManager: JWTProvider<{}> private jwtService: IJWTService | undefined; constructor(args: { baseURL: string, headers: Record, jwtManager: JWTProvider<{}>, // todo: asociar el tipo de token jwtService?: IJWTService, httpsAgent: https.Agent }) { this.client = axios.create({ baseURL: args.baseURL, headers: args.headers, httpsAgent: args.httpsAgent }) this.jwtManager = args.jwtManager if (args.jwtService != undefined) this.jwtService = args.jwtService this.client.interceptors.request.use( async (config) => { // Idealmente estas condiciones no deberian de darse si mantenemos el // token valido de forma preventiva const token = await this.jwtManager.getAccessToken() if (token == undefined) throw new Error("No se ha obtenido el token para la petición") config.headers.Authorization = `Bearer ${this.jwtManager.authToken!.rawToken}` console.log("request completa", config.data) return config; }, (error) => Promise.reject(error) ) // No deberia usarlos de momento this.client.interceptors.response.use( (response) => { return response; }, async (error) => { // TODO: Esta parte no tiene tipos, hay que asegurar el error const req = error.config console.error("[http] Error en la respuesta ", error, error.response) if (error.response?.status == 401) { this.jwtManager.getAccessToken() } return Promise.reject(error) } ) } get get() { return this.client.get } get post() { return this.client.post } get patch() { return this.client.patch } }