import { adapter } from './adapter.ts'; type Fn = (opts: { url?: string; headers?: Record; body?: Record; [key: string]: any; timeout?: number; }) => Promise>; export type QueryOpts = { url?: string; adapter?: typeof adapter; headers?: Record; timeout?: number; }; type Data = { path?: string; key?: string; payload?: Record; [key: string]: any; }; type Result = { code: number; data?: S; message?: string; success: boolean; }; // 额外功能 type DataOpts = Partial & { beforeRequest?: Fn; afterResponse?: (result: Result) => Promise; }; /** * const query = new Query(); * const res = await query.post({ * path: 'demo', * key: '1', * }); * * U是参数 V是返回值 */ export class Query { adapter: typeof adapter; url: string; beforeRequest?: Fn; afterResponse?: (result: Result) => Promise; headers?: Record; timeout?: number; constructor(opts?: QueryOpts) { this.adapter = opts?.adapter || adapter; this.url = opts?.url || '/api/router'; this.headers = opts?.headers || { 'Content-Type': 'application/json', }; this.timeout = opts?.timeout || 60000 * 3; // 默认超时时间为 60s * 3 } async get(params: Record & Data & U & T, options?: DataOpts): Promise> { return this.post(params, options); } async post(body: Record & Data & T, options?: DataOpts): Promise> { const url = options?.url || this.url; const headers = { ...this.headers, ...options?.headers }; const adapter = options?.adapter || this.adapter; const beforeRequest = options?.beforeRequest || this.beforeRequest; const afterResponse = options?.afterResponse || this.afterResponse; const timeout = options?.timeout || this.timeout; const req = { url: url, headers: headers, body, timeout, }; try { if (beforeRequest) { await beforeRequest(req); } } catch (e) { console.error(e); return { code: 500, success: false, message: 'api request beforeFn error', }; } return adapter(req).then(async (res) => { try { res.success = res.code === 200; if (afterResponse) { return await afterResponse(res); } return res; } catch (e) { console.error(e); return { code: 500, success: false, message: 'api request afterFn error', }; } }); } before(fn: Fn) { this.beforeRequest = fn; } after(fn: (result: Result) => Promise) { this.afterResponse = fn; } } export { adapter };