type HttpMethod = | 'GET' | 'get' | 'POST' | 'post' | 'PUT' | 'put' | 'DELETE' | 'delete' | 'CONNECT' | 'connect' | 'OPTIONS' | 'options' | 'TRACE' | 'trace'; interface RequestOptions { baseUrl?: string; url?: string; data?: Record; method?: HttpMethod; header?: Record; params?: Record; timeout?: number, dataType?: string, responseType?: string, sslVerify?: boolean, withCredentials?: boolean firstIpv4?: boolean, enableHttp2?: boolean, enableQuic?: boolean, enableCache?: boolean, enableHttpDNS?: boolean, httpDNSServiceId?: string, enableChunked?: boolean, forceCellularNetwork?: boolean, enableCookie?: boolean, cloudCache?: object | boolean, defer?: boolean, interceptor?: { request?: RequestInterceptor, response?: ResponseInterceptor } } interface UploadOptions { url: string, baseUrl?: string, files?: File[], fileType?: 'image' | 'video' | 'audio', file?: File, filePath?: string, name?: string, header?: object, timeout?: number, formData?: object, interceptor?: { request?: (config: UploadOptions) => UploadOptions, response?: (response: any) => any; } } type RequestInterceptor = (config: RequestOptions) => RequestOptions; type ResponseInterceptor = (response: any) => any; class uniRequest { baseUrl?: string; defaultHeader: Record; interceptors: { request?: RequestInterceptor; response?: ResponseInterceptor }; constructor(request: RequestOptions) { this.baseUrl = request.baseUrl; this.defaultHeader = { "Content-Type": "application/json;charset=UTF-8", ...request.header, }; this.interceptors = {request: request.interceptor?.request, response: request.interceptor?.response}; } setBaseUrl(baseUrl: string): void { this.baseUrl = baseUrl; } setDefaultHeader(header: Record): void { this.defaultHeader = header; } static created(options: RequestOptions) { return new uniRequest(options); } request(options: RequestOptions): Promise { options = this.buildRequestOptions(options) options = options || {}; options.baseUrl = options.baseUrl || this.baseUrl; options.url = `${options.baseUrl}${options.url}`; options.data = options.data || {}; options.method = (options.method?.toUpperCase() || "GET") as HttpMethod; options.header = options.header || this.defaultHeader; if (typeof options.interceptor?.request === 'function') { options = options.interceptor.request(options); } else if (typeof this.interceptors?.request === 'function') { options = this.interceptors.request(options); } return new Promise((resolve, reject) => { // @ts-ignore uni.request({ ...options, success: (res) => { const response = this.handleResponse(res, options); resolve(response); }, fail: (err) => { const error = this.handleError(err); reject(error); }, }); }); } private handleResponse(response: any, options: RequestOptions): any { if (options.interceptor?.response) { response = options.interceptor?.response(response); } else if (this.interceptors?.response) { response = this.interceptors?.response(response); } return response } private handleUploadResponse(res: any, options: UploadOptions){ if (options.interceptor?.response){ res = options.interceptor?.response(res); } return res } private handleError(error: any): any { throw error; } setRequestInterceptor(interceptor: RequestInterceptor): void { this.interceptors.request = interceptor; } setResponseInterceptor(interceptor: ResponseInterceptor): void { this.interceptors.response = interceptor; } get(options: RequestOptions): Promise { options = options || {}; options.method = "GET"; return this.request(this.buildRequestOptions(options)); } upload(options: UploadOptions) { options.url = `${options.baseUrl ?? this.baseUrl}${options.url}`; if (typeof options.interceptor?.request==='function'){ options = options.interceptor.request(options); } return new Promise((resolve, reject) => { uni.uploadFile({ ...options, success: (res) => { resolve(this.handleUploadResponse(res, options)) }, fail(res){ reject(res) } }); }) } private buildRequestOptions(options: RequestOptions): RequestOptions { if (options.params && Object.keys(options.params).length > 0) { const queryString = Object.keys(options.params) .map((key) => `${encodeURIComponent(key)}=${encodeURIComponent(options.params![key])}`) .join('&'); options.url += `?${queryString}`; } delete options.params; return options; } post(options: RequestOptions): Promise { options = options || {}; options.method = "POST"; return this.request(this.buildRequestOptions(options)); } put(options: RequestOptions): Promise { options = options || {}; options.method = "PUT"; return this.request(this.buildRequestOptions(options)); } delete(options: RequestOptions): Promise { options = options || {}; options.method = "DELETE"; return this.request(this.buildRequestOptions(options)); } } export {uniRequest}