import type { HeaderGeneratorOptions } from 'header-generator'; import { register } from 'node-network-devtools'; import { createFetch } from 'ofetch'; import { config } from '@/config'; import logger from '@/utils/logger'; declare module 'ofetch' { interface FetchOptions { headerGeneratorOptions?: Partial; } } config.enableRemoteDebugging && process.env.NODE_ENV === 'dev' && register(); const rofetch = createFetch({ fetch: (input: Parameters[0], init?: Parameters[1]) => fetch(input, init) }).create({ retryStatusCodes: [400, 408, 409, 425, 429, 500, 502, 503, 504], retry: config.requestRetry, retryDelay: 1000, // timeout: config.requestTimeout, onResponseError({ request, response, options }) { if (!options.retry) { return; } logger.warn(`Request ${request} with error ${response.status} remaining retry attempts: ${options.retry}`); if (!options.headers) { (options as any).headers = {}; } if (options.headers instanceof Headers) { options.headers.set('x-prefer-proxy', '1'); } else { ((options as any).headers as Record)['x-prefer-proxy'] = '1'; } }, onRequestError({ request, error }) { logger.error(`Request ${request} fail: ${error.cause} ${error}`); for (let cause: unknown = error.cause; cause instanceof Error; cause = cause.cause) { if (cause.message) { error.message += ` (${cause.message})`; } } }, onResponse({ request, response }) { if (response.redirected) { logger.http(`Redirecting to ${response.url} for ${request}`); } }, }); export default rofetch;