66 lines
2.1 KiB
TypeScript
66 lines
2.1 KiB
TypeScript
import type { RequestConfig, HttpResponse } from '../types';
|
|
import type { RequestAdapter } from './types';
|
|
import { ProxyManager } from '../proxy-manager';
|
|
import { HttpError } from '../types';
|
|
|
|
/**
|
|
* Fetch adapter for HTTP/HTTPS proxies and non-proxy requests
|
|
*/
|
|
export class FetchAdapter implements RequestAdapter {
|
|
canHandle(config: RequestConfig): boolean {
|
|
// Fetch handles non-proxy requests and HTTP/HTTPS proxies
|
|
return !config.proxy || config.proxy.protocol === 'http' || config.proxy.protocol === 'https';
|
|
}
|
|
|
|
async request<T = any>(config: RequestConfig, signal: AbortSignal): Promise<HttpResponse<T>> {
|
|
const { url, method = 'GET', headers, data, proxy } = config;
|
|
|
|
// Prepare fetch options
|
|
const fetchOptions: RequestInit = {
|
|
method,
|
|
headers,
|
|
signal,
|
|
};
|
|
|
|
// Add body for non-GET requests
|
|
if (data && method !== 'GET') {
|
|
fetchOptions.body = typeof data === 'string' ? data : JSON.stringify(data);
|
|
if (typeof data === 'object') {
|
|
fetchOptions.headers = { 'Content-Type': 'application/json', ...fetchOptions.headers };
|
|
}
|
|
}
|
|
|
|
// Add proxy if needed (using Bun's built-in proxy support)
|
|
if (proxy) {
|
|
(fetchOptions as any).proxy = ProxyManager.createProxyUrl(proxy);
|
|
} const response = await fetch(url, fetchOptions);
|
|
|
|
// Parse response based on content type
|
|
let responseData: T;
|
|
const contentType = response.headers.get('content-type') || '';
|
|
|
|
if (contentType.includes('application/json')) {
|
|
responseData = await response.json() as T;
|
|
} else {
|
|
responseData = await response.text() as T;
|
|
}
|
|
|
|
const httpResponse: HttpResponse<T> = {
|
|
data: responseData,
|
|
status: response.status,
|
|
headers: Object.fromEntries(response.headers.entries()),
|
|
ok: response.ok,
|
|
};
|
|
|
|
// Throw HttpError for non-2xx status codes
|
|
if (!response.ok) {
|
|
throw new HttpError(
|
|
`Request failed with status ${response.status}`,
|
|
response.status,
|
|
httpResponse
|
|
);
|
|
}
|
|
|
|
return httpResponse;
|
|
}
|
|
}
|