diff --git a/.env.development b/.env.development index 54366d4..dec961a 100644 --- a/.env.development +++ b/.env.development @@ -2,4 +2,4 @@ NODE_ENV = 'development' # 本地环境接口地址 -VITE_API_URL = '/api' +VUE_APP_BASE_API = '/api' diff --git a/.env.production b/.env.production index 919d1bb..b2c0e64 100644 --- a/.env.production +++ b/.env.production @@ -1,2 +1,5 @@ # 线上环境 NODE_ENV = "production" + +# 线上环境接口地址 +VUE_APP_BASE_API = '/api' diff --git a/.env.test b/.env.test index 1077f31..768f0ae 100644 --- a/.env.test +++ b/.env.test @@ -1,2 +1,6 @@ # 测试环境 NODE_ENV = "test" + + +# 测试环境接口地址 +VUE_APP_BASE_API = '/api' diff --git a/index.html b/index.html index dca5870..8fe7e04 100644 --- a/index.html +++ b/index.html @@ -7,7 +7,64 @@ Vite + Vue + TS -
+
+ +
+
+
+
+
+
+
+
diff --git a/package.json b/package.json index cda7cf2..6f7c98c 100644 --- a/package.json +++ b/package.json @@ -19,6 +19,7 @@ "@vueuse/core": "^9.1.1", "@wangeditor/editor": "^5.1.14", "@wangeditor/editor-for-vue": "^5.1.12", + "axios": "^0.27.2", "clipboard": "^2.0.10", "core-js": "^3.6.5", "dayjs": "^1.11.4", diff --git a/src/api/AxiosRequestConfig.md b/src/api/AxiosRequestConfig.md new file mode 100644 index 0000000..e7140bf --- /dev/null +++ b/src/api/AxiosRequestConfig.md @@ -0,0 +1,108 @@ +``` +export interface AxiosRequestConfig { + // `url` 是用于请求的服务器 URL + url?: string; + + // `method` 是创建请求时使用的方法 + method?: Method; + + // `baseURL` 将自动加在 `url` 前面,除非 `url` 是一个绝对 URL。 + // 它可以通过设置一个 `baseURL` 便于为 axios 实例的方法传递相对 URL + baseURL?: string; + + // `transformRequest` 允许在向服务器发送前,修改请求数据 + // 只能用在 'PUT', 'POST' 和 'PATCH' 这几个请求方法 + // 后面数组中的函数必须返回一个字符串,或 ArrayBuffer,或 Stream + transformRequest?: AxiosTransformer | AxiosTransformer[]; + + // `transformResponse` 在传递给 then/catch 前,允许修改响应数据 + transformResponse?: AxiosTransformer | AxiosTransformer[]; + + // `headers` 是即将被发送的自定义请求头 + headers?: any; + + // `params` 是即将与请求一起发送的 URL 参数 + // 必须是一个无格式对象(plain object)或 URLSearchParams 对象 + params?: any; + + // `paramsSerializer` 是一个负责 `params` 序列化的函数 + paramsSerializer?: (params: any) => string; + + // `data` 是作为请求主体被发送的数据 + // 只适用于这些请求方法 'PUT', 'POST', 和 'PATCH' + // 在没有设置 `transformRequest` 时,必须是以下类型之一: + // - string, plain object, ArrayBuffer, ArrayBufferView, URLSearchParams + // - 浏览器专属:FormData, File, Blob + // - Node 专属: Stream + data?: any; + + // `timeout` 指定请求超时的毫秒数(0 表示无超时时间) + // 如果请求话费了超过 `timeout` 的时间,请求将被中断 + timeout?: number; + + // 超时提示消息 + timeoutErrorMessage?: string; + + // `withCredentials` 表示跨域请求时是否需要使用凭证 + withCredentials?: boolean; + + // `adapter` 允许自定义处理请求,以使测试更轻松 + adapter?: AxiosAdapter; + + // `auth` 表示应该使用 HTTP 基础验证,并提供凭据 + auth?: AxiosBasicCredentials; + + // `responseType` 表示服务器响应的数据类型,可以是 'arraybuffer', 'blob', 'document', 'json', 'text', 'stream' + responseType?: ResponseType; + + // `xsrfCookieName` 是用作 xsrf token 的值的cookie的名称 + xsrfCookieName?: string; + + // `xsrfHeaderName` 是携带 xsrf 令牌值的 http 标头的名称 + xsrfHeaderName?: string; + + // `onUploadProgress` 允许为上传处理进度事件 + onUploadProgress?: (progressEvent: any) => void; + + // `onDownloadProgress` 允许为下载处理进度事件 + onDownloadProgress?: (progressEvent: any) => void; + + // `maxContentLength` 定义允许的响应内容的最大尺寸 + maxContentLength?: number; + + // `validateStatus` 定义对于给定的HTTP 响应状态码是 resolve 或 reject promise 。 + // 如果 `validateStatus` 返回 `true` (或者设置为 `null` 或 `undefined`), + // promise 将被 resolve; 否则,promise 将被 rejecte + validateStatus?: ((status: number) => boolean) | null; + + // 请求体最大尺寸 + maxBodyLength?: number; + + // `maxRedirects` 定义在 node.js 中 follow 的最大重定向数目 + // 如果设置为0,将不会 follow 任何重定向 + maxRedirects?: number; + + // `socketPath` 定义了一个在 node.js 中使用的 UNIX Socket。 + // 只能指定 `socketPath` 或 `proxy`。 + // 如果两者都指定,则使用 `socketPath`。 + socketPath?: string | null; + + // `httpAgent` 和 `httpsAgent` 分别在 node.js 中用于定义在执行 http 和 https 时使用的自定义代理。 + httpAgent?: any; + httpsAgent?: any; + + // 'proxy' 定义代理服务器的主机名称和端口 + proxy?: AxiosProxyConfig | false; + + // `cancelToken` 指定用于取消请求的 cancel token + cancelToken?: CancelToken; + + // 将其设置为`false`,它将不会解压缩您的响应,而是保留原始的Content-Encoding头。 + // 默认是true + decompress?: boolean; + + // 控制响应数据是否转换 + transitional?: TransitionalOptions +} + +``` diff --git a/src/api/helper/errorCodeType.ts b/src/api/helper/errorCodeType.ts new file mode 100644 index 0000000..be8acfe --- /dev/null +++ b/src/api/helper/errorCodeType.ts @@ -0,0 +1,44 @@ +export const errorCodeType = function(code:string):string{ + let errMessage:string = "未知错误" + switch (code) { + case 400: + errMessage = '请求失败!请您稍后重试' + break + case 401: + errMessage = '未授权,请重新登录' + break + case 403: + errMessage = '当前账号无权限访问!' + break + case 404: + errMessage = '你所访问的资源不存在!' + break + case 405: + errMessage = '请求方式错误!请您稍后重试' + break + case 408: + errMessage = '请求超时!请您稍后重试' + break + case 500: + errMessage = '服务器端出错' + break + case 501: + errMessage = '网络未实现' + break + case 502: + errMessage = '网络错误' + break + case 503: + errMessage = '服务不可用' + break + case 504: + errMessage = '网络超时' + break + case 505: + errMessage = 'http版本不支持该请求' + break + default: + errMessage = `其他连接错误 --${code}` + } + return errMessage +} diff --git a/src/api/index.ts b/src/api/index.ts deleted file mode 100644 index 8b13789..0000000 --- a/src/api/index.ts +++ /dev/null @@ -1 +0,0 @@ - diff --git a/src/api/request.ts b/src/api/request.ts new file mode 100644 index 0000000..f9a826e --- /dev/null +++ b/src/api/request.ts @@ -0,0 +1,57 @@ +import axios, { AxiosInstance, AxiosError, AxiosRequestConfig, AxiosResponse } from 'axios' +import { ElMessage } from "element-plus"; +import {useUserStore} from "@/store/modules/user" +// 创建axios实例 进行基本参数配置 +const service = axios.create({ + // 默认请求地址,根据环境的不同可在.env 文件中进行修改 + baseURL: import.meta.env.VUE_APP_BASE_API, + // 设置接口访问超时时间 + timeout: 3000000, // request timeout, + // 跨域时候允许携带凭证 + withCredentials: true +}) + +// request interceptor 接口请求拦截 +service.interceptors.request.use((config:AxiosRequestConfig)=>{ + /** + * 用户登录之后获取服务端返回的token,后面每次请求都在请求头中带上token进行JWT校验 + * token 存储在本地储存中(storage)、vuex、pinia + */ + const userStore = useUserStore(); + const token: string = userStore.token; + // 自定义请求头 + if(token){ config.headers['Authorization'] = token} + return config +},(error: AxiosError) => { + // 请求错误,这里可以用全局提示框进行提示 + return Promise.reject(error); +}) + +// response interceptor 接口响应拦截 +service.interceptors.response.use((response: AxiosResponse) =>{ + // 直接返回res,当然你也可以只返回res.data + // 系统如果有自定义code也可以在这里处理 + return response + + +},(error: AxiosError) => { + return Promise.reject(error) +}) + + +/** + * @description 显示错误消息 + * opt 传入参数 + * err 错误信息 + * type 消息类型 + * duration 消息持续时间 + */ +function showErrMessage (opt, err, type:any= 'error', duration:number = 5000){ + ElMessage({ + message: err.msg, + type:type, + duration: duration + }) +} + +export default service diff --git a/src/api/user.ts b/src/api/user.ts new file mode 100644 index 0000000..376f50a --- /dev/null +++ b/src/api/user.ts @@ -0,0 +1,9 @@ +import request from './request' + +export function login(data) { + return request({ + url: '/vue-element-perfect/user/login', + method: 'post', + data + }) +} diff --git a/src/main.ts b/src/main.ts index 04b9462..b7f20db 100644 --- a/src/main.ts +++ b/src/main.ts @@ -11,15 +11,14 @@ import 'virtual:svg-icons-register' import SvgIcon from '@/components/SvgIcon/index.vue'// svg component // UI框架 element-plus import ElementPlus from 'element-plus' -import UContainerLayout from '@/components/u-container-layout/index.vue' import 'element-plus/dist/index.css' - // 引入暗黑模式 element-plus 2.2 内置暗黑模式 import 'element-plus/theme-chalk/dark/css-vars.css' // 自定义暗黑模式 import "@/styles/element-dark.scss"; - +// 引入全局组件布局 +import UContainerLayout from '@/components/u-container-layout/index.vue' const app = createApp(App) app.component('svg-icon',SvgIcon) diff --git a/src/store/modules/tagsView.ts b/src/store/modules/tagsView.ts index c762d05..be72bbd 100644 --- a/src/store/modules/tagsView.ts +++ b/src/store/modules/tagsView.ts @@ -70,7 +70,6 @@ export const useTagsViewStore = defineStore({ delAllViews(){ return new Promise((resolve) => { this.visitedViews = this.visitedViews.filter(v=>v.meta.affix) - console.log('===============',this.visitedViews) this.cachedViews = this.visitedViews.filter(v=>v.meta.affix) resolve([...this.visitedViews]) }) diff --git a/src/store/modules/user.ts b/src/store/modules/user.ts index 3002aca..b9218ff 100644 --- a/src/store/modules/user.ts +++ b/src/store/modules/user.ts @@ -46,6 +46,7 @@ export const useUserStore = defineStore({ }, }, + // 进行持久化存储 persist: { // 本地存储的名称 key: "userState", diff --git a/src/utils/Print.js b/src/utils/Print.js new file mode 100644 index 0000000..a0a9baf --- /dev/null +++ b/src/utils/Print.js @@ -0,0 +1,124 @@ +/* @Print.js + * DH (http://denghao.me) + * 2017-7-14 + */ +(function (window, document) { + var Print = function (dom, options) { + if (!(this instanceof Print)) return new Print(dom, options); + + this.options = this.extend({ + noPrint: '.no-print', + onStart: function () { }, + onEnd: function () { } + }, options); + + if ((typeof dom) === "string") { + this.dom = document.querySelector(dom); + } else { + this.dom = dom; + } + + this.init(); + }; + Print.prototype = { + init: function () { + var content = this.getStyle() + this.getHtml(); + this.writeIframe(content); + }, + extend: function (obj, obj2) { + for (var k in obj2) { + obj[k] = obj2[k]; + } + return obj; + }, + + getStyle: function () { + var str = "", + styles = document.querySelectorAll('style,link'); + for (var i = 0; i < styles.length; i++) { + str += styles[i].outerHTML; + } + str += ""; + + return str; + }, + + getHtml: function () { + var inputs = document.querySelectorAll('input'); + var textareas = document.querySelectorAll('textarea'); + var selects = document.querySelectorAll('select'); + + for (var k in inputs) { + if (inputs[k].type == "checkbox" || inputs[k].type == "radio") { + if (inputs[k].checked == true) { + inputs[k].setAttribute('checked', "checked") + } else { + inputs[k].removeAttribute('checked') + } + } else if (inputs[k].type == "text") { + inputs[k].setAttribute('value', inputs[k].value) + } + } + + for (var k2 in textareas) { + if (textareas[k2].type == 'textarea') { + textareas[k2].innerHTML = textareas[k2].value + } + } + + for (var k3 in selects) { + if (selects[k3].type == 'select-one') { + var child = selects[k3].children; + for (var i in child) { + if (child[i].tagName == 'OPTION') { + if (child[i].selected == true) { + child[i].setAttribute('selected', "selected") + } else { + child[i].removeAttribute('selected') + } + } + } + } + } + + return this.dom.outerHTML; + }, + + writeIframe: function (content) { + var w, doc, iframe = document.createElement('iframe'), + f = document.body.appendChild(iframe); + iframe.id = "myIframe"; + iframe.style = "position:absolute;width:0;height:0;top:-10px;left:-10px;"; + + w = f.contentWindow || f.contentDocument; + doc = f.contentDocument || f.contentWindow.document; + doc.open(); + doc.write(content); + doc.close(); + this.toPrint(w, function () { + document.body.removeChild(iframe) + }); + }, + + toPrint: function (w, cb) { + var _this = this; + w.onload = function () { + try { + setTimeout(function () { + w.focus(); + typeof _this.options.onStart === 'function' && _this.options.onStart(); + if (!w.document.execCommand('print', false, null)) { + w.print(); + } + typeof _this.options.onEnd === 'function' && _this.options.onEnd(); + w.close(); + cb && cb() + }); + } catch (err) { + console.log('err', err); + } + } + } + }; + window.Print = Print; +}(window, document)); \ No newline at end of file diff --git a/src/utils/emojis.js b/src/utils/emojis.js deleted file mode 100644 index d1da910..0000000 --- a/src/utils/emojis.js +++ /dev/null @@ -1,35 +0,0 @@ -export default { - imgs: [ - '爱你', - '爱情', - '爱心', - '傲慢', - '白眼', - '抱拳', - '鄙视', - '闭嘴', - '便便', - '擦汗', - '菜刀', - '差劲', - '呲牙', - '大哭', - '蛋糕', - '刀', - '得意', - '凋谢', - '发呆', - 'NO', - 'OK', - '发抖', - '发怒', - '饭', - '飞吻', - '奋斗', - '疯了', - '尴尬', - '勾引', - '鼓掌', - '哈欠', - ], -} diff --git a/src/views/charts/components/migration/index.vue b/src/views/charts/components/migration/index.vue index 49628f9..454a44a 100644 --- a/src/views/charts/components/migration/index.vue +++ b/src/views/charts/components/migration/index.vue @@ -42,7 +42,7 @@ 新疆: [87.9236, 43.5883], 河南: [113.4668, 34.6234], - 西藏: [116.3896, 39.91], + 西藏: [91.091762, 30.037072], 浙江: [119.5313, 29.8773], 福建: [119.4543, 25.9222], 湖南: [113.0823, 28.2568], diff --git a/src/views/other/Print.js b/src/views/other/Print.js new file mode 100644 index 0000000..a0a9baf --- /dev/null +++ b/src/views/other/Print.js @@ -0,0 +1,124 @@ +/* @Print.js + * DH (http://denghao.me) + * 2017-7-14 + */ +(function (window, document) { + var Print = function (dom, options) { + if (!(this instanceof Print)) return new Print(dom, options); + + this.options = this.extend({ + noPrint: '.no-print', + onStart: function () { }, + onEnd: function () { } + }, options); + + if ((typeof dom) === "string") { + this.dom = document.querySelector(dom); + } else { + this.dom = dom; + } + + this.init(); + }; + Print.prototype = { + init: function () { + var content = this.getStyle() + this.getHtml(); + this.writeIframe(content); + }, + extend: function (obj, obj2) { + for (var k in obj2) { + obj[k] = obj2[k]; + } + return obj; + }, + + getStyle: function () { + var str = "", + styles = document.querySelectorAll('style,link'); + for (var i = 0; i < styles.length; i++) { + str += styles[i].outerHTML; + } + str += ""; + + return str; + }, + + getHtml: function () { + var inputs = document.querySelectorAll('input'); + var textareas = document.querySelectorAll('textarea'); + var selects = document.querySelectorAll('select'); + + for (var k in inputs) { + if (inputs[k].type == "checkbox" || inputs[k].type == "radio") { + if (inputs[k].checked == true) { + inputs[k].setAttribute('checked', "checked") + } else { + inputs[k].removeAttribute('checked') + } + } else if (inputs[k].type == "text") { + inputs[k].setAttribute('value', inputs[k].value) + } + } + + for (var k2 in textareas) { + if (textareas[k2].type == 'textarea') { + textareas[k2].innerHTML = textareas[k2].value + } + } + + for (var k3 in selects) { + if (selects[k3].type == 'select-one') { + var child = selects[k3].children; + for (var i in child) { + if (child[i].tagName == 'OPTION') { + if (child[i].selected == true) { + child[i].setAttribute('selected', "selected") + } else { + child[i].removeAttribute('selected') + } + } + } + } + } + + return this.dom.outerHTML; + }, + + writeIframe: function (content) { + var w, doc, iframe = document.createElement('iframe'), + f = document.body.appendChild(iframe); + iframe.id = "myIframe"; + iframe.style = "position:absolute;width:0;height:0;top:-10px;left:-10px;"; + + w = f.contentWindow || f.contentDocument; + doc = f.contentDocument || f.contentWindow.document; + doc.open(); + doc.write(content); + doc.close(); + this.toPrint(w, function () { + document.body.removeChild(iframe) + }); + }, + + toPrint: function (w, cb) { + var _this = this; + w.onload = function () { + try { + setTimeout(function () { + w.focus(); + typeof _this.options.onStart === 'function' && _this.options.onStart(); + if (!w.document.execCommand('print', false, null)) { + w.print(); + } + typeof _this.options.onEnd === 'function' && _this.options.onEnd(); + w.close(); + cb && cb() + }); + } catch (err) { + console.log('err', err); + } + } + } + }; + window.Print = Print; +}(window, document)); \ No newline at end of file diff --git a/src/views/other/editor/index.vue b/src/views/other/editor/index.vue index 47d39c4..ef3c20c 100644 --- a/src/views/other/editor/index.vue +++ b/src/views/other/editor/index.vue @@ -23,7 +23,7 @@ 双向绑定的 value 值,使用示例:v-model='content' - https://www.wangeditor.com/v5/for-frame.html + https://www.wangeditor.com/v5/for-frame.html diff --git a/src/views/other/print.vue b/src/views/other/print.vue index f0eae16..3cb46ba 100644 --- a/src/views/other/print.vue +++ b/src/views/other/print.vue @@ -1,25 +1,42 @@ diff --git a/yarn.lock b/yarn.lock index 424f29e..30abce5 100644 --- a/yarn.lock +++ b/yarn.lock @@ -696,11 +696,24 @@ async@^3.2.3: resolved "https://registry.npmmirror.com/async/-/async-3.2.4.tgz#2d22e00f8cddeb5fde5dd33522b56d1cf569a81c" integrity sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ== +asynckit@^0.4.0: + version "0.4.0" + resolved "https://registry.npmmirror.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" + integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q== + atob@^2.1.2: version "2.1.2" resolved "https://registry.npmmirror.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg== +axios@^0.27.2: + version "0.27.2" + resolved "https://registry.npmmirror.com/axios/-/axios-0.27.2.tgz#207658cc8621606e586c85db4b41a750e756d972" + integrity sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ== + dependencies: + follow-redirects "^1.14.9" + form-data "^4.0.0" + balanced-match@^1.0.0: version "1.0.2" resolved "https://registry.npmmirror.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" @@ -950,6 +963,13 @@ color-name@~1.1.4: resolved "https://registry.npmmirror.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== +combined-stream@^1.0.8: + version "1.0.8" + resolved "https://registry.npmmirror.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" + integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== + dependencies: + delayed-stream "~1.0.0" + commander@^2.20.3: version "2.20.3" resolved "https://registry.npmmirror.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" @@ -1164,6 +1184,11 @@ define-property@^2.0.2: is-descriptor "^1.0.2" isobject "^3.0.1" +delayed-stream@~1.0.0: + version "1.0.0" + resolved "https://registry.npmmirror.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" + integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ== + delegate@^3.1.2: version "3.2.0" resolved "https://registry.npmmirror.com/delegate/-/delegate-3.2.0.tgz#b66b71c3158522e8ab5744f720d8ca0c2af59166" @@ -1813,11 +1838,25 @@ flatted@^3.1.0: resolved "https://registry.npmmirror.com/flatted/-/flatted-3.2.6.tgz#022e9218c637f9f3fc9c35ab9c9193f05add60b2" integrity sha512-0sQoMh9s0BYsm+12Huy/rkKxVu4R1+r96YX5cG44rHV0pQ6iC3Q+mkoMFaGWObMFYQxCVT+ssG1ksneA2MI9KQ== +follow-redirects@^1.14.9: + version "1.15.1" + resolved "https://registry.npmmirror.com/follow-redirects/-/follow-redirects-1.15.1.tgz#0ca6a452306c9b276e4d3127483e29575e207ad5" + integrity sha512-yLAMQs+k0b2m7cVxpS1VKJVvoz7SS9Td1zss3XRwXj+ZDH00RJgnuLx7E44wx02kQLrdM3aOOy+FpzS7+8OizA== + for-in@^1.0.2: version "1.0.2" resolved "https://registry.npmmirror.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" integrity sha512-7EwmXrOjyL+ChxMhmG5lnW9MPt1aIeZEwKhQzoBUdTV0N3zuwWDZYVJatDvZ2OyzPUvdIAZDsCetk3coyMfcnQ== +form-data@^4.0.0: + version "4.0.0" + resolved "https://registry.npmmirror.com/form-data/-/form-data-4.0.0.tgz#93919daeaf361ee529584b9b31664dc12c9fa452" + integrity sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww== + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.8" + mime-types "^2.1.12" + frac@~1.1.2: version "1.1.2" resolved "https://registry.npmmirror.com/frac/-/frac-1.1.2.tgz#3d74f7f6478c88a1b5020306d747dc6313c74d0b" @@ -2591,6 +2630,11 @@ micromatch@^4.0.4: braces "^3.0.2" picomatch "^2.3.1" +mime-db@1.52.0: + version "1.52.0" + resolved "https://registry.npmmirror.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" + integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== + mime-match@^1.0.2: version "1.0.2" resolved "https://registry.npmmirror.com/mime-match/-/mime-match-1.0.2.tgz#3f87c31e9af1a5fd485fb9db134428b23bbb7ba8" @@ -2598,6 +2642,13 @@ mime-match@^1.0.2: dependencies: wildcard "^1.1.0" +mime-types@^2.1.12: + version "2.1.35" + resolved "https://registry.npmmirror.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a" + integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== + dependencies: + mime-db "1.52.0" + mimic-response@^3.1.0: version "3.1.0" resolved "https://registry.npmmirror.com/mimic-response/-/mimic-response-3.1.0.tgz#2d1d59af9c1b129815accc2c46a022a5ce1fa3c9"