refactor(project): @vben/vite-connect is reconfigured to support synchronization

pull/48/MERGE
vben 2024-07-13 21:00:31 +08:00
parent c81ac5684c
commit e441d14fa2
20 changed files with 175 additions and 126 deletions

View File

@ -26,6 +26,7 @@
"cross-env": "^7.0.3", "cross-env": "^7.0.3",
"joi": "^17.13.3", "joi": "^17.13.3",
"js-yaml": "^4.1.0", "js-yaml": "^4.1.0",
"mockjs": "^1.1.0",
"passport": "^0.7.0", "passport": "^0.7.0",
"passport-jwt": "^4.0.1", "passport-jwt": "^4.0.1",
"passport-local": "^1.0.0", "passport-local": "^1.0.0",
@ -36,6 +37,7 @@
"@nestjs/cli": "^10.4.2", "@nestjs/cli": "^10.4.2",
"@nestjs/schematics": "^10.1.2", "@nestjs/schematics": "^10.1.2",
"@types/express": "^4.17.21", "@types/express": "^4.17.21",
"@types/mockjs": "^1.0.10",
"@types/node": "^20.14.10", "@types/node": "^20.14.10",
"nodemon": "^3.1.4", "nodemon": "^3.1.4",
"ts-node": "^10.9.2", "ts-node": "^10.9.2",

View File

@ -1,3 +1,5 @@
VITE_PORT = 5555
# spa-title # spa-title
VITE_GLOB_APP_TITLE = Vben Admin Pro VITE_GLOB_APP_TITLE = Vben Admin Pro

View File

@ -1,12 +1,12 @@
{ {
"name": "@vben/web-antd", "name": "@vben/web-antd",
"version": "5.0.0", "version": "5.0.0",
"homepage": "https://github.com/vbenjs/vue-vben-admin", "homepage": "https://vben.pro",
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues", "bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
"repository": { "repository": {
"type": "git", "type": "git",
"url": "git+https://github.com/vbenjs/vue-vben-admin.git", "url": "git+https://github.com/vbenjs/vue-vben-admin.git",
"directory": "apps/vben-admin" "directory": "apps/web-antd"
}, },
"license": "MIT", "license": "MIT",
"author": { "author": {

View File

@ -1,59 +1,33 @@
import { defineConfig, loadAndConvertEnv } from '@vben/vite-config'; import {
defaultImportmapOptions,
defineConfig,
getDefaultPwaOptions,
loadAndConvertEnv,
} from '@vben/vite-config';
export default defineConfig({ export default defineConfig(async () => {
application: async ({ mode }) => { const { appTitle, port, ...envConfig } = await loadAndConvertEnv();
const envConfig = await loadAndConvertEnv(); return {
application: {
return {
...envConfig, ...envConfig,
importmap: false, importmap: false,
importmapOptions: { importmapOptions: defaultImportmapOptions,
// 通过 Importmap CDN 方式引入,
// 目前只有esm.sh源兼容性好一点jspm.io对于 esm 入口要求高
defaultProvider: 'esm.sh',
importmap: [
{ name: 'vue' },
{ name: 'pinia' },
{ name: 'vue-router' },
{ name: 'vue-i18n' },
{ name: 'dayjs' },
{ name: 'vue-demi' },
],
},
pwa: false, pwa: false,
pwaOptions: { pwaOptions: getDefaultPwaOptions(appTitle),
manifest: { },
description: vite: {
'Vben Admin Pro is a modern admin dashboard template based on Vue 3. ', server: {
icons: [ port,
{ proxy: {
sizes: '192x192', '/api': {
src: 'https://cdn.jsdelivr.net/npm/@vbenjs/static-source@0.1.3/source/pwa-icon-192.png', changeOrigin: true,
type: 'image/png', rewrite: (path) => path.replace(/^\/api/, ''),
}, // 代理目标地址 - backend-mock 项目
{ target: 'http://localhost:5320/api',
sizes: '512x512', ws: true,
src: 'https://cdn.jsdelivr.net/npm/@vbenjs/static-source@0.1.3/source/pwa-icon-512.png', },
type: 'image/png',
},
],
name: `Vben Admin Pro ${mode}`,
short_name: `Vben Admin Pro ${mode}`,
},
},
};
},
vite: {
server: {
proxy: {
'/api': {
changeOrigin: true,
rewrite: (path) => path.replace(/^\/api/, ''),
// 代理目标地址 - backend-mock 项目
target: 'http://localhost:5320/api',
ws: true,
}, },
}, },
}, },
}, };
}); });

View File

@ -7,10 +7,11 @@ import { defineConfig, loadEnv, mergeConfig } from 'vite';
import { loadApplicationPlugins } from '../plugins'; import { loadApplicationPlugins } from '../plugins';
import { getCommonConfig } from './common'; import { getCommonConfig } from './common';
function defineApplicationConfig(options: DefineApplicationOptions = {}) { function defineApplicationConfig(userConfigPromise: DefineApplicationOptions) {
return defineConfig(async (config) => { return defineConfig(async (config) => {
const options = await userConfigPromise?.(config);
const { command, mode } = config; const { command, mode } = config;
const { application = {}, vite = {} } = options; const { application = {}, vite = {} } = options || {};
const root = process.cwd(); const root = process.cwd();
const isBuild = command === 'build'; const isBuild = command === 'build';
const env = loadEnv(mode, root); const env = loadEnv(mode, root);
@ -30,9 +31,7 @@ function defineApplicationConfig(options: DefineApplicationOptions = {}) {
mode, mode,
pwa: true, pwa: true,
turboConsole: false, turboConsole: false,
...(typeof application === 'function' ...application,
? await application(config)
: application),
}); });
const applicationConfig: UserConfig = { const applicationConfig: UserConfig = {
@ -69,10 +68,7 @@ function defineApplicationConfig(options: DefineApplicationOptions = {}) {
await getCommonConfig(), await getCommonConfig(),
applicationConfig, applicationConfig,
); );
return mergeConfig( return mergeConfig(mergedConfig, vite);
mergedConfig,
typeof vite === 'function' ? await vite(config) : vite,
);
}); });
} }

View File

@ -9,9 +9,10 @@ import { defineLibraryConfig } from './library';
export * from './application'; export * from './application';
export * from './library'; export * from './library';
function defineConfig(options: DefineConfig = {}) { function defineConfig(
const { type = 'auto', ...defineOptions } = options; userConfigPromise?: DefineConfig,
type: 'application' | 'auto' | 'library' = 'auto',
) {
let projectType = type; let projectType = type;
// 根据包是否存在 index.html,自动判断类型 // 根据包是否存在 index.html,自动判断类型
@ -22,10 +23,10 @@ function defineConfig(options: DefineConfig = {}) {
switch (projectType) { switch (projectType) {
case 'application': { case 'application': {
return defineApplicationConfig(defineOptions); return defineApplicationConfig(userConfigPromise);
} }
case 'library': { case 'library': {
return defineLibraryConfig(defineOptions); return defineLibraryConfig(userConfigPromise);
} }
default: { default: {
throw new Error(`Unsupported project type: ${projectType}`); throw new Error(`Unsupported project type: ${projectType}`);

View File

@ -1,4 +1,4 @@
import type { UserConfig } from 'vite'; import type { ConfigEnv, UserConfig } from 'vite';
import type { DefineLibraryOptions } from '../typing'; import type { DefineLibraryOptions } from '../typing';
@ -9,11 +9,12 @@ import { defineConfig, mergeConfig } from 'vite';
import { loadLibraryPlugins } from '../plugins'; import { loadLibraryPlugins } from '../plugins';
import { getCommonConfig } from './common'; import { getCommonConfig } from './common';
function defineLibraryConfig(options: DefineLibraryOptions = {}) { function defineLibraryConfig(userConfigPromise: DefineLibraryOptions) {
return defineConfig(async (config) => { return defineConfig(async (config: ConfigEnv) => {
const options = await userConfigPromise?.(config);
const { command, mode } = config; const { command, mode } = config;
const root = process.cwd(); const root = process.cwd();
const { library = {}, vite = {} } = options; const { library = {}, vite = {} } = options || {};
const isBuild = command === 'build'; const isBuild = command === 'build';
const plugins = await loadLibraryPlugins({ const plugins = await loadLibraryPlugins({
@ -22,7 +23,7 @@ function defineLibraryConfig(options: DefineLibraryOptions = {}) {
injectMetadata: true, injectMetadata: true,
isBuild, isBuild,
mode, mode,
...(typeof library === 'function' ? await library(config) : library), ...library,
}); });
const { dependencies = {}, peerDependencies = {} } = const { dependencies = {}, peerDependencies = {} } =
@ -52,10 +53,7 @@ function defineLibraryConfig(options: DefineLibraryOptions = {}) {
}; };
const commonConfig = await getCommonConfig(); const commonConfig = await getCommonConfig();
const mergedConfig = mergeConfig(commonConfig, packageConfig); const mergedConfig = mergeConfig(commonConfig, packageConfig);
return mergeConfig( return mergeConfig(mergedConfig, vite);
mergedConfig,
typeof vite === 'function' ? await vite(config) : vite,
);
}); });
} }

View File

@ -1,3 +1,4 @@
export * from './config'; export * from './config';
export * from './options';
export * from './plugins'; export * from './plugins';
export { loadAndConvertEnv } from './utils/env'; export { loadAndConvertEnv } from './utils/env';

View File

@ -0,0 +1,42 @@
import type { Options as PwaPluginOptions } from 'vite-plugin-pwa';
import type { ImportmapPluginOptions } from './typing';
const isDevelopment = process.env.NODE_ENV === 'development';
const getDefaultPwaOptions = (name: string): Partial<PwaPluginOptions> => ({
manifest: {
description:
'Vben Admin Pro is a modern admin dashboard template based on Vue 3. ',
icons: [
{
sizes: '192x192',
src: 'https://cdn.jsdelivr.net/npm/@vbenjs/static-source@0.1.3/source/pwa-icon-192.png',
type: 'image/png',
},
{
sizes: '512x512',
src: 'https://cdn.jsdelivr.net/npm/@vbenjs/static-source@0.1.3/source/pwa-icon-512.png',
type: 'image/png',
},
],
name: `${name}o${isDevelopment ? ' dev' : ''}`,
short_name: `${name}${isDevelopment ? ' dev' : ''}`,
},
});
const defaultImportmapOptions: ImportmapPluginOptions = {
// 通过 Importmap CDN 方式引入,
// 目前只有esm.sh源兼容性好一点jspm.io对于 esm 入口要求高
defaultProvider: 'esm.sh',
importmap: [
{ name: 'vue' },
{ name: 'pinia' },
{ name: 'vue-router' },
{ name: 'vue-i18n' },
{ name: 'dayjs' },
{ name: 'vue-demi' },
],
};
export { defaultImportmapOptions, getDefaultPwaOptions };

View File

@ -44,7 +44,7 @@ async function resolveMonorepoDependencies() {
async function viteMetadataPlugin( async function viteMetadataPlugin(
root = process.cwd(), root = process.cwd(),
): Promise<PluginOption | undefined> { ): Promise<PluginOption | undefined> {
const { author, description, homepage, license, repository, version } = const { author, description, homepage, license, version } =
await readPackageJSON(root); await readPackageJSON(root);
const buildTime = dateUtil().format('YYYY-MM-DD HH:mm:ss'); const buildTime = dateUtil().format('YYYY-MM-DD HH:mm:ss');
@ -53,8 +53,6 @@ async function viteMetadataPlugin(
async config() { async config() {
const { dependencies, devDependencies } = const { dependencies, devDependencies } =
await resolveMonorepoDependencies(); await resolveMonorepoDependencies();
const repositoryUrl =
typeof repository === 'object' ? repository.url : repository;
const isAuthorObject = typeof author === 'object'; const isAuthorObject = typeof author === 'object';
const authorName = isAuthorObject ? author.name : author; const authorName = isAuthorObject ? author.name : author;
@ -73,7 +71,6 @@ async function viteMetadataPlugin(
devDependencies, devDependencies,
homepage, homepage,
license, license,
repositoryUrl,
version, version,
}), }),
}, },

View File

@ -91,22 +91,17 @@ interface ApplicationOptions extends ApplicationPluginOptions {}
interface LibraryOptions extends LibraryPluginOptions {} interface LibraryOptions extends LibraryPluginOptions {}
interface DefineApplicationOptions { type DefineApplicationOptions = (config?: ConfigEnv) => Promise<{
application?: application?: ApplicationOptions;
| ((config: ConfigEnv) => Promise<ApplicationOptions>) vite?: UserConfig;
| ApplicationOptions; }>;
vite?: ((config: ConfigEnv) => Promise<UserConfig>) | UserConfig;
}
interface DefineLibraryOptions { type DefineLibraryOptions = (config?: ConfigEnv) => Promise<{
library?: ((config: ConfigEnv) => Promise<LibraryOptions>) | LibraryOptions; library?: LibraryOptions;
vite?: ((config: ConfigEnv) => Promise<UserConfig>) | UserConfig; vite?: UserConfig;
} }>;
type DefineConfig = { type DefineConfig = DefineApplicationOptions | DefineLibraryOptions;
type?: 'application' | 'auto' | 'library';
} & DefineApplicationOptions &
DefineLibraryOptions;
export type { export type {
ApplicationPluginOptions, ApplicationPluginOptions,

View File

@ -54,7 +54,9 @@ async function loadEnv<T = Record<string, string>>(
async function loadAndConvertEnv( async function loadAndConvertEnv(
match = 'VITE_', match = 'VITE_',
confFiles = getConfFiles(), confFiles = getConfFiles(),
): Promise<Partial<ApplicationPluginOptions>> { ): Promise<
{ appTitle: string; port: number } & Partial<ApplicationPluginOptions>
> {
const envConfig = await loadEnv(match, confFiles); const envConfig = await loadEnv(match, confFiles);
const visualizer = envConfig.visualizer || ''; const visualizer = envConfig.visualizer || '';
const pwa = envConfig.pwa || ''; const pwa = envConfig.pwa || '';
@ -63,8 +65,10 @@ async function loadAndConvertEnv(
.split(',') .split(',')
.filter((item) => ['brotli', 'gzip'].includes(item)); .filter((item) => ['brotli', 'gzip'].includes(item));
return { return {
appTitle: envConfig?.VITE_GLOB_APP_TITLE ?? 'Vben Admin Pro',
compress: !!compress, compress: !!compress,
compressTypes: compressTypes as ('brotli' | 'gzip')[], compressTypes: compressTypes as ('brotli' | 'gzip')[],
port: Number(envConfig.VITE_PORT) || 5173,
pwa: !!pwa, pwa: !!pwa,
visualizer: !!visualizer, visualizer: !!visualizer,
}; };

View File

@ -1,3 +1,7 @@
# @vben-core/forward # @vben-core/forward
该目录内的包可直接被app所引用 该目录内的包可直接被app所引用其是项目基础功能的一层抽象。允许轻微的副作用耦合如`locales`的集成。
## 注意事项
- `forward` 内的包不允许相互引用,有相互引用的情况请考虑是否放到`packages/effects`下

View File

@ -4,6 +4,8 @@ import {
type InternalAxiosRequestConfig, type InternalAxiosRequestConfig,
} from 'axios'; } from 'axios';
const errorHandler = (res: Error) => Promise.reject(res);
class InterceptorManager { class InterceptorManager {
private axiosInstance: AxiosInstance; private axiosInstance: AxiosInstance;
@ -19,7 +21,7 @@ class InterceptorManager {
) { ) {
this.axiosInstance.interceptors.request.use( this.axiosInstance.interceptors.request.use(
fulfilled, fulfilled,
rejected || ((res) => Promise.reject(res)), rejected || errorHandler,
); );
} }
@ -31,7 +33,7 @@ class InterceptorManager {
) { ) {
this.axiosInstance.interceptors.response.use( this.axiosInstance.interceptors.response.use(
fulfilled, fulfilled,
rejected || ((res) => Promise.reject(res)), rejected || errorHandler,
); );
} }
} }

View File

@ -3,10 +3,20 @@
*/ */
const VBEN_GITHUB_URL = 'https://github.com/vbenjs/vue-vben-admin'; const VBEN_GITHUB_URL = 'https://github.com/vbenjs/vue-vben-admin';
/**
* @zh_CN
*/
const VBEN_DOC_URL = 'https://doc.vben.pro';
/** /**
* @zh_CN Vben Logo * @zh_CN Vben Logo
*/ */
const VBEN_LOGO_URL = const VBEN_LOGO_URL =
'https://cdn.jsdelivr.net/npm/@vbenjs/static-source@0.1.3/source/logo-v1.webp'; 'https://cdn.jsdelivr.net/npm/@vbenjs/static-source@0.1.3/source/logo-v1.webp';
export { VBEN_GITHUB_URL, VBEN_LOGO_URL }; /**
* @zh_CN Vben Admin
*/
const VBEN_PREVIEW_URL = 'https://vben.pro';
export { VBEN_DOC_URL, VBEN_GITHUB_URL, VBEN_LOGO_URL, VBEN_PREVIEW_URL };

View File

@ -1,7 +1,9 @@
import { defineConfig } from '@vben/vite-config'; import { defineConfig } from '@vben/vite-config';
export default defineConfig({ export default defineConfig(async () => {
vite: { return {
publicDir: 'src/scss-bem', vite: {
}, publicDir: 'src/scss-bem',
},
};
}); });

View File

@ -2,7 +2,7 @@
`effects` 目录专门用于存放与副作用相关的代码和逻辑。如果你的包具有以下特点,建议将其放置在 `effects` 目录下: `effects` 目录专门用于存放与副作用相关的代码和逻辑。如果你的包具有以下特点,建议将其放置在 `effects` 目录下:
- 使用状态管理框架 Pinia并包含处理副作用如异步操作、API 调用)的部分。 - 使用状态管理框架 `pinia`并包含处理副作用如异步操作、API 调用)的部分。
- 使用 `@vben-core/preferences` 处理用户偏好设置,涉及本地存储或浏览器缓存逻辑(如使用 `localStorage`)。 - 使用 `@vben-core/preferences` 处理用户偏好设置,涉及本地存储或浏览器缓存逻辑(如使用 `localStorage`)。
- 处理导航、页面跳转等场景,需要管理路由变化的逻辑。 - 处理导航、页面跳转等场景,需要管理路由变化的逻辑。
- 包含与特定组件库紧密耦合或依赖大型仓库的部分。 - 包含与特定组件库紧密耦合或依赖大型仓库的部分。

View File

@ -3,6 +3,11 @@ import type { AboutProps, DescriptionItem } from './about';
import { h } from 'vue'; import { h } from 'vue';
import {
VBEN_DOC_URL,
VBEN_GITHUB_URL,
VBEN_PREVIEW_URL,
} from '@vben/constants';
import { VbenLink, VbenRenderContent } from '@vben-core/shadcn-ui'; import { VbenLink, VbenRenderContent } from '@vben-core/shadcn-ui';
interface Props extends AboutProps {} interface Props extends AboutProps {}
@ -27,7 +32,6 @@ const {
devDependencies = {}, devDependencies = {},
homepage, homepage,
license, license,
repositoryUrl,
version, version,
// vite inject-metadata // vite inject-metadata
// eslint-disable-next-line no-undef // eslint-disable-next-line no-undef
@ -47,24 +51,17 @@ const vbenDescriptionItems: DescriptionItem[] = [
title: '最后构建时间', title: '最后构建时间',
}, },
{ {
// TODO:
content: h(VbenLink, { href: homepage }, { default: () => '点击查看' }), content: h(VbenLink, { href: homepage }, { default: () => '点击查看' }),
title: '主页', title: '主页',
}, },
{ {
// TODO: content: h(VbenLink, { href: VBEN_DOC_URL }, { default: () => '点击查看' }),
content: h(
VbenLink,
{ href: repositoryUrl },
{ default: () => '点击查看' },
),
title: '文档地址', title: '文档地址',
}, },
{ {
// TODO:
content: h( content: h(
VbenLink, VbenLink,
{ href: repositoryUrl }, { href: VBEN_PREVIEW_URL },
{ default: () => '点击查看' }, { default: () => '点击查看' },
), ),
title: '预览地址', title: '预览地址',
@ -72,7 +69,7 @@ const vbenDescriptionItems: DescriptionItem[] = [
{ {
content: h( content: h(
VbenLink, VbenLink,
{ href: repositoryUrl }, { href: VBEN_GITHUB_URL },
{ default: () => '点击查看' }, { default: () => '点击查看' },
), ),
title: 'Github', title: 'Github',
@ -113,7 +110,7 @@ const devDependenciesItems = Object.keys(devDependencies).map((key) => ({
{{ title }} {{ title }}
</h3> </h3>
<p class="text-foreground/80 mt-3 text-sm leading-6"> <p class="text-foreground/80 mt-3 text-sm leading-6">
<VbenLink :href="repositoryUrl"> <VbenLink :href="VBEN_GITHUB_URL">
{{ name }} {{ name }}
</VbenLink> </VbenLink>
{{ description }} {{ description }}

View File

@ -1,16 +1,18 @@
import { defineConfig } from '@vben/vite-config'; import { defineConfig } from '@vben/vite-config';
export default defineConfig({ export default defineConfig(async () => {
vite: { return {
build: { vite: {
lib: { build: {
entry: { lib: {
antd: 'src/antd/index.ts', entry: {
index: 'src/index.ts', antd: 'src/antd/index.ts',
index: 'src/index.ts',
},
fileName: (_format, name) => `${name}.mjs`,
}, },
fileName: (_format, name) => `${name}.mjs`,
}, },
publicDir: 'src/bem',
}, },
publicDir: 'src/bem', };
},
}); });

View File

@ -137,6 +137,9 @@ importers:
js-yaml: js-yaml:
specifier: ^4.1.0 specifier: ^4.1.0
version: 4.1.0 version: 4.1.0
mockjs:
specifier: ^1.1.0
version: 1.1.0
passport: passport:
specifier: ^0.7.0 specifier: ^0.7.0
version: 0.7.0 version: 0.7.0
@ -162,6 +165,9 @@ importers:
'@types/express': '@types/express':
specifier: ^4.17.21 specifier: ^4.17.21
version: 4.17.21 version: 4.17.21
'@types/mockjs':
specifier: ^1.0.10
version: 1.0.10
'@types/node': '@types/node':
specifier: ^20.14.10 specifier: ^20.14.10
version: 20.14.10 version: 20.14.10
@ -3002,6 +3008,7 @@ packages:
'@ls-lint/ls-lint@2.2.3': '@ls-lint/ls-lint@2.2.3':
resolution: {integrity: sha512-ekM12jNm/7O2I/hsRv9HvYkRdfrHpiV1epVuI2NP+eTIcEgdIdKkKCs9KgQydu/8R5YXTov9aHdOgplmCHLupw==} resolution: {integrity: sha512-ekM12jNm/7O2I/hsRv9HvYkRdfrHpiV1epVuI2NP+eTIcEgdIdKkKCs9KgQydu/8R5YXTov9aHdOgplmCHLupw==}
cpu: [x64, arm64, s390x]
os: [darwin, linux, win32] os: [darwin, linux, win32]
hasBin: true hasBin: true
@ -3530,6 +3537,9 @@ packages:
'@types/minimist@1.2.5': '@types/minimist@1.2.5':
resolution: {integrity: sha512-hov8bUuiLiyFPGyFPE1lwWhmzYbirOXQNNo40+y3zow8aFVTeyn3VWL0VFFfdNddA8S4Vf0Tc062rzyNr7Paag==} resolution: {integrity: sha512-hov8bUuiLiyFPGyFPE1lwWhmzYbirOXQNNo40+y3zow8aFVTeyn3VWL0VFFfdNddA8S4Vf0Tc062rzyNr7Paag==}
'@types/mockjs@1.0.10':
resolution: {integrity: sha512-SXgrhajHG7boLv6oU93CcmdDm0HYRiceuz6b+7z+/2lCJPTWDv0V5YiwFHT2ejE4bQqgSXQiVPQYPWv7LGsK1g==}
'@types/node@12.20.55': '@types/node@12.20.55':
resolution: {integrity: sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==} resolution: {integrity: sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==}
@ -6710,6 +6720,10 @@ packages:
mlly@1.7.1: mlly@1.7.1:
resolution: {integrity: sha512-rrVRZRELyQzrIUAVMHxP97kv+G786pHmOKzuFII8zDYahFBS7qnHh2AlYSl1GAHhaMPCz6/oHjVMcfFYgFYHgA==} resolution: {integrity: sha512-rrVRZRELyQzrIUAVMHxP97kv+G786pHmOKzuFII8zDYahFBS7qnHh2AlYSl1GAHhaMPCz6/oHjVMcfFYgFYHgA==}
mockjs@1.1.0:
resolution: {integrity: sha512-eQsKcWzIaZzEZ07NuEyO4Nw65g0hdWAyurVol1IPl1gahRwY+svqzfgfey8U8dahLwG44d6/RwEzuK52rSa/JQ==}
hasBin: true
modern-normalize@2.0.0: modern-normalize@2.0.0:
resolution: {integrity: sha512-CxBoEVKh5U4DH3XuNbc5ONLF6dQBc8dSc7pdZ1957FGbIO5JBqGqqchhET9dTexri8/pk9xBL6+5ceOtCIp1QA==} resolution: {integrity: sha512-CxBoEVKh5U4DH3XuNbc5ONLF6dQBc8dSc7pdZ1957FGbIO5JBqGqqchhET9dTexri8/pk9xBL6+5ceOtCIp1QA==}
engines: {node: '>=6'} engines: {node: '>=6'}
@ -12254,6 +12268,8 @@ snapshots:
'@types/minimist@1.2.5': {} '@types/minimist@1.2.5': {}
'@types/mockjs@1.0.10': {}
'@types/node@12.20.55': {} '@types/node@12.20.55': {}
'@types/node@18.19.39': '@types/node@18.19.39':
@ -15922,6 +15938,10 @@ snapshots:
pkg-types: 1.1.3 pkg-types: 1.1.3
ufo: 1.5.3 ufo: 1.5.3
mockjs@1.1.0:
dependencies:
commander: 12.1.0
modern-normalize@2.0.0: {} modern-normalize@2.0.0: {}
mri@1.2.0: {} mri@1.2.0: {}