refactor of data-service

This commit is contained in:
Boki 2025-06-12 08:03:09 -04:00
parent 6fb98c69f2
commit 09c97df1a8
49 changed files with 2394 additions and 112 deletions

View file

@ -11,15 +11,17 @@ export class AxiosAdapter implements RequestAdapter {
canHandle(config: RequestConfig): boolean {
// Axios handles SOCKS proxies
return Boolean(
config.proxy && (config.proxy.protocol === 'socks4' || config.proxy.protocol === 'socks5')
config.proxy &&
typeof config.proxy !== 'string' &&
(config.proxy.protocol === 'socks4' || config.proxy.protocol === 'socks5')
);
}
async request<T = any>(config: RequestConfig, signal: AbortSignal): Promise<HttpResponse<T>> {
const { url, method = 'GET', headers, data, proxy } = config;
if (!proxy) {
throw new Error('Axios adapter requires proxy configuration');
if (!proxy || typeof proxy === 'string') {
throw new Error('Axios adapter requires ProxyInfo configuration');
}
// Create proxy configuration using ProxyManager

View file

@ -9,6 +9,9 @@ import type { RequestAdapter } from './types';
export class FetchAdapter implements RequestAdapter {
canHandle(config: RequestConfig): boolean {
// Fetch handles non-proxy requests and HTTP/HTTPS proxies
if (typeof config.proxy === 'string') {
return config.proxy.startsWith('http');
}
return !config.proxy || config.proxy.protocol === 'http' || config.proxy.protocol === 'https';
}
@ -31,7 +34,11 @@ export class FetchAdapter implements RequestAdapter {
}
// Add proxy if needed (using Bun's built-in proxy support)
if (proxy) {
if (typeof proxy === 'string') {
// If proxy is a URL string, use it directly
(fetchOptions as any).proxy = proxy;
} else if (proxy) {
// If proxy is a ProxyInfo object, create a proxy URL
(fetchOptions as any).proxy = ProxyManager.createProxyUrl(proxy);
}
const response = await fetch(url, fetchOptions);

View file

@ -2,6 +2,7 @@ import type { Logger } from '@stock-bot/logger';
import { AdapterFactory } from './adapters/index';
import type { HttpClientConfig, HttpResponse, RequestConfig } from './types';
import { HttpError } from './types';
import { getRandomUserAgent } from './user-agent';
export class HttpClient {
private readonly config: HttpClientConfig;
@ -165,9 +166,17 @@ export class HttpClient {
* Merge configs with defaults
*/
private mergeConfig(config: RequestConfig): RequestConfig {
// Merge headers with automatic User-Agent assignment
const mergedHeaders = { ...this.config.headers, ...config.headers };
// Add random User-Agent if not specified
if (!mergedHeaders['User-Agent'] && !mergedHeaders['user-agent']) {
mergedHeaders['User-Agent'] = getRandomUserAgent();
}
return {
...config,
headers: { ...this.config.headers, ...config.headers },
headers: mergedHeaders,
timeout: config.timeout ?? this.config.timeout,
};
}

View file

@ -1,8 +1,9 @@
// Re-export all types and classes
export * from './types';
export * from './adapters/index';
export * from './client';
export * from './proxy-manager';
export * from './adapters/index';
export * from './types';
export * from './user-agent';
// Default export
export { HttpClient as default } from './client';

View file

@ -32,7 +32,7 @@ export interface RequestConfig {
headers?: Record<string, string>;
data?: any; // Changed from 'body' to 'data' for consistency
timeout?: number;
proxy?: ProxyInfo;
proxy?: ProxyInfo | string; // Proxy can be a ProxyInfo object or a URL string
}
export interface HttpResponse<T = any> {

View file

@ -0,0 +1,6 @@
import UserAgent from 'user-agents';
export function getRandomUserAgent(): string {
const userAgent = new UserAgent();
return userAgent.toString();
}