import axios, { AxiosRequestConfig, type AxiosInstance } from 'axios'; import { HttpProxyAgent } from 'http-proxy-agent'; import { HttpsProxyAgent } from 'https-proxy-agent'; import { SocksProxyAgent } from 'socks-proxy-agent'; import type { ProxyInfo } from './types'; export class ProxyManager { /** * Determine if we should use Bun fetch (HTTP/HTTPS) or Axios (SOCKS) */ static shouldUseBunFetch(proxy: ProxyInfo): boolean { return proxy.protocol === 'http' || proxy.protocol === 'https'; } /** * Create proxy URL for both Bun fetch and Axios proxy agents */ static createProxyUrl(proxy: ProxyInfo): string { const { protocol, host, port, username, password } = proxy; if (username && password) { return `${protocol}://${encodeURIComponent(username)}:${encodeURIComponent(password)}@${host}:${port}`; } return `${protocol}://${host}:${port}`; } /** * Create appropriate agent for Axios based on proxy type */ static createProxyAgent(proxy: ProxyInfo) { this.validateConfig(proxy); const proxyUrl = this.createProxyUrl(proxy); switch (proxy.protocol) { case 'socks4': case 'socks5': // console.log(`Using SOCKS proxy: ${proxyUrl}`); return new SocksProxyAgent(proxyUrl); case 'http': return new HttpProxyAgent(proxyUrl); case 'https': return new HttpsProxyAgent(proxyUrl); default: throw new Error(`Unsupported proxy protocol: ${proxy.protocol}`); } } /** * Create Axios instance with proxy configuration */ static createAxiosConfig(proxy: ProxyInfo): AxiosRequestConfig { const agent = this.createProxyAgent(proxy); return { httpAgent: agent, httpsAgent: agent, }; } /** * Simple proxy config validation */ static validateConfig(proxy: ProxyInfo): void { if (!proxy.host || !proxy.port) { throw new Error('Proxy host and port are required'); } if (!['http', 'https', 'socks4', 'socks5'].includes(proxy.protocol)) { throw new Error(`Unsupported proxy protocol: ${proxy.protocol}`); } } }