import { setMeta, getMeta, type ApiMethodMeta } from './meta'; import { AxiosHttpClient, type BaseError } from '../client'; // ApiError错误接口 export interface ApiError { status: number; // 状态码(来自response的status) statusText: string; // 状态文本(来自response的msg) code: string; // 错误码(字符串) message: string; // 报错信息(字符串) // 没有别的细节了,错误码直接对照常量映射 } // 客户端请求参数接口 export interface ClientRequestParams { method: string; url: string; query?: Record; body?: any; } // 创建 AxiosHttpClient 单例实例 const apiClientInstance = new AxiosHttpClient(); /** * 创建 HTTP 方法装饰器的通用函数 * @param method HTTP 方法类型 * @returns 装饰器函数 */ export function createHttpMethodDecorator(method: ApiMethodMeta['method']) { return function(path: string) { return function(_target: Object, context: ClassMethodDecoratorContext) { // 确保只应用于方法 if (context.kind !== 'method') { throw new Error(`HTTP method decorator (${method}) can only be applied to methods`); } // 获取原始方法 const originalMethod = _target[context.name as keyof Object] as Function; // 设置元数据 setMeta(originalMethod, 'api', { method, path } as ApiMethodMeta); }; }; } /** * 为 API 客户端类绑定 HTTP 客户端实例的装饰器 * @description 该装饰器对当前类注入 AxiosHttpClient 实例 */ export function ApiClientBound(target: T, _context: ClassDecoratorContext) { // 定义一个新类,继承自目标类 return class extends target { // 在构造函数中初始化客户端实例 constructor(...args: any[]) { super(...args); // 添加客户端实例 this.client = apiClientInstance; } } } /** * 请求执行装饰器,自动处理 API 调用逻辑 */ export function Request(target: Object, context: ClassMethodDecoratorContext) { const methodName = String(context.name); // 确保只应用于方法 if (context.kind !== 'method') { throw new Error('Request decorator can only be applied to methods'); } // 保存原始方法 const originalMethod = target[context.name as keyof Object] as Function; // 定义新的方法实现 async function replacementMethod(this: { client: { request: (params: ClientRequestParams) => Promise } }, ...args: any[]) { // 获取 API 元数据 const meta = getMeta(originalMethod, 'api') as ApiMethodMeta | undefined; if (!meta) { throw new Error(`Missing API metadata on ${methodName}. Please use an HTTP method decorator (GET, POST, etc.)`); } const { method, path } = meta; // 处理请求参数 const params = args[0] ?? {}; const body = args[1]; // 替换路径中的动态参数段 let finalPath = path.replace(/:([\w]+)/g, (_, key) => { const paramValue = params[key]; if (paramValue === undefined) { throw new Error(`Missing required path parameter '${key}' for API endpoint '${path}'`); } return String(paramValue); }); // 执行请求并处理错误 try { return await this.client.request({ method, url: finalPath, query: params, body, }); } catch (error: BaseError | any) { // 确保错误对象符合 ApiError 接口 const apiError: ApiError = { status: error.response?.status || 500, statusText: error.response?.msg || 'Internal Server Error', code: error?.code || 'UNKNOWN_ERROR', message: error?.message || 'An unexpected error occurred', }; throw apiError; } } // TS5+直接返回新方法定义 return replacementMethod; }