{"version":3,"file":"index.mjs","sources":["../../../../src/axios/index.ts"],"sourcesContent":["import axios, { AxiosError } from \"axios\";\nimport { isNil, isObject, isString } from \"lodash-unified\";\nimport { createUniAppAxiosAdapter } from \"../uni-adapter\";\nimport { useFastAxios } from \"./fastAxios\";\nimport type { ApiResponse, AxiosOptions, FastAxiosRequestConfig } from \"./types\";\nimport type { AxiosRequestConfig, AxiosResponse, InternalAxiosRequestConfig } from \"axios\";\n\nconst axiosOptions: AxiosOptions = {\n\tcancelDuplicateRequest: true,\n\tloading: false,\n\tloadingText: \"加载中...\",\n\tcache: false,\n\tgetMethodCacheHandle: true,\n\tsimpleDataFormat: true,\n\tshowErrorMessage: true,\n\tshowCodeMessage: true,\n\tautoDownloadFile: true,\n\trestfulResult: true,\n};\n\nconst pendingMap = new Map();\n\n/**\n * 生成每个请求的唯一key\n */\nconst getPendingKey = (axiosConfig: AxiosRequestConfig): string => {\n\tlet { data } = axiosConfig;\n\tconst { url, method, params } = axiosConfig;\n\t// response里面返回的config.data是个字符串对象\n\tif (isString(data)) data = JSON.parse(data);\n\treturn [url, method, JSON.stringify(params), JSON.stringify(data)].join(\"&\");\n};\n\n/**\n * 储存每个请求的唯一cancel回调, 以此为标识\n */\nconst addPending = (pendingKey: string, axiosConfig: AxiosRequestConfig): void => {\n\taxiosConfig.cancelToken =\n\t\taxiosConfig.cancelToken ||\n\t\tnew axios.CancelToken((cancel) => {\n\t\t\tif (!pendingMap.has(pendingKey)) {\n\t\t\t\tpendingMap.set(pendingKey, cancel);\n\t\t\t}\n\t\t});\n};\n\n/**\n * 删除重复的请求\n */\nconst removePending = (pendingKey: string): void => {\n\tif (pendingMap.has(pendingKey)) {\n\t\tconst cancelToken = pendingMap.get(pendingKey);\n\t\tcancelToken(pendingKey);\n\t\tpendingMap.delete(pendingKey);\n\t}\n};\n\n/**\n * Http 错误状态码处理\n */\nconst httpErrorStatusHandle = async (error: AxiosError | any): Promise<string> => {\n\tlet message = \"\";\n\t// 其他错误码处理\n\t// 尝试获取 Restful 风格返回Code，或者获取响应状态码\n\tconst code = error?.response?.data?.code || error?.response?.status || error?.code || error?.message || \"default\";\n\t// 400业务异常\n\t// 500服务器内部错误，可能返回错误信息\n\t// 判断响应类型是否为blob\n\tif (error?.request?.responseType === \"blob\") {\n\t\ttry {\n\t\t\tmessage = JSON.parse(await error?.response?.data?.text())?.message;\n\t\t} catch {\n\t\t\tmessage = error?.response?.data?.message || useFastAxios().errorCode[code];\n\t\t}\n\t} else {\n\t\tmessage = error?.response?.data?.message || useFastAxios().errorCode[code];\n\t}\n\treturn message;\n};\n\n/**\n * 下载文件\n */\nconst downloadFile = (response: AxiosResponse): void => {\n\tif (typeof uni !== \"undefined\") {\n\t\t// 暂不支持\n\t} else {\n\t\tconst blob = new Blob([response.data], { type: \"application/octet-stream;charset=UTF-8\" });\n\t\tconst contentDisposition = response.headers[\"content-disposition\"];\n\t\tconst result = /filename=([^;]+\\.[^.;]+);*/.exec(contentDisposition);\n\t\tconst filename = result[1];\n\t\tconst downloadElement = document.createElement(\"a\");\n\t\tconst href = window.URL.createObjectURL(blob); // 创建下载的链接\n\t\tconst reg = /^\"(.*)\"$/g;\n\t\tdownloadElement.style.display = \"none\";\n\t\tdownloadElement.href = href;\n\t\tdownloadElement.download = decodeURI(filename.replace(reg, \"$1\")); // 下载后文件名\n\t\tdocument.body.appendChild(downloadElement);\n\t\t// 点击下载\n\t\tdownloadElement.click();\n\t\t// 下载完成移除元素\n\t\tdocument.body.removeChild(downloadElement);\n\t\twindow.URL.revokeObjectURL(href);\n\t}\n};\n\n/**\n * 创建 Axios\n * @param axiosConfig axios 请求配置\n */\nconst createAxios = <Output = any, Input = any>(axiosConfig: FastAxiosRequestConfig<Input>): Promise<Output> => {\n\tconst fastAxios = useFastAxios();\n\n\t// 合并选项\n\tconst options = { ...axiosOptions, ...axiosConfig };\n\n\tif (isNil(options.requestCipher)) {\n\t\toptions.requestCipher = fastAxios.requestCipher;\n\t}\n\n\t// 只有Get请求并且开启了简洁响应才可以进行缓存处理，且默认是不存在loading的\n\tif (options.cache && options.method.toUpperCase() === \"GET\" && options.restfulResult && options.simpleDataFormat) {\n\t\t// 如果启用缓存，则默认是不能携带参数的\n\t\tif (options.params) {\n\t\t\tconsole.warn(\"[Fast.Axios] 如果使用 Http Cache，则不能存在任何 'params' 参数\");\n\t\t}\n\n\t\tif (fastAxios.cache?.get) {\n\t\t\tconst cacheRes = fastAxios.cache.get(options.url);\n\t\t\tif (cacheRes) {\n\t\t\t\treturn Promise.resolve(cacheRes);\n\t\t\t}\n\t\t}\n\t} else {\n\t\t// 不满足上述条件，则默认不使用缓存\n\t\toptions.cache = false;\n\t}\n\n\t// 获取请求唯一 Key\n\tconst pendingKey = getPendingKey(axiosConfig);\n\n\tconst timestamp = Date.now();\n\n\t// 创建 Axios 请求\n\tconst Axios = axios.create({\n\t\t/** 如果是 UniApp 则默认使用适配器 */\n\t\tadapter: typeof uni !== \"undefined\" ? createUniAppAxiosAdapter() : undefined,\n\t\tbaseURL: fastAxios.baseUrl,\n\t\ttimeout: fastAxios.timeout,\n\t\theaders: fastAxios.headers,\n\t\tresponseType: \"json\",\n\t});\n\n\t/**\n\t * 请求拦截\n\t */\n\tAxios.interceptors.request.use(\n\t\t(config: InternalAxiosRequestConfig<Input>) => {\n\t\t\t// 删除重复请求\n\t\t\tremovePending(pendingKey);\n\n\t\t\t// 判断是否开启取消重复请求\n\t\t\toptions.cancelDuplicateRequest && addPending(pendingKey, config);\n\n\t\t\t// 自定义请求拦截器\n\t\t\tfastAxios.interceptors?.request(config);\n\n\t\t\t// 判断是否显示loading层\n\t\t\toptions.loading && fastAxios.loading?.show(options.loadingText);\n\n\t\t\tif (config.responseType === \"json\") {\n\t\t\t\t// 请求参数加密\n\t\t\t\tif (options.requestCipher) {\n\t\t\t\t\tfastAxios.crypto?.encrypt(config, timestamp);\n\t\t\t\t} else {\n\t\t\t\t\t// Get请求缓存处理\n\t\t\t\t\tif (options.getMethodCacheHandle && config.method.toUpperCase() === \"GET\") {\n\t\t\t\t\t\tconfig.params = config.params || {};\n\t\t\t\t\t\tconfig.params._ = timestamp;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn config;\n\t\t},\n\t\t(error) => {\n\t\t\tconsole.error(\"[Fast.Axios]\", error);\n\t\t\treturn Promise.reject(error);\n\t\t}\n\t);\n\n\t/**\n\t * 响应拦截\n\t */\n\tAxios.interceptors.response.use(\n\t\t(response: AxiosResponse<Output, Input>) => {\n\t\t\t// 删除重复请求标识\n\t\t\tremovePending(pendingKey);\n\n\t\t\t// 关闭loading层\n\t\t\toptions.loading && fastAxios.loading?.close(options);\n\n\t\t\t// 自定义响应拦截器\n\t\t\tif (fastAxios.interceptors?.response) {\n\t\t\t\ttry {\n\t\t\t\t\tconst result = fastAxios.interceptors.response(response, options);\n\t\t\t\t\tif (!isNil(result)) {\n\t\t\t\t\t\treturn Promise.resolve(result);\n\t\t\t\t\t}\n\t\t\t\t} catch (error) {\n\t\t\t\t\tconsole.error(\"[Fast.Axios]\", error);\n\t\t\t\t\treturn Promise.reject(error);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (response.config.responseType === \"blob\" || options.method.toUpperCase() === \"DOWNLOAD\") {\n\t\t\t\tif (response.status === 200) {\n\t\t\t\t\t// 判断是否自动下载\n\t\t\t\t\tif (options.autoDownloadFile) {\n\t\t\t\t\t\tdownloadFile(response);\n\t\t\t\t\t}\n\t\t\t\t\t// 这里直接返回\n\t\t\t\t\treturn Promise.resolve(response);\n\t\t\t\t} else {\n\t\t\t\t\tfastAxios.message?.error(fastAxios.errorCode[\"fileDownloadError\"]);\n\t\t\t\t\treturn Promise.reject(response);\n\t\t\t\t}\n\t\t\t} else if (response.config.responseType === \"json\") {\n\t\t\t\tlet responseData = response.data;\n\t\t\t\tif (options.restfulResult) {\n\t\t\t\t\tconst restfulData = responseData as ApiResponse<Output, Input>;\n\t\t\t\t\tconst code: number = restfulData?.code ?? response.status;\n\t\t\t\t\tif (code < 200 || code > 299 || restfulData?.success === false) {\n\t\t\t\t\t\t// 判断是否显示错误消息\n\t\t\t\t\t\tif (options.showCodeMessage) {\n\t\t\t\t\t\t\t// 判断返回的 message 是否为对象类型\n\t\t\t\t\t\t\tif (restfulData?.message) {\n\t\t\t\t\t\t\t\tif (isObject(restfulData?.message)) {\n\t\t\t\t\t\t\t\t\tfastAxios.message?.error(JSON.stringify(restfulData?.message));\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tfastAxios.message?.error(restfulData?.message);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tconsole.error(\"[Fast.Axios]\", new AxiosError(restfulData?.message ?? \"服务器内部错误！\"));\n\t\t\t\t\t\treturn Promise.reject(new AxiosError(restfulData?.message ?? \"服务器内部错误！\"));\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// 请求响应解密\n\t\t\t\tif (options.requestCipher) {\n\t\t\t\t\tresponseData = fastAxios.crypto?.decrypt(response, options);\n\t\t\t\t}\n\n\t\t\t\t// 判断是否缓存\n\t\t\t\tif (options.cache && options.restfulResult && options.simpleDataFormat) {\n\t\t\t\t\tfastAxios.cache?.set(options.url, (responseData as ApiResponse<Output, Input>)?.data);\n\t\t\t\t}\n\n\t\t\t\tif (options.simpleDataFormat) {\n\t\t\t\t\treturn Promise.resolve((responseData as ApiResponse<Output, Input>)?.data);\n\t\t\t\t} else {\n\t\t\t\t\treturn Promise.resolve(responseData);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif (options.simpleDataFormat) {\n\t\t\t\t\treturn Promise.resolve(response.data);\n\t\t\t\t} else {\n\t\t\t\t\treturn Promise.resolve(response);\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\tasync (error: AxiosError) => {\n\t\t\t// 删除重复请求标识\n\t\t\tremovePending(pendingKey);\n\n\t\t\t// 关闭loading层\n\t\t\toptions.loading && fastAxios.loading?.close(options);\n\n\t\t\t// 判断请求是否被取消\n\t\t\tif (axios.isCancel(error)) {\n\t\t\t\tconsole.warn(`[Fast.Axios] ${fastAxios.errorCode[\"cancelDuplicate\"]}`);\n\t\t\t\treturn Promise.reject();\n\t\t\t}\n\n\t\t\t// 判断是否断网\n\t\t\tif (globalThis?.navigator?.onLine === false) {\n\t\t\t\tfastAxios.message?.error(fastAxios.errorCode[\"offLine\"]);\n\t\t\t\treturn Promise.reject();\n\t\t\t}\n\n\t\t\t// 自定义响应错误拦截器\n\t\t\tif (fastAxios.interceptors?.responseError) {\n\t\t\t\ttry {\n\t\t\t\t\tconst result = fastAxios.interceptors.responseError(error, options);\n\t\t\t\t\tif (!isNil(result)) {\n\t\t\t\t\t\treturn Promise.reject(result);\n\t\t\t\t\t}\n\t\t\t\t} catch (error) {\n\t\t\t\t\tconsole.error(\"[Fast.Axios]\", error);\n\t\t\t\t\treturn Promise.reject(error);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// 处理错误状态码\n\t\t\tif (options.showErrorMessage) {\n\t\t\t\tconst message = await httpErrorStatusHandle(error);\n\t\t\t\tfastAxios.message?.error(message);\n\t\t\t}\n\n\t\t\t// 错误继续返回给到具体页面\n\t\t\tconsole.error(\"[Fast.Axios]\", error);\n\t\t\treturn Promise.reject(error);\n\t\t}\n\t);\n\n\treturn Axios(options);\n};\n\nexport const axiosUtil = {\n\t/**\n\t * 请求\n\t * @param axiosConfig axios 请求配置\n\t * @param loading loading配置\n\t */\n\trequest: createAxios,\n\t/**\n\t * 下载文件\n\t */\n\tdownloadFile,\n};\n\nexport * from \"./types/options\";\nexport * from \"./fastAxios\";\n"],"names":["axiosOptions","cancelDuplicateRequest","loading","loadingText","cache","getMethodCacheHandle","simpleDataFormat","showErrorMessage","showCodeMessage","autoDownloadFile","restfulResult","pendingMap","Map","removePending","pendingKey","has","get","cancelToken","delete","downloadFile","response","uni","blob","Blob","data","type","contentDisposition","headers","filename","exec","downloadElement","document","createElement","href","window","URL","createObjectURL","reg","style","display","download","decodeURI","replace","body","appendChild","click","removeChild","revokeObjectURL","axiosUtil","request","axiosConfig","fastAxios","useFastAxios","options","isNil","requestCipher","method","toUpperCase","params","console","warn","cacheRes","url","Promise","resolve","isString","JSON","parse","stringify","join","getPendingKey","timestamp","Date","now","Axios","axios","create","adapter","createUniAppAxiosAdapter","baseURL","baseUrl","timeout","responseType","interceptors","use","config","CancelToken","cancel","set","addPending","show","crypto","encrypt","_","error","reject","close","result","status","message","errorCode","responseData","restfulData","code","success","isObject","AxiosError","decrypt","async","isCancel","globalThis","navigator","onLine","responseError","text","httpErrorStatusHandle"],"mappings":"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"}