import axios, { type AxiosRequestConfig, type AxiosResponse } from 'axios'; import { ProxyManager } from '../proxy-manager'; import type { HttpResponse, RequestConfig } from '../types'; import { HttpError } from '../types'; import type { RequestAdapter } from './types'; /** * Axios adapter for SOCKS proxies */ export class AxiosAdapter implements RequestAdapter { canHandle(config: RequestConfig): boolean { // Axios handles SOCKS proxies return Boolean( config.proxy && typeof config.proxy !== 'string' && (config.proxy.protocol === 'socks4' || config.proxy.protocol === 'socks5') ); } async request(config: RequestConfig, signal: AbortSignal): Promise> { const { url, method = 'GET', headers, data, proxy } = config; if (!proxy || typeof proxy === 'string') { throw new Error('Axios adapter requires ProxyInfo configuration'); } // Create proxy configuration using ProxyManager const axiosConfig: AxiosRequestConfig = { ...ProxyManager.createAxiosConfig(proxy), url, method, headers, data, signal, // Don't throw on non-2xx status codes - let caller handle validateStatus: () => true, }; const response: AxiosResponse = await axios(axiosConfig); const httpResponse: HttpResponse = { data: response.data, status: response.status, headers: response.headers as Record, ok: response.status >= 200 && response.status < 300, }; // Throw HttpError for non-2xx status codes if (!httpResponse.ok) { throw new HttpError( `Request failed with status ${response.status}`, response.status, httpResponse ); } return httpResponse; } }