// Cliente da API sobre o axios: uma instância configurada e dois // interceptors fazem o que, com fetch, precisaria ser repetido em cada chamada. import axios, { isAxiosError } from 'axios'; import { API_URL } from './api.js'; import { ErroDaApi, ehCorpoDeErro, sessao, type ClienteDaApi } from './erro-da-api.js'; export function criarClienteAxios(baseURL = API_URL): ClienteDaApi { // Configuração comum a todas as chamadas desta instância. A instância // padrão (`axios.get`, usada nos exemplos 01 a 04) não é alterada. const api = axios.create({ baseURL, timeout: 5000 }); // Interceptor de requisição: roda antes de cada envio. api.interceptors.request.use((config) => { if (sessao.token) { config.headers.Authorization = `Bearer ${sessao.token}`; } return config; }); // Interceptor de resposta: o primeiro callback recebe as respostas 2xx; o // segundo, as rejeições. Aqui toda falha vira ErroDaApi. api.interceptors.response.use( (resposta) => resposta, (erro: unknown) => { if (!isAxiosError(erro)) return Promise.reject(erro); if (!erro.response) { return Promise.reject(new ErroDaApi(null, [erro.code ?? erro.message], { cause: erro })); } const corpo: unknown = erro.response.data; const detalhes = ehCorpoDeErro(corpo) ? corpo.detalhes : [erro.message]; return Promise.reject(new ErroDaApi(erro.response.status, detalhes, { cause: erro })); }, ); return { get: async (caminho: string) => (await api.get(caminho)).data, post: async (caminho: string, corpo: unknown) => (await api.post(caminho, corpo)).data, patch: async (caminho: string, corpo: unknown) => (await api.patch(caminho, corpo)).data, delete: async (caminho: string) => { await api.delete(caminho); }, }; }