diff --git a/README.md b/README.md index 6b6474d..46cc959 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Frontend -`Frontend/` 是 AppPlatform 的前端工作区,采用 `pnpm workspace + Turbo` 的 monorepo 组织方式。当前目录同时承载主业务应用、能力演示、文档站、Mock 服务以及一组共享包和工程脚本。 +`Frontend/` 是 AppPlatform 的前端工作区,采用 `pnpm workspace + Turbo` 的 monorepo 组织方式。当前目录主要承载主业务应用、文档站、一组共享包和工程脚本。 项目整体基于 Vue 3 技术栈,并延续 `Vue Vben Admin v5` 的分层方式做业务化扩展。 @@ -14,8 +14,6 @@ - Turbo - pnpm workspace - VitePress -- Playwright -- Nitro Mock - Ant Design Vue / antdv-next ## 2. 工作区结构 @@ -23,9 +21,7 @@ ```text Frontend/ ├── apps/ 主业务应用(数据平台) -├── playground/ 示例应用、能力演示、E2E 验证入口 ├── docs/ VitePress 文档站 -├── backend-mock/ Nitro Mock 服务 ├── packages/ 业务与框架共享包 ├── internal/ 内部工程配置与构建基础设施 ├── scripts/ CLI 与部署脚本 @@ -58,23 +54,7 @@ Frontend/ - `adapter`:表单、组件等适配层 - `locales`:国际化资源 -### 3.2 playground - -演示与验证用应用,包名为 `@vben/playground`。 - -- 默认开发端口为 `5555` -- 开发态接口前缀为 `/api` -- 代理目标为 `http://localhost:5320/api` -- 默认开启 `VITE_NITRO_MOCK=true` -- 内置 Playwright E2E,配置位于 `playground/playwright.config.ts` - -适合用于: - -- 验证基础能力包是否可用 -- 编写和运行 E2E 用例 -- 调试通用组件、布局、示例页面 - -### 3.3 docs +### 3.2 docs 文档站应用,包名为 `@vben/docs`,基于 VitePress。 @@ -82,15 +62,7 @@ Frontend/ - 同时提供中文与英文站点 - 首页内容位于 `docs/src/index.md` 和 `docs/src/en/index.md` -### 3.4 backend-mock - -Mock 服务包名为 `@vben/backend-mock`,基于 Nitro。 - -- 默认端口来自 `backend-mock/.env`,当前为 `5320` -- 提供前端开发期所需的接口、鉴权、上传等模拟能力 -- 按现有说明,通常由开发流程集成启用,不一定需要单独常驻手动启动 - -### 3.5 packages +### 3.3 packages 共享包分为几层: @@ -108,7 +80,7 @@ Mock 服务包名为 `@vben/backend-mock`,基于 Nitro。 - `packages/constants|icons|locales|preferences|stores|styles|types|utils` - 面向应用的共享常量、样式、类型、工具与状态能力 -### 3.6 internal +### 3.4 internal 内部工程基础设施,不直接承载业务页面: @@ -118,7 +90,7 @@ Mock 服务包名为 `@vben/backend-mock`,基于 Nitro。 - `internal/tailwind-config`:Tailwind 配置 - `internal/node-utils`:Node 侧工具能力 -### 3.7 scripts +### 3.5 scripts 工程脚本目录: @@ -156,9 +128,6 @@ pnpm dev # 启动主业务应用 pnpm dev:antdv-next -# 启动 playground -pnpm dev:play - # 启动文档站 pnpm dev:docs ``` @@ -172,9 +141,6 @@ pnpm build # 构建主应用 pnpm build:antdv-next -# 构建 playground -pnpm build:play - # 构建文档站 pnpm build:docs @@ -195,8 +161,6 @@ pnpm check # 单元测试 pnpm test:unit -# E2E 测试 -pnpm test:e2e ``` ## 5. 环境变量与运行时约定 @@ -210,27 +174,11 @@ pnpm test:e2e - `VITE_APP_STORE_SECURE_KEY`:持久化加密密钥 - `VITE_PORT`:开发端口 - `VITE_GLOB_API_URL`:接口基地址 -- `VITE_NITRO_MOCK`:是否启用 Nitro Mock 当前开发环境关键值: - 端口:`5999` - 接口:`http://127.0.0.1:2700/console` -- Mock:`false` - -### 5.2 playground - -当前开发环境关键值: - -- 端口:`5555` -- 接口:`/api` -- Mock:`true` - -### 5.3 backend-mock - -- `PORT=5320` -- `ACCESS_TOKEN_SECRET` -- `REFRESH_TOKEN_SECRET` ## 6. 全局工程约定 @@ -252,8 +200,8 @@ pnpm test:e2e 4. `apps/package.json` 5. `apps/src/main.ts` 6. `apps/src/bootstrap.ts` -7. `playground/package.json` -8. `backend-mock/README.md` +7. `docs/.vitepress/config/index.mts` +8. `internal/vite-config/src/config/application.ts` ## 8. 补充说明 diff --git a/backend-mock/.env b/backend-mock/.env deleted file mode 100644 index b20c4a6..0000000 --- a/backend-mock/.env +++ /dev/null @@ -1,3 +0,0 @@ -PORT=5320 -ACCESS_TOKEN_SECRET=access_token_secret -REFRESH_TOKEN_SECRET=refresh_token_secret diff --git a/backend-mock/README.md b/backend-mock/README.md deleted file mode 100644 index 401bda7..0000000 --- a/backend-mock/README.md +++ /dev/null @@ -1,15 +0,0 @@ -# @vben/backend-mock - -## Description - -Vben Admin 数据 mock 服务,没有对接任何的数据库,所有数据都是模拟的,用于前端开发时提供数据支持。线上环境不再提供 mock 集成,可自行部署服务或者对接真实数据,由于 `mock.js` 等工具有一些限制,比如上传文件不行、无法模拟复杂的逻辑等,所以这里使用了真实的后端服务来实现。唯一麻烦的是本地需要同时启动后端服务和前端服务,但是这样可以更好的模拟真实环境。该服务不需要手动启动,已经集成在 vite 插件内,随应用一起启用。 - -## Running the app - -```bash -# development -$ pnpm run start - -# production mode -$ pnpm run build -``` diff --git a/backend-mock/api/auth/codes.ts b/backend-mock/api/auth/codes.ts deleted file mode 100644 index e610b33..0000000 --- a/backend-mock/api/auth/codes.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { eventHandler } from 'h3'; -import { verifyAccessToken } from '~/utils/jwt-utils'; -import { MOCK_CODES } from '~/utils/mock-data'; -import { unAuthorizedResponse, useResponseSuccess } from '~/utils/response'; - -export default eventHandler((event) => { - const userinfo = verifyAccessToken(event); - if (!userinfo) { - return unAuthorizedResponse(event); - } - - const codes = - MOCK_CODES.find((item) => item.username === userinfo.username)?.codes ?? []; - - return useResponseSuccess(codes); -}); diff --git a/backend-mock/api/auth/login.post.ts b/backend-mock/api/auth/login.post.ts deleted file mode 100644 index e23942c..0000000 --- a/backend-mock/api/auth/login.post.ts +++ /dev/null @@ -1,42 +0,0 @@ -import { defineEventHandler, readBody, setResponseStatus } from 'h3'; -import { - clearRefreshTokenCookie, - setRefreshTokenCookie, -} from '~/utils/cookie-utils'; -import { generateAccessToken, generateRefreshToken } from '~/utils/jwt-utils'; -import { MOCK_USERS } from '~/utils/mock-data'; -import { - forbiddenResponse, - useResponseError, - useResponseSuccess, -} from '~/utils/response'; - -export default defineEventHandler(async (event) => { - const { password, username } = await readBody(event); - if (!password || !username) { - setResponseStatus(event, 400); - return useResponseError( - 'BadRequestException', - 'Username and password are required', - ); - } - - const findUser = MOCK_USERS.find( - (item) => item.username === username && item.password === password, - ); - - if (!findUser) { - clearRefreshTokenCookie(event); - return forbiddenResponse(event, 'Username or password is incorrect.'); - } - - const accessToken = generateAccessToken(findUser); - const refreshToken = generateRefreshToken(findUser); - - setRefreshTokenCookie(event, refreshToken); - - return useResponseSuccess({ - ...findUser, - accessToken, - }); -}); diff --git a/backend-mock/api/auth/logout.post.ts b/backend-mock/api/auth/logout.post.ts deleted file mode 100644 index 74c8d31..0000000 --- a/backend-mock/api/auth/logout.post.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { defineEventHandler } from 'h3'; -import { - clearRefreshTokenCookie, - getRefreshTokenFromCookie, -} from '~/utils/cookie-utils'; -import { useResponseSuccess } from '~/utils/response'; - -export default defineEventHandler(async (event) => { - const refreshToken = getRefreshTokenFromCookie(event); - if (!refreshToken) { - return useResponseSuccess(''); - } - - clearRefreshTokenCookie(event); - - return useResponseSuccess(''); -}); diff --git a/backend-mock/api/auth/refresh.post.ts b/backend-mock/api/auth/refresh.post.ts deleted file mode 100644 index 7d8d3a5..0000000 --- a/backend-mock/api/auth/refresh.post.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { defineEventHandler } from 'h3'; -import { - clearRefreshTokenCookie, - getRefreshTokenFromCookie, - setRefreshTokenCookie, -} from '~/utils/cookie-utils'; -import { generateAccessToken, verifyRefreshToken } from '~/utils/jwt-utils'; -import { MOCK_USERS } from '~/utils/mock-data'; -import { forbiddenResponse } from '~/utils/response'; - -export default defineEventHandler(async (event) => { - const refreshToken = getRefreshTokenFromCookie(event); - if (!refreshToken) { - return forbiddenResponse(event); - } - - clearRefreshTokenCookie(event); - - const userinfo = verifyRefreshToken(refreshToken); - if (!userinfo) { - return forbiddenResponse(event); - } - - const findUser = MOCK_USERS.find( - (item) => item.username === userinfo.username, - ); - if (!findUser) { - return forbiddenResponse(event); - } - const accessToken = generateAccessToken(findUser); - - setRefreshTokenCookie(event, refreshToken); - - return accessToken; -}); diff --git a/backend-mock/api/demo/bigint.ts b/backend-mock/api/demo/bigint.ts deleted file mode 100644 index 00d6c28..0000000 --- a/backend-mock/api/demo/bigint.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { eventHandler, setHeader } from 'h3'; -import { verifyAccessToken } from '~/utils/jwt-utils'; -import { unAuthorizedResponse } from '~/utils/response'; - -export default eventHandler(async (event) => { - const userinfo = verifyAccessToken(event); - if (!userinfo) { - return unAuthorizedResponse(event); - } - const data = ` - { - "code": 0, - "message": "success", - "data": [ - { - "id": 123456789012345678901234567890123456789012345678901234567890, - "name": "John Doe", - "age": 30, - "email": "john-doe@demo.com" - }, - { - "id": 987654321098765432109876543210987654321098765432109876543210, - "name": "Jane Smith", - "age": 25, - "email": "jane@demo.com" - } - ] - } - `; - setHeader(event, 'Content-Type', 'application/json'); - return data; -}); diff --git a/backend-mock/api/menu/all.ts b/backend-mock/api/menu/all.ts deleted file mode 100644 index 7923f7c..0000000 --- a/backend-mock/api/menu/all.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { eventHandler } from 'h3'; -import { verifyAccessToken } from '~/utils/jwt-utils'; -import { MOCK_MENUS } from '~/utils/mock-data'; -import { unAuthorizedResponse, useResponseSuccess } from '~/utils/response'; - -export default eventHandler(async (event) => { - const userinfo = verifyAccessToken(event); - if (!userinfo) { - return unAuthorizedResponse(event); - } - - const menus = - MOCK_MENUS.find((item) => item.username === userinfo.username)?.menus ?? []; - return useResponseSuccess(menus); -}); diff --git a/backend-mock/api/status.ts b/backend-mock/api/status.ts deleted file mode 100644 index 4378209..0000000 --- a/backend-mock/api/status.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { eventHandler, getQuery, setResponseStatus } from 'h3'; -import { useResponseError } from '~/utils/response'; - -export default eventHandler((event) => { - const { status } = getQuery(event); - setResponseStatus(event, Number(status)); - return useResponseError(`${status}`); -}); diff --git a/backend-mock/api/system/dept/.post.ts b/backend-mock/api/system/dept/.post.ts deleted file mode 100644 index 9a4896a..0000000 --- a/backend-mock/api/system/dept/.post.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { eventHandler } from 'h3'; -import { verifyAccessToken } from '~/utils/jwt-utils'; -import { - sleep, - unAuthorizedResponse, - useResponseSuccess, -} from '~/utils/response'; - -export default eventHandler(async (event) => { - const userinfo = verifyAccessToken(event); - if (!userinfo) { - return unAuthorizedResponse(event); - } - await sleep(600); - return useResponseSuccess(null); -}); diff --git a/backend-mock/api/system/dept/[id].delete.ts b/backend-mock/api/system/dept/[id].delete.ts deleted file mode 100644 index eac0f58..0000000 --- a/backend-mock/api/system/dept/[id].delete.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { eventHandler } from 'h3'; -import { verifyAccessToken } from '~/utils/jwt-utils'; -import { - sleep, - unAuthorizedResponse, - useResponseSuccess, -} from '~/utils/response'; - -export default eventHandler(async (event) => { - const userinfo = verifyAccessToken(event); - if (!userinfo) { - return unAuthorizedResponse(event); - } - await sleep(1000); - return useResponseSuccess(null); -}); diff --git a/backend-mock/api/system/dept/[id].put.ts b/backend-mock/api/system/dept/[id].put.ts deleted file mode 100644 index 6805e13..0000000 --- a/backend-mock/api/system/dept/[id].put.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { eventHandler } from 'h3'; -import { verifyAccessToken } from '~/utils/jwt-utils'; -import { - sleep, - unAuthorizedResponse, - useResponseSuccess, -} from '~/utils/response'; - -export default eventHandler(async (event) => { - const userinfo = verifyAccessToken(event); - if (!userinfo) { - return unAuthorizedResponse(event); - } - await sleep(2000); - return useResponseSuccess(null); -}); diff --git a/backend-mock/api/system/dept/list.ts b/backend-mock/api/system/dept/list.ts deleted file mode 100644 index a649a0d..0000000 --- a/backend-mock/api/system/dept/list.ts +++ /dev/null @@ -1,62 +0,0 @@ -import { faker } from '@faker-js/faker'; -import { eventHandler } from 'h3'; -import { verifyAccessToken } from '~/utils/jwt-utils'; -import { unAuthorizedResponse, useResponseSuccess } from '~/utils/response'; - -const formatterCN = new Intl.DateTimeFormat('zh-CN', { - timeZone: 'Asia/Shanghai', - year: 'numeric', - month: '2-digit', - day: '2-digit', - hour: '2-digit', - minute: '2-digit', - second: '2-digit', -}); - -function generateMockDataList(count: number) { - const dataList = []; - - for (let i = 0; i < count; i++) { - const dataItem: Record = { - id: faker.string.uuid(), - pid: 0, - name: faker.commerce.department(), - status: faker.helpers.arrayElement([0, 1]), - createTime: formatterCN.format( - faker.date.between({ from: '2021-01-01', to: '2022-12-31' }), - ), - remark: faker.lorem.sentence(), - }; - if (faker.datatype.boolean()) { - dataItem.children = Array.from( - { length: faker.number.int({ min: 1, max: 5 }) }, - () => ({ - id: faker.string.uuid(), - pid: dataItem.id, - name: faker.commerce.department(), - status: faker.helpers.arrayElement([0, 1]), - createTime: formatterCN.format( - faker.date.between({ from: '2023-01-01', to: '2023-12-31' }), - ), - remark: faker.lorem.sentence(), - }), - ); - } - dataList.push(dataItem); - } - - return dataList; -} - -const mockData = generateMockDataList(10); - -export default eventHandler(async (event) => { - const userinfo = verifyAccessToken(event); - if (!userinfo) { - return unAuthorizedResponse(event); - } - - const listData = structuredClone(mockData); - - return useResponseSuccess(listData); -}); diff --git a/backend-mock/api/system/menu/list.ts b/backend-mock/api/system/menu/list.ts deleted file mode 100644 index ce96bb1..0000000 --- a/backend-mock/api/system/menu/list.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { eventHandler } from 'h3'; -import { verifyAccessToken } from '~/utils/jwt-utils'; -import { MOCK_MENU_LIST } from '~/utils/mock-data'; -import { unAuthorizedResponse, useResponseSuccess } from '~/utils/response'; - -export default eventHandler(async (event) => { - const userinfo = verifyAccessToken(event); - if (!userinfo) { - return unAuthorizedResponse(event); - } - - return useResponseSuccess(MOCK_MENU_LIST); -}); diff --git a/backend-mock/api/system/menu/name-exists.ts b/backend-mock/api/system/menu/name-exists.ts deleted file mode 100644 index 7d5551b..0000000 --- a/backend-mock/api/system/menu/name-exists.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { eventHandler, getQuery } from 'h3'; -import { verifyAccessToken } from '~/utils/jwt-utils'; -import { MOCK_MENU_LIST } from '~/utils/mock-data'; -import { unAuthorizedResponse, useResponseSuccess } from '~/utils/response'; - -const namesMap: Record = {}; - -function getNames(menus: any[]) { - menus.forEach((menu) => { - namesMap[menu.name] = String(menu.id); - if (menu.children) { - getNames(menu.children); - } - }); -} -getNames(MOCK_MENU_LIST); - -export default eventHandler(async (event) => { - const userinfo = verifyAccessToken(event); - if (!userinfo) { - return unAuthorizedResponse(event); - } - const { id, name } = getQuery(event); - - return (name as string) in namesMap && - (!id || namesMap[name as string] !== String(id)) - ? useResponseSuccess(true) - : useResponseSuccess(false); -}); diff --git a/backend-mock/api/system/menu/path-exists.ts b/backend-mock/api/system/menu/path-exists.ts deleted file mode 100644 index f3c3be9..0000000 --- a/backend-mock/api/system/menu/path-exists.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { eventHandler, getQuery } from 'h3'; -import { verifyAccessToken } from '~/utils/jwt-utils'; -import { MOCK_MENU_LIST } from '~/utils/mock-data'; -import { unAuthorizedResponse, useResponseSuccess } from '~/utils/response'; - -const pathMap: Record = { '/': 0 }; - -function getPaths(menus: any[]) { - menus.forEach((menu) => { - pathMap[menu.path] = String(menu.id); - if (menu.children) { - getPaths(menu.children); - } - }); -} -getPaths(MOCK_MENU_LIST); - -export default eventHandler(async (event) => { - const userinfo = verifyAccessToken(event); - if (!userinfo) { - return unAuthorizedResponse(event); - } - const { id, path } = getQuery(event); - - return (path as string) in pathMap && - (!id || pathMap[path as string] !== String(id)) - ? useResponseSuccess(true) - : useResponseSuccess(false); -}); diff --git a/backend-mock/api/system/role/list.ts b/backend-mock/api/system/role/list.ts deleted file mode 100644 index bad29a5..0000000 --- a/backend-mock/api/system/role/list.ts +++ /dev/null @@ -1,84 +0,0 @@ -import { faker } from '@faker-js/faker'; -import { eventHandler, getQuery } from 'h3'; -import { verifyAccessToken } from '~/utils/jwt-utils'; -import { getMenuIds, MOCK_MENU_LIST } from '~/utils/mock-data'; -import { unAuthorizedResponse, usePageResponseSuccess } from '~/utils/response'; - -const formatterCN = new Intl.DateTimeFormat('zh-CN', { - timeZone: 'Asia/Shanghai', - year: 'numeric', - month: '2-digit', - day: '2-digit', - hour: '2-digit', - minute: '2-digit', - second: '2-digit', -}); - -const menuIds = getMenuIds(MOCK_MENU_LIST); - -function generateMockDataList(count: number) { - const dataList = []; - - for (let i = 0; i < count; i++) { - const dataItem: Record = { - id: faker.string.uuid(), - name: faker.commerce.product(), - status: faker.helpers.arrayElement([0, 1]), - createTime: formatterCN.format( - faker.date.between({ from: '2022-01-01', to: '2025-01-01' }), - ), - permissions: faker.helpers.arrayElements(menuIds), - remark: faker.lorem.sentence(), - }; - - dataList.push(dataItem); - } - - return dataList; -} - -const mockData = generateMockDataList(100); - -export default eventHandler(async (event) => { - const userinfo = verifyAccessToken(event); - if (!userinfo) { - return unAuthorizedResponse(event); - } - - const { - page = 1, - pageSize = 20, - name, - id, - remark, - startTime, - endTime, - status, - } = getQuery(event); - let listData = structuredClone(mockData); - if (name) { - listData = listData.filter((item) => - item.name.toLowerCase().includes(String(name).toLowerCase()), - ); - } - if (id) { - listData = listData.filter((item) => - item.id.toLowerCase().includes(String(id).toLowerCase()), - ); - } - if (remark) { - listData = listData.filter((item) => - item.remark?.toLowerCase()?.includes(String(remark).toLowerCase()), - ); - } - if (startTime) { - listData = listData.filter((item) => item.createTime >= startTime); - } - if (endTime) { - listData = listData.filter((item) => item.createTime <= endTime); - } - if (['0', '1'].includes(status as string)) { - listData = listData.filter((item) => item.status === Number(status)); - } - return usePageResponseSuccess(page as string, pageSize as string, listData); -}); diff --git a/backend-mock/api/table/list.ts b/backend-mock/api/table/list.ts deleted file mode 100644 index f81571e..0000000 --- a/backend-mock/api/table/list.ts +++ /dev/null @@ -1,117 +0,0 @@ -import { faker } from '@faker-js/faker'; -import { eventHandler, getQuery } from 'h3'; -import { verifyAccessToken } from '~/utils/jwt-utils'; -import { - sleep, - unAuthorizedResponse, - usePageResponseSuccess, -} from '~/utils/response'; - -function generateMockDataList(count: number) { - const dataList = []; - - for (let i = 0; i < count; i++) { - const dataItem = { - id: faker.string.uuid(), - imageUrl: faker.image.avatar(), - imageUrl2: faker.image.avatar(), - open: faker.datatype.boolean(), - status: faker.helpers.arrayElement(['success', 'error', 'warning']), - productName: faker.commerce.productName(), - price: faker.commerce.price(), - currency: faker.finance.currencyCode(), - quantity: faker.number.int({ min: 1, max: 100 }), - available: faker.datatype.boolean(), - category: faker.commerce.department(), - releaseDate: faker.date.past(), - rating: faker.number.float({ min: 1, max: 5 }), - description: faker.commerce.productDescription(), - weight: faker.number.float({ min: 0.1, max: 10 }), - color: faker.color.human(), - inProduction: faker.datatype.boolean(), - tags: Array.from({ length: 3 }, () => faker.commerce.productAdjective()), - }; - - dataList.push(dataItem); - } - - return dataList; -} - -const mockData = generateMockDataList(100); - -export default eventHandler(async (event) => { - const userinfo = verifyAccessToken(event); - if (!userinfo) { - return unAuthorizedResponse(event); - } - - await sleep(600); - - const { page, pageSize, sortBy, sortOrder } = getQuery(event); - // 规范化分页参数,处理 string[] - const pageRaw = Array.isArray(page) ? page[0] : page; - const pageSizeRaw = Array.isArray(pageSize) ? pageSize[0] : pageSize; - const pageNumber = Math.max( - 1, - Number.parseInt(String(pageRaw ?? '1'), 10) || 1, - ); - const pageSizeNumber = Math.min( - 100, - Math.max(1, Number.parseInt(String(pageSizeRaw ?? '10'), 10) || 10), - ); - const listData = structuredClone(mockData); - - // 规范化 query 入参,兼容 string[] - const sortKeyRaw = Array.isArray(sortBy) ? sortBy[0] : sortBy; - const sortOrderRaw = Array.isArray(sortOrder) ? sortOrder[0] : sortOrder; - // 检查 sortBy 是否是 listData 元素的合法属性键 - if ( - typeof sortKeyRaw === 'string' && - listData[0] && - Object.prototype.hasOwnProperty.call(listData[0], sortKeyRaw) - ) { - // 定义数组元素的类型 - type ItemType = (typeof listData)[0]; - const sortKey = sortKeyRaw as keyof ItemType; // 将 sortBy 断言为合法键 - const isDesc = sortOrderRaw === 'desc'; - listData.sort((a, b) => { - const aValue = a[sortKey] as unknown; - const bValue = b[sortKey] as unknown; - - let result: number; - - if (typeof aValue === 'number' && typeof bValue === 'number') { - result = aValue - bValue; - } else if (aValue instanceof Date && bValue instanceof Date) { - result = aValue.getTime() - bValue.getTime(); - } else if (typeof aValue === 'boolean' && typeof bValue === 'boolean') { - if (aValue === bValue) { - result = 0; - } else { - result = aValue ? 1 : -1; - } - } else { - const aStr = String(aValue); - const bStr = String(bValue); - const aNum = Number(aStr); - const bNum = Number(bStr); - result = - Number.isFinite(aNum) && Number.isFinite(bNum) - ? aNum - bNum - : aStr.localeCompare(bStr, undefined, { - numeric: true, - sensitivity: 'base', - }); - } - - return isDesc ? -result : result; - }); - } - - return usePageResponseSuccess( - String(pageNumber), - String(pageSizeNumber), - listData, - ); -}); diff --git a/backend-mock/api/test.get.ts b/backend-mock/api/test.get.ts deleted file mode 100644 index dc2ceef..0000000 --- a/backend-mock/api/test.get.ts +++ /dev/null @@ -1,3 +0,0 @@ -import { defineEventHandler } from 'h3'; - -export default defineEventHandler(() => 'Test get handler'); diff --git a/backend-mock/api/test.post.ts b/backend-mock/api/test.post.ts deleted file mode 100644 index 0e9e337..0000000 --- a/backend-mock/api/test.post.ts +++ /dev/null @@ -1,3 +0,0 @@ -import { defineEventHandler } from 'h3'; - -export default defineEventHandler(() => 'Test post handler'); diff --git a/backend-mock/api/timezone/getTimezone.ts b/backend-mock/api/timezone/getTimezone.ts deleted file mode 100644 index 0cbcb6e..0000000 --- a/backend-mock/api/timezone/getTimezone.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { eventHandler } from 'h3'; -import { verifyAccessToken } from '~/utils/jwt-utils'; -import { unAuthorizedResponse, useResponseSuccess } from '~/utils/response'; -import { getTimezone } from '~/utils/timezone-utils'; - -export default eventHandler((event) => { - const userinfo = verifyAccessToken(event); - if (!userinfo) { - return unAuthorizedResponse(event); - } - return useResponseSuccess(getTimezone()); -}); diff --git a/backend-mock/api/timezone/getTimezoneOptions.ts b/backend-mock/api/timezone/getTimezoneOptions.ts deleted file mode 100644 index 6c24186..0000000 --- a/backend-mock/api/timezone/getTimezoneOptions.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { eventHandler } from 'h3'; -import { TIME_ZONE_OPTIONS } from '~/utils/mock-data'; -import { useResponseSuccess } from '~/utils/response'; - -export default eventHandler(() => { - const data = TIME_ZONE_OPTIONS.map((o) => ({ - label: `${o.timezone} (GMT${o.offset >= 0 ? `+${o.offset}` : o.offset})`, - value: o.timezone, - })); - return useResponseSuccess(data); -}); diff --git a/backend-mock/api/timezone/setTimezone.ts b/backend-mock/api/timezone/setTimezone.ts deleted file mode 100644 index 34d8f19..0000000 --- a/backend-mock/api/timezone/setTimezone.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { eventHandler, readBody } from 'h3'; -import { verifyAccessToken } from '~/utils/jwt-utils'; -import { TIME_ZONE_OPTIONS } from '~/utils/mock-data'; -import { unAuthorizedResponse, useResponseSuccess } from '~/utils/response'; -import { setTimezone } from '~/utils/timezone-utils'; - -export default eventHandler(async (event) => { - const userinfo = verifyAccessToken(event); - if (!userinfo) { - return unAuthorizedResponse(event); - } - const body = await readBody<{ timezone?: unknown }>(event); - const timezone = - typeof body?.timezone === 'string' ? body.timezone : undefined; - const allowed = TIME_ZONE_OPTIONS.some((o) => o.timezone === timezone); - if (!timezone || !allowed) { - setResponseStatus(event, 400); - return useResponseError('Bad Request', 'Invalid timezone'); - } - setTimezone(timezone); - return useResponseSuccess({}); -}); diff --git a/backend-mock/api/upload.ts b/backend-mock/api/upload.ts deleted file mode 100644 index 436b63c..0000000 --- a/backend-mock/api/upload.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { eventHandler } from 'h3'; -import { verifyAccessToken } from '~/utils/jwt-utils'; -import { unAuthorizedResponse, useResponseSuccess } from '~/utils/response'; - -export default eventHandler((event) => { - const userinfo = verifyAccessToken(event); - if (!userinfo) { - return unAuthorizedResponse(event); - } - return useResponseSuccess({ - url: 'https://unpkg.com/@vbenjs/static-source@0.1.7/source/logo-v1.webp', - }); - // return useResponseError("test") -}); diff --git a/backend-mock/api/user/info.ts b/backend-mock/api/user/info.ts deleted file mode 100644 index 138cb43..0000000 --- a/backend-mock/api/user/info.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { eventHandler } from 'h3'; -import { verifyAccessToken } from '~/utils/jwt-utils'; -import { unAuthorizedResponse, useResponseSuccess } from '~/utils/response'; - -export default eventHandler((event) => { - const userinfo = verifyAccessToken(event); - if (!userinfo) { - return unAuthorizedResponse(event); - } - return useResponseSuccess(userinfo); -}); diff --git a/backend-mock/error.ts b/backend-mock/error.ts deleted file mode 100644 index e20beac..0000000 --- a/backend-mock/error.ts +++ /dev/null @@ -1,7 +0,0 @@ -import type { NitroErrorHandler } from 'nitropack'; - -const errorHandler: NitroErrorHandler = function (error, event) { - event.node.res.end(`[Error Handler] ${error.stack}`); -}; - -export default errorHandler; diff --git a/backend-mock/middleware/1.api.ts b/backend-mock/middleware/1.api.ts deleted file mode 100644 index 339cda4..0000000 --- a/backend-mock/middleware/1.api.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { defineEventHandler } from 'h3'; -import { forbiddenResponse, sleep } from '~/utils/response'; - -export default defineEventHandler(async (event) => { - event.node.res.setHeader( - 'Access-Control-Allow-Origin', - event.headers.get('Origin') ?? '*', - ); - if (event.method === 'OPTIONS') { - event.node.res.statusCode = 204; - event.node.res.statusMessage = 'No Content.'; - return 'OK'; - } else if ( - ['DELETE', 'PATCH', 'POST', 'PUT'].includes(event.method) && - event.path.startsWith('/api/system/') - ) { - await sleep(Math.floor(Math.random() * 2000)); - return forbiddenResponse(event, '演示环境,禁止修改'); - } -}); diff --git a/backend-mock/nitro.config.ts b/backend-mock/nitro.config.ts deleted file mode 100644 index c0fc13e..0000000 --- a/backend-mock/nitro.config.ts +++ /dev/null @@ -1,20 +0,0 @@ -import errorHandler from './error'; - -process.env.COMPATIBILITY_DATE = new Date().toISOString(); -export default defineNitroConfig({ - devErrorHandler: errorHandler, - errorHandler: '~/error', - routeRules: { - '/api/**': { - cors: true, - headers: { - 'Access-Control-Allow-Credentials': 'true', - 'Access-Control-Allow-Headers': - 'Accept, Authorization, Content-Length, Content-Type, If-Match, If-Modified-Since, If-None-Match, If-Unmodified-Since, X-CSRF-TOKEN, X-Requested-With', - 'Access-Control-Allow-Methods': 'GET,HEAD,PUT,PATCH,POST,DELETE', - 'Access-Control-Allow-Origin': '*', - 'Access-Control-Expose-Headers': '*', - }, - }, - }, -}); diff --git a/backend-mock/package.json b/backend-mock/package.json deleted file mode 100644 index 3f170d5..0000000 --- a/backend-mock/package.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "name": "@vben/backend-mock", - "version": "5.7.0", - "description": "", - "private": true, - "license": "MIT", - "author": "", - "scripts": { - "build": "nitro build", - "start": "nitro dev" - }, - "dependencies": { - "@faker-js/faker": "^10.3.0", - "jsonwebtoken": "^9.0.3", - "nitropack": "^2.13.2" - }, - "devDependencies": { - "@types/jsonwebtoken": "^9.0.10", - "h3": "^1.15.10" - } -} diff --git a/backend-mock/routes/[...].ts b/backend-mock/routes/[...].ts deleted file mode 100644 index 5a22563..0000000 --- a/backend-mock/routes/[...].ts +++ /dev/null @@ -1,15 +0,0 @@ -import { defineEventHandler } from 'h3'; - -export default defineEventHandler(() => { - return ` -

Hello Vben Admin

-

Mock service is starting

- -`; -}); diff --git a/backend-mock/tsconfig.build.json b/backend-mock/tsconfig.build.json deleted file mode 100644 index 64f86c6..0000000 --- a/backend-mock/tsconfig.build.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "extends": "./tsconfig.json", - "exclude": ["node_modules", "test", "dist", "**/*spec.ts"] -} diff --git a/backend-mock/tsconfig.json b/backend-mock/tsconfig.json deleted file mode 100644 index 43008af..0000000 --- a/backend-mock/tsconfig.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "extends": "./.nitro/types/tsconfig.json" -} diff --git a/backend-mock/utils/cookie-utils.ts b/backend-mock/utils/cookie-utils.ts deleted file mode 100644 index 187ce2f..0000000 --- a/backend-mock/utils/cookie-utils.ts +++ /dev/null @@ -1,28 +0,0 @@ -import type { EventHandlerRequest, H3Event } from 'h3'; - -import { deleteCookie, getCookie, setCookie } from 'h3'; - -export function clearRefreshTokenCookie(event: H3Event) { - deleteCookie(event, 'jwt', { - httpOnly: true, - sameSite: 'none', - secure: true, - }); -} - -export function setRefreshTokenCookie( - event: H3Event, - refreshToken: string, -) { - setCookie(event, 'jwt', refreshToken, { - httpOnly: true, - maxAge: 24 * 60 * 60, // unit: seconds - sameSite: 'none', - secure: true, - }); -} - -export function getRefreshTokenFromCookie(event: H3Event) { - const refreshToken = getCookie(event, 'jwt'); - return refreshToken; -} diff --git a/backend-mock/utils/jwt-utils.ts b/backend-mock/utils/jwt-utils.ts deleted file mode 100644 index 7185830..0000000 --- a/backend-mock/utils/jwt-utils.ts +++ /dev/null @@ -1,77 +0,0 @@ -import type { EventHandlerRequest, H3Event } from 'h3'; - -import type { UserInfo } from './mock-data'; - -import { getHeader } from 'h3'; -import jwt from 'jsonwebtoken'; - -import { MOCK_USERS } from './mock-data'; - -// TODO: Replace with your own secret key -const ACCESS_TOKEN_SECRET = 'access_token_secret'; -const REFRESH_TOKEN_SECRET = 'refresh_token_secret'; - -export interface UserPayload extends UserInfo { - iat: number; - exp: number; -} - -export function generateAccessToken(user: UserInfo) { - return jwt.sign(user, ACCESS_TOKEN_SECRET, { expiresIn: '7d' }); -} - -export function generateRefreshToken(user: UserInfo) { - return jwt.sign(user, REFRESH_TOKEN_SECRET, { - expiresIn: '30d', - }); -} - -export function verifyAccessToken( - event: H3Event, -): null | Omit { - const authHeader = getHeader(event, 'Authorization'); - if (!authHeader?.startsWith('Bearer')) { - return null; - } - - const tokenParts = authHeader.split(' '); - if (tokenParts.length !== 2) { - return null; - } - const token = tokenParts[1] as string; - try { - const decoded = jwt.verify( - token, - ACCESS_TOKEN_SECRET, - ) as unknown as UserPayload; - - const username = decoded.username; - const user = MOCK_USERS.find((item) => item.username === username); - if (!user) { - return null; - } - const { password: _pwd, ...userinfo } = user; - return userinfo; - } catch { - return null; - } -} - -export function verifyRefreshToken( - token: string, -): null | Omit { - try { - const decoded = jwt.verify(token, REFRESH_TOKEN_SECRET) as UserPayload; - const username = decoded.username; - const user = MOCK_USERS.find( - (item) => item.username === username, - ) as UserInfo; - if (!user) { - return null; - } - const { password: _pwd, ...userinfo } = user; - return userinfo; - } catch { - return null; - } -} diff --git a/backend-mock/utils/mock-data.ts b/backend-mock/utils/mock-data.ts deleted file mode 100644 index b22b049..0000000 --- a/backend-mock/utils/mock-data.ts +++ /dev/null @@ -1,393 +0,0 @@ -export interface UserInfo { - id: number; - password: string; - realName: string; - roles: string[]; - username: string; - homePath?: string; -} - -export interface TimezoneOption { - offset: number; - timezone: string; -} - -export const MOCK_USERS: UserInfo[] = [ - { - id: 0, - password: '123456', - realName: 'Vben', - roles: ['super'], - username: 'vben', - }, - { - id: 1, - password: '123456', - realName: 'Admin', - roles: ['admin'], - username: 'admin', - homePath: '/workspace', - }, - { - id: 2, - password: '123456', - realName: 'Jack', - roles: ['user'], - username: 'jack', - homePath: '/analytics', - }, -]; - -export const MOCK_CODES = [ - // super - { - codes: ['AC_100100', 'AC_100110', 'AC_100120', 'AC_100010'], - username: 'vben', - }, - { - // admin - codes: ['AC_100010', 'AC_100020', 'AC_100030'], - username: 'admin', - }, - { - // user - codes: ['AC_1000001', 'AC_1000002'], - username: 'jack', - }, -]; - -const dashboardMenus = [ - { - meta: { - order: -1, - title: 'page.dashboard.title', - }, - name: 'Dashboard', - path: '/dashboard', - redirect: '/analytics', - children: [ - { - name: 'Analytics', - path: '/analytics', - component: '/dashboard/analytics/index', - meta: { - affixTab: true, - title: 'page.dashboard.analytics', - }, - }, - { - name: 'Workspace', - path: '/workspace', - component: '/dashboard/workspace/index', - meta: { - title: 'page.dashboard.workspace', - }, - }, - ], - }, -]; - -const createDemosMenus = (role: 'admin' | 'super' | 'user') => { - const roleWithMenus = { - admin: { - component: '/demos/access/admin-visible', - meta: { - icon: 'mdi:button-cursor', - title: 'demos.access.adminVisible', - }, - name: 'AccessAdminVisibleDemo', - path: '/demos/access/admin-visible', - }, - super: { - component: '/demos/access/super-visible', - meta: { - icon: 'mdi:button-cursor', - title: 'demos.access.superVisible', - }, - name: 'AccessSuperVisibleDemo', - path: '/demos/access/super-visible', - }, - user: { - component: '/demos/access/user-visible', - meta: { - icon: 'mdi:button-cursor', - title: 'demos.access.userVisible', - }, - name: 'AccessUserVisibleDemo', - path: '/demos/access/user-visible', - }, - }; - - return [ - { - meta: { - icon: 'ic:baseline-view-in-ar', - keepAlive: true, - order: 1000, - title: 'demos.title', - }, - name: 'Demos', - path: '/demos', - redirect: '/demos/access', - children: [ - { - name: 'AccessDemos', - path: '/demosaccess', - meta: { - icon: 'mdi:cloud-key-outline', - title: 'demos.access.backendPermissions', - }, - redirect: '/demos/access/page-control', - children: [ - { - name: 'AccessPageControlDemo', - path: '/demos/access/page-control', - component: '/demos/access/index', - meta: { - icon: 'mdi:page-previous-outline', - title: 'demos.access.pageAccess', - }, - }, - { - name: 'AccessButtonControlDemo', - path: '/demos/access/button-control', - component: '/demos/access/button-control', - meta: { - icon: 'mdi:button-cursor', - title: 'demos.access.buttonControl', - }, - }, - { - name: 'AccessMenuVisible403Demo', - path: '/demos/access/menu-visible-403', - component: '/demos/access/menu-visible-403', - meta: { - authority: ['no-body'], - icon: 'mdi:button-cursor', - menuVisibleWithForbidden: true, - title: 'demos.access.menuVisible403', - }, - }, - roleWithMenus[role], - ], - }, - ], - }, - ]; -}; - -export const MOCK_MENUS = [ - { - menus: [...dashboardMenus, ...createDemosMenus('super')], - username: 'vben', - }, - { - menus: [...dashboardMenus, ...createDemosMenus('admin')], - username: 'admin', - }, - { - menus: [...dashboardMenus, ...createDemosMenus('user')], - username: 'jack', - }, -]; - -export const MOCK_MENU_LIST = [ - { - id: 1, - name: 'Workspace', - status: 1, - type: 'menu', - icon: 'mdi:dashboard', - path: '/workspace', - component: '/dashboard/workspace/index', - meta: { - icon: 'carbon:workspace', - title: 'page.dashboard.workspace', - affixTab: true, - order: 0, - }, - }, - { - id: 2, - meta: { - icon: 'carbon:settings', - order: 9997, - title: 'system.title', - badge: 'new', - badgeType: 'normal', - badgeVariants: 'primary', - }, - status: 1, - type: 'catalog', - name: 'System', - path: '/system', - children: [ - { - id: 201, - pid: 2, - path: '/system/menu', - name: 'SystemMenu', - authCode: 'System:Menu:List', - status: 1, - type: 'menu', - meta: { - icon: 'carbon:menu', - title: 'system.menu.title', - }, - component: '/system/menu/list', - children: [ - { - id: 20_101, - pid: 201, - name: 'SystemMenuCreate', - status: 1, - type: 'button', - authCode: 'System:Menu:Create', - meta: { title: 'common.create' }, - }, - { - id: 20_102, - pid: 201, - name: 'SystemMenuEdit', - status: 1, - type: 'button', - authCode: 'System:Menu:Edit', - meta: { title: 'common.edit' }, - }, - { - id: 20_103, - pid: 201, - name: 'SystemMenuDelete', - status: 1, - type: 'button', - authCode: 'System:Menu:Delete', - meta: { title: 'common.delete' }, - }, - ], - }, - { - id: 202, - pid: 2, - path: '/system/dept', - name: 'SystemDept', - status: 1, - type: 'menu', - authCode: 'System:Dept:List', - meta: { - icon: 'carbon:container-services', - title: 'system.dept.title', - }, - component: '/system/dept/list', - children: [ - { - id: 20_401, - pid: 202, - name: 'SystemDeptCreate', - status: 1, - type: 'button', - authCode: 'System:Dept:Create', - meta: { title: 'common.create' }, - }, - { - id: 20_402, - pid: 202, - name: 'SystemDeptEdit', - status: 1, - type: 'button', - authCode: 'System:Dept:Edit', - meta: { title: 'common.edit' }, - }, - { - id: 20_403, - pid: 202, - name: 'SystemDeptDelete', - status: 1, - type: 'button', - authCode: 'System:Dept:Delete', - meta: { title: 'common.delete' }, - }, - ], - }, - ], - }, - { - id: 9, - meta: { - badgeType: 'dot', - order: 9998, - title: 'demos.vben.title', - icon: 'carbon:data-center', - }, - name: 'Project', - path: '/vben-admin', - type: 'catalog', - status: 1, - children: [ - { - id: 903, - pid: 9, - name: 'VbenAntdv', - path: '/vben-admin/antdv', - component: 'IFrameView', - type: 'link', - status: 0, - meta: { - icon: 'carbon:hexagon-vertical-solid', - badgeType: 'dot', - link: 'https://ant.vben.pro', - title: 'demos.vben.antdv', - }, - }, - ], - }, - { - id: 10, - component: '_core/about/index', - type: 'menu', - status: 1, - meta: { - icon: 'lucide:copyright', - order: 9999, - title: 'demos.vben.about', - }, - name: 'About', - path: '/about', - }, -]; - -export function getMenuIds(menus: any[]) { - const ids: number[] = []; - menus.forEach((item) => { - ids.push(item.id); - if (item.children && item.children.length > 0) { - ids.push(...getMenuIds(item.children)); - } - }); - return ids; -} - -/** - * 时区选项 - */ -export const TIME_ZONE_OPTIONS: TimezoneOption[] = [ - { - offset: -5, - timezone: 'America/New_York', - }, - { - offset: 0, - timezone: 'Europe/London', - }, - { - offset: 8, - timezone: 'Asia/Shanghai', - }, - { - offset: 9, - timezone: 'Asia/Tokyo', - }, - { - offset: 9, - timezone: 'Asia/Seoul', - }, -]; diff --git a/backend-mock/utils/response.ts b/backend-mock/utils/response.ts deleted file mode 100644 index 2d4242e..0000000 --- a/backend-mock/utils/response.ts +++ /dev/null @@ -1,70 +0,0 @@ -import type { EventHandlerRequest, H3Event } from 'h3'; - -import { setResponseStatus } from 'h3'; - -export function useResponseSuccess(data: T) { - return { - code: 0, - data, - error: null, - message: 'ok', - }; -} - -export function usePageResponseSuccess( - page: number | string, - pageSize: number | string, - list: T[], - { message = 'ok' } = {}, -) { - const pageData = pagination( - Number.parseInt(`${page}`), - Number.parseInt(`${pageSize}`), - list, - ); - - return { - ...useResponseSuccess({ - items: pageData, - total: list.length, - }), - message, - }; -} - -export function useResponseError(message: string, error: any = null) { - return { - code: -1, - data: null, - error, - message, - }; -} - -export function forbiddenResponse( - event: H3Event, - message = 'Forbidden Exception', -) { - setResponseStatus(event, 403); - return useResponseError(message, message); -} - -export function unAuthorizedResponse(event: H3Event) { - setResponseStatus(event, 401); - return useResponseError('Unauthorized Exception', 'Unauthorized Exception'); -} - -export function sleep(ms: number) { - return new Promise((resolve) => setTimeout(resolve, ms)); -} - -export function pagination( - pageNo: number, - pageSize: number, - array: T[], -): T[] { - const offset = (pageNo - 1) * Number(pageSize); - return offset + Number(pageSize) >= array.length - ? array.slice(offset) - : array.slice(offset, offset + Number(pageSize)); -} diff --git a/backend-mock/utils/timezone-utils.ts b/backend-mock/utils/timezone-utils.ts deleted file mode 100644 index da35f92..0000000 --- a/backend-mock/utils/timezone-utils.ts +++ /dev/null @@ -1,9 +0,0 @@ -let mockTimeZone: null | string = null; - -export const setTimezone = (timeZone: string) => { - mockTimeZone = timeZone; -}; - -export const getTimezone = () => { - return mockTimeZone; -}; diff --git a/docs/src/components/common-ui/vben-api-component.md b/docs/src/components/common-ui/vben-api-component.md index 5465f15..f5803cf 100644 --- a/docs/src/components/common-ui/vben-api-component.md +++ b/docs/src/components/common-ui/vben-api-component.md @@ -125,7 +125,7 @@ function fetchApi(): Promise> { ## 并发和缓存 -有些场景下可能需要使用多个ApiComponent,它们使用了相同的远程数据源(例如用在可编辑的表格中)。如果直接将请求后端接口的函数传递给api属性,则每一个实例都会访问一次接口,这会造成资源浪费,是完全没有必要的。Tanstack Query提供了并发控制、缓存、重试等诸多特性,我们可以将接口请求函数用useQuery包装一下再传递给ApiComponent,这样的话无论页面有多少个使用相同数据源的ApiComponent实例,都只会发起一次远程请求。演示效果请参考 [Playground vue-query](https://www.vben.pro/#/demos/features/vue-query),具体代码请查看项目文件[concurrency-caching](https://github.com/vbenjs/vue-vben-admin/blob/main/playground/src/views/demos/features/vue-query/concurrency-caching.vue) +有些场景下可能需要使用多个ApiComponent,它们使用了相同的远程数据源(例如用在可编辑的表格中)。如果直接将请求后端接口的函数传递给api属性,则每一个实例都会访问一次接口,这会造成资源浪费,是完全没有必要的。Tanstack Query提供了并发控制、缓存、重试等诸多特性,我们可以将接口请求函数用useQuery包装一下再传递给ApiComponent,这样的话无论页面有多少个使用相同数据源的ApiComponent实例,都只会发起一次远程请求。 ## API diff --git a/docs/src/en/guide/essentials/concept.md b/docs/src/en/guide/essentials/concept.md index 8c940a9..e2b18cb 100644 --- a/docs/src/en/guide/essentials/concept.md +++ b/docs/src/en/guide/essentials/concept.md @@ -12,7 +12,7 @@ Applications refer to a complete project; a project can contain multiple applica ::: tip -Applications are not limited to front-end applications; they can also be back-end applications, mobile applications, etc. For example, `apps/backend-mock` is a back-end service. +Applications are not limited to front-end projects; they can also be mobile applications or other independently runnable projects. ::: diff --git a/docs/src/en/guide/essentials/development.md b/docs/src/en/guide/essentials/development.md index a31a9a6..b128fbd 100644 --- a/docs/src/en/guide/essentials/development.md +++ b/docs/src/en/guide/essentials/development.md @@ -64,8 +64,6 @@ The execution command is: `pnpm run [script]` or `npm run [script]`. "build:naive": "pnpm run build --filter=@vben/web-naive", // Build the web-tdesign application separately "build:tdesign": "pnpm run build --filter=@vben/web-tdesign", - // Build the playground application separately - "build:play": "pnpm run build --filter=@vben/playground", // Changeset version management "changeset": "pnpm exec changeset", // Check for various issues in the project @@ -96,8 +94,6 @@ The execution command is: `pnpm run [script]` or `npm run [script]`. "dev:naive": "pnpm -F @vben/web-naive run dev", // Start the web-tdesign application "dev:tdesign": "pnpm -F @vben/web-tdesign run dev", - // Start the playground application - "dev:play": "pnpm -F @vben/playground run dev", // Format code "format": "vsh lint --format", // Lint code diff --git a/docs/src/en/guide/essentials/server.md b/docs/src/en/guide/essentials/server.md index 67e0b1f..4864b07 100644 --- a/docs/src/en/guide/essentials/server.md +++ b/docs/src/en/guide/essentials/server.md @@ -338,19 +338,6 @@ The new version no longer supports mock in the production environment. Please us Mock data is an indispensable part of frontend development, serving as a key link in separating frontend and backend development. By agreeing on interfaces with the server side in advance and simulating request data and even logic, frontend development can proceed independently, without being blocked by the backend development process. -The project uses [Nitro](https://nitro.unjs.io/) for local mock data processing. The principle is to start an additional backend service locally, which is a real backend service that can handle requests and return data. +This workspace does not include a built-in local mock service. In development, requests go directly to the real API or to the proxy configured by the application. -### Using Nitro - -The mock service code is located in the `apps/backend-mock` directory. It does not need to be started manually and is already integrated into the project. You only need to run `pnpm dev` in the project root directory. After running successfully, the console will print `http://localhost:5320/api`, and you can access this address to view the mock service. - -[Nitro](https://nitro.unjs.io/) syntax is simple, and you can configure and develop according to your needs. For specific configurations, you can refer to the [Nitro documentation](https://nitro.unjs.io/). - -## Disabling Mock Service - -Since mock is essentially a real backend service, if you do not need the mock service, you can configure `VITE_NITRO_MOCK=false` in the `.env.development` file in the project root directory to disable the mock service. - -```bash -# .env.development -VITE_NITRO_MOCK=false -``` +If you need local mock support, you can add an independent mock service yourself or forward requests to a dedicated test environment through Vite proxy. diff --git a/docs/src/en/guide/essentials/settings.md b/docs/src/en/guide/essentials/settings.md index 59bb390..fff013d 100644 --- a/docs/src/en/guide/essentials/settings.md +++ b/docs/src/en/guide/essentials/settings.md @@ -47,9 +47,6 @@ VITE_BASE=/ # API URL VITE_GLOB_API_URL=/api -# Whether to enable Nitro Mock service, true to enable, false to disable -VITE_NITRO_MOCK=true - # Whether to open devtools, true to open, false to close VITE_DEVTOOLS=true diff --git a/docs/src/en/guide/introduction/quick-start.md b/docs/src/en/guide/introduction/quick-start.md index 12793c6..8bf503d 100644 --- a/docs/src/en/guide/introduction/quick-start.md +++ b/docs/src/en/guide/introduction/quick-start.md @@ -89,8 +89,7 @@ You will see an output similar to the following, allowing you to select the proj │ ○ @vben/web-ele │ ○ @vben/web-naive │ ○ @vben/docs -│ ○ @vben/playground └ ``` -Now, you can visit `http://localhost:5555` in your browser to view the project. +Now, open the URL printed by the terminal in your browser. In this workspace, the main business application uses `http://localhost:5999` by default. diff --git a/docs/src/en/guide/introduction/thin.md b/docs/src/en/guide/introduction/thin.md index 7ca0468..ad696aa 100644 --- a/docs/src/en/guide/introduction/thin.md +++ b/docs/src/en/guide/introduction/thin.md @@ -18,22 +18,13 @@ If your project doesn’t include the `UI` component library you need, you can d ::: -## Demo Code Slimming - -If you don’t need demo code, you can simply delete the `playground` folder - ## Documentation Slimming If you don’t need documentation, you can delete the `docs` folder. ## Remove Mock Service -If you don’t need the `Mock` service, you can delete the `apps/backend-mock` folder. Also, remove the `VITE_NITRO_MOCK` variable from the `.env.development` file in your application. - -```bash -# Whether to enable Nitro Mock service, true to enable, false to disable -VITE_NITRO_MOCK=false -``` +This workspace does not include a built-in `Mock` service, so there is nothing extra to remove here. ## Installing Dependencies @@ -57,11 +48,9 @@ After slimming down, you may need to adjust commands according to your project. "build:ele": "pnpm run build --filter=@vben/web-ele", "build:naive": "pnpm run build --filter=@vben/web-naive", "build:tdesign": "pnpm run build --filter=@vben/web-tdesign", - "build:play": "pnpm run build --filter=@vben/playground", "dev:antd": "pnpm -F @vben/web-antd run dev", "dev:docs": "pnpm -F @vben/docs run dev", "dev:ele": "pnpm -F @vben/web-ele run dev", - "dev:play": "pnpm -F @vben/playground run dev", "dev:naive": "pnpm -F @vben/web-naive run dev" } } diff --git a/docs/src/en/guide/project/dir.md b/docs/src/en/guide/project/dir.md index 47b92cb..4d6d6a9 100644 --- a/docs/src/en/guide/project/dir.md +++ b/docs/src/en/guide/project/dir.md @@ -6,7 +6,6 @@ The repository uses Monorepo management, and the project structure is as follows . ├── README.md # Project documentation ├── apps # Project applications directory -│ ├── backend-mock # Backend mock service application │ ├── web-antd # Frontend application based on Ant Design Vue │ ├── web-antdv-next # Frontend application based on Ant Design Vue Next │ ├── web-ele # Frontend application based on Element Plus @@ -58,7 +57,6 @@ The repository uses Monorepo management, and the project structure is as follows │ ├── styles # Styles │ ├── types # Type definitions │ └── utils # Utilities -├── playground # Demo directory ├── pnpm-lock.yaml # pnpm lock file ├── pnpm-workspace.yaml # pnpm workspace configuration file ├── scripts # Scripts directory diff --git a/docs/src/guide/essentials/concept.md b/docs/src/guide/essentials/concept.md index 8f9d8b5..5df6427 100644 --- a/docs/src/guide/essentials/concept.md +++ b/docs/src/guide/essentials/concept.md @@ -12,7 +12,7 @@ ::: tip -应用不限于前端应用,也可以是后端应用、移动端应用等,例如 `apps/backend-mock`就是一个后端服务。 +应用不限于前端应用,也可以是移动端应用或其他可独立运行的工程。 ::: diff --git a/docs/src/guide/essentials/development.md b/docs/src/guide/essentials/development.md index cdd8f46..eb27331 100644 --- a/docs/src/guide/essentials/development.md +++ b/docs/src/guide/essentials/development.md @@ -64,8 +64,6 @@ npm 脚本是项目常见的配置,用于执行一些常见的任务,比如 "build:naive": "pnpm run build --filter=@vben/web-naive", // 单独构建 web-tdesign 应用 "build:tdesign": "pnpm run build --filter=@vben/web-tdesign", - // 单独构建 playground 应用 - "build:play": "pnpm run build --filter=@vben/playground", // changeset 版本管理 "changeset": "pnpm exec changeset", // 检查项目各种问题 @@ -96,8 +94,6 @@ npm 脚本是项目常见的配置,用于执行一些常见的任务,比如 "dev:naive": "pnpm -F @vben/web-naive run dev", // 启动 web-tdesign 应用 "dev:tdesign": "pnpm -F @vben/web-tdesign run dev", - // 启动演示应用 - "dev:play": "pnpm -F @vben/playground run dev", // 格式化代码 "format": "vsh lint --format", // lint 代码 diff --git a/docs/src/guide/essentials/route.md b/docs/src/guide/essentials/route.md index 8383e76..695cc91 100644 --- a/docs/src/guide/essentials/route.md +++ b/docs/src/guide/essentials/route.md @@ -10,7 +10,7 @@ outline: deep 路由分为核心路由、静态路由和动态路由,核心路由是框架内置的路由,包含了根路由、登录路由、404路由等;静态路由是在项目启动时就已经确定的路由;动态路由一般是在用户登录后,根据用户的权限动态生成的路由。 -静态路由和动态路由都会走权限控制,可以通过配置路由的 `meta` 属性中的 `authority` 字段来控制权限,可以参考[路由权限控制](https://github.com/vbenjs/vue-vben-admin/blob/main/playground/src/router/routes/modules/demos.ts)。 +静态路由和动态路由都会走权限控制,可以通过配置路由的 `meta` 属性中的 `authority` 字段来控制权限,业务项目中可直接参考应用下 `src/router/routes/modules/*` 的路由元信息写法。 ### 核心路由 diff --git a/docs/src/guide/essentials/server.md b/docs/src/guide/essentials/server.md index cd61d3a..6833104 100644 --- a/docs/src/guide/essentials/server.md +++ b/docs/src/guide/essentials/server.md @@ -369,19 +369,6 @@ async function doRefreshToken() { Mock 数据是前端开发过程中必不可少的一环,是分离前后端开发的关键链路。通过预先跟服务器端约定好的接口,模拟请求数据甚至逻辑,能够让前端开发独立自主,不会被服务端的开发进程所阻塞。 -项目使用 [Nitro](https://nitro.unjs.io/) 来进行本地 mock 数据处理。其原理是本地额外启动一个后端服务,是一个真实的后端服务,可以处理请求,返回数据。 +当前工作区未内置本地 Mock 服务,开发环境默认直接走真实接口或应用侧代理。 -### Nitro 使用 - -Mock 服务代码位于`apps/backend-mock`目录下,无需手动启动,已经集成在项目中,只需要在项目根目录下运行`pnpm dev`即可,运行成功之后,控制台会打印 `http://localhost:5320/api`, 访问该地址即可查看 mock 服务。 - -[Nitro](https://nitro.unjs.io/) 语法简单,可以根据自己的需求进行配置及开发,具体配置可以查看 [Nitro 文档](https://nitro.unjs.io/)。 - -## 关闭 Mock 服务 - -mock的本质是一个真实的后端服务,如果不需要 mock 服务,可以在项目根目录下的 `.env.development` 文件中配置 `VITE_NITRO_MOCK=false` 即可关闭 mock 服务。 - -```bash -# .env.development -VITE_NITRO_MOCK=false -``` +如果你需要本地 mock,可以自行接入独立的 mock 服务,或者使用 Vite 代理把请求转发到自建测试环境。 diff --git a/docs/src/guide/essentials/settings.md b/docs/src/guide/essentials/settings.md index 9637114..c7c3b3c 100644 --- a/docs/src/guide/essentials/settings.md +++ b/docs/src/guide/essentials/settings.md @@ -47,9 +47,6 @@ VITE_BASE=/ # 接口地址 VITE_GLOB_API_URL=/api -# 是否开启 Nitro Mock服务,true 为开启,false 为关闭 -VITE_NITRO_MOCK=true - # 是否打开 devtools,true 为打开,false 为关闭 VITE_DEVTOOLS=true diff --git a/docs/src/guide/introduction/quick-start.md b/docs/src/guide/introduction/quick-start.md index f940672..e3cede3 100644 --- a/docs/src/guide/introduction/quick-start.md +++ b/docs/src/guide/introduction/quick-start.md @@ -93,11 +93,10 @@ pnpm dev │ ○ @vben/web-ele │ ○ @vben/web-naive │ ○ @vben/docs -│ ● @vben/playground └ ``` -现在,你可以在浏览器访问 `http://localhost:5555` 查看项目。 +现在,你可以在浏览器访问终端输出的地址查看项目;当前主业务应用默认端口是 `http://localhost:5999`。 #### 运行指定项目 diff --git a/docs/src/guide/introduction/thin.md b/docs/src/guide/introduction/thin.md index 8a37c25..596435d 100644 --- a/docs/src/guide/introduction/thin.md +++ b/docs/src/guide/introduction/thin.md @@ -22,22 +22,13 @@ apps/web-naive ::: -## 演示代码精简 - -如果你不需要演示代码,你可以直接删除 `playground` 文件夹。 - ## 文档精简 如果你不需要文档,你可以直接删除`docs`文件夹。 ## Mock 服务精简 -如果你不需要`Mock`服务,你可以直接删除`apps/backend-mock`文件夹。同时在你的应用下`.env.development`文件中删除`VITE_NITRO_MOCK`变量。 - -```bash -# 是否开启 Nitro Mock服务,true 为开启,false 为关闭 -VITE_NITRO_MOCK=false -``` +当前工作区未内置 `Mock` 服务,无需额外移除。 ## 安装依赖 @@ -61,11 +52,9 @@ pnpm install "build:ele": "pnpm run build --filter=@vben/web-ele", "build:naive": "pnpm run build --filter=@vben/web-naive", "build:tdesign": "pnpm run build --filter=@vben/web-tdesign", - "build:play": "pnpm run build --filter=@vben/playground", "dev:antd": "pnpm -F @vben/web-antd run dev", "dev:docs": "pnpm -F @vben/docs run dev", "dev:ele": "pnpm -F @vben/web-ele run dev", - "dev:play": "pnpm -F @vben/playground run dev", "dev:naive": "pnpm -F @vben/web-naive run dev" } } diff --git a/docs/src/guide/project/dir.md b/docs/src/guide/project/dir.md index 124e2e4..b3f1599 100644 --- a/docs/src/guide/project/dir.md +++ b/docs/src/guide/project/dir.md @@ -6,7 +6,6 @@ . ├── README.md # 项目说明文档 ├── apps # 项目应用目录 -│ ├── backend-mock # 后端模拟服务应用 │ ├── web-antd # 基于 Ant Design Vue 的前端应用 │ ├── web-antdv-next # 基于 Ant Design Vue Next 的前端应用 │ ├── web-ele # 基于 Element Plus 的前端应用 @@ -58,7 +57,6 @@ │ ├── styles # 样式 │ ├── types # 类型定义 │ └── utils # 工具 -├── playground # 演示目录 ├── pnpm-lock.yaml # pnpm 锁定文件 ├── pnpm-workspace.yaml # pnpm 工作区配置文件 ├── scripts # 脚本目录 diff --git a/internal/tailwind-config/src/theme.css b/internal/tailwind-config/src/theme.css index c212dc6..504b423 100644 --- a/internal/tailwind-config/src/theme.css +++ b/internal/tailwind-config/src/theme.css @@ -8,7 +8,6 @@ @source '../../../packages/'; @source '../../../apps/'; @source '../../../docs/'; -@source '../../../playground/'; /* Dark mode uses .dark class selector, not prefers-color-scheme */ @custom-variant dark (&:is(.dark *)); diff --git a/internal/vite-config/package.json b/internal/vite-config/package.json index ca20490..a3e6c45 100644 --- a/internal/vite-config/package.json +++ b/internal/vite-config/package.json @@ -33,9 +33,7 @@ "@vben/node-utils": "workspace:*", "archiver": "catalog:", "cheerio": "catalog:", - "get-port": "catalog:", "html-minifier-terser": "catalog:", - "nitropack": "catalog:", "resolve.exports": "catalog:", "vite-plugin-pwa": "catalog:", "vite-plugin-vue-devtools": "catalog:" diff --git a/internal/vite-config/src/config/application.ts b/internal/vite-config/src/config/application.ts index f8c2264..c54bf91 100644 --- a/internal/vite-config/src/config/application.ts +++ b/internal/vite-config/src/config/application.ts @@ -40,8 +40,6 @@ function defineApplicationConfig(userConfigPromise?: DefineApplicationOptions) { isBuild, license: true, mode, - nitroMock: !isBuild, - nitroMockOptions: {}, print: !isBuild, printInfoMap: { 'Vben Admin Docs': 'https://doc.vben.pro', diff --git a/internal/vite-config/src/plugins/index.ts b/internal/vite-config/src/plugins/index.ts index 9d3ba3f..0ef16c9 100644 --- a/internal/vite-config/src/plugins/index.ts +++ b/internal/vite-config/src/plugins/index.ts @@ -24,7 +24,6 @@ import { viteImportMapPlugin } from './importmap'; import { viteInjectAppLoadingPlugin } from './inject-app-loading'; import { viteMetadataPlugin } from './inject-metadata'; import { viteLicensePlugin } from './license'; -import { viteNitroMockPlugin } from './nitro-mock'; import { vitePrintPlugin } from './print'; import { viteTailwindReferencePlugin } from './tailwind-reference'; import { viteVxeTableImportsPlugin } from './vxe-table'; @@ -110,8 +109,6 @@ async function loadApplicationPlugins( importmapOptions, injectAppLoading, license, - nitroMock, - nitroMockOptions, print, printInfoMap, pwa, @@ -148,13 +145,6 @@ async function loadApplicationPlugins( return [await viteVxeTableImportsPlugin()]; }, }, - { - condition: nitroMock, - plugins: async () => { - return [await viteNitroMockPlugin(nitroMockOptions)]; - }, - }, - { condition: injectAppLoading, plugins: async () => [await viteInjectAppLoadingPlugin(!!isBuild, env)], diff --git a/internal/vite-config/src/plugins/nitro-mock.ts b/internal/vite-config/src/plugins/nitro-mock.ts deleted file mode 100644 index 2a22e1d..0000000 --- a/internal/vite-config/src/plugins/nitro-mock.ts +++ /dev/null @@ -1,102 +0,0 @@ -import type { PluginOption } from 'vite'; - -import type { NitroMockPluginOptions } from '../typing'; - -import { colors, consola, getPackage } from '@vben/node-utils'; - -import getPort from 'get-port'; -import { build, createDevServer, createNitro, prepare } from 'nitropack'; - -const hmrKeyRe = /^runtimeConfig\.|routeRules\./; - -export const viteNitroMockPlugin = ({ - mockServerPackage, - port = 5320, - verbose = true, -}: NitroMockPluginOptions = {}): PluginOption => { - return { - async configureServer(server) { - if (!mockServerPackage) { - return; - } - - const availablePort = await getPort({ port }); - if (availablePort !== port) { - return; - } - - const pkg = await getPackage(mockServerPackage); - if (!pkg) { - consola.log( - `Package ${mockServerPackage} not found. Skip mock server.`, - ); - return; - } - - runNitroServer(pkg.dir, port, verbose); - - const _printUrls = server.printUrls; - server.printUrls = () => { - _printUrls(); - - consola.log( - ` ${colors.green('➜')} ${colors.bold('Nitro Mock Server')}: ${colors.cyan(`http://localhost:${port}/api`)}`, - ); - }; - }, - enforce: 'pre', - name: 'vite:mock-server', - }; -}; - -async function runNitroServer(rootDir: string, port: number, verbose: boolean) { - let nitro: any; - const reload = async () => { - if (nitro) { - consola.info('Restarting dev server...'); - if ('unwatch' in nitro.options._c12) { - await nitro.options._c12.unwatch(); - } - await nitro.close(); - } - nitro = await createNitro( - { - dev: true, - preset: 'nitro-dev', - rootDir, - }, - { - c12: { - async onUpdate({ getDiff, newConfig }) { - const diff = getDiff(); - if (diff.length === 0) { - return; - } - verbose && - consola.info( - `Nitro config updated:\n${diff - .map((entry) => ` ${entry.toString()}`) - .join('\n')}`, - ); - await (diff.every((e) => hmrKeyRe.test(e.key)) - ? nitro.updateConfig(newConfig.config) - : reload()); - }, - }, - watch: true, - }, - ); - nitro.hooks.hookOnce('restart', reload); - - const server = createDevServer(nitro); - await server.listen(port, { showURL: false }); - await prepare(nitro); - await build(nitro); - - if (verbose) { - console.log(''); - consola.success(colors.bold(colors.green('Nitro Mock Server started.'))); - } - }; - return await reload(); -} diff --git a/internal/vite-config/src/typing.ts b/internal/vite-config/src/typing.ts index dfa2682..e3c704b 100644 --- a/internal/vite-config/src/typing.ts +++ b/internal/vite-config/src/typing.ts @@ -53,30 +53,6 @@ interface PrintPluginOptions { infoMap?: Record; } -/** - * Nitro Mock 插件配置选项 - * @description 用于配置 Nitro Mock 服务器的行为 - */ -interface NitroMockPluginOptions { - /** - * Mock 服务器包名 - * @default undefined - */ - mockServerPackage?: string; - - /** - * Mock 服务端口 - * @default 3000 - */ - port?: number; - - /** - * 是否打印 Mock 日志 - * @default false - */ - verbose?: boolean; -} - /** * 归档插件配置选项 * @description 用于配置构建产物的压缩归档 @@ -247,15 +223,6 @@ interface ApplicationPluginOptions extends CommonPluginOptions { * @default true */ license?: boolean; - /** - * 是否开启 Nitro Mock - * @default false - */ - nitroMock?: boolean; - /** - * Nitro Mock 插件配置 - */ - nitroMockOptions?: NitroMockPluginOptions; /** * 是否开启控制台打印 * @default false @@ -345,7 +312,6 @@ export type { IImportMap, ImportmapPluginOptions, LibraryPluginOptions, - NitroMockPluginOptions, PrintPluginOptions, VbenViteConfig, }; diff --git a/internal/vite-config/src/utils/env.ts b/internal/vite-config/src/utils/env.ts index f342216..2532717 100644 --- a/internal/vite-config/src/utils/env.ts +++ b/internal/vite-config/src/utils/env.ts @@ -82,7 +82,6 @@ async function loadAndConvertEnv( VITE_COMPRESS, VITE_DEVTOOLS, VITE_INJECT_APP_LOADING, - VITE_NITRO_MOCK, VITE_PORT, VITE_PWA, VITE_VISUALIZER, @@ -100,7 +99,6 @@ async function loadAndConvertEnv( compressTypes, devtools: getBoolean(VITE_DEVTOOLS), injectAppLoading: getBoolean(VITE_INJECT_APP_LOADING), - nitroMock: getBoolean(VITE_NITRO_MOCK), port: getNumber(VITE_PORT, 5173), pwa: getBoolean(VITE_PWA), visualizer: getBoolean(VITE_VISUALIZER), diff --git a/package.json b/package.json index de4d280..794689a 100644 --- a/package.json +++ b/package.json @@ -11,7 +11,6 @@ "build:antdv-next": "pnpm run build --filter=@vben/web-antdv-next", "build:docker": "./scripts/deploy/build-local-docker-image.sh", "build:docs": "pnpm run build --filter=@vben/docs", - "build:play": "pnpm run build --filter=@vben/playground", "changeset": "pnpm exec changeset", "check": "pnpm run check:circular && pnpm run check:dep && pnpm run check:type && pnpm check:cspell", "check:circular": "vsh check-circular", @@ -22,7 +21,6 @@ "dev": "turbo-run dev", "dev:antdv-next": "pnpm -F @vben/web-antdv-next run dev", "dev:docs": "pnpm -F @vben/docs run dev", - "dev:play": "pnpm -F @vben/playground run dev", "format": "vsh lint --format", "lint": "vsh lint", "postinstall": "pnpm -r run stub --if-present", @@ -31,7 +29,6 @@ "publint": "vsh publint", "reinstall": "pnpm clean --del-lock && pnpm install", "test:unit": "vitest run --dom", - "test:e2e": "turbo run test:e2e", "update:deps": "npx taze -r -w", "version": "pnpm exec changeset version && pnpm install --no-frozen-lockfile", "catalog": "pnpx codemod pnpm/catalog" @@ -39,7 +36,6 @@ "devDependencies": { "@changesets/changelog-github": "catalog:", "@changesets/cli": "catalog:", - "@playwright/test": "catalog:", "@tsdown/css": "catalog:", "@types/node": "catalog:", "@vben/eslint-config": "workspace:*", @@ -55,7 +51,6 @@ "cross-env": "catalog:", "cspell": "catalog:", "happy-dom": "catalog:", - "playwright": "catalog:", "rimraf": "catalog:", "tailwindcss": "catalog:", "tsdown": "catalog:", diff --git a/playground/.env b/playground/.env deleted file mode 100644 index 94ff4fa..0000000 --- a/playground/.env +++ /dev/null @@ -1,8 +0,0 @@ -# 应用标题 -VITE_APP_TITLE=Vben Admin - -# 应用命名空间,用于缓存、store等功能的前缀,确保隔离 -VITE_APP_NAMESPACE=vben-web-play - -# 对store进行加密的密钥,在将store持久化到localStorage时会使用该密钥进行加密 -VITE_APP_STORE_SECURE_KEY=please-replace-me-with-your-own-key diff --git a/playground/.env.analyze b/playground/.env.analyze deleted file mode 100644 index ffafa8d..0000000 --- a/playground/.env.analyze +++ /dev/null @@ -1,7 +0,0 @@ -# public path -VITE_BASE=/ - -# Basic interface address SPA -VITE_GLOB_API_URL=/api - -VITE_VISUALIZER=true diff --git a/playground/.env.development b/playground/.env.development deleted file mode 100644 index 0b1dc05..0000000 --- a/playground/.env.development +++ /dev/null @@ -1,20 +0,0 @@ -# 端口号 -VITE_PORT=5555 - -VITE_BASE=/ - -# 接口地址 -VITE_GLOB_API_URL=/api - -# 是否开启 Nitro Mock服务,true 为开启,false 为关闭 -VITE_NITRO_MOCK=true - -# 是否打开 devtools,true 为打开,false 为关闭 -VITE_DEVTOOLS=false - -# 是否注入全局loading -VITE_INJECT_APP_LOADING=true - -# 钉钉登录配置 -VITE_GLOB_AUTH_DINGDING_CLIENT_ID=应用的clientId -VITE_GLOB_AUTH_DINGDING_CORP_ID=应用的corpId diff --git a/playground/.env.production b/playground/.env.production deleted file mode 100644 index 5375847..0000000 --- a/playground/.env.production +++ /dev/null @@ -1,19 +0,0 @@ -VITE_BASE=/ - -# 接口地址 -VITE_GLOB_API_URL=https://mock-napi.vben.pro/api - -# 是否开启压缩,可以设置为 none, brotli, gzip -VITE_COMPRESS=none - -# 是否开启 PWA -VITE_PWA=false - -# vue-router 的模式 -VITE_ROUTER_HISTORY=hash - -# 是否注入全局loading -VITE_INJECT_APP_LOADING=true - -# 打包后是否生成dist.zip -VITE_ARCHIVER=true diff --git a/playground/__tests__/e2e/auth-login.spec.ts b/playground/__tests__/e2e/auth-login.spec.ts deleted file mode 100644 index bb6cd28..0000000 --- a/playground/__tests__/e2e/auth-login.spec.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { expect, test } from '@playwright/test'; - -import { authLogin } from './common/auth'; - -test.beforeEach(async ({ page }) => { - await page.goto('/'); -}); - -test.describe('Auth Login Page Tests', () => { - test('check title and page elements', async ({ page }) => { - // 获取页面标题并断言标题包含 'Vben Admin' - const title = await page.title(); - expect(title).toContain('Vben Admin'); - }); - - // 测试用例: 成功登录 - test('should successfully login with valid credentials', async ({ page }) => { - await authLogin(page); - }); -}); diff --git a/playground/__tests__/e2e/common/auth.ts b/playground/__tests__/e2e/common/auth.ts deleted file mode 100644 index 26b526f..0000000 --- a/playground/__tests__/e2e/common/auth.ts +++ /dev/null @@ -1,46 +0,0 @@ -import type { Page } from '@playwright/test'; - -import { expect } from '@playwright/test'; - -export async function authLogin(page: Page) { - // 确保登录表单正常 - const usernameInput = await page.locator(`input[name='username']`); - await expect(usernameInput).toBeVisible(); - - const passwordInput = await page.locator(`input[name='password']`); - await expect(passwordInput).toBeVisible(); - - const sliderCaptcha = await page.locator(`div[name='captcha']`); - const sliderCaptchaAction = await page.locator(`div[name='captcha-action']`); - await expect(sliderCaptcha).toBeVisible(); - await expect(sliderCaptchaAction).toBeVisible(); - - // 拖动验证码滑块 - // 获取拖动按钮的位置 - const sliderCaptchaBox = await sliderCaptcha.boundingBox(); - if (!sliderCaptchaBox) throw new Error('滑块未找到'); - - const actionBoundingBox = await sliderCaptchaAction.boundingBox(); - if (!actionBoundingBox) throw new Error('要拖动的按钮未找到'); - - // 计算起始位置和目标位置 - const startX = actionBoundingBox.x + actionBoundingBox.width / 2; // div 中心的 x 坐标 - const startY = actionBoundingBox.y + actionBoundingBox.height / 2; // div 中心的 y 坐标 - - const targetX = startX + sliderCaptchaBox.width + actionBoundingBox.width; // 向右拖动容器的宽度 - const targetY = startY; // y 坐标保持不变 - - // 模拟鼠标拖动 - await page.mouse.move(startX, startY); // 移动到 action 的中心 - await page.mouse.down(); // 按下鼠标 - await page.mouse.move(targetX, targetY, { steps: 20 }); // 拖动到目标位置 - await page.mouse.up(); // 松开鼠标 - - // 在拖动后进行断言,检查action是否在预期位置, - const newActionBoundingBox = await sliderCaptchaAction.boundingBox(); - expect(newActionBoundingBox?.x).toBeGreaterThan(actionBoundingBox.x); - - // 到这里已经校验成功,点击进行登录 - await page.waitForTimeout(300); - await page.getByRole('button', { name: 'login' }).click(); -} diff --git a/playground/index.html b/playground/index.html deleted file mode 100644 index ca53269..0000000 --- a/playground/index.html +++ /dev/null @@ -1,35 +0,0 @@ - - - - - - - - - - - - <%= VITE_APP_TITLE %> - - - - -
- - - diff --git a/playground/package.json b/playground/package.json deleted file mode 100644 index ddb2e03..0000000 --- a/playground/package.json +++ /dev/null @@ -1,61 +0,0 @@ -{ - "name": "@vben/playground", - "version": "5.7.0", - "homepage": "https://vben.pro", - "bugs": "https://github.com/vbenjs/vue-vben-admin/issues", - "repository": { - "type": "git", - "url": "git+https://github.com/vbenjs/vue-vben-admin.git", - "directory": "playground" - }, - "license": "MIT", - "author": { - "name": "vben", - "email": "ann.vben@gmail.com", - "url": "https://github.com/anncwb" - }, - "type": "module", - "scripts": { - "build": "pnpm vite build --mode production", - "build:analyze": "pnpm vite build --mode analyze", - "dev": "pnpm vite --mode development", - "preview": "vite preview", - "typecheck": "vue-tsc --noEmit --skipLibCheck", - "test:e2e": "playwright test", - "test:e2e-ui": "playwright test --ui", - "test:e2e-codegen": "playwright codegen" - }, - "imports": { - "#/*": "./src/*" - }, - "dependencies": { - "@tanstack/vue-query": "catalog:", - "@vben-core/design": "workspace:*", - "@vben-core/menu-ui": "workspace:*", - "@vben-core/shadcn-ui": "workspace:*", - "@vben/access": "workspace:*", - "@vben/common-ui": "workspace:*", - "@vben/constants": "workspace:*", - "@vben/hooks": "workspace:*", - "@vben/icons": "workspace:*", - "@vben/layouts": "workspace:*", - "@vben/locales": "workspace:*", - "@vben/plugins": "workspace:*", - "@vben/preferences": "workspace:*", - "@vben/request": "workspace:*", - "@vben/stores": "workspace:*", - "@vben/styles": "workspace:*", - "@vben/types": "workspace:*", - "@vben/utils": "workspace:*", - "@vueuse/core": "catalog:", - "ant-design-vue": "catalog:", - "dayjs": "catalog:", - "json-bigint": "catalog:", - "pinia": "catalog:", - "vue": "catalog:", - "vue-router": "catalog:" - }, - "devDependencies": { - "@types/json-bigint": "catalog:" - } -} diff --git a/playground/playwright.config.ts b/playground/playwright.config.ts deleted file mode 100644 index ca0c908..0000000 --- a/playground/playwright.config.ts +++ /dev/null @@ -1,108 +0,0 @@ -import type { PlaywrightTestConfig } from '@playwright/test'; - -import { devices } from '@playwright/test'; - -/** - * Read environment variables from file. - * https://github.com/motdotla/dotenv - */ -// require('dotenv').config(); - -/** - * See https://playwright.dev/docs/test-configuration. - */ -const config: PlaywrightTestConfig = { - expect: { - /** - * Maximum time expect() should wait for the condition to be met. - * For example in `await expect(locator).toHaveText();` - */ - timeout: 5000, - }, - /* Fail the build on CI if you accidentally left test.only in the source code. */ - forbidOnly: !!process.env.CI, - /* Folder for test artifacts such as screenshots, videos, traces, etc. */ - outputDir: 'node_modules/.e2e/test-results/', - /* Configure projects for major browsers */ - projects: [ - { - name: 'chromium', - use: { - ...devices['Desktop Chrome'], - }, - }, - // { - // name: 'firefox', - // use: { - // ...devices['Desktop Firefox'], - // }, - // }, - // { - // name: 'webkit', - // use: { - // ...devices['Desktop Safari'], - // }, - // }, - - /* Test against mobile viewports. */ - // { - // name: 'Mobile Chrome', - // use: { - // ...devices['Pixel 5'], - // }, - // }, - // { - // name: 'Mobile Safari', - // use: { - // ...devices['iPhone 12'], - // }, - // }, - - /* Test against branded browsers. */ - // { - // name: 'Microsoft Edge', - // use: { - // channel: 'msedge', - // }, - // }, - // { - // name: 'Google Chrome', - // use: { - // channel: 'chrome', - // }, - // }, - ], - /* Reporter to use. See https://playwright.dev/docs/test-reporters */ - reporter: [ - ['list'], - ['html', { outputFolder: 'node_modules/.e2e/test-results' }], - ], - /* Retry on CI only */ - retries: process.env.CI ? 2 : 0, - testDir: './__tests__/e2e', - /* Maximum time one test can run for. */ - timeout: 30 * 1000, - /* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */ - use: { - /* Maximum time each action such as `click()` can take. Defaults to 0 (no limit). */ - actionTimeout: 0, - /* Base URL to use in actions like `await page.goto('/')`. */ - baseURL: 'http://localhost:5555', - /* Only on CI systems run the tests headless */ - headless: !!process.env.CI, - /* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */ - trace: 'retain-on-failure', - }, - - /* Run your local dev server before starting the tests */ - webServer: { - command: process.env.CI ? 'pnpm preview --port 5555' : 'pnpm dev', - port: 5555, - reuseExistingServer: !process.env.CI, - }, - - /* Opt out of parallel tests on CI. */ - workers: process.env.CI ? 1 : undefined, -}; - -export default config; diff --git a/playground/public/favicon.ico b/playground/public/favicon.ico deleted file mode 100644 index fcf9818..0000000 Binary files a/playground/public/favicon.ico and /dev/null differ diff --git a/playground/src/adapter/component/index.ts b/playground/src/adapter/component/index.ts deleted file mode 100644 index 6176051..0000000 --- a/playground/src/adapter/component/index.ts +++ /dev/null @@ -1,674 +0,0 @@ -/** - * 通用组件共同的使用的基础组件,原先放在 adapter/form 内部,限制了使用范围,这里提取出来,方便其他地方使用 - * 可用于 vben-form、vben-modal、vben-drawer 等组件使用, - */ - -/* eslint-disable vue/one-component-per-file */ - -import type { - UploadChangeParam, - UploadFile, - UploadProps, -} from 'ant-design-vue'; - -import type { Component, Ref } from 'vue'; - -import type { BaseFormComponentType } from '@vben/common-ui'; -import type { Sortable } from '@vben/hooks'; -import type { Recordable } from '@vben/types'; - -import { - computed, - defineAsyncComponent, - defineComponent, - h, - nextTick, - onMounted, - onUnmounted, - ref, - render, - unref, - watch, -} from 'vue'; - -import { - ApiComponent, - globalShareState, - IconPicker, - VCropper, -} from '@vben/common-ui'; -import { useSortable } from '@vben/hooks'; -import { IconifyIcon } from '@vben/icons'; -import { $t } from '@vben/locales'; -import { isEmpty } from '@vben/utils'; - -import { message, Modal, notification } from 'ant-design-vue'; - -const AutoComplete = defineAsyncComponent( - () => import('ant-design-vue/es/auto-complete'), -); -const Button = defineAsyncComponent(() => import('ant-design-vue/es/button')); -const Checkbox = defineAsyncComponent( - () => import('ant-design-vue/es/checkbox'), -); -const CheckboxGroup = defineAsyncComponent(() => - import('ant-design-vue/es/checkbox').then((res) => res.CheckboxGroup), -); -const DatePicker = defineAsyncComponent( - () => import('ant-design-vue/es/date-picker'), -); -const Divider = defineAsyncComponent(() => import('ant-design-vue/es/divider')); -const Input = defineAsyncComponent(() => import('ant-design-vue/es/input')); -const InputNumber = defineAsyncComponent( - () => import('ant-design-vue/es/input-number'), -); -const InputPassword = defineAsyncComponent(() => - import('ant-design-vue/es/input').then((res) => res.InputPassword), -); -const Mentions = defineAsyncComponent( - () => import('ant-design-vue/es/mentions'), -); -const Radio = defineAsyncComponent(() => import('ant-design-vue/es/radio')); -const RadioGroup = defineAsyncComponent(() => - import('ant-design-vue/es/radio').then((res) => res.RadioGroup), -); -const RangePicker = defineAsyncComponent(() => - import('ant-design-vue/es/date-picker').then((res) => res.RangePicker), -); -const Rate = defineAsyncComponent(() => import('ant-design-vue/es/rate')); -const Select = defineAsyncComponent(() => import('ant-design-vue/es/select')); -const Space = defineAsyncComponent(() => import('ant-design-vue/es/space')); -const Switch = defineAsyncComponent(() => import('ant-design-vue/es/switch')); -const Textarea = defineAsyncComponent(() => - import('ant-design-vue/es/input').then((res) => res.Textarea), -); -const TimePicker = defineAsyncComponent( - () => import('ant-design-vue/es/time-picker'), -); -const TreeSelect = defineAsyncComponent( - () => import('ant-design-vue/es/tree-select'), -); -const Cascader = defineAsyncComponent( - () => import('ant-design-vue/es/cascader'), -); -const Upload = defineAsyncComponent(() => import('ant-design-vue/es/upload')); -const Image = defineAsyncComponent(() => import('ant-design-vue/es/image')); -const PreviewGroup = defineAsyncComponent(() => - import('ant-design-vue/es/image').then((res) => res.ImagePreviewGroup), -); - -const withDefaultPlaceholder = ( - component: T, - type: 'input' | 'select', - componentProps: Recordable = {}, -) => { - return defineComponent({ - name: component.name, - inheritAttrs: false, - setup: (props: any, { attrs, expose, slots }) => { - const placeholder = - props?.placeholder || - attrs?.placeholder || - $t(`ui.placeholder.${type}`); - // 透传组件暴露的方法 - const innerRef = ref(); - expose( - new Proxy( - {}, - { - get: (_target, key) => innerRef.value?.[key], - has: (_target, key) => key in (innerRef.value || {}), - }, - ), - ); - return () => - h( - component, - { ...componentProps, placeholder, ...props, ...attrs, ref: innerRef }, - slots, - ); - }, - }); -}; - -const IMAGE_EXTENSIONS = new Set([ - 'bmp', - 'gif', - 'jpeg', - 'jpg', - 'png', - 'svg', - 'webp', -]); - -/** - * 检查是否为图片文件 - */ -function isImageFile(file: UploadFile): boolean { - if (file.url) { - try { - const pathname = new URL(file.url, 'http://localhost').pathname; - const ext = pathname.split('.').pop()?.toLowerCase(); - return ext ? IMAGE_EXTENSIONS.has(ext) : false; - } catch { - const ext = file.url?.split('.').pop()?.toLowerCase(); - return ext ? IMAGE_EXTENSIONS.has(ext) : false; - } - } - if (!file.type) { - const ext = file.name?.split('.').pop()?.toLowerCase(); - return ext ? IMAGE_EXTENSIONS.has(ext) : false; - } - return file.type.startsWith('image/'); -} - -/** - * 创建默认的上传按钮插槽 - */ -function createDefaultUploadSlots(listType: string, placeholder: string) { - if (listType === 'picture-card') { - return { default: () => placeholder }; - } - return { - default: () => - h( - Button, - { - icon: h(IconifyIcon, { - icon: 'ant-design:upload-outlined', - class: 'mb-1 size-4', - }), - }, - () => placeholder, - ), - }; -} - -/** - * 获取文件的 Base64 - */ -function getBase64(file: File): Promise { - return new Promise((resolve, reject) => { - const reader = new FileReader(); - reader.readAsDataURL(file); - reader.addEventListener('load', () => resolve(reader.result as string)); - reader.addEventListener('error', reject); - }); -} - -/** - * 预览图片 - */ -async function previewImage( - file: UploadFile, - visible: Ref, - fileList: Ref, -) { - // 非图片文件直接打开链接 - if (!isImageFile(file)) { - const url = file.url || file.preview; - if (url) { - window.open(url, '_blank'); - } else { - message.error($t('ui.formRules.previewWarning')); - } - return; - } - - const [ImageComponent, PreviewGroupComponent] = await Promise.all([ - Image, - PreviewGroup, - ]); - - // 过滤图片文件并生成预览 - const imageFiles = (unref(fileList) || []).filter((f) => isImageFile(f)); - - for (const imgFile of imageFiles) { - if (!imgFile.url && !imgFile.preview && imgFile.originFileObj) { - imgFile.preview = await getBase64(imgFile.originFileObj); - } - } - - const container = document.createElement('div'); - document.body.append(container); - let isUnmounted = false; - - const currentIndex = imageFiles.findIndex((f) => f.uid === file.uid); - - const PreviewWrapper = { - setup() { - return () => { - if (isUnmounted) return null; - return h( - PreviewGroupComponent, - { - class: 'hidden', - preview: { - visible: visible.value, - current: currentIndex, - onVisibleChange: (value: boolean) => { - visible.value = value; - if (!value) { - setTimeout(() => { - if (!isUnmounted && container) { - isUnmounted = true; - render(null, container); - container.remove(); - } - }, 300); - } - }, - }, - }, - () => - imageFiles.map((imgFile) => - h(ImageComponent, { - key: imgFile.uid, - src: imgFile.url || imgFile.preview, - }), - ), - ); - }; - }, - }; - - render(h(PreviewWrapper), container); -} - -/** - * 图片裁剪操作 - */ -function cropImage(file: File, aspectRatio: string | undefined) { - return new Promise((resolve, reject) => { - const container = document.createElement('div'); - document.body.append(container); - - let isUnmounted = false; - let objectUrl: null | string = null; - - const open = ref(true); - const cropperRef = ref | null>(null); - - const closeModal = () => { - open.value = false; - setTimeout(() => { - if (!isUnmounted && container) { - if (objectUrl) { - URL.revokeObjectURL(objectUrl); - } - isUnmounted = true; - render(null, container); - container.remove(); - } - }, 300); - }; - - const CropperWrapper = { - setup() { - return () => { - if (isUnmounted) return null; - if (!objectUrl) { - objectUrl = URL.createObjectURL(file); - } - return h( - Modal, - { - open: open.value, - title: h('div', {}, [ - $t('ui.crop.title'), - h( - 'span', - { - class: `${aspectRatio ? '' : 'hidden'} ml-2 text-sm text-gray-400 font-normal`, - }, - $t('ui.crop.titleTip', [aspectRatio]), - ), - ]), - centered: true, - width: 548, - keyboard: false, - maskClosable: false, - closable: false, - cancelText: $t('common.cancel'), - okText: $t('ui.crop.confirm'), - destroyOnClose: true, - onOk: async () => { - const cropper = cropperRef.value; - if (!cropper) { - reject(new Error('Cropper not found')); - closeModal(); - return; - } - try { - const dataUrl = await cropper.getCropImage(); - if (dataUrl) { - resolve(dataUrl); - } else { - reject(new Error($t('ui.crop.errorTip'))); - } - } catch { - reject(new Error($t('ui.crop.errorTip'))); - } finally { - closeModal(); - } - }, - onCancel() { - resolve(''); - closeModal(); - }, - }, - () => - h(VCropper, { - ref: (ref: any) => (cropperRef.value = ref), - img: objectUrl as string, - aspectRatio, - }), - ); - }; - }, - }; - - render(h(CropperWrapper), container); - }); -} - -/** - * 带预览功能的上传组件 - */ -const withPreviewUpload = () => { - return defineComponent({ - name: Upload.name, - emits: ['update:modelValue'], - setup( - props: any, - { attrs, slots, emit }: { attrs: any; emit: any; slots: any }, - ) { - const previewVisible = ref(false); - const placeholder = attrs?.placeholder || $t('ui.placeholder.upload'); - const listType = attrs?.listType || attrs?.['list-type'] || 'text'; - const fileList = ref( - attrs?.fileList || attrs?.['file-list'] || [], - ); - - const maxSize = computed(() => attrs?.maxSize ?? attrs?.['max-size']); - const aspectRatio = computed( - () => attrs?.aspectRatio ?? attrs?.['aspect-ratio'], - ); - - const handleBeforeUpload = async ( - file: UploadFile, - originFileList: Array, - ) => { - // 文件大小限制 - if (maxSize.value && (file.size || 0) / 1024 / 1024 > maxSize.value) { - message.error($t('ui.formRules.sizeLimit', [maxSize.value])); - file.status = 'removed'; - return false; - } - - // 图片裁剪处理 - if ( - attrs.crop && - !attrs.multiple && - originFileList[0] && - isImageFile(file) - ) { - file.status = 'removed'; - const blob = await cropImage(originFileList[0], aspectRatio.value); - if (!blob) { - throw new Error($t('ui.crop.errorTip')); - } - return blob; - } - - return attrs.beforeUpload?.(file) ?? true; - }; - - const handleChange = (event: UploadChangeParam) => { - try { - attrs.handleChange?.(event); - attrs.onHandleChange?.(event); - } catch (error) { - console.error(error); - } - fileList.value = event.fileList.filter( - (file) => file.status !== 'removed', - ); - emit( - 'update:modelValue', - event.fileList?.length ? fileList.value : undefined, - ); - }; - - const handlePreview = async (file: UploadFile) => { - previewVisible.value = true; - await previewImage(file, previewVisible, fileList); - }; - - const renderUploadButton = () => { - if (attrs.disabled) return null; - return isEmpty(slots) - ? createDefaultUploadSlots(listType, placeholder) - : slots; - }; - - // 拖拽排序 - const draggable = computed( - () => (attrs.draggable ?? false) && !attrs.disabled, - ); - const uploadId = `upload-${Date.now()}-${Math.random().toString(36).slice(2, 9)}`; - const sortableInstance = ref(null); - - const styleId = `upload-drag-style-${uploadId}`; - - function injectDragStyle() { - if (!document.querySelector(`[id="${styleId}"]`)) { - const style = document.createElement('style'); - style.id = styleId; - style.textContent = ` - [data-upload-id="${uploadId}"] .ant-upload-list-item { cursor: move; } - [data-upload-id="${uploadId}"] .ant-upload-list-item:hover { box-shadow: 0 2px 8px rgba(0,0,0,0.15); } - `; - document.head.append(style); - } - } - - function removeDragStyle() { - document.querySelector(`[id="${styleId}"]`)?.remove(); - } - - async function initSortable(retryCount = 0) { - if (!draggable.value) return; - - injectDragStyle(); - await nextTick(); - await new Promise((resolve) => setTimeout(resolve, 100)); - - const container = document.querySelector( - `[data-upload-id="${uploadId}"] .ant-upload-list`, - ) as HTMLElement; - - if (!container) { - if (retryCount < 5) { - setTimeout(() => initSortable(retryCount + 1), 200); - } - return; - } - - const { initializeSortable } = useSortable(container, { - animation: 300, - delay: 400, - delayOnTouchOnly: true, - filter: - '.ant-upload-select, .ant-upload-list-item-error, .ant-upload-list-item-uploading', - onEnd: (evt) => { - const { oldIndex, newIndex } = evt; - if ( - oldIndex === undefined || - newIndex === undefined || - oldIndex === newIndex - ) { - return; - } - - const list = [...(fileList.value || [])]; - const [movedItem] = list.splice(oldIndex, 1); - if (movedItem) { - list.splice(newIndex, 0, movedItem); - fileList.value = list; - } - - attrs.onDragSort?.(oldIndex, newIndex); - emit('update:modelValue', fileList.value); - }, - }); - - sortableInstance.value = await initializeSortable(); - } - - // 监听表单值变化 - watch( - () => attrs.modelValue, - (res) => { - fileList.value = res; - }, - ); - - onMounted(initSortable); - onUnmounted(() => { - sortableInstance.value?.destroy(); - removeDragStyle(); - }); - - return () => - h( - 'div', - { 'data-upload-id': uploadId, class: 'w-full' }, - h( - Upload, - { - ...props, - ...attrs, - fileList: fileList.value, - beforeUpload: handleBeforeUpload, - onChange: handleChange, - onPreview: handlePreview, - }, - renderUploadButton() as any, - ), - ); - }, - }); -}; - -// 这里需要自行根据业务组件库进行适配,需要用到的组件都需要在这里类型说明 -export type ComponentType = - | 'ApiCascader' - | 'ApiSelect' - | 'ApiTreeSelect' - | 'AutoComplete' - | 'Cascader' - | 'Checkbox' - | 'CheckboxGroup' - | 'DatePicker' - | 'DefaultButton' - | 'Divider' - | 'IconPicker' - | 'Input' - | 'InputNumber' - | 'InputPassword' - | 'Mentions' - | 'PrimaryButton' - | 'Radio' - | 'RadioGroup' - | 'RangePicker' - | 'Rate' - | 'Select' - | 'Space' - | 'Switch' - | 'Textarea' - | 'TimePicker' - | 'TreeSelect' - | 'Upload' - | BaseFormComponentType; - -async function initComponentAdapter() { - const components: Partial> = { - // 如果你的组件体积比较大,可以使用异步加载 - // Button: () => - // import('xxx').then((res) => res.Button), - - ApiCascader: withDefaultPlaceholder(ApiComponent, 'select', { - component: Cascader, - fieldNames: { label: 'label', value: 'value', children: 'children' }, - loadingSlot: 'suffixIcon', - modelPropName: 'value', - visibleEvent: 'onVisibleChange', - }), - ApiSelect: withDefaultPlaceholder(ApiComponent, 'select', { - component: Select, - loadingSlot: 'suffixIcon', - modelPropName: 'value', - visibleEvent: 'onVisibleChange', - }), - ApiTreeSelect: withDefaultPlaceholder(ApiComponent, 'select', { - component: TreeSelect, - fieldNames: { label: 'label', value: 'value', children: 'children' }, - loadingSlot: 'suffixIcon', - modelPropName: 'value', - optionsPropName: 'treeData', - visibleEvent: 'onVisibleChange', - }), - AutoComplete, - Cascader, - Checkbox, - CheckboxGroup, - DatePicker, - // 自定义默认按钮 - DefaultButton: (props, { attrs, slots }) => { - return h(Button, { ...props, attrs, type: 'default' }, slots); - }, - Divider, - IconPicker: withDefaultPlaceholder(IconPicker, 'select', { - iconSlot: 'addonAfter', - inputComponent: Input, - modelValueProp: 'value', - }), - Input: withDefaultPlaceholder(Input, 'input'), - InputNumber: withDefaultPlaceholder(InputNumber, 'input'), - InputPassword: withDefaultPlaceholder(InputPassword, 'input'), - Mentions: withDefaultPlaceholder(Mentions, 'input'), - // 自定义主要按钮 - PrimaryButton: (props, { attrs, slots }) => { - return h(Button, { ...props, attrs, type: 'primary' }, slots); - }, - Radio, - RadioGroup, - RangePicker, - Rate, - Select: withDefaultPlaceholder(Select, 'select'), - Space, - Switch, - Textarea: withDefaultPlaceholder(Textarea, 'input'), - TimePicker, - TreeSelect: withDefaultPlaceholder(TreeSelect, 'select'), - Upload: withPreviewUpload(), - }; - - // 将组件注册到全局共享状态中 - globalShareState.setComponents(components); - - // 定义全局共享状态中的消息提示 - globalShareState.defineMessage({ - // 复制成功消息提示 - copyPreferencesSuccess: (title, content) => { - notification.success({ - description: content, - message: title, - placement: 'bottomRight', - }); - }, - }); -} - -export { initComponentAdapter }; diff --git a/playground/src/adapter/form.ts b/playground/src/adapter/form.ts deleted file mode 100644 index c5589aa..0000000 --- a/playground/src/adapter/form.ts +++ /dev/null @@ -1,47 +0,0 @@ -import type { - VbenFormSchema as FormSchema, - VbenFormProps, -} from '@vben/common-ui'; - -import type { ComponentType } from './component'; - -import { setupVbenForm, useVbenForm as useForm, z } from '@vben/common-ui'; -import { $t } from '@vben/locales'; - -async function initSetupVbenForm() { - setupVbenForm({ - config: { - // ant design vue组件库默认都是 v-model:value - baseModelPropName: 'value', - // 一些组件是 v-model:checked 或者 v-model:fileList - modelPropNameMap: { - Checkbox: 'checked', - Radio: 'checked', - Switch: 'checked', - Upload: 'fileList', - }, - }, - defineRules: { - // 输入项目必填国际化适配 - required: (value, _params, ctx) => { - if (value === undefined || value === null || value.length === 0) { - return $t('ui.formRules.required', [ctx.label]); - } - return true; - }, - // 选择项目必填国际化适配 - selectRequired: (value, _params, ctx) => { - if (value === undefined || value === null) { - return $t('ui.formRules.selectRequired', [ctx.label]); - } - return true; - }, - }, - }); -} - -const useVbenForm = useForm; - -export { initSetupVbenForm, useVbenForm, z }; -export type VbenFormSchema = FormSchema; -export type { VbenFormProps }; diff --git a/playground/src/adapter/vxe-table.ts b/playground/src/adapter/vxe-table.ts deleted file mode 100644 index 07e9a8d..0000000 --- a/playground/src/adapter/vxe-table.ts +++ /dev/null @@ -1,295 +0,0 @@ -import type { VxeTableGridOptions } from '@vben/plugins/vxe-table'; -import type { Recordable } from '@vben/types'; - -import type { ComponentType } from './component'; - -import { h } from 'vue'; - -import { IconifyIcon } from '@vben/icons'; -import { $te } from '@vben/locales'; -import { - setupVbenVxeTable, - useVbenVxeGrid as useGrid, -} from '@vben/plugins/vxe-table'; -import { get, isFunction, isString } from '@vben/utils'; - -import { objectOmit } from '@vueuse/core'; -import { Button, Image, Popconfirm, Switch, Tag } from 'ant-design-vue'; - -import { $t } from '#/locales'; - -setupVbenVxeTable({ - configVxeTable: (vxeUI) => { - vxeUI.setConfig({ - grid: { - align: 'center', - border: false, - columnConfig: { - resizable: true, - }, - - formConfig: { - // 全局禁用vxe-table的表单配置,使用formOptions - enabled: false, - }, - minHeight: 180, - proxyConfig: { - autoLoad: true, - response: { - result: 'items', - total: 'total', - list: '', - }, - showActiveMsg: true, - showResponseMsg: false, - }, - round: true, - showOverflow: true, - size: 'small', - } as VxeTableGridOptions, - }); - - /** - * 解决vxeTable在热更新时可能会出错的问题 - */ - vxeUI.renderer.forEach((_item, key) => { - if (key.startsWith('Cell')) { - vxeUI.renderer.delete(key); - } - }); - - // 表格配置项可以用 cellRender: { name: 'CellImage' }, - vxeUI.renderer.add('CellImage', { - renderTableDefault(renderOpts, params) { - const { props } = renderOpts; - const { column, row } = params; - return h(Image, { src: row[column.field], ...props }); - }, - }); - - // 表格配置项可以用 cellRender: { name: 'CellLink' }, - vxeUI.renderer.add('CellLink', { - renderTableDefault(renderOpts) { - const { props } = renderOpts; - return h( - Button, - { size: 'small', type: 'link' }, - { default: () => props?.text }, - ); - }, - }); - - // 单元格渲染: Tag - vxeUI.renderer.add('CellTag', { - renderTableDefault({ options, props }, { column, row }) { - const value = get(row, column.field); - const tagOptions = options ?? [ - { color: 'success', label: $t('common.enabled'), value: 1 }, - { color: 'error', label: $t('common.disabled'), value: 0 }, - ]; - const tagItem = tagOptions.find((item) => item.value === value); - return h( - Tag, - { - ...props, - ...objectOmit(tagItem ?? {}, ['label']), - }, - { default: () => tagItem?.label ?? value }, - ); - }, - }); - - vxeUI.renderer.add('CellSwitch', { - renderTableDefault({ attrs, props }, { column, row }) { - const loadingKey = `__loading_${column.field}`; - const finallyProps = { - checkedChildren: $t('common.enabled'), - checkedValue: 1, - unCheckedChildren: $t('common.disabled'), - unCheckedValue: 0, - ...props, - checked: row[column.field], - loading: row[loadingKey] ?? false, - 'onUpdate:checked': onChange, - }; - async function onChange(newVal: any) { - row[loadingKey] = true; - try { - const result = await attrs?.beforeChange?.(newVal, row); - if (result !== false) { - row[column.field] = newVal; - } - } finally { - row[loadingKey] = false; - } - } - return h(Switch, finallyProps); - }, - }); - - /** - * 注册表格的操作按钮渲染器 - */ - vxeUI.renderer.add('CellOperation', { - renderTableDefault({ attrs, options, props }, { column, row }) { - const defaultProps = { size: 'small', type: 'link', ...props }; - let align: string; - switch (column.align) { - case 'center': { - align = 'center'; - break; - } - case 'left': { - align = 'start'; - break; - } - default: { - align = 'end'; - break; - } - } - const presets: Recordable> = { - delete: { - danger: true, - text: $t('common.delete'), - }, - edit: { - text: $t('common.edit'), - }, - }; - const operations: Array> = ( - options || ['edit', 'delete'] - ) - .map((opt) => { - if (isString(opt)) { - return presets[opt] - ? { code: opt, ...presets[opt], ...defaultProps } - : { - code: opt, - text: $te(`common.${opt}`) ? $t(`common.${opt}`) : opt, - ...defaultProps, - }; - } else { - return { ...defaultProps, ...presets[opt.code], ...opt }; - } - }) - .map((opt) => { - const optBtn: Recordable = {}; - Object.keys(opt).forEach((key) => { - optBtn[key] = isFunction(opt[key]) ? opt[key](row) : opt[key]; - }); - return optBtn; - }) - .filter((opt) => opt.show !== false); - - function renderBtn(opt: Recordable, listen = true) { - return h( - Button, - { - ...props, - ...opt, - icon: undefined, - onClick: listen - ? () => - attrs?.onClick?.({ - code: opt.code, - row, - }) - : undefined, - }, - { - default: () => { - const content = []; - if (opt.icon) { - content.push( - h(IconifyIcon, { class: 'size-5', icon: opt.icon }), - ); - } - content.push(opt.text); - return content; - }, - }, - ); - } - - function renderConfirm(opt: Recordable) { - let viewportWrapper: HTMLElement | null = null; - return h( - Popconfirm, - { - /** - * 当popconfirm用在固定列中时,将固定列作为弹窗的容器时可能会因为固定列较窄而无法容纳弹窗 - * 将表格主体区域作为弹窗容器时又会因为固定列的层级较高而遮挡弹窗 - * 将body或者表格视口区域作为弹窗容器时又会导致弹窗无法跟随表格滚动。 - * 鉴于以上各种情况,一种折中的解决方案是弹出层展示时,禁止操作表格的滚动条。 - * 这样既解决了弹窗的遮挡问题,又不至于让弹窗随着表格的滚动而跑出视口区域。 - */ - getPopupContainer(el) { - viewportWrapper = el.closest('.vxe-table--viewport-wrapper'); - return document.body; - }, - placement: 'topLeft', - title: $t('ui.actionTitle.delete', [attrs?.nameTitle || '']), - ...props, - ...opt, - icon: undefined, - onOpenChange: (open: boolean) => { - // 当弹窗打开时,禁止表格的滚动 - if (open) { - viewportWrapper?.style.setProperty('pointer-events', 'none'); - } else { - viewportWrapper?.style.removeProperty('pointer-events'); - } - }, - onConfirm: () => { - attrs?.onClick?.({ - code: opt.code, - row, - }); - }, - }, - { - default: () => renderBtn({ ...opt }, false), - description: () => - h( - 'div', - { class: 'truncate' }, - $t('ui.actionMessage.deleteConfirm', [ - row[attrs?.nameField || 'name'], - ]), - ), - }, - ); - } - - const btns = operations.map((opt) => - opt.code === 'delete' ? renderConfirm(opt) : renderBtn(opt), - ); - return h( - 'div', - { - class: 'flex table-operations', - style: { justifyContent: align }, - }, - btns, - ); - }, - }); - - // 这里可以自行扩展 vxe-table 的全局配置,比如自定义格式化 - // vxeUI.formats.add - }, -}); - -export const useVbenVxeGrid = >( - ...rest: Parameters> -) => useGrid(...rest); - -export type OnActionClickParams> = { - code: string; - row: T; -}; -export type OnActionClickFn> = ( - params: OnActionClickParams, -) => void; -export type * from '@vben/plugins/vxe-table'; diff --git a/playground/src/api/core/auth.ts b/playground/src/api/core/auth.ts deleted file mode 100644 index b4627cb..0000000 --- a/playground/src/api/core/auth.ts +++ /dev/null @@ -1,57 +0,0 @@ -import { baseRequestClient, requestClient } from '#/api/request'; - -export namespace AuthApi { - /** 登录接口参数 */ - export interface LoginParams { - password?: string; - username?: string; - } - - /** 登录接口返回值 */ - export interface LoginResult { - accessToken: string; - } - - export interface RefreshTokenResult { - data: string; - status: number; - } -} - -/** - * 登录 - */ -export async function loginApi(data: AuthApi.LoginParams) { - return requestClient.post('/auth/login', data, { - withCredentials: true, - }); -} - -/** - * 刷新accessToken - */ -export async function refreshTokenApi() { - return baseRequestClient.post( - '/auth/refresh', - null, - { - withCredentials: true, - }, - ); -} - -/** - * 退出登录 - */ -export async function logoutApi() { - return baseRequestClient.post('/auth/logout', null, { - withCredentials: true, - }); -} - -/** - * 获取用户权限码 - */ -export async function getAccessCodesApi() { - return requestClient.get('/auth/codes'); -} diff --git a/playground/src/api/core/index.ts b/playground/src/api/core/index.ts deleted file mode 100644 index 7134366..0000000 --- a/playground/src/api/core/index.ts +++ /dev/null @@ -1,4 +0,0 @@ -export * from './auth'; -export * from './menu'; -export * from './timezone'; -export * from './user'; diff --git a/playground/src/api/core/menu.ts b/playground/src/api/core/menu.ts deleted file mode 100644 index 9ef60b1..0000000 --- a/playground/src/api/core/menu.ts +++ /dev/null @@ -1,10 +0,0 @@ -import type { RouteRecordStringComponent } from '@vben/types'; - -import { requestClient } from '#/api/request'; - -/** - * 获取用户所有菜单 - */ -export async function getAllMenusApi() { - return requestClient.get('/menu/all'); -} diff --git a/playground/src/api/core/timezone.ts b/playground/src/api/core/timezone.ts deleted file mode 100644 index 13d44d1..0000000 --- a/playground/src/api/core/timezone.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { requestClient } from '#/api/request'; - -/** - * 获取系统支持的时区列表 - */ -export async function getTimezoneOptionsApi() { - return await requestClient.get< - { - label: string; - value: string; - }[] - >('/timezone/getTimezoneOptions'); -} -/** - * 获取用户时区 - */ -export async function getTimezoneApi(): Promise { - return requestClient.get('/timezone/getTimezone'); -} -/** - * 设置用户时区 - * @param timezone 时区 - */ -export async function setTimezoneApi(timezone: string): Promise { - return requestClient.post('/timezone/setTimezone', { timezone }); -} diff --git a/playground/src/api/core/user.ts b/playground/src/api/core/user.ts deleted file mode 100644 index 7e28ea8..0000000 --- a/playground/src/api/core/user.ts +++ /dev/null @@ -1,10 +0,0 @@ -import type { UserInfo } from '@vben/types'; - -import { requestClient } from '#/api/request'; - -/** - * 获取用户信息 - */ -export async function getUserInfoApi() { - return requestClient.get('/user/info'); -} diff --git a/playground/src/api/examples/download.ts b/playground/src/api/examples/download.ts deleted file mode 100644 index 0b4dcd3..0000000 --- a/playground/src/api/examples/download.ts +++ /dev/null @@ -1,28 +0,0 @@ -import type { RequestResponse } from '@vben/request'; - -import { requestClient } from '../request'; - -/** - * 下载文件,获取Blob - * @returns Blob - */ -async function downloadFile1() { - return requestClient.download( - 'https://unpkg.com/@vbenjs/static-source@0.1.7/source/logo-v1.webp', - ); -} - -/** - * 下载文件,获取完整的Response - * @returns RequestResponse - */ -async function downloadFile2() { - return requestClient.download>( - 'https://unpkg.com/@vbenjs/static-source@0.1.7/source/logo-v1.webp', - { - responseReturn: 'raw', - }, - ); -} - -export { downloadFile1, downloadFile2 }; diff --git a/playground/src/api/examples/index.ts b/playground/src/api/examples/index.ts deleted file mode 100644 index c830b81..0000000 --- a/playground/src/api/examples/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from './status'; -export * from './table'; diff --git a/playground/src/api/examples/json-bigint.ts b/playground/src/api/examples/json-bigint.ts deleted file mode 100644 index 19e41e2..0000000 --- a/playground/src/api/examples/json-bigint.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { requestClient } from '#/api/request'; - -/** - * 发起请求 - */ -async function getBigIntData() { - return requestClient.get('/demo/bigint'); -} - -export { getBigIntData }; diff --git a/playground/src/api/examples/params.ts b/playground/src/api/examples/params.ts deleted file mode 100644 index 6568ec6..0000000 --- a/playground/src/api/examples/params.ts +++ /dev/null @@ -1,19 +0,0 @@ -import type { Recordable } from '@vben/types'; - -import { requestClient } from '#/api/request'; - -/** - * 发起数组请求 - */ -async function getParamsData( - params: Recordable, - type: 'brackets' | 'comma' | 'indices' | 'repeat', -) { - return requestClient.get('/status', { - params, - paramsSerializer: type, - responseReturn: 'raw', - }); -} - -export { getParamsData }; diff --git a/playground/src/api/examples/status.ts b/playground/src/api/examples/status.ts deleted file mode 100644 index 4a75fe7..0000000 --- a/playground/src/api/examples/status.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { requestClient } from '#/api/request'; - -/** - * 模拟任意状态码 - */ -async function getMockStatusApi(status: string) { - return requestClient.get('/status', { params: { status } }); -} - -export { getMockStatusApi }; diff --git a/playground/src/api/examples/table.ts b/playground/src/api/examples/table.ts deleted file mode 100644 index 4739ca9..0000000 --- a/playground/src/api/examples/table.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { requestClient } from '#/api/request'; - -export namespace DemoTableApi { - export interface PageFetchParams { - [key: string]: any; - page: number; - pageSize: number; - } -} - -/** - * 获取示例表格数据 - */ -async function getExampleTableApi(params: DemoTableApi.PageFetchParams) { - return requestClient.get('/table/list', { params }); -} - -export { getExampleTableApi }; diff --git a/playground/src/api/examples/upload.ts b/playground/src/api/examples/upload.ts deleted file mode 100644 index 246d4f2..0000000 --- a/playground/src/api/examples/upload.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { requestClient } from '#/api/request'; - -interface UploadFileParams { - file: File; - onError?: (error: Error) => void; - onProgress?: (progress: { percent: number }) => void; - onSuccess?: (data: any, file: File) => void; -} -export async function upload_file({ - file, - onError, - onProgress, - onSuccess, -}: UploadFileParams) { - try { - onProgress?.({ percent: 0 }); - - const data = await requestClient.upload('/upload', { file }); - - onProgress?.({ percent: 100 }); - onSuccess?.(data, file); - } catch (error) { - onError?.(error instanceof Error ? error : new Error(String(error))); - } -} diff --git a/playground/src/api/index.ts b/playground/src/api/index.ts deleted file mode 100644 index 3c3fa0d..0000000 --- a/playground/src/api/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -export * from './core'; -export * from './examples'; -export * from './system'; diff --git a/playground/src/api/request.ts b/playground/src/api/request.ts deleted file mode 100644 index a885536..0000000 --- a/playground/src/api/request.ts +++ /dev/null @@ -1,133 +0,0 @@ -/** - * 该文件可自行根据业务逻辑进行调整 - */ -import type { AxiosResponseHeaders, RequestClientOptions } from '@vben/request'; - -import { useAppConfig } from '@vben/hooks'; -import { preferences } from '@vben/preferences'; -import { - authenticateResponseInterceptor, - defaultResponseInterceptor, - errorMessageResponseInterceptor, - RequestClient, -} from '@vben/request'; -import { useAccessStore } from '@vben/stores'; -import { cloneDeep } from '@vben/utils'; - -import { message } from 'ant-design-vue'; -import JSONBigInt from 'json-bigint'; - -import { useAuthStore } from '#/store'; - -import { refreshTokenApi } from './core'; - -const { apiURL } = useAppConfig(import.meta.env, import.meta.env.PROD); - -function createRequestClient(baseURL: string, options?: RequestClientOptions) { - const client = new RequestClient({ - ...options, - baseURL, - transformResponse: (data: any, header: AxiosResponseHeaders) => { - // storeAsString指示将BigInt存储为字符串,设为false则会存储为内置的BigInt类型 - if ( - header.getContentType()?.toString().includes('application/json') && - typeof data === 'string' - ) { - return cloneDeep( - JSONBigInt({ storeAsString: true, strict: true }).parse(data), - ); - } - return data; - }, - }); - - /** - * 重新认证逻辑 - */ - async function doReAuthenticate() { - console.warn('Access token or refresh token is invalid or expired. '); - const accessStore = useAccessStore(); - const authStore = useAuthStore(); - accessStore.setAccessToken(null); - if ( - preferences.app.loginExpiredMode === 'modal' && - accessStore.isAccessChecked - ) { - accessStore.setLoginExpired(true); - } else { - await authStore.logout(); - } - } - - /** - * 刷新token逻辑 - */ - async function doRefreshToken() { - const accessStore = useAccessStore(); - const resp = await refreshTokenApi(); - const newToken = resp.data; - accessStore.setAccessToken(newToken); - return newToken; - } - - function formatToken(token: null | string) { - return token ? `Bearer ${token}` : null; - } - - // 请求头处理 - client.addRequestInterceptor({ - fulfilled: async (config) => { - const accessStore = useAccessStore(); - - config.headers.Authorization = formatToken(accessStore.accessToken); - config.headers['Accept-Language'] = preferences.app.locale; - return config; - }, - }); - - // 处理返回的响应数据格式 - client.addResponseInterceptor( - defaultResponseInterceptor({ - codeField: 'code', - dataField: 'data', - successCode: 0, - }), - ); - - // token过期的处理 - client.addResponseInterceptor( - authenticateResponseInterceptor({ - client, - doReAuthenticate, - doRefreshToken, - enableRefreshToken: preferences.app.enableRefreshToken, - formatToken, - }), - ); - - // 通用的错误处理,如果没有进入上面的错误处理逻辑,就会进入这里 - client.addResponseInterceptor( - errorMessageResponseInterceptor((msg: string, error) => { - // 这里可以根据业务进行定制,你可以拿到 error 内的信息进行定制化处理,根据不同的 code 做不同的提示,而不是直接使用 message.error 提示 msg - // 当前mock接口返回的错误字段是 error 或者 message - const responseData = error?.response?.data ?? {}; - const errorMessage = responseData?.error ?? responseData?.message ?? ''; - // 如果没有错误信息,则会根据状态码进行提示 - message.error(errorMessage || msg); - }), - ); - - return client; -} - -export const requestClient = createRequestClient(apiURL, { - responseReturn: 'data', -}); - -export const baseRequestClient = new RequestClient({ baseURL: apiURL }); - -export interface PageFetchParams { - [key: string]: any; - pageNo?: number; - pageSize?: number; -} diff --git a/playground/src/api/system/dept.ts b/playground/src/api/system/dept.ts deleted file mode 100644 index ce2b0de..0000000 --- a/playground/src/api/system/dept.ts +++ /dev/null @@ -1,54 +0,0 @@ -import { requestClient } from '#/api/request'; - -export namespace SystemDeptApi { - export interface SystemDept { - [key: string]: any; - children?: SystemDept[]; - id: string; - name: string; - remark?: string; - status: 0 | 1; - } -} - -/** - * 获取部门列表数据 - */ -async function getDeptList() { - return requestClient.get>( - '/system/dept/list', - ); -} - -/** - * 创建部门 - * @param data 部门数据 - */ -async function createDept( - data: Omit, -) { - return requestClient.post('/system/dept', data); -} - -/** - * 更新部门 - * - * @param id 部门 ID - * @param data 部门数据 - */ -async function updateDept( - id: string, - data: Omit, -) { - return requestClient.put(`/system/dept/${id}`, data); -} - -/** - * 删除部门 - * @param id 部门 ID - */ -async function deleteDept(id: string) { - return requestClient.delete(`/system/dept/${id}`); -} - -export { createDept, deleteDept, getDeptList, updateDept }; diff --git a/playground/src/api/system/index.ts b/playground/src/api/system/index.ts deleted file mode 100644 index f2a248f..0000000 --- a/playground/src/api/system/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -export * from './dept'; -export * from './menu'; -export * from './role'; diff --git a/playground/src/api/system/menu.ts b/playground/src/api/system/menu.ts deleted file mode 100644 index 507a5ae..0000000 --- a/playground/src/api/system/menu.ts +++ /dev/null @@ -1,158 +0,0 @@ -import type { Recordable } from '@vben/types'; - -import { requestClient } from '#/api/request'; - -export namespace SystemMenuApi { - /** 徽标颜色集合 */ - export const BadgeVariants = [ - 'default', - 'destructive', - 'primary', - 'success', - 'warning', - ] as const; - /** 徽标类型集合 */ - export const BadgeTypes = ['dot', 'normal'] as const; - /** 菜单类型集合 */ - export const MenuTypes = [ - 'catalog', - 'menu', - 'embedded', - 'link', - 'button', - ] as const; - /** 系统菜单 */ - export interface SystemMenu { - [key: string]: any; - /** 后端权限标识 */ - authCode: string; - /** 子级 */ - children?: SystemMenu[]; - /** 组件 */ - component?: string; - /** 菜单ID */ - id: string; - /** 菜单元数据 */ - meta?: { - /** 激活时显示的图标 */ - activeIcon?: string; - /** 作为路由时,需要激活的菜单的Path */ - activePath?: string; - /** 固定在标签栏 */ - affixTab?: boolean; - /** 在标签栏固定的顺序 */ - affixTabOrder?: number; - /** 徽标内容(当徽标类型为normal时有效) */ - badge?: string; - /** 徽标类型 */ - badgeType?: (typeof BadgeTypes)[number]; - /** 徽标颜色 */ - badgeVariants?: (typeof BadgeVariants)[number]; - /** 在菜单中隐藏下级 */ - hideChildrenInMenu?: boolean; - /** 在面包屑中隐藏 */ - hideInBreadcrumb?: boolean; - /** 在菜单中隐藏 */ - hideInMenu?: boolean; - /** 在标签栏中隐藏 */ - hideInTab?: boolean; - /** 菜单图标 */ - icon?: string; - /** 内嵌Iframe的URL */ - iframeSrc?: string; - /** 是否缓存页面 */ - keepAlive?: boolean; - /** 外链页面的URL */ - link?: string; - /** 同一个路由最大打开的标签数 */ - maxNumOfOpenTab?: number; - /** 无需基础布局 */ - noBasicLayout?: boolean; - /** 是否在新窗口打开 */ - openInNewWindow?: boolean; - /** 菜单排序 */ - order?: number; - /** 额外的路由参数 */ - query?: Recordable; - /** 菜单标题 */ - title?: string; - }; - /** 菜单名称 */ - name: string; - /** 路由路径 */ - path: string; - /** 父级ID */ - pid: string; - /** 重定向 */ - redirect?: string; - /** 菜单类型 */ - type: (typeof MenuTypes)[number]; - } -} - -/** - * 获取菜单数据列表 - */ -async function getMenuList() { - return requestClient.get>( - '/system/menu/list', - ); -} - -async function isMenuNameExists( - name: string, - id?: SystemMenuApi.SystemMenu['id'], -) { - return requestClient.get('/system/menu/name-exists', { - params: { id, name }, - }); -} - -async function isMenuPathExists( - path: string, - id?: SystemMenuApi.SystemMenu['id'], -) { - return requestClient.get('/system/menu/path-exists', { - params: { id, path }, - }); -} - -/** - * 创建菜单 - * @param data 菜单数据 - */ -async function createMenu( - data: Omit, -) { - return requestClient.post('/system/menu', data); -} - -/** - * 更新菜单 - * - * @param id 菜单 ID - * @param data 菜单数据 - */ -async function updateMenu( - id: string, - data: Omit, -) { - return requestClient.put(`/system/menu/${id}`, data); -} - -/** - * 删除菜单 - * @param id 菜单 ID - */ -async function deleteMenu(id: string) { - return requestClient.delete(`/system/menu/${id}`); -} - -export { - createMenu, - deleteMenu, - getMenuList, - isMenuNameExists, - isMenuPathExists, - updateMenu, -}; diff --git a/playground/src/api/system/role.ts b/playground/src/api/system/role.ts deleted file mode 100644 index 60b465a..0000000 --- a/playground/src/api/system/role.ts +++ /dev/null @@ -1,55 +0,0 @@ -import type { Recordable } from '@vben/types'; - -import { requestClient } from '#/api/request'; - -export namespace SystemRoleApi { - export interface SystemRole { - [key: string]: any; - id: string; - name: string; - permissions: string[]; - remark?: string; - status: 0 | 1; - } -} - -/** - * 获取角色列表数据 - */ -async function getRoleList(params: Recordable) { - return requestClient.get>( - '/system/role/list', - { params }, - ); -} - -/** - * 创建角色 - * @param data 角色数据 - */ -async function createRole(data: Omit) { - return requestClient.post('/system/role', data); -} - -/** - * 更新角色 - * - * @param id 角色 ID - * @param data 角色数据 - */ -async function updateRole( - id: string, - data: Omit, -) { - return requestClient.put(`/system/role/${id}`, data); -} - -/** - * 删除角色 - * @param id 角色 ID - */ -async function deleteRole(id: string) { - return requestClient.delete(`/system/role/${id}`); -} - -export { createRole, deleteRole, getRoleList, updateRole }; diff --git a/playground/src/app.vue b/playground/src/app.vue deleted file mode 100644 index bbaccce..0000000 --- a/playground/src/app.vue +++ /dev/null @@ -1,39 +0,0 @@ - - - diff --git a/playground/src/bootstrap.ts b/playground/src/bootstrap.ts deleted file mode 100644 index 1685a71..0000000 --- a/playground/src/bootstrap.ts +++ /dev/null @@ -1,90 +0,0 @@ -import { createApp, watchEffect } from 'vue'; - -import { registerAccessDirective } from '@vben/access'; -import { registerLoadingDirective } from '@vben/common-ui'; -import { providePluginsOptions } from '@vben/plugins'; -import { preferences } from '@vben/preferences'; -import { initStores } from '@vben/stores'; -import '@vben/styles'; -import '@vben/styles/antd'; - -import { useTitle } from '@vueuse/core'; - -import { $t, setupI18n } from '#/locales'; -import { router } from '#/router'; - -import { initComponentAdapter } from './adapter/component'; -import { initSetupVbenForm, useVbenForm } from './adapter/form'; -import App from './app.vue'; -import { initTimezone } from './timezone-init'; - -async function bootstrap(namespace: string) { - // 初始化组件适配器 - await initComponentAdapter(); - - // 初始化表单组件 - await initSetupVbenForm(); - - // 注入插件全局配置 - providePluginsOptions({ - form: { useVbenForm }, - }); - - // 设置弹窗的默认配置 - // setDefaultModalProps({ - // fullscreenButton: false, - // }); - // 设置抽屉的默认配置 - // setDefaultDrawerProps({ - // zIndex: 1020, - // }); - - const app = createApp(App); - - // 注册v-loading指令 - registerLoadingDirective(app, { - loading: 'loading', // 在这里可以自定义指令名称,也可以明确提供false表示不注册这个指令 - spinning: 'spinning', - }); - - // 国际化 i18n 配置 - await setupI18n(app); - - // 配置 pinia-tore - await initStores(app, { namespace }); - - // 初始化时区HANDLER - initTimezone(); - - // 安装权限指令 - registerAccessDirective(app); - - // 初始化 tippy - const { initTippy } = await import('@vben/common-ui/es/tippy'); - initTippy(app); - - // 配置路由及路由守卫 - app.use(router); - - // 配置@tanstack/vue-query - const { VueQueryPlugin } = await import('@tanstack/vue-query'); - app.use(VueQueryPlugin); - - // 配置Motion插件 - const { MotionPlugin } = await import('@vben/plugins/motion'); - app.use(MotionPlugin); - - // 动态更新标题 - watchEffect(() => { - if (preferences.app.dynamicTitle) { - const routeTitle = router.currentRoute.value.meta?.title; - const pageTitle = - (routeTitle ? `${$t(routeTitle)} - ` : '') + preferences.app.name; - useTitle(pageTitle); - } - }); - - app.mount('#app'); -} - -export { bootstrap }; diff --git a/playground/src/layouts/auth.vue b/playground/src/layouts/auth.vue deleted file mode 100644 index c33a632..0000000 --- a/playground/src/layouts/auth.vue +++ /dev/null @@ -1,25 +0,0 @@ - - - diff --git a/playground/src/layouts/basic.vue b/playground/src/layouts/basic.vue deleted file mode 100644 index 04b73ac..0000000 --- a/playground/src/layouts/basic.vue +++ /dev/null @@ -1,202 +0,0 @@ - - - diff --git a/playground/src/layouts/index.ts b/playground/src/layouts/index.ts deleted file mode 100644 index a432078..0000000 --- a/playground/src/layouts/index.ts +++ /dev/null @@ -1,6 +0,0 @@ -const BasicLayout = () => import('./basic.vue'); -const AuthPageLayout = () => import('./auth.vue'); - -const IFrameView = () => import('@vben/layouts').then((m) => m.IFrameView); - -export { AuthPageLayout, BasicLayout, IFrameView }; diff --git a/playground/src/locales/README.md b/playground/src/locales/README.md deleted file mode 100644 index 7b45103..0000000 --- a/playground/src/locales/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# locale - -每个app使用的国际化可能不同,这里用于扩展国际化的功能,例如扩展 dayjs、antd组件库的多语言切换,以及app本身的国际化文件。 diff --git a/playground/src/locales/index.ts b/playground/src/locales/index.ts deleted file mode 100644 index 7f32bd1..0000000 --- a/playground/src/locales/index.ts +++ /dev/null @@ -1,102 +0,0 @@ -import type { Locale } from 'ant-design-vue/es/locale'; - -import type { App } from 'vue'; - -import type { LocaleSetupOptions, SupportedLanguagesType } from '@vben/locales'; - -import { ref } from 'vue'; - -import { - $t, - setupI18n as coreSetup, - loadLocalesMapFromDir, -} from '@vben/locales'; -import { preferences } from '@vben/preferences'; - -import antdEnLocale from 'ant-design-vue/es/locale/en_US'; -import antdDefaultLocale from 'ant-design-vue/es/locale/zh_CN'; -import dayjs from 'dayjs'; - -const antdLocale = ref(antdDefaultLocale); - -const modules = import.meta.glob('./langs/**/*.json'); - -const localesMap = loadLocalesMapFromDir( - /\.\/langs\/([^/]+)\/(.*)\.json$/, - modules, -); -/** - * 加载应用特有的语言包 - * 这里也可以改造为从服务端获取翻译数据 - * @param lang - */ -async function loadMessages(lang: SupportedLanguagesType) { - const [appLocaleMessages] = await Promise.all([ - localesMap[lang]?.(), - loadThirdPartyMessage(lang), - ]); - return appLocaleMessages?.default; -} - -/** - * 加载第三方组件库的语言包 - * @param lang - */ -async function loadThirdPartyMessage(lang: SupportedLanguagesType) { - await Promise.all([loadAntdLocale(lang), loadDayjsLocale(lang)]); -} - -/** - * 加载dayjs的语言包 - * @param lang - */ -async function loadDayjsLocale(lang: SupportedLanguagesType) { - let locale; - switch (lang) { - case 'en-US': { - locale = await import('dayjs/locale/en'); - break; - } - case 'zh-CN': { - locale = await import('dayjs/locale/zh-cn'); - break; - } - // 默认使用英语 - default: { - locale = await import('dayjs/locale/en'); - } - } - if (locale) { - dayjs.locale(locale); - } else { - console.error(`Failed to load dayjs locale for ${lang}`); - } -} - -/** - * 加载antd的语言包 - * @param lang - */ -async function loadAntdLocale(lang: SupportedLanguagesType) { - switch (lang) { - case 'en-US': { - antdLocale.value = antdEnLocale; - break; - } - case 'zh-CN': { - antdLocale.value = antdDefaultLocale; - break; - } - } -} - -async function setupI18n(app: App, options: LocaleSetupOptions = {}) { - await coreSetup(app, { - defaultLocale: preferences.app.locale, - loadMessages, - missingWarn: !import.meta.env.PROD, - ...options, - }); -} - -export { $t, antdLocale, setupI18n }; diff --git a/playground/src/locales/langs/en-US/demos.json b/playground/src/locales/langs/en-US/demos.json deleted file mode 100644 index 6b2fcfb..0000000 --- a/playground/src/locales/langs/en-US/demos.json +++ /dev/null @@ -1,72 +0,0 @@ -{ - "title": "Demos", - "access": { - "frontendPermissions": "Frontend Permissions", - "backendPermissions": "Backend Permissions", - "pageAccess": "Page Access", - "buttonControl": "Button Control", - "menuVisible403": "Menu Visible(403)", - "superVisible": "Visible to Super", - "adminVisible": "Visible to Admin", - "userVisible": "Visible to User" - }, - "nested": { - "title": "Nested Menu", - "menu1": "Menu 1", - "menu2": "Menu 2", - "menu2_1": "Menu 2-1", - "menu3": "Menu 3", - "menu3_1": "Menu 3-1", - "menu3_2": "Menu 3-2", - "menu3_2_1": "Menu 3-2-1" - }, - "outside": { - "title": "External Pages", - "embedded": "Embedded", - "externalLink": "External Link" - }, - "badge": { - "title": "Menu Badge", - "dot": "Dot Badge", - "text": "Text Badge", - "color": "Badge Color" - }, - "activeIcon": { - "title": "Active Menu Icon", - "children": "Children Active Icon" - }, - "fallback": { - "title": "Fallback Page" - }, - "features": { - "title": "Features", - "hideChildrenInMenu": "Hide Menu Children", - "loginExpired": "Login Expired", - "icons": "Icons", - "watermark": "Watermark", - "tabs": "Tabs", - "tabDetail": "Tab Detail Page", - "fullScreen": "FullScreen", - "clipboard": "Clipboard", - "menuWithQuery": "Menu With Query", - "openInNewWindow": "Open in New Window", - "fileDownload": "File Download" - }, - "breadcrumb": { - "navigation": "Breadcrumb Navigation", - "lateral": "Lateral Mode", - "lateralDetail": "Lateral Mode Detail", - "level": "Level Mode", - "levelDetail": "Level Mode Detail" - }, - "vben": { - "title": "Project", - "about": "About", - "document": "Document", - "antdv": "Ant Design Vue Version", - "antdv-next": "Antdv Next Version", - "naive-ui": "Naive UI Version", - "element-plus": "Element Plus Version", - "tdesign": "TDesign Vue Version" - } -} diff --git a/playground/src/locales/langs/en-US/examples.json b/playground/src/locales/langs/en-US/examples.json deleted file mode 100644 index 0503548..0000000 --- a/playground/src/locales/langs/en-US/examples.json +++ /dev/null @@ -1,83 +0,0 @@ -{ - "title": "Examples", - "modal": { - "title": "Modal" - }, - "drawer": { - "title": "Drawer" - }, - "ellipsis": { - "title": "EllipsisText" - }, - "form": { - "title": "Form", - "basic": "Basic Form", - "layout": "Custom Layout", - "query": "Query Form", - "rules": "Form Rules", - "dynamic": "Dynamic Form", - "custom": "Custom Component", - "api": "Api", - "merge": "Merge Form", - "scrollToError": "Scroll to Error Field", - "upload-error": "Partial file upload failed", - "upload-urls": "Urls after file upload", - "file": "file", - "crop-image": "Crop image", - "upload-image": "Click to upload image" - }, - "vxeTable": { - "title": "Vxe Table", - "basic": "Basic Table", - "remote": "Remote Load", - "tree": "Tree Table", - "fixed": "Fixed Header/Column", - "virtual": "Virtual Scroll", - "editCell": "Edit Cell", - "editRow": "Edit Row", - "custom-cell": "Custom Cell", - "form": "Form Table" - }, - "captcha": { - "title": "Captcha", - "pointSelection": "Point Selection Captcha", - "sliderCaptcha": "Slider Captcha", - "sliderRotateCaptcha": "Rotate Captcha", - "sliderTranslateCaptcha": "Translate Captcha", - "captchaCardTitle": "Please complete the security verification", - "pageDescription": "Verify user identity by clicking on specific locations in the image.", - "pageTitle": "Captcha Component Example", - "basic": "Basic Usage", - "titlePlaceholder": "Captcha Title Text", - "captchaImageUrlPlaceholder": "Captcha Image (supports img tag src attribute value)", - "hintImage": "Hint Image", - "hintText": "Hint Text", - "hintImagePlaceholder": "Hint Image (supports img tag src attribute value)", - "hintTextPlaceholder": "Hint Text", - "showConfirm": "Show Confirm", - "hideConfirm": "Hide Confirm", - "widthPlaceholder": "Captcha Image Width Default 300px", - "heightPlaceholder": "Captcha Image Height Default 220px", - "paddingXPlaceholder": "Horizontal Padding Default 12px", - "paddingYPlaceholder": "Vertical Padding Default 16px", - "index": "Index:", - "timestamp": "Timestamp:", - "x": "x:", - "y": "y:" - }, - "resize": { - "title": "Resize" - }, - "layout": { - "col-page": "ColPage Layout" - }, - "button-group": { - "title": "Button Group" - }, - "function": { - "contentMenu": "Content Menu" - }, - "cropper": { - "title": "Cropper" - } -} diff --git a/playground/src/locales/langs/en-US/page.json b/playground/src/locales/langs/en-US/page.json deleted file mode 100644 index 32e323c..0000000 --- a/playground/src/locales/langs/en-US/page.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "auth": { - "login": "Login", - "register": "Register", - "codeLogin": "Code Login", - "qrcodeLogin": "Qr Code Login", - "forgetPassword": "Forget Password", - "sendingCode": "SMS Code is sending...", - "codeSentTo": "Code has been sent to {0}", - "profile": "Profile" - }, - "dashboard": { - "title": "Dashboard", - "analytics": "Analytics", - "workspace": "Workspace" - } -} diff --git a/playground/src/locales/langs/en-US/system.json b/playground/src/locales/langs/en-US/system.json deleted file mode 100644 index 003dfbb..0000000 --- a/playground/src/locales/langs/en-US/system.json +++ /dev/null @@ -1,65 +0,0 @@ -{ - "title": "System Management", - "dept": { - "name": "Department", - "title": "Department Management", - "deptName": "Department Name", - "status": "Status", - "createTime": "Create Time", - "remark": "Remark", - "operation": "Operation", - "parentDept": "Parent Department" - }, - "menu": { - "title": "Menu Management", - "parent": "Parent Menu", - "menuTitle": "Title", - "menuName": "Menu Name", - "name": "Menu", - "type": "Type", - "typeCatalog": "Catalog", - "typeMenu": "Menu", - "typeButton": "Button", - "typeLink": "Link", - "typeEmbedded": "Embedded", - "icon": "Icon", - "activeIcon": "Active Icon", - "activePath": "Active Path", - "path": "Route Path", - "component": "Component", - "status": "Status", - "authCode": "Auth Code", - "badge": "Badge", - "operation": "Operation", - "linkSrc": "Link Address", - "affixTab": "Affix In Tabs", - "keepAlive": "Keep Alive", - "hideInMenu": "Hide In Menu", - "hideInTab": "Hide In Tabbar", - "hideChildrenInMenu": "Hide Children In Menu", - "hideInBreadcrumb": "Hide In Breadcrumb", - "advancedSettings": "Other Settings", - "activePathMustExist": "The path could not find a valid menu", - "activePathHelp": "When jumping to the current route, \nthe menu path that needs to be activated must be specified when it does not display in the navigation menu.", - "badgeType": { - "title": "Badge Type", - "dot": "Dot", - "normal": "Text", - "none": "None" - }, - "badgeVariants": "Badge Style" - }, - "role": { - "title": "Role Management", - "list": "Role List", - "name": "Role", - "roleName": "Role Name", - "id": "Role ID", - "status": "Status", - "remark": "Remark", - "createTime": "Creation Time", - "operation": "Operation", - "permissions": "Permissions", - "setPermissions": "Permissions" - } -} diff --git a/playground/src/locales/langs/zh-CN/demos.json b/playground/src/locales/langs/zh-CN/demos.json deleted file mode 100644 index 9191a8e..0000000 --- a/playground/src/locales/langs/zh-CN/demos.json +++ /dev/null @@ -1,73 +0,0 @@ -{ - "title": "演示", - "access": { - "frontendPermissions": "前端权限", - "backendPermissions": "后端权限", - "pageAccess": "页面访问", - "buttonControl": "按钮控制", - "menuVisible403": "菜单可见(403)", - "superVisible": "Super 可见", - "adminVisible": "Admin 可见", - "userVisible": "User 可见" - }, - "nested": { - "title": "嵌套菜单", - "menu1": "菜单 1", - "menu2": "菜单 2", - "menu2_1": "菜单 2-1", - "menu3": "菜单 3", - "menu3_1": "菜单 3-1", - "menu3_2": "菜单 3-2", - "menu3_2_1": "菜单 3-2-1" - }, - "outside": { - "title": "外部页面", - "embedded": "内嵌", - "externalLink": "外链" - }, - "badge": { - "title": "菜单徽标", - "dot": "点徽标", - "text": "文本徽标", - "color": "徽标颜色" - }, - "activeIcon": { - "title": "菜单激活图标", - "children": "子级激活图标" - }, - "fallback": { - "title": "缺省页" - }, - "features": { - "title": "功能", - "hideChildrenInMenu": "隐藏子菜单", - "loginExpired": "登录过期", - "icons": "图标", - "watermark": "水印", - "tabs": "标签页", - "tabDetail": "标签详情页", - "fullScreen": "全屏", - "clipboard": "剪贴板", - "menuWithQuery": "带参菜单", - "openInNewWindow": "新窗口打开", - "fileDownload": "文件下载", - "requestParamsSerializer": "参数序列化" - }, - "breadcrumb": { - "navigation": "面包屑导航", - "lateral": "平级模式", - "level": "层级模式", - "levelDetail": "层级模式详情", - "lateralDetail": "平级模式详情" - }, - "vben": { - "title": "项目", - "about": "关于", - "document": "文档", - "antdv": "Ant Design Vue 版本", - "antdv-next": "Antdv Next 版本", - "naive-ui": "Naive UI 版本", - "element-plus": "Element Plus 版本", - "tdesign": "TDesign Vue 版本" - } -} diff --git a/playground/src/locales/langs/zh-CN/examples.json b/playground/src/locales/langs/zh-CN/examples.json deleted file mode 100644 index 3b0d934..0000000 --- a/playground/src/locales/langs/zh-CN/examples.json +++ /dev/null @@ -1,83 +0,0 @@ -{ - "title": "示例", - "modal": { - "title": "弹窗" - }, - "drawer": { - "title": "抽屉" - }, - "ellipsis": { - "title": "文本省略" - }, - "resize": { - "title": "拖动调整" - }, - "form": { - "title": "表单", - "basic": "基础表单", - "layout": "自定义布局", - "query": "查询表单", - "rules": "表单校验", - "dynamic": "动态表单", - "custom": "自定义组件", - "api": "Api", - "merge": "合并表单", - "scrollToError": "滚动到错误字段", - "upload-error": "部分文件上传失败", - "upload-urls": "文件上传后的网址", - "file": "文件", - "crop-image": "裁剪图片", - "upload-image": "点击上传图片" - }, - "vxeTable": { - "title": "Vxe 表格", - "basic": "基础表格", - "remote": "远程加载", - "tree": "树形表格", - "fixed": "固定表头/列", - "virtual": "虚拟滚动", - "editCell": "单元格编辑", - "editRow": "行编辑", - "custom-cell": "自定义单元格", - "form": "搜索表单" - }, - "captcha": { - "title": "验证码", - "pointSelection": "点选验证", - "sliderCaptcha": "滑块验证", - "sliderRotateCaptcha": "旋转验证", - "sliderTranslateCaptcha": "拼图滑块验证", - "captchaCardTitle": "请完成安全验证", - "pageDescription": "通过点击图片中的特定位置来验证用户身份。", - "pageTitle": "验证码组件示例", - "basic": "基本使用", - "titlePlaceholder": "验证码标题文案", - "captchaImageUrlPlaceholder": "验证码图片(支持img标签src属性值)", - "hintImage": "提示图片", - "hintText": "提示文本", - "hintImagePlaceholder": "提示图片(支持img标签src属性值)", - "hintTextPlaceholder": "提示文本", - "showConfirm": "展示确认", - "hideConfirm": "隐藏确认", - "widthPlaceholder": "验证码图片宽度 默认300px", - "heightPlaceholder": "验证码图片高度 默认220px", - "paddingXPlaceholder": "水平内边距 默认12px", - "paddingYPlaceholder": "垂直内边距 默认16px", - "index": "索引:", - "timestamp": "时间戳:", - "x": "x:", - "y": "y:" - }, - "layout": { - "col-page": "双列布局" - }, - "button-group": { - "title": "按钮组" - }, - "function": { - "contentMenu": "上下文菜单" - }, - "cropper": { - "title": "图片裁剪" - } -} diff --git a/playground/src/locales/langs/zh-CN/page.json b/playground/src/locales/langs/zh-CN/page.json deleted file mode 100644 index 437068c..0000000 --- a/playground/src/locales/langs/zh-CN/page.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "auth": { - "login": "登录", - "register": "注册", - "codeLogin": "验证码登录", - "qrcodeLogin": "二维码登录", - "forgetPassword": "忘记密码", - "sendingCode": "正在发送验证码", - "codeSentTo": "验证码已发送至{0}", - "profile": "个人中心" - }, - "dashboard": { - "title": "概览", - "analytics": "分析页", - "workspace": "工作台" - } -} diff --git a/playground/src/locales/langs/zh-CN/system.json b/playground/src/locales/langs/zh-CN/system.json deleted file mode 100644 index be5a7ae..0000000 --- a/playground/src/locales/langs/zh-CN/system.json +++ /dev/null @@ -1,67 +0,0 @@ -{ - "title": "系统管理", - "dept": { - "list": "部门列表", - "createTime": "创建时间", - "deptName": "部门名称", - "name": "部门", - "operation": "操作", - "parentDept": "上级部门", - "remark": "备注", - "status": "状态", - "title": "部门管理" - }, - "menu": { - "list": "菜单列表", - "activeIcon": "激活图标", - "activePath": "激活路径", - "activePathHelp": "跳转到当前路由时,需要激活的菜单路径。\n当不在导航菜单中显示时,需要指定激活路径", - "activePathMustExist": "该路径未能找到有效的菜单", - "advancedSettings": "其它设置", - "affixTab": "固定在标签", - "authCode": "权限标识", - "badge": "徽章内容", - "badgeVariants": "徽标样式", - "badgeType": { - "dot": "点", - "none": "无", - "normal": "文字", - "title": "徽标类型" - }, - "component": "页面组件", - "hideChildrenInMenu": "隐藏子菜单", - "hideInBreadcrumb": "在面包屑中隐藏", - "hideInMenu": "隐藏菜单", - "hideInTab": "在标签栏中隐藏", - "icon": "图标", - "keepAlive": "缓存标签页", - "linkSrc": "链接地址", - "menuName": "菜单名称", - "menuTitle": "标题", - "name": "菜单", - "operation": "操作", - "parent": "上级菜单", - "path": "路由地址", - "status": "状态", - "title": "菜单管理", - "type": "类型", - "typeButton": "按钮", - "typeCatalog": "目录", - "typeEmbedded": "内嵌", - "typeLink": "外链", - "typeMenu": "菜单" - }, - "role": { - "title": "角色管理", - "list": "角色列表", - "name": "角色", - "roleName": "角色名称", - "id": "角色ID", - "status": "状态", - "remark": "备注", - "createTime": "创建时间", - "operation": "操作", - "permissions": "权限", - "setPermissions": "授权" - } -} diff --git a/playground/src/main.ts b/playground/src/main.ts deleted file mode 100644 index 5d728a0..0000000 --- a/playground/src/main.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { initPreferences } from '@vben/preferences'; -import { unmountGlobalLoading } from '@vben/utils'; - -import { overridesPreferences } from './preferences'; - -/** - * 应用初始化完成之后再进行页面加载渲染 - */ -async function initApplication() { - // name用于指定项目唯一标识 - // 用于区分不同项目的偏好设置以及存储数据的key前缀以及其他一些需要隔离的数据 - const env = import.meta.env.PROD ? 'prod' : 'dev'; - const appVersion = import.meta.env.VITE_APP_VERSION; - const namespace = `${import.meta.env.VITE_APP_NAMESPACE}-${appVersion}-${env}`; - - // app偏好设置初始化 - await initPreferences({ - namespace, - overrides: overridesPreferences, - }); - - // 启动应用并挂载 - // vue应用主要逻辑及视图 - const { bootstrap } = await import('./bootstrap'); - await bootstrap(namespace); - - // 移除并销毁loading - unmountGlobalLoading(); -} - -initApplication(); diff --git a/playground/src/preferences.ts b/playground/src/preferences.ts deleted file mode 100644 index b2e9ace..0000000 --- a/playground/src/preferences.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { defineOverridesPreferences } from '@vben/preferences'; - -/** - * @description 项目配置文件 - * 只需要覆盖项目中的一部分配置,不需要的配置不用覆盖,会自动使用默认配置 - * !!! 更改配置后请清空缓存,否则可能不生效 - */ -export const overridesPreferences = defineOverridesPreferences({ - // overrides - app: { - name: import.meta.env.VITE_APP_TITLE, - }, -}); diff --git a/playground/src/router/access.ts b/playground/src/router/access.ts deleted file mode 100644 index 3a48be2..0000000 --- a/playground/src/router/access.ts +++ /dev/null @@ -1,42 +0,0 @@ -import type { - ComponentRecordType, - GenerateMenuAndRoutesOptions, -} from '@vben/types'; - -import { generateAccessible } from '@vben/access'; -import { preferences } from '@vben/preferences'; - -import { message } from 'ant-design-vue'; - -import { getAllMenusApi } from '#/api'; -import { BasicLayout, IFrameView } from '#/layouts'; -import { $t } from '#/locales'; - -const forbiddenComponent = () => import('#/views/_core/fallback/forbidden.vue'); - -async function generateAccess(options: GenerateMenuAndRoutesOptions) { - const pageMap: ComponentRecordType = import.meta.glob('../views/**/*.vue'); - - const layoutMap: ComponentRecordType = { - BasicLayout, - IFrameView, - }; - - return await generateAccessible(preferences.app.accessMode, { - ...options, - fetchMenuListAsync: async () => { - message.loading({ - content: `${$t('common.loadingMenu')}...`, - duration: 1.5, - }); - return await getAllMenusApi(); - }, - // 可以指定没有权限跳转403页面 - forbiddenComponent, - // 如果 route.meta.menuVisibleWithForbidden = true - layoutMap, - pageMap, - }); -} - -export { generateAccess }; diff --git a/playground/src/router/guard.ts b/playground/src/router/guard.ts deleted file mode 100644 index 167a84d..0000000 --- a/playground/src/router/guard.ts +++ /dev/null @@ -1,136 +0,0 @@ -import type { Router } from 'vue-router'; - -import { LOGIN_PATH } from '@vben/constants'; -import { preferences } from '@vben/preferences'; -import { useAccessStore, useUserStore } from '@vben/stores'; -import { startProgress, stopProgress } from '@vben/utils'; - -import { accessRoutes, coreRouteNames } from '#/router/routes'; -import { useAuthStore } from '#/store'; - -import { generateAccess } from './access'; - -/** - * 通用守卫配置 - * @param router - */ -function setupCommonGuard(router: Router) { - // 记录已经加载的页面 - const loadedPaths = new Set(); - - router.beforeEach((to) => { - to.meta.loaded = loadedPaths.has(to.path); - - // 页面加载进度条 - if (!to.meta.loaded && preferences.transition.progress) { - startProgress(); - } - return true; - }); - - router.afterEach((to) => { - // 记录页面是否加载,如果已经加载,后续的页面切换动画等效果不在重复执行 - loadedPaths.add(to.path); - - // 关闭页面加载进度条 - if (preferences.transition.progress) { - stopProgress(); - } - }); -} - -/** - * 权限访问守卫配置 - * @param router - */ -function setupAccessGuard(router: Router) { - router.beforeEach(async (to, from) => { - const accessStore = useAccessStore(); - const userStore = useUserStore(); - const authStore = useAuthStore(); - // 基本路由,这些路由不需要进入权限拦截 - if (coreRouteNames.includes(to.name as string)) { - if (to.path === LOGIN_PATH && accessStore.accessToken) { - return decodeURIComponent( - (to.query?.redirect as string) || - userStore.userInfo?.homePath || - preferences.app.defaultHomePath, - ); - } - return true; - } - - // accessToken 检查 - if (!accessStore.accessToken) { - // 明确声明忽略权限访问权限,则可以访问 - if (to.meta.ignoreAccess) { - return true; - } - - // 没有访问权限,跳转登录页面 - if (to.fullPath !== LOGIN_PATH) { - return { - path: LOGIN_PATH, - // 如不需要,直接删除 query - query: - to.fullPath === preferences.app.defaultHomePath - ? {} - : { redirect: encodeURIComponent(to.fullPath) }, - // 携带当前跳转的页面,登录后重新跳转该页面 - replace: true, - }; - } - return to; - } - - // 是否已经生成过动态路由 - if (accessStore.isAccessChecked) { - return true; - } - - // 生成路由表 - // 当前登录用户拥有的角色标识列表 - const userInfo = userStore.userInfo || (await authStore.fetchUserInfo()); - const userRoles = userInfo.roles ?? []; - - // 生成菜单和路由 - const { accessibleMenus, accessibleRoutes } = await generateAccess({ - roles: userRoles, - router, - // 则会在菜单中显示,但是访问会被重定向到403 - routes: accessRoutes, - }); - - // 保存菜单信息和路由信息 - accessStore.setAccessMenus(accessibleMenus); - accessStore.setAccessRoutes(accessibleRoutes); - accessStore.setIsAccessChecked(true); - let redirectPath: string; - if (from.query.redirect) { - redirectPath = from.query.redirect as string; - } else if (to.fullPath === preferences.app.defaultHomePath) { - redirectPath = preferences.app.defaultHomePath; - } else if (userInfo.homePath && to.fullPath === userInfo.homePath) { - redirectPath = userInfo.homePath; - } else { - redirectPath = to.fullPath; - } - return { - ...router.resolve(decodeURIComponent(redirectPath)), - replace: true, - }; - }); -} - -/** - * 项目守卫配置 - * @param router - */ -function createRouterGuard(router: Router) { - /** 通用 */ - setupCommonGuard(router); - /** 权限访问 */ - setupAccessGuard(router); -} - -export { createRouterGuard }; diff --git a/playground/src/router/index.ts b/playground/src/router/index.ts deleted file mode 100644 index 4840230..0000000 --- a/playground/src/router/index.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { - createRouter, - createWebHashHistory, - createWebHistory, -} from 'vue-router'; - -import { resetStaticRoutes } from '@vben/utils'; - -import { createRouterGuard } from './guard'; -import { routes } from './routes'; - -/** - * @zh_CN 创建vue-router实例 - */ -const router = createRouter({ - history: - import.meta.env.VITE_ROUTER_HISTORY === 'hash' - ? createWebHashHistory(import.meta.env.VITE_BASE) - : createWebHistory(import.meta.env.VITE_BASE), - // 应该添加到路由的初始路由列表。 - routes, - scrollBehavior: (to, _from, savedPosition) => { - if (savedPosition) { - return savedPosition; - } - return to.hash ? { behavior: 'smooth', el: to.hash } : { left: 0, top: 0 }; - }, - // 是否应该禁止尾部斜杠。 - // strict: true, -}); - -const resetRoutes = () => resetStaticRoutes(router, routes); - -// 创建路由守卫 -createRouterGuard(router); - -export { resetRoutes, router }; diff --git a/playground/src/router/routes/core.ts b/playground/src/router/routes/core.ts deleted file mode 100644 index 949b0b6..0000000 --- a/playground/src/router/routes/core.ts +++ /dev/null @@ -1,97 +0,0 @@ -import type { RouteRecordRaw } from 'vue-router'; - -import { LOGIN_PATH } from '@vben/constants'; -import { preferences } from '@vben/preferences'; - -import { $t } from '#/locales'; - -const BasicLayout = () => import('#/layouts/basic.vue'); -const AuthPageLayout = () => import('#/layouts/auth.vue'); -/** 全局404页面 */ -const fallbackNotFoundRoute: RouteRecordRaw = { - component: () => import('#/views/_core/fallback/not-found.vue'), - meta: { - hideInBreadcrumb: true, - hideInMenu: true, - hideInTab: true, - title: '404', - }, - name: 'FallbackNotFound', - path: '/:path(.*)*', -}; - -/** 基本路由,这些路由是必须存在的 */ -const coreRoutes: RouteRecordRaw[] = [ - /** - * 根路由 - * 使用基础布局,作为所有页面的父级容器,子级就不必配置BasicLayout。 - * 此路由必须存在,且不应修改 - */ - { - component: BasicLayout, - meta: { - hideInBreadcrumb: true, - title: 'Root', - }, - name: 'Root', - path: '/', - redirect: preferences.app.defaultHomePath, - children: [], - }, - { - component: AuthPageLayout, - meta: { - hideInTab: true, - title: 'Authentication', - }, - name: 'Authentication', - path: '/auth', - redirect: LOGIN_PATH, - children: [ - { - name: 'Login', - path: 'login', - component: () => import('#/views/_core/authentication/login.vue'), - meta: { - title: $t('page.auth.login'), - }, - }, - { - name: 'CodeLogin', - path: 'code-login', - component: () => import('#/views/_core/authentication/code-login.vue'), - meta: { - title: $t('page.auth.codeLogin'), - }, - }, - { - name: 'QrCodeLogin', - path: 'qrcode-login', - component: () => - import('#/views/_core/authentication/qrcode-login.vue'), - meta: { - title: $t('page.auth.qrcodeLogin'), - }, - }, - { - name: 'ForgetPassword', - path: 'forget-password', - component: () => - import('#/views/_core/authentication/forget-password.vue'), - meta: { - title: $t('page.auth.forgetPassword'), - }, - }, - { - name: 'Register', - path: 'register', - component: () => import('#/views/_core/authentication/register.vue'), - meta: { - title: $t('page.auth.register'), - }, - }, - ], - }, -]; - -export { coreRoutes, fallbackNotFoundRoute }; diff --git a/playground/src/router/routes/index.ts b/playground/src/router/routes/index.ts deleted file mode 100644 index 275eb83..0000000 --- a/playground/src/router/routes/index.ts +++ /dev/null @@ -1,47 +0,0 @@ -import type { RouteRecordRaw } from 'vue-router'; - -import { mergeRouteModules, traverseTreeValues } from '@vben/utils'; - -import { coreRoutes, fallbackNotFoundRoute } from './core'; - -const dynamicRouteFiles = import.meta.glob('./modules/**/*.ts', { - eager: true, -}); - -// 有需要可以自行打开注释,并创建文件夹 -// const externalRouteFiles = import.meta.glob('./external/**/*.ts', { eager: true }); -// const staticRouteFiles = import.meta.glob('./static/**/*.ts', { eager: true }); - -/** 动态路由 */ -const dynamicRoutes: RouteRecordRaw[] = mergeRouteModules(dynamicRouteFiles); - -/** 外部路由列表,访问这些页面可以不需要Layout,可能用于内嵌在别的系统(不会显示在菜单中) */ -// const externalRoutes: RouteRecordRaw[] = mergeRouteModules(externalRouteFiles); -// const staticRoutes: RouteRecordRaw[] = mergeRouteModules(staticRouteFiles); -const staticRoutes: RouteRecordRaw[] = []; -const externalRoutes: RouteRecordRaw[] = []; - -/** 路由列表,由基本路由、外部路由和404兜底路由组成 - * 无需走权限验证(会一直显示在菜单中) */ -const routes: RouteRecordRaw[] = [ - ...coreRoutes, - ...externalRoutes, - fallbackNotFoundRoute, -]; - -/** 基本路由列表,这些路由不需要进入权限拦截 */ -const coreRouteNames = traverseTreeValues(coreRoutes, (route) => route.name); - -/** 有权限校验的路由列表,包含动态路由和静态路由 */ -const accessRoutes = [...dynamicRoutes, ...staticRoutes]; - -const componentKeys: string[] = Object.keys( - import.meta.glob('../../views/**/*.vue'), -) - .filter((item) => !item.includes('/modules/')) - .map((v) => { - const path = v.replace('../../views/', '/'); - return path.endsWith('.vue') ? path.slice(0, -4) : path; - }); - -export { accessRoutes, componentKeys, coreRouteNames, routes }; diff --git a/playground/src/router/routes/modules/dashboard.ts b/playground/src/router/routes/modules/dashboard.ts deleted file mode 100644 index 7ef3cfb..0000000 --- a/playground/src/router/routes/modules/dashboard.ts +++ /dev/null @@ -1,39 +0,0 @@ -import type { RouteRecordRaw } from 'vue-router'; - -import { $t } from '#/locales'; - -const routes: RouteRecordRaw[] = [ - { - meta: { - icon: 'lucide:layout-dashboard', - order: -1, - title: $t('page.dashboard.title'), - }, - name: 'Dashboard', - path: '/dashboard', - children: [ - { - name: 'Analytics', - path: '/analytics', - component: () => import('#/views/dashboard/analytics/index.vue'), - meta: { - affixTab: true, - icon: 'lucide:area-chart', - title: $t('page.dashboard.analytics'), - keepAlive: true, - }, - }, - { - name: 'Workspace', - path: '/workspace', - component: () => import('#/views/dashboard/workspace/index.vue'), - meta: { - icon: 'carbon:workspace', - title: $t('page.dashboard.workspace'), - }, - }, - ], - }, -]; - -export default routes; diff --git a/playground/src/router/routes/modules/demos.ts b/playground/src/router/routes/modules/demos.ts deleted file mode 100644 index 8cb9f51..0000000 --- a/playground/src/router/routes/modules/demos.ts +++ /dev/null @@ -1,589 +0,0 @@ -import type { RouteRecordRaw } from 'vue-router'; - -import { IFrameView } from '#/layouts'; -import { $t } from '#/locales'; - -const routes: RouteRecordRaw[] = [ - { - meta: { - icon: 'ic:baseline-view-in-ar', - keepAlive: true, - order: 1000, - title: $t('demos.title'), - }, - name: 'Demos', - path: '/demos', - children: [ - // 权限控制 - { - meta: { - icon: 'mdi:shield-key-outline', - title: $t('demos.access.frontendPermissions'), - }, - name: 'AccessDemos', - path: '/demos/access', - children: [ - { - name: 'AccessPageControlDemo', - path: '/demos/access/page-control', - component: () => import('#/views/demos/access/index.vue'), - meta: { - icon: 'mdi:page-previous-outline', - title: $t('demos.access.pageAccess'), - domCached: true, - }, - }, - { - name: 'AccessButtonControlDemo', - path: '/demos/access/button-control', - component: () => import('#/views/demos/access/button-control.vue'), - meta: { - icon: 'mdi:button-cursor', - title: $t('demos.access.buttonControl'), - }, - }, - { - name: 'AccessMenuVisible403Demo', - path: '/demos/access/menu-visible-403', - component: () => - import('#/views/demos/access/menu-visible-403.vue'), - meta: { - authority: ['no-body'], - icon: 'mdi:button-cursor', - menuVisibleWithForbidden: true, - title: $t('demos.access.menuVisible403'), - }, - }, - { - name: 'AccessSuperVisibleDemo', - path: '/demos/access/super-visible', - component: () => import('#/views/demos/access/super-visible.vue'), - meta: { - authority: ['super'], - icon: 'mdi:button-cursor', - title: $t('demos.access.superVisible'), - }, - }, - { - name: 'AccessAdminVisibleDemo', - path: '/demos/access/admin-visible', - component: () => import('#/views/demos/access/admin-visible.vue'), - meta: { - authority: ['admin'], - icon: 'mdi:button-cursor', - title: $t('demos.access.adminVisible'), - }, - }, - { - name: 'AccessUserVisibleDemo', - path: '/demos/access/user-visible', - component: () => import('#/views/demos/access/user-visible.vue'), - meta: { - authority: ['user'], - icon: 'mdi:button-cursor', - title: $t('demos.access.userVisible'), - }, - }, - ], - }, - // 功能 - { - meta: { - icon: 'mdi:feature-highlight', - title: $t('demos.features.title'), - }, - name: 'FeaturesDemos', - path: '/demos/features', - children: [ - { - name: 'LoginExpiredDemo', - path: '/demos/features/login-expired', - component: () => - import('#/views/demos/features/login-expired/index.vue'), - meta: { - icon: 'mdi:encryption-expiration', - title: $t('demos.features.loginExpired'), - }, - }, - { - name: 'IconsDemo', - path: '/demos/features/icons', - component: () => import('#/views/demos/features/icons/index.vue'), - meta: { - icon: 'lucide:annoyed', - title: $t('demos.features.icons'), - }, - }, - { - name: 'WatermarkDemo', - path: '/demos/features/watermark', - component: () => - import('#/views/demos/features/watermark/index.vue'), - meta: { - icon: 'lucide:tags', - title: $t('demos.features.watermark'), - }, - }, - { - name: 'FeatureTabsDemo', - path: '/demos/features/tabs', - component: () => import('#/views/demos/features/tabs/index.vue'), - meta: { - icon: 'lucide:app-window', - title: $t('demos.features.tabs'), - }, - }, - { - name: 'FeatureTabDetailDemo', - path: '/demos/features/tabs/detail/:id', - component: () => - import('#/views/demos/features/tabs/tab-detail.vue'), - meta: { - activePath: '/demos/features/tabs', - hideInMenu: true, - maxNumOfOpenTab: 3, - title: $t('demos.features.tabDetail'), - }, - }, - { - name: 'HideChildrenInMenuParentDemo', - path: '/demos/features/hide-menu-children', - meta: { - hideChildrenInMenu: true, - icon: 'ic:round-menu', - title: $t('demos.features.hideChildrenInMenu'), - }, - children: [ - { - name: 'HideChildrenInMenuDemo', - path: '', - component: () => - import('#/views/demos/features/hide-menu-children/parent.vue'), - meta: { - // hideInMenu: true, - title: $t('demos.features.hideChildrenInMenu'), - }, - }, - { - name: 'HideChildrenInMenuChildrenDemo', - path: '/demos/features/hide-menu-children/children', - component: () => - import('#/views/demos/features/hide-menu-children/children.vue'), - meta: { - activePath: '/demos/features/hide-menu-children', - title: $t('demos.features.hideChildrenInMenu'), - }, - }, - ], - }, - { - name: 'FullScreenDemo', - path: '/demos/features/full-screen', - component: () => - import('#/views/demos/features/full-screen/index.vue'), - meta: { - icon: 'lucide:fullscreen', - title: $t('demos.features.fullScreen'), - }, - }, - { - name: 'FileDownloadDemo', - path: '/demos/features/file-download', - component: () => - import('#/views/demos/features/file-download/index.vue'), - meta: { - icon: 'lucide:hard-drive-download', - title: $t('demos.features.fileDownload'), - }, - }, - { - name: 'ClipboardDemo', - path: '/demos/features/clipboard', - component: () => - import('#/views/demos/features/clipboard/index.vue'), - meta: { - icon: 'lucide:copy', - title: $t('demos.features.clipboard'), - }, - }, - { - name: 'MenuQueryDemo', - path: '/demos/menu-query', - component: () => - import('#/views/demos/features/menu-query/index.vue'), - meta: { - icon: 'lucide:curly-braces', - query: { - id: 1, - }, - title: $t('demos.features.menuWithQuery'), - }, - }, - { - name: 'NewWindowDemo', - path: '/demos/new-window', - component: () => - import('#/views/demos/features/new-window/index.vue'), - meta: { - icon: 'lucide:app-window', - openInNewWindow: true, - title: $t('demos.features.openInNewWindow'), - }, - }, - { - name: 'VueQueryDemo', - path: '/demos/features/vue-query', - component: () => - import('#/views/demos/features/vue-query/index.vue'), - meta: { - icon: 'lucide:git-pull-request-arrow', - title: 'Tanstack Query', - }, - }, - { - name: 'RequestParamsSerializerDemo', - path: '/demos/features/request-params-serializer', - component: () => - import('#/views/demos/features/request-params-serializer/index.vue'), - meta: { - icon: 'lucide:git-pull-request-arrow', - title: $t('demos.features.requestParamsSerializer'), - }, - }, - { - name: 'BigIntDemo', - path: '/demos/features/json-bigint', - component: () => - import('#/views/demos/features/json-bigint/index.vue'), - meta: { - icon: 'lucide:grape', - title: 'JSON BigInt', - }, - }, - ], - }, - // 面包屑导航 - { - name: 'BreadcrumbDemos', - path: '/demos/breadcrumb', - meta: { - icon: 'lucide:navigation', - title: $t('demos.breadcrumb.navigation'), - }, - children: [ - { - name: 'BreadcrumbLateralDemo', - path: '/demos/breadcrumb/lateral', - component: () => import('#/views/demos/breadcrumb/lateral.vue'), - meta: { - icon: 'lucide:navigation', - title: $t('demos.breadcrumb.lateral'), - }, - }, - { - name: 'BreadcrumbLateralDetailDemo', - path: '/demos/breadcrumb/lateral-detail', - component: () => - import('#/views/demos/breadcrumb/lateral-detail.vue'), - meta: { - activePath: '/demos/breadcrumb/lateral', - hideInMenu: true, - title: $t('demos.breadcrumb.lateralDetail'), - }, - }, - { - name: 'BreadcrumbLevelDemo', - path: '/demos/breadcrumb/level', - meta: { - icon: 'lucide:navigation', - title: $t('demos.breadcrumb.level'), - }, - children: [ - { - name: 'BreadcrumbLevelDetailDemo', - path: '/demos/breadcrumb/level/detail', - component: () => - import('#/views/demos/breadcrumb/level-detail.vue'), - meta: { - title: $t('demos.breadcrumb.levelDetail'), - }, - }, - ], - }, - ], - }, - // 缺省页 - { - meta: { - icon: 'mdi:lightbulb-error-outline', - title: $t('demos.fallback.title'), - }, - name: 'FallbackDemos', - path: '/demos/fallback', - children: [ - { - name: 'Fallback403Demo', - path: '/demos/fallback/403', - component: () => import('#/views/_core/fallback/forbidden.vue'), - meta: { - icon: 'mdi:do-not-disturb-alt', - title: '403', - }, - }, - { - name: 'Fallback404Demo', - path: '/demos/fallback/404', - component: () => import('#/views/_core/fallback/not-found.vue'), - meta: { - icon: 'mdi:table-off', - title: '404', - }, - }, - { - name: 'Fallback500Demo', - path: '/demos/fallback/500', - component: () => - import('#/views/_core/fallback/internal-error.vue'), - meta: { - icon: 'mdi:server-network-off', - title: '500', - }, - }, - { - name: 'FallbackOfflineDemo', - path: '/demos/fallback/offline', - component: () => import('#/views/_core/fallback/offline.vue'), - meta: { - icon: 'mdi:offline', - title: $t('ui.fallback.offline'), - }, - }, - ], - }, - // 菜单徽标 - { - meta: { - badgeType: 'dot', - badgeVariants: 'destructive', - icon: 'lucide:circle-dot', - title: $t('demos.badge.title'), - }, - name: 'BadgeDemos', - path: '/demos/badge', - children: [ - { - name: 'BadgeDotDemo', - component: () => import('#/views/demos/badge/index.vue'), - path: '/demos/badge/dot', - meta: { - badgeType: 'dot', - icon: 'lucide:square-dot', - title: $t('demos.badge.dot'), - }, - }, - { - name: 'BadgeTextDemo', - component: () => import('#/views/demos/badge/index.vue'), - path: '/demos/badge/text', - meta: { - badge: '10', - icon: 'lucide:square-dot', - title: $t('demos.badge.text'), - }, - }, - { - name: 'BadgeColorDemo', - component: () => import('#/views/demos/badge/index.vue'), - path: '/demos/badge/color', - meta: { - badge: 'Hot', - badgeVariants: 'destructive', - icon: 'lucide:square-dot', - title: $t('demos.badge.color'), - }, - }, - ], - }, - // 菜单激活图标 - { - meta: { - activeIcon: 'fluent-emoji:radioactive', - icon: 'bi:radioactive', - title: $t('demos.activeIcon.title'), - }, - name: 'ActiveIconDemos', - path: '/demos/active-icon', - children: [ - { - name: 'ActiveIconDemo', - component: () => import('#/views/demos/active-icon/index.vue'), - path: '/demos/active-icon/children', - meta: { - activeIcon: 'fluent-emoji:radioactive', - icon: 'bi:radioactive', - title: $t('demos.activeIcon.children'), - }, - }, - ], - }, - // 外部链接 - { - meta: { - icon: 'ic:round-settings-input-composite', - title: $t('demos.outside.title'), - }, - name: 'OutsideDemos', - path: '/demos/outside', - children: [ - { - name: 'IframeDemos', - path: '/demos/outside/iframe', - meta: { - icon: 'mdi:newspaper-variant-outline', - title: $t('demos.outside.embedded'), - }, - children: [ - { - name: 'VueDocumentDemo', - path: '/demos/outside/iframe/vue-document', - component: IFrameView, - meta: { - icon: 'logos:vue', - iframeSrc: 'https://cn.vuejs.org/', - keepAlive: true, - title: 'Vue', - }, - }, - { - name: 'TailwindcssDemo', - path: '/demos/outside/iframe/tailwindcss', - component: IFrameView, - meta: { - icon: 'devicon:tailwindcss', - iframeSrc: 'https://tailwindcss.com/', - // keepAlive: true, - title: 'Tailwindcss', - }, - }, - ], - }, - { - name: 'ExternalLinkDemos', - path: '/demos/outside/external-link', - meta: { - icon: 'mdi:newspaper-variant-multiple-outline', - title: $t('demos.outside.externalLink'), - }, - children: [ - { - name: 'ViteDemo', - path: '/demos/outside/external-link/vite', - component: IFrameView, - meta: { - icon: 'logos:vitejs', - link: 'https://vitejs.dev/', - title: 'Vite', - }, - }, - { - name: 'VueUseDemo', - path: '/demos/outside/external-link/vue-use', - component: IFrameView, - meta: { - icon: 'logos:vueuse', - link: 'https://vueuse.org', - title: 'VueUse', - }, - }, - ], - }, - ], - }, - // 嵌套菜单 - { - meta: { - icon: 'ic:round-menu', - title: $t('demos.nested.title'), - }, - name: 'NestedDemos', - path: '/demos/nested', - children: [ - { - name: 'Menu1Demo', - path: '/demos/nested/menu1', - component: () => import('#/views/demos/nested/menu-1.vue'), - meta: { - icon: 'ic:round-menu', - keepAlive: true, - title: $t('demos.nested.menu1'), - }, - }, - { - name: 'Menu2Demo', - path: '/demos/nested/menu2', - meta: { - icon: 'ic:round-menu', - keepAlive: true, - title: $t('demos.nested.menu2'), - }, - children: [ - { - name: 'Menu21Demo', - path: '/demos/nested/menu2/menu2-1', - component: () => import('#/views/demos/nested/menu-2-1.vue'), - meta: { - icon: 'ic:round-menu', - keepAlive: true, - title: $t('demos.nested.menu2_1'), - }, - }, - ], - }, - { - name: 'Menu3Demo', - path: '/demos/nested/menu3', - meta: { - icon: 'ic:round-menu', - title: $t('demos.nested.menu3'), - }, - children: [ - { - name: 'Menu31Demo', - path: '/demos/nested/menu3/menu3-1', - component: () => import('#/views/demos/nested/menu-3-1.vue'), - meta: { - icon: 'ic:round-menu', - keepAlive: true, - title: $t('demos.nested.menu3_1'), - }, - }, - { - name: 'Menu32Demo', - path: '/demos/nested/menu3/menu3-2', - meta: { - icon: 'ic:round-menu', - title: $t('demos.nested.menu3_2'), - }, - children: [ - { - name: 'Menu321Demo', - path: '/demos/nested/menu3/menu3-2/menu3-2-1', - component: () => - import('#/views/demos/nested/menu-3-2-1.vue'), - meta: { - icon: 'ic:round-menu', - keepAlive: true, - title: $t('demos.nested.menu3_2_1'), - }, - }, - ], - }, - ], - }, - ], - }, - ], - }, -]; - -export default routes; diff --git a/playground/src/router/routes/modules/examples.ts b/playground/src/router/routes/modules/examples.ts deleted file mode 100644 index 017b2c2..0000000 --- a/playground/src/router/routes/modules/examples.ts +++ /dev/null @@ -1,353 +0,0 @@ -import type { RouteRecordRaw } from 'vue-router'; - -import { $t } from '#/locales'; - -const routes: RouteRecordRaw[] = [ - { - meta: { - icon: 'ion:layers-outline', - keepAlive: true, - order: 1000, - title: $t('examples.title'), - }, - name: 'Examples', - path: '/examples', - children: [ - { - name: 'FormExample', - path: '/examples/form', - meta: { - icon: 'mdi:form-select', - title: $t('examples.form.title'), - }, - children: [ - { - name: 'FormBasicExample', - path: '/examples/form/basic', - component: () => import('#/views/examples/form/basic.vue'), - meta: { - title: $t('examples.form.basic'), - }, - }, - { - name: 'FormQueryExample', - path: '/examples/form/query', - component: () => import('#/views/examples/form/query.vue'), - meta: { - title: $t('examples.form.query'), - }, - }, - { - name: 'FormRulesExample', - path: '/examples/form/rules', - component: () => import('#/views/examples/form/rules.vue'), - meta: { - title: $t('examples.form.rules'), - }, - }, - { - name: 'FormDynamicExample', - path: '/examples/form/dynamic', - component: () => import('#/views/examples/form/dynamic.vue'), - meta: { - title: $t('examples.form.dynamic'), - }, - }, - { - name: 'FormLayoutExample', - path: '/examples/form/custom-layout', - component: () => import('#/views/examples/form/custom-layout.vue'), - meta: { - title: $t('examples.form.layout'), - }, - }, - { - name: 'FormCustomExample', - path: '/examples/form/custom', - component: () => import('#/views/examples/form/custom.vue'), - meta: { - title: $t('examples.form.custom'), - }, - }, - { - name: 'FormApiExample', - path: '/examples/form/api', - component: () => import('#/views/examples/form/api.vue'), - meta: { - title: $t('examples.form.api'), - }, - }, - { - name: 'FormMergeExample', - path: '/examples/form/merge', - component: () => import('#/views/examples/form/merge.vue'), - meta: { - title: $t('examples.form.merge'), - }, - }, - { - name: 'FormScrollToErrorExample', - path: '/examples/form/scroll-to-error-test', - component: () => - import('#/views/examples/form/scroll-to-error-test.vue'), - meta: { - title: $t('examples.form.scrollToError'), - }, - }, - ], - }, - { - name: 'VxeTableExample', - path: '/examples/vxe-table', - meta: { - icon: 'lucide:table', - title: $t('examples.vxeTable.title'), - }, - children: [ - { - name: 'VxeTableBasicExample', - path: '/examples/vxe-table/basic', - component: () => import('#/views/examples/vxe-table/basic.vue'), - meta: { - title: $t('examples.vxeTable.basic'), - }, - }, - { - name: 'VxeTableRemoteExample', - path: '/examples/vxe-table/remote', - component: () => import('#/views/examples/vxe-table/remote.vue'), - meta: { - title: $t('examples.vxeTable.remote'), - }, - }, - { - name: 'VxeTableTreeExample', - path: '/examples/vxe-table/tree', - component: () => import('#/views/examples/vxe-table/tree.vue'), - meta: { - title: $t('examples.vxeTable.tree'), - }, - }, - { - name: 'VxeTableFixedExample', - path: '/examples/vxe-table/fixed', - component: () => import('#/views/examples/vxe-table/fixed.vue'), - meta: { - title: $t('examples.vxeTable.fixed'), - }, - }, - { - name: 'VxeTableCustomCellExample', - path: '/examples/vxe-table/custom-cell', - component: () => - import('#/views/examples/vxe-table/custom-cell.vue'), - meta: { - title: $t('examples.vxeTable.custom-cell'), - }, - }, - { - name: 'VxeTableFormExample', - path: '/examples/vxe-table/form', - component: () => import('#/views/examples/vxe-table/form.vue'), - meta: { - title: $t('examples.vxeTable.form'), - }, - }, - { - name: 'VxeTableEditCellExample', - path: '/examples/vxe-table/edit-cell', - component: () => import('#/views/examples/vxe-table/edit-cell.vue'), - meta: { - title: $t('examples.vxeTable.editCell'), - }, - }, - { - name: 'VxeTableEditRowExample', - path: '/examples/vxe-table/edit-row', - component: () => import('#/views/examples/vxe-table/edit-row.vue'), - meta: { - title: $t('examples.vxeTable.editRow'), - }, - }, - { - name: 'VxeTableVirtualExample', - path: '/examples/vxe-table/virtual', - component: () => import('#/views/examples/vxe-table/virtual.vue'), - meta: { - title: $t('examples.vxeTable.virtual'), - }, - }, - ], - }, - { - name: 'CaptchaExample', - path: '/examples/captcha', - meta: { - icon: 'logos:recaptcha', - title: $t('examples.captcha.title'), - }, - children: [ - { - name: 'DragVerifyExample', - path: '/examples/captcha/slider', - component: () => - import('#/views/examples/captcha/slider-captcha.vue'), - meta: { - title: $t('examples.captcha.sliderCaptcha'), - }, - }, - { - name: 'RotateVerifyExample', - path: '/examples/captcha/slider-rotate', - component: () => - import('#/views/examples/captcha/slider-rotate-captcha.vue'), - meta: { - title: $t('examples.captcha.sliderRotateCaptcha'), - }, - }, - { - name: 'TranslateVerifyExample', - path: '/examples/captcha/slider-translate', - component: () => - import('#/views/examples/captcha/slider-translate-captcha.vue'), - meta: { - title: $t('examples.captcha.sliderTranslateCaptcha'), - }, - }, - { - name: 'CaptchaPointSelectionExample', - path: '/examples/captcha/point-selection', - component: () => - import('#/views/examples/captcha/point-selection-captcha.vue'), - meta: { - title: $t('examples.captcha.pointSelection'), - }, - }, - ], - }, - { - name: 'ModalExample', - path: '/examples/modal', - component: () => import('#/views/examples/modal/index.vue'), - meta: { - icon: 'system-uicons:window-content', - keepAlive: true, - title: $t('examples.modal.title'), - }, - }, - { - name: 'DrawerExample', - path: '/examples/drawer', - component: () => import('#/views/examples/drawer/index.vue'), - meta: { - icon: 'iconoir:drawer', - keepAlive: true, - title: $t('examples.drawer.title'), - }, - }, - { - name: 'EllipsisExample', - path: '/examples/ellipsis', - component: () => import('#/views/examples/ellipsis/index.vue'), - meta: { - icon: 'ion:ellipsis-horizontal', - title: $t('examples.ellipsis.title'), - }, - }, - { - name: 'VueResizeDemo', - path: '/demos/resize/basic', - component: () => import('#/views/examples/resize/basic.vue'), - meta: { - icon: 'material-symbols:resize', - title: $t('examples.resize.title'), - }, - }, - { - name: 'ColPageDemo', - path: '/examples/layout/col-page', - component: () => import('#/views/examples/layout/col-page.vue'), - meta: { - badge: 'Alpha', - badgeVariants: 'destructive', - icon: 'material-symbols:horizontal-distribute', - title: $t('examples.layout.col-page'), - }, - }, - { - name: 'TippyDemo', - path: '/examples/tippy', - component: () => import('#/views/examples/tippy/index.vue'), - meta: { - icon: 'mdi:message-settings-outline', - title: 'Tippy', - }, - }, - { - name: 'JsonViewer', - path: '/examples/json-viewer', - component: () => import('#/views/examples/json-viewer/index.vue'), - meta: { - icon: 'tabler:json', - title: 'JsonViewer', - }, - }, - { - name: 'Motion', - path: '/examples/motion', - component: () => import('#/views/examples/motion/index.vue'), - meta: { - icon: 'mdi:animation-play', - title: 'Motion', - }, - }, - { - name: 'CountTo', - path: '/examples/count-to', - component: () => import('#/views/examples/count-to/index.vue'), - meta: { - icon: 'mdi:animation-play', - title: 'CountTo', - }, - }, - { - name: 'Loading', - path: '/examples/loading', - component: () => import('#/views/examples/loading/index.vue'), - meta: { - icon: 'mdi:circle-double', - title: 'Loading', - }, - }, - { - name: 'ButtonGroup', - path: '/examples/button-group', - component: () => import('#/views/examples/button-group/index.vue'), - meta: { - icon: 'mdi:check-circle', - title: $t('examples.button-group.title'), - }, - }, - { - name: 'ContextMenu', - path: '/examples/context-menu', - component: () => import('#/views/examples/context-menu/index.vue'), - meta: { - icon: 'mdi:menu', - title: $t('examples.function.contentMenu'), - }, - }, - { - name: 'CropperDemo', - path: '/examples/cropper', - component: () => import('#/views/examples/cropper/index.vue'), - meta: { - icon: 'mdi:crop', - title: $t('examples.cropper.title'), - }, - }, - ], - }, -]; - -export default routes; diff --git a/playground/src/router/routes/modules/system.ts b/playground/src/router/routes/modules/system.ts deleted file mode 100644 index e1bf712..0000000 --- a/playground/src/router/routes/modules/system.ts +++ /dev/null @@ -1,46 +0,0 @@ -import type { RouteRecordRaw } from 'vue-router'; - -import { $t } from '#/locales'; - -const routes: RouteRecordRaw[] = [ - { - meta: { - icon: 'ion:settings-outline', - order: 9997, - title: $t('system.title'), - }, - name: 'System', - path: '/system', - children: [ - { - path: '/system/role', - name: 'SystemRole', - meta: { - icon: 'mdi:account-group', - title: $t('system.role.title'), - }, - component: () => import('#/views/system/role/list.vue'), - }, - { - path: '/system/menu', - name: 'SystemMenu', - meta: { - icon: 'mdi:menu', - title: $t('system.menu.title'), - }, - component: () => import('#/views/system/menu/list.vue'), - }, - { - path: '/system/dept', - name: 'SystemDept', - meta: { - icon: 'charm:organisation', - title: $t('system.dept.title'), - }, - component: () => import('#/views/system/dept/list.vue'), - }, - ], - }, -]; - -export default routes; diff --git a/playground/src/router/routes/modules/vben.ts b/playground/src/router/routes/modules/vben.ts deleted file mode 100644 index bd7f98b..0000000 --- a/playground/src/router/routes/modules/vben.ts +++ /dev/null @@ -1,111 +0,0 @@ -import type { RouteRecordRaw } from 'vue-router'; - -import { - VBEN_ANT_PREVIEW_URL, - VBEN_ANTDV_NEXT_PREVIEW_URL, - VBEN_ELE_PREVIEW_URL, - VBEN_LOGO_URL, - VBEN_NAIVE_PREVIEW_URL, - VBEN_TD_PREVIEW_URL, -} from '@vben/constants'; -import { - SvgAntdvLogoIcon, - SvgAntdvNextLogoIcon, - SvgTDesignIcon, -} from '@vben/icons'; - -import { IFrameView } from '#/layouts'; -import { $t } from '#/locales'; - -const routes: RouteRecordRaw[] = [ - { - meta: { - badgeType: 'dot', - icon: VBEN_LOGO_URL, - order: 9998, - title: $t('demos.vben.title'), - }, - name: 'VbenProject', - path: '/vben-admin', - children: [ - { - name: 'VbenAntdv', - path: '/vben-admin/antdv', - component: IFrameView, - meta: { - badgeType: 'dot', - icon: SvgAntdvLogoIcon, - link: VBEN_ANT_PREVIEW_URL, - title: $t('demos.vben.antdv'), - }, - }, - { - name: 'VbenAntdVNext', - path: '/vben-admin/antdv-next', - component: IFrameView, - meta: { - badgeType: 'dot', - icon: SvgAntdvNextLogoIcon, - link: VBEN_ANTDV_NEXT_PREVIEW_URL, - title: $t('demos.vben.antdv-next'), - }, - }, - - { - name: 'VbenNaive', - path: '/vben-admin/naive', - component: IFrameView, - meta: { - badgeType: 'dot', - icon: 'logos:naiveui', - link: VBEN_NAIVE_PREVIEW_URL, - title: $t('demos.vben.naive-ui'), - }, - }, - { - name: 'VbenElementPlus', - path: '/vben-admin/ele', - component: IFrameView, - meta: { - badgeType: 'dot', - icon: 'logos:element', - link: VBEN_ELE_PREVIEW_URL, - title: $t('demos.vben.element-plus'), - }, - }, - { - name: 'VbenTDesign', - path: '/vben-admin/tdesign', - component: IFrameView, - meta: { - badgeType: 'dot', - icon: SvgTDesignIcon, - link: VBEN_TD_PREVIEW_URL, - title: $t('demos.vben.tdesign'), - }, - }, - ], - }, - { - component: () => import('#/views/_core/about/index.vue'), - meta: { - icon: 'lucide:copyright', - order: 9999, - title: $t('demos.vben.about'), - }, - name: 'VbenAbout', - path: '/vben-admin/about', - }, - { - name: 'Profile', - path: '/profile', - component: () => import('#/views/_core/profile/index.vue'), - meta: { - icon: 'lucide:user', - hideInMenu: true, - title: $t('page.auth.profile'), - }, - }, -]; - -export default routes; diff --git a/playground/src/store/auth.ts b/playground/src/store/auth.ts deleted file mode 100644 index a08386e..0000000 --- a/playground/src/store/auth.ts +++ /dev/null @@ -1,126 +0,0 @@ -import type { Recordable, UserInfo } from '@vben/types'; - -import { ref } from 'vue'; -import { useRouter } from 'vue-router'; - -import { LOGIN_PATH } from '@vben/constants'; -import { preferences } from '@vben/preferences'; -import { resetAllStores, useAccessStore, useUserStore } from '@vben/stores'; - -import { notification } from 'ant-design-vue'; -import { defineStore } from 'pinia'; - -import { getAccessCodesApi, getUserInfoApi, loginApi, logoutApi } from '#/api'; -import { $t } from '#/locales'; - -export const useAuthStore = defineStore('auth', () => { - const accessStore = useAccessStore(); - const userStore = useUserStore(); - const router = useRouter(); - - const loginLoading = ref(false); - - /** - * 异步处理登录操作 - * Asynchronously handle the login process - * @param params 登录表单数据 - * @param onSuccess 成功之后的回调函数 - */ - async function authLogin( - params: Recordable, - onSuccess?: () => Promise | void, - ) { - // 异步处理用户登录操作并获取 accessToken - let userInfo: null | UserInfo = null; - try { - loginLoading.value = true; - const { accessToken } = await loginApi(params); - - // 如果成功获取到 accessToken - if (accessToken) { - accessStore.setAccessToken(accessToken); - - // 获取用户信息并存储到 accessStore 中 - const [fetchUserInfoResult, accessCodes] = await Promise.all([ - fetchUserInfo(), - getAccessCodesApi(), - ]); - - userInfo = fetchUserInfoResult; - - userStore.setUserInfo(userInfo); - accessStore.setAccessCodes(accessCodes); - - if (accessStore.loginExpired) { - accessStore.setLoginExpired(false); - } else { - onSuccess - ? await onSuccess?.() - : await router.push( - userInfo.homePath || preferences.app.defaultHomePath, - ); - } - - if (userInfo?.realName) { - notification.success({ - description: `${$t('authentication.loginSuccessDesc')}:${userInfo?.realName}`, - duration: 3, - message: $t('authentication.loginSuccess'), - }); - } - } - } finally { - loginLoading.value = false; - } - - return { - userInfo, - }; - } - - const isLoggingOut = ref(false); // 正在 logout 标识, 防止 /logout 死循环. - - async function logout(redirect: boolean = true) { - if (isLoggingOut.value) return; // 正在登出中, 说明已进入循环, 直接返回. - isLoggingOut.value = true; // 设置 标识 - - try { - await logoutApi(); - } catch { - // 不做任何处理 - } finally { - isLoggingOut.value = false; // 重置 标识 - - resetAllStores(); - accessStore.setLoginExpired(false); - } - - // 回登录页带上当前路由地址 - await router.replace({ - path: LOGIN_PATH, - query: redirect - ? { - redirect: encodeURIComponent(router.currentRoute.value.fullPath), - } - : {}, - }); - } - - async function fetchUserInfo() { - const userInfo = await getUserInfoApi(); - userStore.setUserInfo(userInfo); - return userInfo; - } - - function $reset() { - loginLoading.value = false; - } - - return { - $reset, - authLogin, - fetchUserInfo, - loginLoading, - logout, - }; -}); diff --git a/playground/src/store/index.ts b/playground/src/store/index.ts deleted file mode 100644 index 269586e..0000000 --- a/playground/src/store/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './auth'; diff --git a/playground/src/timezone-init.ts b/playground/src/timezone-init.ts deleted file mode 100644 index 1d82bd4..0000000 --- a/playground/src/timezone-init.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { setTimezoneHandler } from '@vben/stores'; - -import { getTimezoneApi, getTimezoneOptionsApi, setTimezoneApi } from '#/api'; - -/** - * 初始化时区处理,通过API保存时区设置 - */ -export function initTimezone() { - setTimezoneHandler({ - getTimezone() { - return getTimezoneApi(); - }, - setTimezone(timezone: string) { - return setTimezoneApi(timezone); - }, - getTimezoneOptions() { - return getTimezoneOptionsApi(); - }, - }); -} diff --git a/playground/src/views/_core/README.md b/playground/src/views/_core/README.md deleted file mode 100644 index 8248afe..0000000 --- a/playground/src/views/_core/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# \_core - -此目录包含应用程序正常运行所需的基本视图。这些视图是应用程序布局中使用的视图。 diff --git a/playground/src/views/_core/about/index.vue b/playground/src/views/_core/about/index.vue deleted file mode 100644 index 0ee5243..0000000 --- a/playground/src/views/_core/about/index.vue +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/playground/src/views/_core/authentication/code-login.vue b/playground/src/views/_core/authentication/code-login.vue deleted file mode 100644 index cc789a7..0000000 --- a/playground/src/views/_core/authentication/code-login.vue +++ /dev/null @@ -1,108 +0,0 @@ - - - diff --git a/playground/src/views/_core/authentication/forget-password.vue b/playground/src/views/_core/authentication/forget-password.vue deleted file mode 100644 index 9082cb9..0000000 --- a/playground/src/views/_core/authentication/forget-password.vue +++ /dev/null @@ -1,41 +0,0 @@ - - - diff --git a/playground/src/views/_core/authentication/login.vue b/playground/src/views/_core/authentication/login.vue deleted file mode 100644 index 162398e..0000000 --- a/playground/src/views/_core/authentication/login.vue +++ /dev/null @@ -1,132 +0,0 @@ - - - diff --git a/playground/src/views/_core/authentication/qrcode-login.vue b/playground/src/views/_core/authentication/qrcode-login.vue deleted file mode 100644 index 23f5f2d..0000000 --- a/playground/src/views/_core/authentication/qrcode-login.vue +++ /dev/null @@ -1,10 +0,0 @@ - - - diff --git a/playground/src/views/_core/authentication/register.vue b/playground/src/views/_core/authentication/register.vue deleted file mode 100644 index 8c42953..0000000 --- a/playground/src/views/_core/authentication/register.vue +++ /dev/null @@ -1,95 +0,0 @@ - - - diff --git a/playground/src/views/_core/fallback/coming-soon.vue b/playground/src/views/_core/fallback/coming-soon.vue deleted file mode 100644 index f394930..0000000 --- a/playground/src/views/_core/fallback/coming-soon.vue +++ /dev/null @@ -1,7 +0,0 @@ - - - diff --git a/playground/src/views/_core/fallback/forbidden.vue b/playground/src/views/_core/fallback/forbidden.vue deleted file mode 100644 index 8ea65fe..0000000 --- a/playground/src/views/_core/fallback/forbidden.vue +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/playground/src/views/_core/fallback/internal-error.vue b/playground/src/views/_core/fallback/internal-error.vue deleted file mode 100644 index 819a47d..0000000 --- a/playground/src/views/_core/fallback/internal-error.vue +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/playground/src/views/_core/fallback/not-found.vue b/playground/src/views/_core/fallback/not-found.vue deleted file mode 100644 index 4d178e9..0000000 --- a/playground/src/views/_core/fallback/not-found.vue +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/playground/src/views/_core/fallback/offline.vue b/playground/src/views/_core/fallback/offline.vue deleted file mode 100644 index 5de4a88..0000000 --- a/playground/src/views/_core/fallback/offline.vue +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/playground/src/views/_core/profile/index.vue b/playground/src/views/_core/profile/index.vue deleted file mode 100644 index b4169e9..0000000 --- a/playground/src/views/_core/profile/index.vue +++ /dev/null @@ -1,31 +0,0 @@ - - diff --git a/playground/src/views/_core/profile/password-setting.vue b/playground/src/views/_core/profile/password-setting.vue deleted file mode 100644 index e5609c0..0000000 --- a/playground/src/views/_core/profile/password-setting.vue +++ /dev/null @@ -1,63 +0,0 @@ - - diff --git a/playground/src/views/dashboard/analytics/analytics-trends.vue b/playground/src/views/dashboard/analytics/analytics-trends.vue deleted file mode 100644 index f1f0b23..0000000 --- a/playground/src/views/dashboard/analytics/analytics-trends.vue +++ /dev/null @@ -1,98 +0,0 @@ - - - diff --git a/playground/src/views/dashboard/analytics/analytics-visits-data.vue b/playground/src/views/dashboard/analytics/analytics-visits-data.vue deleted file mode 100644 index 190fb41..0000000 --- a/playground/src/views/dashboard/analytics/analytics-visits-data.vue +++ /dev/null @@ -1,82 +0,0 @@ - - - diff --git a/playground/src/views/dashboard/analytics/analytics-visits-sales.vue b/playground/src/views/dashboard/analytics/analytics-visits-sales.vue deleted file mode 100644 index 6ff5208..0000000 --- a/playground/src/views/dashboard/analytics/analytics-visits-sales.vue +++ /dev/null @@ -1,46 +0,0 @@ - - - diff --git a/playground/src/views/dashboard/analytics/analytics-visits-source.vue b/playground/src/views/dashboard/analytics/analytics-visits-source.vue deleted file mode 100644 index 0915c7a..0000000 --- a/playground/src/views/dashboard/analytics/analytics-visits-source.vue +++ /dev/null @@ -1,65 +0,0 @@ - - - diff --git a/playground/src/views/dashboard/analytics/analytics-visits.vue b/playground/src/views/dashboard/analytics/analytics-visits.vue deleted file mode 100644 index 7e0f101..0000000 --- a/playground/src/views/dashboard/analytics/analytics-visits.vue +++ /dev/null @@ -1,55 +0,0 @@ - - - diff --git a/playground/src/views/dashboard/analytics/index.vue b/playground/src/views/dashboard/analytics/index.vue deleted file mode 100644 index e794c99..0000000 --- a/playground/src/views/dashboard/analytics/index.vue +++ /dev/null @@ -1,90 +0,0 @@ - - - diff --git a/playground/src/views/dashboard/workspace/index.vue b/playground/src/views/dashboard/workspace/index.vue deleted file mode 100644 index b95d613..0000000 --- a/playground/src/views/dashboard/workspace/index.vue +++ /dev/null @@ -1,266 +0,0 @@ - - - diff --git a/playground/src/views/demos/access/admin-visible.vue b/playground/src/views/demos/access/admin-visible.vue deleted file mode 100644 index 079b930..0000000 --- a/playground/src/views/demos/access/admin-visible.vue +++ /dev/null @@ -1,11 +0,0 @@ - - - diff --git a/playground/src/views/demos/access/button-control.vue b/playground/src/views/demos/access/button-control.vue deleted file mode 100644 index 878cf02..0000000 --- a/playground/src/views/demos/access/button-control.vue +++ /dev/null @@ -1,157 +0,0 @@ - - - diff --git a/playground/src/views/demos/access/index.vue b/playground/src/views/demos/access/index.vue deleted file mode 100644 index a28f1e2..0000000 --- a/playground/src/views/demos/access/index.vue +++ /dev/null @@ -1,98 +0,0 @@ - - - diff --git a/playground/src/views/demos/access/menu-visible-403.vue b/playground/src/views/demos/access/menu-visible-403.vue deleted file mode 100644 index 7e3cde8..0000000 --- a/playground/src/views/demos/access/menu-visible-403.vue +++ /dev/null @@ -1,11 +0,0 @@ - - - diff --git a/playground/src/views/demos/access/super-visible.vue b/playground/src/views/demos/access/super-visible.vue deleted file mode 100644 index 877fcd1..0000000 --- a/playground/src/views/demos/access/super-visible.vue +++ /dev/null @@ -1,11 +0,0 @@ - - - diff --git a/playground/src/views/demos/access/user-visible.vue b/playground/src/views/demos/access/user-visible.vue deleted file mode 100644 index a3c5f00..0000000 --- a/playground/src/views/demos/access/user-visible.vue +++ /dev/null @@ -1,11 +0,0 @@ - - - diff --git a/playground/src/views/demos/active-icon/index.vue b/playground/src/views/demos/active-icon/index.vue deleted file mode 100644 index af9f69a..0000000 --- a/playground/src/views/demos/active-icon/index.vue +++ /dev/null @@ -1,11 +0,0 @@ - - - diff --git a/playground/src/views/demos/badge/index.vue b/playground/src/views/demos/badge/index.vue deleted file mode 100644 index 9247caf..0000000 --- a/playground/src/views/demos/badge/index.vue +++ /dev/null @@ -1,117 +0,0 @@ - - - diff --git a/playground/src/views/demos/breadcrumb/lateral-detail.vue b/playground/src/views/demos/breadcrumb/lateral-detail.vue deleted file mode 100644 index 8a4de64..0000000 --- a/playground/src/views/demos/breadcrumb/lateral-detail.vue +++ /dev/null @@ -1,21 +0,0 @@ - - - diff --git a/playground/src/views/demos/breadcrumb/lateral.vue b/playground/src/views/demos/breadcrumb/lateral.vue deleted file mode 100644 index 2c24abf..0000000 --- a/playground/src/views/demos/breadcrumb/lateral.vue +++ /dev/null @@ -1,25 +0,0 @@ - - - diff --git a/playground/src/views/demos/breadcrumb/level-detail.vue b/playground/src/views/demos/breadcrumb/level-detail.vue deleted file mode 100644 index 7aa18d4..0000000 --- a/playground/src/views/demos/breadcrumb/level-detail.vue +++ /dev/null @@ -1,11 +0,0 @@ - - - diff --git a/playground/src/views/demos/features/clipboard/index.vue b/playground/src/views/demos/features/clipboard/index.vue deleted file mode 100644 index d14bb53..0000000 --- a/playground/src/views/demos/features/clipboard/index.vue +++ /dev/null @@ -1,25 +0,0 @@ - - - diff --git a/playground/src/views/demos/features/file-download/base64.ts b/playground/src/views/demos/features/file-download/base64.ts deleted file mode 100644 index ee6ac2b..0000000 --- a/playground/src/views/demos/features/file-download/base64.ts +++ /dev/null @@ -1 +0,0 @@ -export default `data:image/png;base64,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`; diff --git a/playground/src/views/demos/features/file-download/index.vue b/playground/src/views/demos/features/file-download/index.vue deleted file mode 100644 index 5342141..0000000 --- a/playground/src/views/demos/features/file-download/index.vue +++ /dev/null @@ -1,100 +0,0 @@ - - - diff --git a/playground/src/views/demos/features/full-screen/index.vue b/playground/src/views/demos/features/full-screen/index.vue deleted file mode 100644 index a4b9c8a..0000000 --- a/playground/src/views/demos/features/full-screen/index.vue +++ /dev/null @@ -1,47 +0,0 @@ - - - diff --git a/playground/src/views/demos/features/hide-menu-children/children.vue b/playground/src/views/demos/features/hide-menu-children/children.vue deleted file mode 100644 index 1959f96..0000000 --- a/playground/src/views/demos/features/hide-menu-children/children.vue +++ /dev/null @@ -1,23 +0,0 @@ - - - diff --git a/playground/src/views/demos/features/hide-menu-children/parent.vue b/playground/src/views/demos/features/hide-menu-children/parent.vue deleted file mode 100644 index b732c1b..0000000 --- a/playground/src/views/demos/features/hide-menu-children/parent.vue +++ /dev/null @@ -1,17 +0,0 @@ - - - diff --git a/playground/src/views/demos/features/icons/index.vue b/playground/src/views/demos/features/icons/index.vue deleted file mode 100644 index cc53919..0000000 --- a/playground/src/views/demos/features/icons/index.vue +++ /dev/null @@ -1,115 +0,0 @@ - - - diff --git a/playground/src/views/demos/features/json-bigint/index.vue b/playground/src/views/demos/features/json-bigint/index.vue deleted file mode 100644 index d1f5814..0000000 --- a/playground/src/views/demos/features/json-bigint/index.vue +++ /dev/null @@ -1,39 +0,0 @@ - - diff --git a/playground/src/views/demos/features/login-expired/index.vue b/playground/src/views/demos/features/login-expired/index.vue deleted file mode 100644 index 5b03d85..0000000 --- a/playground/src/views/demos/features/login-expired/index.vue +++ /dev/null @@ -1,39 +0,0 @@ - - - diff --git a/playground/src/views/demos/features/menu-query/index.vue b/playground/src/views/demos/features/menu-query/index.vue deleted file mode 100644 index 6943a24..0000000 --- a/playground/src/views/demos/features/menu-query/index.vue +++ /dev/null @@ -1,11 +0,0 @@ - - - diff --git a/playground/src/views/demos/features/new-window/index.vue b/playground/src/views/demos/features/new-window/index.vue deleted file mode 100644 index 68f89d0..0000000 --- a/playground/src/views/demos/features/new-window/index.vue +++ /dev/null @@ -1,11 +0,0 @@ - - - diff --git a/playground/src/views/demos/features/request-params-serializer/index.vue b/playground/src/views/demos/features/request-params-serializer/index.vue deleted file mode 100644 index 4ed4d08..0000000 --- a/playground/src/views/demos/features/request-params-serializer/index.vue +++ /dev/null @@ -1,61 +0,0 @@ - - diff --git a/playground/src/views/demos/features/tabs/index.vue b/playground/src/views/demos/features/tabs/index.vue deleted file mode 100644 index f1af13d..0000000 --- a/playground/src/views/demos/features/tabs/index.vue +++ /dev/null @@ -1,105 +0,0 @@ - - - diff --git a/playground/src/views/demos/features/tabs/tab-detail.vue b/playground/src/views/demos/features/tabs/tab-detail.vue deleted file mode 100644 index c03b61c..0000000 --- a/playground/src/views/demos/features/tabs/tab-detail.vue +++ /dev/null @@ -1,23 +0,0 @@ - - - diff --git a/playground/src/views/demos/features/vue-query/concurrency-caching.vue b/playground/src/views/demos/features/vue-query/concurrency-caching.vue deleted file mode 100644 index 1e0f328..0000000 --- a/playground/src/views/demos/features/vue-query/concurrency-caching.vue +++ /dev/null @@ -1,61 +0,0 @@ - - diff --git a/playground/src/views/demos/features/vue-query/index.vue b/playground/src/views/demos/features/vue-query/index.vue deleted file mode 100644 index 3077f6f..0000000 --- a/playground/src/views/demos/features/vue-query/index.vue +++ /dev/null @@ -1,40 +0,0 @@ - - - diff --git a/playground/src/views/demos/features/vue-query/infinite-queries.vue b/playground/src/views/demos/features/vue-query/infinite-queries.vue deleted file mode 100644 index 2add4c1..0000000 --- a/playground/src/views/demos/features/vue-query/infinite-queries.vue +++ /dev/null @@ -1,58 +0,0 @@ - - - diff --git a/playground/src/views/demos/features/vue-query/paginated-queries.vue b/playground/src/views/demos/features/vue-query/paginated-queries.vue deleted file mode 100644 index a29e4b9..0000000 --- a/playground/src/views/demos/features/vue-query/paginated-queries.vue +++ /dev/null @@ -1,53 +0,0 @@ - - - diff --git a/playground/src/views/demos/features/vue-query/query-retries.vue b/playground/src/views/demos/features/vue-query/query-retries.vue deleted file mode 100644 index 0080386..0000000 --- a/playground/src/views/demos/features/vue-query/query-retries.vue +++ /dev/null @@ -1,34 +0,0 @@ - - - diff --git a/playground/src/views/demos/features/vue-query/typing.ts b/playground/src/views/demos/features/vue-query/typing.ts deleted file mode 100644 index 95558dd..0000000 --- a/playground/src/views/demos/features/vue-query/typing.ts +++ /dev/null @@ -1,18 +0,0 @@ -export interface IProducts { - limit: number; - products: { - brand: string; - category: string; - description: string; - discountPercentage: string; - id: string; - images: string[]; - price: string; - rating: string; - stock: string; - thumbnail: string; - title: string; - }[]; - skip: number; - total: number; -} diff --git a/playground/src/views/demos/features/watermark/index.vue b/playground/src/views/demos/features/watermark/index.vue deleted file mode 100644 index 3041e90..0000000 --- a/playground/src/views/demos/features/watermark/index.vue +++ /dev/null @@ -1,86 +0,0 @@ - - - diff --git a/playground/src/views/demos/nested/menu-1.vue b/playground/src/views/demos/nested/menu-1.vue deleted file mode 100644 index f394930..0000000 --- a/playground/src/views/demos/nested/menu-1.vue +++ /dev/null @@ -1,7 +0,0 @@ - - - diff --git a/playground/src/views/demos/nested/menu-2-1.vue b/playground/src/views/demos/nested/menu-2-1.vue deleted file mode 100644 index f394930..0000000 --- a/playground/src/views/demos/nested/menu-2-1.vue +++ /dev/null @@ -1,7 +0,0 @@ - - - diff --git a/playground/src/views/demos/nested/menu-3-1.vue b/playground/src/views/demos/nested/menu-3-1.vue deleted file mode 100644 index f394930..0000000 --- a/playground/src/views/demos/nested/menu-3-1.vue +++ /dev/null @@ -1,7 +0,0 @@ - - - diff --git a/playground/src/views/demos/nested/menu-3-2-1.vue b/playground/src/views/demos/nested/menu-3-2-1.vue deleted file mode 100644 index f394930..0000000 --- a/playground/src/views/demos/nested/menu-3-2-1.vue +++ /dev/null @@ -1,7 +0,0 @@ - - - diff --git a/playground/src/views/examples/button-group/index.vue b/playground/src/views/examples/button-group/index.vue deleted file mode 100644 index 23861da..0000000 --- a/playground/src/views/examples/button-group/index.vue +++ /dev/null @@ -1,229 +0,0 @@ - - diff --git a/playground/src/views/examples/captcha/point-selection-captcha.vue b/playground/src/views/examples/captcha/point-selection-captcha.vue deleted file mode 100644 index 498a977..0000000 --- a/playground/src/views/examples/captcha/point-selection-captcha.vue +++ /dev/null @@ -1,181 +0,0 @@ - - - diff --git a/playground/src/views/examples/captcha/slider-captcha.vue b/playground/src/views/examples/captcha/slider-captcha.vue deleted file mode 100644 index ee91966..0000000 --- a/playground/src/views/examples/captcha/slider-captcha.vue +++ /dev/null @@ -1,117 +0,0 @@ - - - diff --git a/playground/src/views/examples/captcha/slider-rotate-captcha.vue b/playground/src/views/examples/captcha/slider-rotate-captcha.vue deleted file mode 100644 index 67e6d6e..0000000 --- a/playground/src/views/examples/captcha/slider-rotate-captcha.vue +++ /dev/null @@ -1,28 +0,0 @@ - - - diff --git a/playground/src/views/examples/captcha/slider-translate-captcha.vue b/playground/src/views/examples/captcha/slider-translate-captcha.vue deleted file mode 100644 index 1d2cc08..0000000 --- a/playground/src/views/examples/captcha/slider-translate-captcha.vue +++ /dev/null @@ -1,27 +0,0 @@ - - - diff --git a/playground/src/views/examples/context-menu/index.vue b/playground/src/views/examples/context-menu/index.vue deleted file mode 100644 index 711b4c6..0000000 --- a/playground/src/views/examples/context-menu/index.vue +++ /dev/null @@ -1,59 +0,0 @@ - - - diff --git a/playground/src/views/examples/count-to/index.vue b/playground/src/views/examples/count-to/index.vue deleted file mode 100644 index 4b73833..0000000 --- a/playground/src/views/examples/count-to/index.vue +++ /dev/null @@ -1,178 +0,0 @@ - - diff --git a/playground/src/views/examples/cropper/index.vue b/playground/src/views/examples/cropper/index.vue deleted file mode 100644 index 09ba10c..0000000 --- a/playground/src/views/examples/cropper/index.vue +++ /dev/null @@ -1,144 +0,0 @@ - - - diff --git a/playground/src/views/examples/doc-button.vue b/playground/src/views/examples/doc-button.vue deleted file mode 100644 index 4dad2a8..0000000 --- a/playground/src/views/examples/doc-button.vue +++ /dev/null @@ -1,22 +0,0 @@ - - - diff --git a/playground/src/views/examples/drawer/auto-height-demo.vue b/playground/src/views/examples/drawer/auto-height-demo.vue deleted file mode 100644 index 676a537..0000000 --- a/playground/src/views/examples/drawer/auto-height-demo.vue +++ /dev/null @@ -1,47 +0,0 @@ - - diff --git a/playground/src/views/examples/drawer/base-demo.vue b/playground/src/views/examples/drawer/base-demo.vue deleted file mode 100644 index 08bc68f..0000000 --- a/playground/src/views/examples/drawer/base-demo.vue +++ /dev/null @@ -1,35 +0,0 @@ - - diff --git a/playground/src/views/examples/drawer/dynamic-demo.vue b/playground/src/views/examples/drawer/dynamic-demo.vue deleted file mode 100644 index ce5560f..0000000 --- a/playground/src/views/examples/drawer/dynamic-demo.vue +++ /dev/null @@ -1,31 +0,0 @@ - - diff --git a/playground/src/views/examples/drawer/form-drawer-demo.vue b/playground/src/views/examples/drawer/form-drawer-demo.vue deleted file mode 100644 index 5af392f..0000000 --- a/playground/src/views/examples/drawer/form-drawer-demo.vue +++ /dev/null @@ -1,56 +0,0 @@ - - diff --git a/playground/src/views/examples/drawer/in-content-demo.vue b/playground/src/views/examples/drawer/in-content-demo.vue deleted file mode 100644 index f67b978..0000000 --- a/playground/src/views/examples/drawer/in-content-demo.vue +++ /dev/null @@ -1,48 +0,0 @@ - - diff --git a/playground/src/views/examples/drawer/index.vue b/playground/src/views/examples/drawer/index.vue deleted file mode 100644 index 4aaa779..0000000 --- a/playground/src/views/examples/drawer/index.vue +++ /dev/null @@ -1,195 +0,0 @@ - - - diff --git a/playground/src/views/examples/drawer/shared-data-demo.vue b/playground/src/views/examples/drawer/shared-data-demo.vue deleted file mode 100644 index d542273..0000000 --- a/playground/src/views/examples/drawer/shared-data-demo.vue +++ /dev/null @@ -1,29 +0,0 @@ - - diff --git a/playground/src/views/examples/ellipsis/index.vue b/playground/src/views/examples/ellipsis/index.vue deleted file mode 100644 index b88c819..0000000 --- a/playground/src/views/examples/ellipsis/index.vue +++ /dev/null @@ -1,46 +0,0 @@ - - - diff --git a/playground/src/views/examples/form/api.vue b/playground/src/views/examples/form/api.vue deleted file mode 100644 index a7e15a0..0000000 --- a/playground/src/views/examples/form/api.vue +++ /dev/null @@ -1,274 +0,0 @@ - - - diff --git a/playground/src/views/examples/form/basic.vue b/playground/src/views/examples/form/basic.vue deleted file mode 100644 index d8fde46..0000000 --- a/playground/src/views/examples/form/basic.vue +++ /dev/null @@ -1,518 +0,0 @@ - - - diff --git a/playground/src/views/examples/form/custom-layout.vue b/playground/src/views/examples/form/custom-layout.vue deleted file mode 100644 index cd7146b..0000000 --- a/playground/src/views/examples/form/custom-layout.vue +++ /dev/null @@ -1,111 +0,0 @@ - - - diff --git a/playground/src/views/examples/form/custom.vue b/playground/src/views/examples/form/custom.vue deleted file mode 100644 index 7fab17a..0000000 --- a/playground/src/views/examples/form/custom.vue +++ /dev/null @@ -1,100 +0,0 @@ - - - diff --git a/playground/src/views/examples/form/dynamic.vue b/playground/src/views/examples/form/dynamic.vue deleted file mode 100644 index c11a3c1..0000000 --- a/playground/src/views/examples/form/dynamic.vue +++ /dev/null @@ -1,262 +0,0 @@ - - - diff --git a/playground/src/views/examples/form/merge.vue b/playground/src/views/examples/form/merge.vue deleted file mode 100644 index 95a37c6..0000000 --- a/playground/src/views/examples/form/merge.vue +++ /dev/null @@ -1,116 +0,0 @@ - - - diff --git a/playground/src/views/examples/form/modules/two-fields.vue b/playground/src/views/examples/form/modules/two-fields.vue deleted file mode 100644 index 6779101..0000000 --- a/playground/src/views/examples/form/modules/two-fields.vue +++ /dev/null @@ -1,42 +0,0 @@ - - diff --git a/playground/src/views/examples/form/query.vue b/playground/src/views/examples/form/query.vue deleted file mode 100644 index 5efae67..0000000 --- a/playground/src/views/examples/form/query.vue +++ /dev/null @@ -1,276 +0,0 @@ - - - diff --git a/playground/src/views/examples/form/rules.vue b/playground/src/views/examples/form/rules.vue deleted file mode 100644 index 7ec9549..0000000 --- a/playground/src/views/examples/form/rules.vue +++ /dev/null @@ -1,245 +0,0 @@ - - - diff --git a/playground/src/views/examples/form/scroll-to-error-test.vue b/playground/src/views/examples/form/scroll-to-error-test.vue deleted file mode 100644 index 1a78248..0000000 --- a/playground/src/views/examples/form/scroll-to-error-test.vue +++ /dev/null @@ -1,180 +0,0 @@ - - - diff --git a/playground/src/views/examples/json-viewer/data.ts b/playground/src/views/examples/json-viewer/data.ts deleted file mode 100644 index b2bb402..0000000 --- a/playground/src/views/examples/json-viewer/data.ts +++ /dev/null @@ -1,66 +0,0 @@ -export const json1 = { - additionalInfo: { - author: 'Your Name', - debug: true, - version: '1.3.10', - versionCode: 132, - }, - additionalNotes: 'This JSON is used for demonstration purposes', - tools: [ - { - description: 'Description of Tool 1', - name: 'Tool 1', - }, - { - description: 'Description of Tool 2', - name: 'Tool 2', - }, - { - description: 'Description of Tool 3', - name: 'Tool 3', - }, - { - description: 'Description of Tool 4', - name: 'Tool 4', - }, - ], -}; - -export const json2 = JSON.parse(` - { - "id": "chatgpt-123", - "object": "chat.completion", - "created": 1677652288, - "model": "gpt-3.5-turbo-0613", - "system_fingerprint": "fp_44709d6fcb", - "choices": [{ - "index": 0, - "message": { - "role": "assistant", - "content": "Hello there, how may I assist you today?" - }, - "finish_reason": "stop" - }], - "usage": { - "prompt_tokens": 9, - "completion_tokens": 12, - "total_tokens": 21, - "debug_mode": true - }, - "debug": { - "startAt": "2021-08-01T00:00:00Z", - "logs": [ - { - "timestamp": "2021-08-01T00:00:00Z", - "message": "This is a debug message", - "extra":[ "extra1", "extra2" ] - }, - { - "timestamp": "2021-08-01T00:00:01Z", - "message": "This is another debug message", - "extra":[ "extra3", "extra4" ] - } - ] - } -} - `); diff --git a/playground/src/views/examples/json-viewer/index.vue b/playground/src/views/examples/json-viewer/index.vue deleted file mode 100644 index a91e042..0000000 --- a/playground/src/views/examples/json-viewer/index.vue +++ /dev/null @@ -1,51 +0,0 @@ - - diff --git a/playground/src/views/examples/layout/col-page.vue b/playground/src/views/examples/layout/col-page.vue deleted file mode 100644 index 1da8d24..0000000 --- a/playground/src/views/examples/layout/col-page.vue +++ /dev/null @@ -1,104 +0,0 @@ - - diff --git a/playground/src/views/examples/loading/index.vue b/playground/src/views/examples/loading/index.vue deleted file mode 100644 index ff5152a..0000000 --- a/playground/src/views/examples/loading/index.vue +++ /dev/null @@ -1,92 +0,0 @@ - - diff --git a/playground/src/views/examples/modal/auto-height-demo.vue b/playground/src/views/examples/modal/auto-height-demo.vue deleted file mode 100644 index b44664b..0000000 --- a/playground/src/views/examples/modal/auto-height-demo.vue +++ /dev/null @@ -1,49 +0,0 @@ - - - diff --git a/playground/src/views/examples/modal/base-demo.vue b/playground/src/views/examples/modal/base-demo.vue deleted file mode 100644 index 8b3e608..0000000 --- a/playground/src/views/examples/modal/base-demo.vue +++ /dev/null @@ -1,34 +0,0 @@ - - diff --git a/playground/src/views/examples/modal/blur-demo.vue b/playground/src/views/examples/modal/blur-demo.vue deleted file mode 100644 index 432ce0d..0000000 --- a/playground/src/views/examples/modal/blur-demo.vue +++ /dev/null @@ -1,23 +0,0 @@ - - diff --git a/playground/src/views/examples/modal/drag-demo.vue b/playground/src/views/examples/modal/drag-demo.vue deleted file mode 100644 index 4520303..0000000 --- a/playground/src/views/examples/modal/drag-demo.vue +++ /dev/null @@ -1,19 +0,0 @@ - - diff --git a/playground/src/views/examples/modal/dynamic-demo.vue b/playground/src/views/examples/modal/dynamic-demo.vue deleted file mode 100644 index 33d1c4e..0000000 --- a/playground/src/views/examples/modal/dynamic-demo.vue +++ /dev/null @@ -1,41 +0,0 @@ - - diff --git a/playground/src/views/examples/modal/form-modal-demo.vue b/playground/src/views/examples/modal/form-modal-demo.vue deleted file mode 100644 index 6d58aa1..0000000 --- a/playground/src/views/examples/modal/form-modal-demo.vue +++ /dev/null @@ -1,91 +0,0 @@ - - diff --git a/playground/src/views/examples/modal/in-content-demo.vue b/playground/src/views/examples/modal/in-content-demo.vue deleted file mode 100644 index 9ab3145..0000000 --- a/playground/src/views/examples/modal/in-content-demo.vue +++ /dev/null @@ -1,30 +0,0 @@ - - diff --git a/playground/src/views/examples/modal/index.vue b/playground/src/views/examples/modal/index.vue deleted file mode 100644 index 31412e7..0000000 --- a/playground/src/views/examples/modal/index.vue +++ /dev/null @@ -1,278 +0,0 @@ - - - diff --git a/playground/src/views/examples/modal/nested-demo.vue b/playground/src/views/examples/modal/nested-demo.vue deleted file mode 100644 index 6251fd0..0000000 --- a/playground/src/views/examples/modal/nested-demo.vue +++ /dev/null @@ -1,24 +0,0 @@ - - diff --git a/playground/src/views/examples/modal/shared-data-demo.vue b/playground/src/views/examples/modal/shared-data-demo.vue deleted file mode 100644 index 8ba6e7e..0000000 --- a/playground/src/views/examples/modal/shared-data-demo.vue +++ /dev/null @@ -1,29 +0,0 @@ - - diff --git a/playground/src/views/examples/motion/index.vue b/playground/src/views/examples/motion/index.vue deleted file mode 100644 index 405b536..0000000 --- a/playground/src/views/examples/motion/index.vue +++ /dev/null @@ -1,207 +0,0 @@ - - diff --git a/playground/src/views/examples/resize/basic.vue b/playground/src/views/examples/resize/basic.vue deleted file mode 100644 index 7894e7f..0000000 --- a/playground/src/views/examples/resize/basic.vue +++ /dev/null @@ -1,58 +0,0 @@ - - - diff --git a/playground/src/views/examples/tippy/index.vue b/playground/src/views/examples/tippy/index.vue deleted file mode 100644 index f4449c3..0000000 --- a/playground/src/views/examples/tippy/index.vue +++ /dev/null @@ -1,303 +0,0 @@ - - diff --git a/playground/src/views/examples/vxe-table/basic.vue b/playground/src/views/examples/vxe-table/basic.vue deleted file mode 100644 index d204724..0000000 --- a/playground/src/views/examples/vxe-table/basic.vue +++ /dev/null @@ -1,111 +0,0 @@ - - - diff --git a/playground/src/views/examples/vxe-table/custom-cell.vue b/playground/src/views/examples/vxe-table/custom-cell.vue deleted file mode 100644 index 2625880..0000000 --- a/playground/src/views/examples/vxe-table/custom-cell.vue +++ /dev/null @@ -1,108 +0,0 @@ - - - diff --git a/playground/src/views/examples/vxe-table/edit-cell.vue b/playground/src/views/examples/vxe-table/edit-cell.vue deleted file mode 100644 index 9aebde8..0000000 --- a/playground/src/views/examples/vxe-table/edit-cell.vue +++ /dev/null @@ -1,57 +0,0 @@ - - - diff --git a/playground/src/views/examples/vxe-table/edit-row.vue b/playground/src/views/examples/vxe-table/edit-row.vue deleted file mode 100644 index f9d25ca..0000000 --- a/playground/src/views/examples/vxe-table/edit-row.vue +++ /dev/null @@ -1,94 +0,0 @@ - - - diff --git a/playground/src/views/examples/vxe-table/fixed.vue b/playground/src/views/examples/vxe-table/fixed.vue deleted file mode 100644 index 399d352..0000000 --- a/playground/src/views/examples/vxe-table/fixed.vue +++ /dev/null @@ -1,69 +0,0 @@ - - - diff --git a/playground/src/views/examples/vxe-table/form.vue b/playground/src/views/examples/vxe-table/form.vue deleted file mode 100644 index 95de704..0000000 --- a/playground/src/views/examples/vxe-table/form.vue +++ /dev/null @@ -1,127 +0,0 @@ - - - diff --git a/playground/src/views/examples/vxe-table/remote.vue b/playground/src/views/examples/vxe-table/remote.vue deleted file mode 100644 index 7042019..0000000 --- a/playground/src/views/examples/vxe-table/remote.vue +++ /dev/null @@ -1,81 +0,0 @@ - - - diff --git a/playground/src/views/examples/vxe-table/table-data.ts b/playground/src/views/examples/vxe-table/table-data.ts deleted file mode 100644 index b4eb5ed..0000000 --- a/playground/src/views/examples/vxe-table/table-data.ts +++ /dev/null @@ -1,172 +0,0 @@ -interface TableRowData { - address: string; - age: number; - id: number; - name: string; - nickname: string; - role: string; -} - -const roles = ['User', 'Admin', 'Manager', 'Guest']; - -export const MOCK_TABLE_DATA: TableRowData[] = (() => { - const data: TableRowData[] = []; - for (let i = 0; i < 40; i++) { - data.push({ - address: `New York${i}`, - age: i + 1, - id: i, - name: `Test${i}`, - nickname: `Test${i}`, - role: roles[Math.floor(Math.random() * roles.length)] as string, - }); - } - return data; -})(); - -export const MOCK_TREE_TABLE_DATA = [ - { - date: '2020-08-01', - id: 10_000, - name: 'Test1', - parentId: null, - size: 1024, - type: 'mp3', - }, - { - date: '2021-04-01', - id: 10_050, - name: 'Test2', - parentId: null, - size: 0, - type: 'mp4', - }, - { - date: '2020-03-01', - id: 24_300, - name: 'Test3', - parentId: 10_050, - size: 1024, - type: 'avi', - }, - { - date: '2021-04-01', - id: 20_045, - name: 'Test4', - parentId: 24_300, - size: 600, - type: 'html', - }, - { - date: '2021-04-01', - id: 10_053, - name: 'Test5', - parentId: 24_300, - size: 0, - type: 'avi', - }, - { - date: '2021-10-01', - id: 24_330, - name: 'Test6', - parentId: 10_053, - size: 25, - type: 'txt', - }, - { - date: '2020-01-01', - id: 21_011, - name: 'Test7', - parentId: 10_053, - size: 512, - type: 'pdf', - }, - { - date: '2021-06-01', - id: 22_200, - name: 'Test8', - parentId: 10_053, - size: 1024, - type: 'js', - }, - { - date: '2020-11-01', - id: 23_666, - name: 'Test9', - parentId: null, - size: 2048, - type: 'xlsx', - }, - { - date: '2021-06-01', - id: 23_677, - name: 'Test10', - parentId: 23_666, - size: 1024, - type: 'js', - }, - { - date: '2021-06-01', - id: 23_671, - name: 'Test11', - parentId: 23_677, - size: 1024, - type: 'js', - }, - { - date: '2021-06-01', - id: 23_672, - name: 'Test12', - parentId: 23_677, - size: 1024, - type: 'js', - }, - { - date: '2021-06-01', - id: 23_688, - name: 'Test13', - parentId: 23_666, - size: 1024, - type: 'js', - }, - { - date: '2021-06-01', - id: 23_681, - name: 'Test14', - parentId: 23_688, - size: 1024, - type: 'js', - }, - { - date: '2021-06-01', - id: 23_682, - name: 'Test15', - parentId: 23_688, - size: 1024, - type: 'js', - }, - { - date: '2020-10-01', - id: 24_555, - name: 'Test16', - parentId: null, - size: 224, - type: 'avi', - }, - { - date: '2021-06-01', - id: 24_566, - name: 'Test17', - parentId: 24_555, - size: 1024, - type: 'js', - }, - { - date: '2021-06-01', - id: 24_577, - name: 'Test18', - parentId: 24_555, - size: 1024, - type: 'js', - }, -]; diff --git a/playground/src/views/examples/vxe-table/tree.vue b/playground/src/views/examples/vxe-table/tree.vue deleted file mode 100644 index c8a1df4..0000000 --- a/playground/src/views/examples/vxe-table/tree.vue +++ /dev/null @@ -1,62 +0,0 @@ - - - diff --git a/playground/src/views/examples/vxe-table/virtual.vue b/playground/src/views/examples/vxe-table/virtual.vue deleted file mode 100644 index f35a691..0000000 --- a/playground/src/views/examples/vxe-table/virtual.vue +++ /dev/null @@ -1,66 +0,0 @@ - - - diff --git a/playground/src/views/system/dept/data.ts b/playground/src/views/system/dept/data.ts deleted file mode 100644 index b0699e7..0000000 --- a/playground/src/views/system/dept/data.ts +++ /dev/null @@ -1,135 +0,0 @@ -import type { VxeTableGridColumns } from '@vben/plugins/vxe-table'; - -import type { VbenFormSchema } from '#/adapter/form'; -import type { OnActionClickFn } from '#/adapter/vxe-table'; -import type { SystemDeptApi } from '#/api/system/dept'; - -import { z } from '#/adapter/form'; -import { getDeptList } from '#/api/system/dept'; -import { $t } from '#/locales'; - -/** - * 获取编辑表单的字段配置。如果没有使用多语言,可以直接export一个数组常量 - */ -export function useSchema(): VbenFormSchema[] { - return [ - { - component: 'Input', - fieldName: 'name', - label: $t('system.dept.deptName'), - rules: z - .string() - .min(2, $t('ui.formRules.minLength', [$t('system.dept.deptName'), 2])) - .max( - 20, - $t('ui.formRules.maxLength', [$t('system.dept.deptName'), 20]), - ), - }, - { - component: 'ApiTreeSelect', - componentProps: { - allowClear: true, - api: getDeptList, - class: 'w-full', - labelField: 'name', - valueField: 'id', - childrenField: 'children', - }, - fieldName: 'pid', - label: $t('system.dept.parentDept'), - }, - { - component: 'RadioGroup', - componentProps: { - buttonStyle: 'solid', - options: [ - { label: $t('common.enabled'), value: 1 }, - { label: $t('common.disabled'), value: 0 }, - ], - optionType: 'button', - }, - defaultValue: 1, - fieldName: 'status', - label: $t('system.dept.status'), - }, - { - component: 'Textarea', - componentProps: { - maxLength: 50, - rows: 3, - showCount: true, - }, - fieldName: 'remark', - label: $t('system.dept.remark'), - rules: z - .string() - .max(50, $t('ui.formRules.maxLength', [$t('system.dept.remark'), 50])) - .optional(), - }, - ]; -} - -/** - * 获取表格列配置 - * @description 使用函数的形式返回列数据而不是直接export一个Array常量,是为了响应语言切换时重新翻译表头 - * @param onActionClick 表格操作按钮点击事件 - */ -export function useColumns( - onActionClick?: OnActionClickFn, -): VxeTableGridColumns { - return [ - { - align: 'left', - field: 'name', - fixed: 'left', - title: $t('system.dept.deptName'), - treeNode: true, - width: 150, - }, - { - cellRender: { name: 'CellTag' }, - field: 'status', - title: $t('system.dept.status'), - width: 100, - }, - { - field: 'createTime', - title: $t('system.dept.createTime'), - width: 180, - }, - { - field: 'remark', - title: $t('system.dept.remark'), - }, - { - align: 'right', - cellRender: { - attrs: { - nameField: 'name', - nameTitle: $t('system.dept.name'), - onClick: onActionClick, - }, - name: 'CellOperation', - options: [ - { - code: 'append', - text: '新增下级', - }, - 'edit', // 默认的编辑按钮 - { - code: 'delete', // 默认的删除按钮 - disabled: (row: SystemDeptApi.SystemDept) => { - return !!(row.children && row.children.length > 0); - }, - }, - ], - }, - field: 'operation', - fixed: 'right', - headerAlign: 'center', - showOverflow: false, - title: $t('system.dept.operation'), - width: 200, - }, - ]; -} diff --git a/playground/src/views/system/dept/list.vue b/playground/src/views/system/dept/list.vue deleted file mode 100644 index 13d45a6..0000000 --- a/playground/src/views/system/dept/list.vue +++ /dev/null @@ -1,143 +0,0 @@ - - diff --git a/playground/src/views/system/dept/modules/form.vue b/playground/src/views/system/dept/modules/form.vue deleted file mode 100644 index 18a1396..0000000 --- a/playground/src/views/system/dept/modules/form.vue +++ /dev/null @@ -1,78 +0,0 @@ - - - diff --git a/playground/src/views/system/menu/data.ts b/playground/src/views/system/menu/data.ts deleted file mode 100644 index 11aa2bd..0000000 --- a/playground/src/views/system/menu/data.ts +++ /dev/null @@ -1,109 +0,0 @@ -import type { OnActionClickFn, VxeTableGridColumns } from '#/adapter/vxe-table'; -import type { SystemMenuApi } from '#/api/system/menu'; - -import { $t } from '#/locales'; - -export function getMenuTypeOptions() { - return [ - { - color: 'processing', - label: $t('system.menu.typeCatalog'), - value: 'catalog', - }, - { color: 'default', label: $t('system.menu.typeMenu'), value: 'menu' }, - { color: 'error', label: $t('system.menu.typeButton'), value: 'button' }, - { - color: 'success', - label: $t('system.menu.typeEmbedded'), - value: 'embedded', - }, - { color: 'warning', label: $t('system.menu.typeLink'), value: 'link' }, - ]; -} - -export function useColumns( - onActionClick: OnActionClickFn, -): VxeTableGridColumns { - return [ - { - align: 'left', - field: 'meta.title', - fixed: 'left', - slots: { default: 'title' }, - title: $t('system.menu.menuTitle'), - treeNode: true, - width: 250, - }, - { - align: 'center', - cellRender: { name: 'CellTag', options: getMenuTypeOptions() }, - field: 'type', - title: $t('system.menu.type'), - width: 100, - }, - { - field: 'authCode', - title: $t('system.menu.authCode'), - width: 200, - }, - { - align: 'left', - field: 'path', - title: $t('system.menu.path'), - width: 200, - }, - - { - align: 'left', - field: 'component', - formatter: ({ row }) => { - switch (row.type) { - case 'catalog': - case 'menu': { - return row.component ?? ''; - } - case 'embedded': { - return row.meta?.iframeSrc ?? ''; - } - case 'link': { - return row.meta?.link ?? ''; - } - } - return ''; - }, - minWidth: 200, - title: $t('system.menu.component'), - }, - { - cellRender: { name: 'CellTag' }, - field: 'status', - title: $t('system.menu.status'), - width: 100, - }, - - { - align: 'right', - cellRender: { - attrs: { - nameField: 'name', - onClick: onActionClick, - }, - name: 'CellOperation', - options: [ - { - code: 'append', - text: '新增下级', - }, - 'edit', // 默认的编辑按钮 - 'delete', // 默认的删除按钮 - ], - }, - field: 'operation', - fixed: 'right', - headerAlign: 'center', - showOverflow: false, - title: $t('system.menu.operation'), - width: 200, - }, - ]; -} diff --git a/playground/src/views/system/menu/list.vue b/playground/src/views/system/menu/list.vue deleted file mode 100644 index 7152435..0000000 --- a/playground/src/views/system/menu/list.vue +++ /dev/null @@ -1,162 +0,0 @@ - - - diff --git a/playground/src/views/system/menu/modules/form.vue b/playground/src/views/system/menu/modules/form.vue deleted file mode 100644 index be521d2..0000000 --- a/playground/src/views/system/menu/modules/form.vue +++ /dev/null @@ -1,504 +0,0 @@ - - diff --git a/playground/src/views/system/role/data.ts b/playground/src/views/system/role/data.ts deleted file mode 100644 index 9c9d0fb..0000000 --- a/playground/src/views/system/role/data.ts +++ /dev/null @@ -1,127 +0,0 @@ -import type { VbenFormSchema } from '#/adapter/form'; -import type { OnActionClickFn, VxeTableGridColumns } from '#/adapter/vxe-table'; -import type { SystemRoleApi } from '#/api'; - -import { $t } from '#/locales'; - -export function useFormSchema(): VbenFormSchema[] { - return [ - { - component: 'Input', - fieldName: 'name', - label: $t('system.role.roleName'), - rules: 'required', - }, - { - component: 'RadioGroup', - componentProps: { - buttonStyle: 'solid', - options: [ - { label: $t('common.enabled'), value: 1 }, - { label: $t('common.disabled'), value: 0 }, - ], - optionType: 'button', - }, - defaultValue: 1, - fieldName: 'status', - label: $t('system.role.status'), - }, - { - component: 'Textarea', - fieldName: 'remark', - label: $t('system.role.remark'), - }, - { - component: 'Input', - fieldName: 'permissions', - formItemClass: 'items-start', - label: $t('system.role.setPermissions'), - modelPropName: 'modelValue', - }, - ]; -} - -export function useGridFormSchema(): VbenFormSchema[] { - return [ - { - component: 'Input', - fieldName: 'name', - label: $t('system.role.roleName'), - }, - { component: 'Input', fieldName: 'id', label: $t('system.role.id') }, - { - component: 'Select', - componentProps: { - allowClear: true, - options: [ - { label: $t('common.enabled'), value: 1 }, - { label: $t('common.disabled'), value: 0 }, - ], - }, - fieldName: 'status', - label: $t('system.role.status'), - }, - { - component: 'Input', - fieldName: 'remark', - label: $t('system.role.remark'), - }, - { - component: 'RangePicker', - fieldName: 'createTime', - label: $t('system.role.createTime'), - }, - ]; -} - -export function useColumns( - onActionClick: OnActionClickFn, - onStatusChange?: (newStatus: any, row: T) => PromiseLike, -): VxeTableGridColumns { - return [ - { - field: 'name', - title: $t('system.role.roleName'), - width: 200, - }, - { - field: 'id', - title: $t('system.role.id'), - width: 200, - }, - { - cellRender: { - attrs: { beforeChange: onStatusChange }, - name: onStatusChange ? 'CellSwitch' : 'CellTag', - }, - field: 'status', - title: $t('system.role.status'), - width: 100, - }, - { - field: 'remark', - minWidth: 100, - title: $t('system.role.remark'), - }, - { - field: 'createTime', - title: $t('system.role.createTime'), - width: 200, - }, - { - align: 'center', - cellRender: { - attrs: { - nameField: 'name', - nameTitle: $t('system.role.name'), - onClick: onActionClick, - }, - name: 'CellOperation', - }, - field: 'operation', - fixed: 'right', - title: $t('system.role.operation'), - width: 130, - }, - ]; -} diff --git a/playground/src/views/system/role/list.vue b/playground/src/views/system/role/list.vue deleted file mode 100644 index 4775c02..0000000 --- a/playground/src/views/system/role/list.vue +++ /dev/null @@ -1,164 +0,0 @@ - - diff --git a/playground/src/views/system/role/modules/form.vue b/playground/src/views/system/role/modules/form.vue deleted file mode 100644 index d3601e0..0000000 --- a/playground/src/views/system/role/modules/form.vue +++ /dev/null @@ -1,138 +0,0 @@ - - - diff --git a/playground/tsconfig.json b/playground/tsconfig.json deleted file mode 100644 index 858a0ec..0000000 --- a/playground/tsconfig.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "$schema": "https://json.schemastore.org/tsconfig", - "extends": "@vben/tsconfig/web-app.json", - "compilerOptions": { - "paths": { - "#/*": ["./src/*"] - } - }, - "references": [{ "path": "./tsconfig.node.json" }], - "include": ["src/**/*.ts", "src/**/*.tsx", "src/**/*.vue"] -} diff --git a/playground/tsconfig.node.json b/playground/tsconfig.node.json deleted file mode 100644 index 36e9fb5..0000000 --- a/playground/tsconfig.node.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "$schema": "https://json.schemastore.org/tsconfig", - "extends": "@vben/tsconfig/node.json", - "compilerOptions": { - "composite": true, - "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo", - "noEmit": false - }, - "include": ["vite.config.ts"] -} diff --git a/playground/vite.config.ts b/playground/vite.config.ts deleted file mode 100644 index b6360f1..0000000 --- a/playground/vite.config.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { defineConfig } from '@vben/vite-config'; - -export default defineConfig(async () => { - return { - application: {}, - vite: { - server: { - proxy: { - '/api': { - changeOrigin: true, - rewrite: (path) => path.replace(/^\/api/, ''), - // mock代理目标地址 - target: 'http://localhost:5320/api', - ws: true, - }, - }, - }, - }, - }; -}); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e5e5301..8b09411 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -45,9 +45,6 @@ catalogs: '@nolebase/vitepress-plugin-git-changelog': specifier: ^2.18.2 version: 2.18.2 - '@playwright/test': - specifier: ^1.58.2 - version: 1.58.2 '@pnpm/workspace.read-manifest': specifier: ^1000.3.0 version: 1000.3.0 @@ -60,9 +57,6 @@ catalogs: '@tailwindcss/vite': specifier: ^4.2.2 version: 4.2.2 - '@tanstack/vue-query': - specifier: ^5.95.0 - version: 5.95.0 '@tanstack/vue-store': specifier: ^0.9.2 version: 0.9.2 @@ -219,9 +213,6 @@ catalogs: find-up: specifier: ^8.0.0 version: 8.0.0 - get-port: - specifier: ^7.2.0 - version: 7.2.0 globals: specifier: ^17.4.0 version: 17.4.0 @@ -243,9 +234,6 @@ catalogs: medium-zoom: specifier: ^1.1.0 version: 1.1.0 - nitropack: - specifier: ^2.13.2 - version: 2.13.2 nprogress: specifier: ^0.2.0 version: 0.2.0 @@ -258,9 +246,6 @@ catalogs: pkg-types: specifier: ^2.3.0 version: 2.3.0 - playwright: - specifier: ^1.58.2 - version: 1.58.2 postcss: specifier: ^8.5.8 version: 8.5.8 @@ -444,9 +429,6 @@ importers: '@changesets/cli': specifier: 'catalog:' version: 2.30.0(@types/node@25.5.0) - '@playwright/test': - specifier: 'catalog:' - version: 1.58.2 '@tsdown/css': specifier: 'catalog:' version: 0.21.4(jiti@2.6.1)(postcss@8.5.8)(sass-embedded@1.98.0)(sass@1.98.0)(tsdown@0.21.4)(yaml@2.8.3) @@ -492,9 +474,6 @@ importers: happy-dom: specifier: 'catalog:' version: 20.8.4(bufferutil@4.1.0)(utf-8-validate@5.0.10) - playwright: - specifier: 'catalog:' - version: 1.58.2 rimraf: specifier: 'catalog:' version: 6.1.3 @@ -818,15 +797,9 @@ importers: cheerio: specifier: 'catalog:' version: 1.2.0 - get-port: - specifier: 'catalog:' - version: 7.2.0 html-minifier-terser: specifier: 'catalog:' version: 7.2.0 - nitropack: - specifier: 'catalog:' - version: 2.13.2(rolldown@1.0.0-rc.10)(xml2js@0.6.2) resolve.exports: specifier: 'catalog:' version: 2.0.3 @@ -1518,88 +1491,6 @@ importers: specifier: 'catalog:' version: 5.0.4(@vue/compiler-sfc@3.5.30)(pinia@3.0.4(typescript@5.9.3)(vue@3.5.30(typescript@5.9.3)))(vue@3.5.30(typescript@5.9.3)) - playground: - dependencies: - '@tanstack/vue-query': - specifier: 'catalog:' - version: 5.95.0(vue@3.5.30(typescript@5.9.3)) - '@vben-core/design': - specifier: workspace:* - version: link:../packages/@core/base/design - '@vben-core/menu-ui': - specifier: workspace:* - version: link:../packages/@core/ui-kit/menu-ui - '@vben-core/shadcn-ui': - specifier: workspace:* - version: link:../packages/@core/ui-kit/shadcn-ui - '@vben/access': - specifier: workspace:* - version: link:../packages/effects/access - '@vben/common-ui': - specifier: workspace:* - version: link:../packages/effects/common-ui - '@vben/constants': - specifier: workspace:* - version: link:../packages/constants - '@vben/hooks': - specifier: workspace:* - version: link:../packages/effects/hooks - '@vben/icons': - specifier: workspace:* - version: link:../packages/icons - '@vben/layouts': - specifier: workspace:* - version: link:../packages/effects/layouts - '@vben/locales': - specifier: workspace:* - version: link:../packages/locales - '@vben/plugins': - specifier: workspace:* - version: link:../packages/effects/plugins - '@vben/preferences': - specifier: workspace:* - version: link:../packages/preferences - '@vben/request': - specifier: workspace:* - version: link:../packages/effects/request - '@vben/stores': - specifier: workspace:* - version: link:../packages/stores - '@vben/styles': - specifier: workspace:* - version: link:../packages/styles - '@vben/types': - specifier: workspace:* - version: link:../packages/types - '@vben/utils': - specifier: workspace:* - version: link:../packages/utils - '@vueuse/core': - specifier: 'catalog:' - version: 14.2.1(vue@3.5.30(typescript@5.9.3)) - ant-design-vue: - specifier: 'catalog:' - version: 4.2.6(vue@3.5.30(typescript@5.9.3)) - dayjs: - specifier: 'catalog:' - version: 1.11.20 - json-bigint: - specifier: 'catalog:' - version: 1.0.0 - pinia: - specifier: ^3.0.4 - version: 3.0.4(typescript@5.9.3)(vue@3.5.30(typescript@5.9.3)) - vue: - specifier: ^3.5.30 - version: 3.5.30(typescript@5.9.3) - vue-router: - specifier: 'catalog:' - version: 5.0.4(@vue/compiler-sfc@3.5.30)(pinia@3.0.4(typescript@5.9.3)(vue@3.5.30(typescript@5.9.3)))(vue@3.5.30(typescript@5.9.3)) - devDependencies: - '@types/json-bigint': - specifier: 'catalog:' - version: 1.0.4 - scripts/turbo-run: dependencies: '@clack/prompts': @@ -2444,10 +2335,6 @@ packages: '@clack/prompts@1.1.0': resolution: {integrity: sha512-pkqbPGtohJAvm4Dphs2M8xE29ggupihHdy1x84HNojZuMtFsHiUlRvqD24tM2+XmI+61LlfNceM3Wr7U5QES5g==} - '@cloudflare/kv-asset-handler@0.4.2': - resolution: {integrity: sha512-SIOD2DxrRRwQ+jgzlXCqoEFiKOFqaPjhnNTGKXSRLvp1HiOvapLaFG2kEr9dYQTYe8rKrd9uvDUzmAITeNyaHQ==} - engines: {node: '>=18.0.0'} - '@cspell/cspell-bundled-dicts@9.7.0': resolution: {integrity: sha512-s7h1vo++Q3AsfQa3cs0u/KGwm3SYInuIlC4kjlCBWjQmb4KddiZB5O1u0+3TlA7GycHb5M4CR7MDfHUICgJf+w==} engines: {node: '>=20'} @@ -3405,9 +3292,6 @@ packages: vue-i18n: optional: true - '@ioredis/commands@1.5.1': - resolution: {integrity: sha512-JH8ZL/ywcJyR9MmJ5BNqZllXNZQqQbnVZOqpPQqE1vHiFgAw4NHbvE0FOduNU8IX9babitBT46571OnPTT0Zcw==} - '@isaacs/cliui@8.0.2': resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} engines: {node: '>=12'} @@ -3416,10 +3300,6 @@ packages: resolution: {integrity: sha512-AokJm4tuBHillT+FpMtxQ60n8ObyXBatq7jD2/JA9dxbDDokKQm8KMht5ibGzLVU9IJDIKK4TPKgMHEYMn3lMg==} engines: {node: '>=18'} - '@isaacs/fs-minipass@4.0.1': - resolution: {integrity: sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==} - engines: {node: '>=18.0.0'} - '@jridgewell/gen-mapping@0.3.13': resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==} @@ -3472,11 +3352,6 @@ packages: resolution: {integrity: sha512-0FOIepYR4ugPYaHwK7hDeHDkfPOBVvayt9QpvRbi2LT/h2b0GaE/gM9Gag7fsnyYyNaTZ2IGyOuVg07IYepvYQ==} engines: {node: '>=20.0.0'} - '@mapbox/node-pre-gyp@2.0.3': - resolution: {integrity: sha512-uwPAhccfFJlsfCxMYTwOdVfOz3xqyj8xYL3zJj8f0pb30tLohnnFPhLuqp4/qoEz8sNxe4SESZedcBojRefIzg==} - engines: {node: '>=18'} - hasBin: true - '@napi-rs/wasm-runtime@1.1.1': resolution: {integrity: sha512-p64ah1M1ld8xjWv3qbvFwHiFVWrq1yFvV4f7w+mzaqiR4IlSgkqhcRdHwsGgomwzBH51sRY4NEowLxnaBjcW/A==} @@ -3594,12 +3469,6 @@ packages: os: [linux] libc: [musl] - '@parcel/watcher-wasm@2.5.6': - resolution: {integrity: sha512-byAiBZ1t3tXQvc8dMD/eoyE7lTXYorhn+6uVW5AC+JGI1KtJC/LvDche5cfUE+qiefH+Ybq0bUCJU0aB1cSHUA==} - engines: {node: '>= 10.0.0'} - bundledDependencies: - - napi-wasm - '@parcel/watcher-win32-arm64@2.5.6': resolution: {integrity: sha512-3ukyebjc6eGlw9yRt678DxVF7rjXatWiHvTXqphZLvo7aC5NdEgFufVwjFfY51ijYEWpXbqF5jtrK275z52D4Q==} engines: {node: '>= 10.0.0'} @@ -3630,11 +3499,6 @@ packages: resolution: {integrity: sha512-QNqXyfVS2wm9hweSYD2O7F0G06uurj9kZ96TRQE5Y9hU7+tgdZwIkbAKc5Ocy1HxEY2kuDQa6cQ1WRs/O5LFKA==} engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} - '@playwright/test@1.58.2': - resolution: {integrity: sha512-akea+6bHYBBfA9uQqSYmlJXn61cTa+jbO87xVLCWbTqbWadRVmhxlXATaOjOgcBaWU4ePo0wB41KMFv3o35IXA==} - engines: {node: '>=18'} - hasBin: true - '@pnpm/config.env-replace@1.1.0': resolution: {integrity: sha512-htyl8TWnKL7K/ESFa1oW2UB5lVDxuF5DpM7tBi6Hu2LNL3mWkIzNLG6N4zoCUP1lCKNxWy/3iu8mS8MvToGd6w==} engines: {node: '>=12.22.0'} @@ -3669,15 +3533,6 @@ packages: '@popperjs/core@2.11.8': resolution: {integrity: sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==} - '@poppinss/colors@4.1.6': - resolution: {integrity: sha512-H9xkIdFswbS8n1d6vmRd8+c10t2Qe+rZITbbDHHkQixH5+2x1FDGmi/0K+WgWiqQFKPSlIYB7jlH6Kpfn6Fleg==} - - '@poppinss/dumper@0.7.0': - resolution: {integrity: sha512-0UTYalzk2t6S4rA2uHOz5bSSW2CHdv4vggJI6Alg90yvl0UgXs6XSXpH96OH+bRkX4J/06djv29pqXJ0lq5Kag==} - - '@poppinss/exception@1.2.3': - resolution: {integrity: sha512-dCED+QRChTVatE9ibtoaxc+WkdzOSjYTKi/+uacHWIsfodVfpsueo3+DKpgU5Px8qXjgmXkSvhXvSCz3fnP9lw==} - '@publint/pack@0.1.4': resolution: {integrity: sha512-HDVTWq3H0uTXiU0eeSQntcVUTPP3GamzeXI41+x7uU9J65JgWQh3qWZHblR1i0npXfFtF+mxBiU2nJH8znxWnQ==} engines: {node: '>=18'} @@ -3884,15 +3739,6 @@ packages: '@rolldown/pluginutils@1.0.0-rc.9': resolution: {integrity: sha512-w6oiRWgEBl04QkFZgmW+jnU1EC9b57Oihi2ot3HNWIQRqgHp5PnYDia5iZ5FF7rpa4EQdiqMDXjlqKGXBhsoXw==} - '@rollup/plugin-alias@6.0.0': - resolution: {integrity: sha512-tPCzJOtS7uuVZd+xPhoy5W4vThe6KWXNmsFCNktaAh5RTqcLiSfT4huPQIXkgJ6YCOjJHvecOAzQxLFhPxKr+g==} - engines: {node: '>=20.19.0'} - peerDependencies: - rollup: '>=4.0.0' - peerDependenciesMeta: - rollup: - optional: true - '@rollup/plugin-babel@5.3.1': resolution: {integrity: sha512-WFfdLWU/xVWKeRQnKmIAQULUI7Il0gZnBIH/ZFO069wYIfPu+8zrfp/KMW0atmELoRDq8FbiP3VCss9MhCut7Q==} engines: {node: '>= 10.0.0'} @@ -3904,33 +3750,6 @@ packages: '@types/babel__core': optional: true - '@rollup/plugin-commonjs@29.0.2': - resolution: {integrity: sha512-S/ggWH1LU7jTyi9DxZOKyxpVd4hF/OZ0JrEbeLjXk/DFXwRny0tjD2c992zOUYQobLrVkRVMDdmHP16HKP7GRg==} - engines: {node: '>=16.0.0 || 14 >= 14.17'} - peerDependencies: - rollup: ^2.68.0||^3.0.0||^4.0.0 - peerDependenciesMeta: - rollup: - optional: true - - '@rollup/plugin-inject@5.0.5': - resolution: {integrity: sha512-2+DEJbNBoPROPkgTDNe8/1YXWcqxbN5DTjASVIOx8HS+pITXushyNiBV56RB08zuptzz8gT3YfkqriTBVycepg==} - engines: {node: '>=14.0.0'} - peerDependencies: - rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 - peerDependenciesMeta: - rollup: - optional: true - - '@rollup/plugin-json@6.1.0': - resolution: {integrity: sha512-EGI2te5ENk1coGeADSIwZ7G2Q8CJS2sF120T7jLw4xFw9n7wIOXHo+kIYRAoVpJAN+kmqZSoO3Fp4JtoNF4ReA==} - engines: {node: '>=14.0.0'} - peerDependencies: - rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 - peerDependenciesMeta: - rollup: - optional: true - '@rollup/plugin-node-resolve@15.3.1': resolution: {integrity: sha512-tgg6b91pAybXHJQMAAwW9VuWBO6Thi+q7BCNARLwSqlmsHz0XYURtGvh/AuwSADXSI4h/2uHbs7s4FzlZDGSGA==} engines: {node: '>=14.0.0'} @@ -3940,29 +3759,11 @@ packages: rollup: optional: true - '@rollup/plugin-node-resolve@16.0.3': - resolution: {integrity: sha512-lUYM3UBGuM93CnMPG1YocWu7X802BrNF3jW2zny5gQyLQgRFJhV1Sq0Zi74+dh/6NBx1DxFC4b4GXg9wUCG5Qg==} - engines: {node: '>=14.0.0'} - peerDependencies: - rollup: ^2.78.0||^3.0.0||^4.0.0 - peerDependenciesMeta: - rollup: - optional: true - '@rollup/plugin-replace@2.4.2': resolution: {integrity: sha512-IGcu+cydlUMZ5En85jxHH4qj2hta/11BHq95iHEyb2sbgiN0eCdzvUcHw5gt9pBL5lTi4JDYJ1acCoMGpTvEZg==} peerDependencies: rollup: ^1.20.0 || ^2.0.0 - '@rollup/plugin-replace@6.0.3': - resolution: {integrity: sha512-J4RZarRvQAm5IF0/LwUUg+obsm+xZhYnbMXmXROyoSE1ATJe3oXSb9L5MMppdxP2ylNSjv6zFBwKYjcKMucVfA==} - engines: {node: '>=14.0.0'} - peerDependencies: - rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 - peerDependenciesMeta: - rollup: - optional: true - '@rollup/plugin-terser@0.4.4': resolution: {integrity: sha512-XHeJC5Bgvs8LfukDwWZp7yeqin6ns8RTl2B9avbejt6tZqsqvVoWI7ZTQrcNsfKEDWBTnTxM8nMDkO2IFFbd0A==} engines: {node: '>=14.0.0'} @@ -3972,15 +3773,6 @@ packages: rollup: optional: true - '@rollup/plugin-terser@1.0.0': - resolution: {integrity: sha512-FnCxhTBx6bMOYQrar6C8h3scPt8/JwIzw3+AJ2K++6guogH5fYaIFia+zZuhqv0eo1RN7W1Pz630SyvLbDjhtQ==} - engines: {node: '>=20.0.0'} - peerDependencies: - rollup: ^2.0.0||^3.0.0||^4.0.0 - peerDependenciesMeta: - rollup: - optional: true - '@rollup/pluginutils@3.1.0': resolution: {integrity: sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg==} engines: {node: '>= 8.0.0'} @@ -4168,10 +3960,6 @@ packages: '@simonwep/pickr@1.8.2': resolution: {integrity: sha512-/l5w8BIkrpP6n1xsetx9MWPWlU6OblN5YgZZphxan0Tq4BByTCETL6lyIeY8lagalS2Nbt4F2W034KHLIiunKA==} - '@sindresorhus/is@7.2.0': - resolution: {integrity: sha512-P1Cz1dWaFfR4IR+U13mqqiGsLFf1KbayybWwdd2vfctdV6hDpUkgCY0nKOLLTMSoRd/jJNjtbqzf13K8DCCXQw==} - engines: {node: '>=18'} - '@sindresorhus/merge-streams@2.3.0': resolution: {integrity: sha512-LtoMMhxAlorcGhmFYI+LhPgbPZCkgP6ra1YL604EeF6U98pLlQ3iWIGMdWSC+vWmPBWBNgmDBAhnAobLROJmwg==} engines: {node: '>=18'} @@ -4180,9 +3968,6 @@ packages: resolution: {integrity: sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ==} engines: {node: '>=18'} - '@speed-highlight/core@1.2.15': - resolution: {integrity: sha512-BMq1K3DsElxDWawkX6eLg9+CKJrTVGCBAWVuHXVUV2u0s2711qiChLSId6ikYPfxhdYocLNt3wWwSvDiTvFabw==} - '@standard-schema/spec@1.1.0': resolution: {integrity: sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==} @@ -4297,28 +4082,12 @@ packages: peerDependencies: vite: ^5.2.0 || ^6 || ^7 || ^8 - '@tanstack/match-sorter-utils@8.19.4': - resolution: {integrity: sha512-Wo1iKt2b9OT7d+YGhvEPD3DXvPv2etTusIMhMUoG7fbhmxcXCtIjJDEygy91Y2JFlwGyjqiBPRozme7UD8hoqg==} - engines: {node: '>=12'} - - '@tanstack/query-core@5.95.0': - resolution: {integrity: sha512-H1/CWCe8tGL3YIVeo770Z6kPbt0B3M1d/iQXIIK1qlFiFt6G2neYdkHgLapOC8uMYNt9DmHjmGukEKgdMk1P+A==} - '@tanstack/store@0.9.2': resolution: {integrity: sha512-K013lUJEFJK2ofFQ/hZKJUmCnpcV00ebLyOyFOWQvyQHUOZp/iYO84BM6aOGiV81JzwbX0APTVmW8YI7yiG5oA==} '@tanstack/virtual-core@3.13.23': resolution: {integrity: sha512-zSz2Z2HNyLjCplANTDyl3BcdQJc2k1+yyFoKhNRmCr7V7dY8o8q5m8uFTI1/Pg1kL+Hgrz6u3Xo6eFUB7l66cg==} - '@tanstack/vue-query@5.95.0': - resolution: {integrity: sha512-pxZQlXf0mzlcp40EzTfxjrveCc0QYwnjx2CH6QEzjaMmH4N5iWdESGvfOqxfbgx5zbWhRk0T8p79XMbs97y/RA==} - peerDependencies: - '@vue/composition-api': ^1.1.2 - vue: ^3.5.30 - peerDependenciesMeta: - '@vue/composition-api': - optional: true - '@tanstack/vue-store@0.9.2': resolution: {integrity: sha512-Cz2QvwWg/vDziuCnP5TVjmZroshM8rI+Yaifqiv6A5jK8eaMxD5r86SJLUtznnOEGmqpTOPdp3ryvWzuPVTZrA==} peerDependencies: @@ -4765,11 +4534,6 @@ packages: peerDependencies: zod: ^3.24.0 - '@vercel/nft@1.5.0': - resolution: {integrity: sha512-IWTDeIoWhQ7ZtRO/JRKH+jhmeQvZYhtGPmzw/QGDY+wDCQqfm25P9yIdoAFagu4fWsK4IwZXDFIjrmp5rRm/sA==} - engines: {node: '>=20'} - hasBin: true - '@vite-pwa/vitepress@1.1.0': resolution: {integrity: sha512-enif5C2JmepS69Ak7PSr6K3Eimsg7VyryZo1Z6NiIPNDnjXFlOqxwBYaq8R/d0M7akArJsjos7KmQnEfNFf5nA==} peerDependencies: @@ -5072,19 +4836,10 @@ packages: resolution: {integrity: sha512-6/mh1E2u2YgEsCHdY0Yx5oW+61gZU+1vXaoiHHrpKeuRNNgFvS+/jrwHiQhB5apAf5oB7UB7E19ol2R2LKH8hQ==} engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} - abbrev@3.0.1: - resolution: {integrity: sha512-AO2ac6pjRB3SJmGJo+v5/aK6Omggp6fsLrs6wN9bd35ulu4cCwaAU9+7ZhXjeqHVkaHThLuzH0nZr0YpCDhygg==} - engines: {node: ^18.17.0 || >=20.5.0} - abort-controller@3.0.0: resolution: {integrity: sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==} engines: {node: '>=6.5'} - acorn-import-attributes@1.9.5: - resolution: {integrity: sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ==} - peerDependencies: - acorn: ^8 - acorn-jsx@5.3.2: resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} peerDependencies: @@ -5099,10 +4854,6 @@ packages: resolution: {integrity: sha512-4B/qKCfeE/ODUaAUpSwfzazo5x29WD4r3vXiWsB7I2mSDAihwEqKO+g8GELZUQSSAo5e1XTYh3ZVfLyxBc12nA==} engines: {node: '>= 10.0.0'} - agent-base@7.1.4: - resolution: {integrity: sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==} - engines: {node: '>= 14'} - agentkeepalive@3.5.3: resolution: {integrity: sha512-yqXL+k5rr8+ZRpOAntkaaRgWgE5o8ESAj5DyRmVTCSoZxXmqemb9Dd7T4i5UzwuERdLAJUy6XzR9zFVuf0kzkw==} engines: {node: '>= 4.0.0'} @@ -5167,10 +4918,6 @@ packages: any-promise@1.3.0: resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==} - anymatch@3.1.3: - resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} - engines: {node: '>= 8'} - archiver-utils@5.0.2: resolution: {integrity: sha512-wuLJMmIBQYCsGZgYLTy5FIB2pF6Lfb6cXMSF8Qywwk3t20zWnAi7zLcQFdKQmIB8wyZpY5ER38x08GbwtR2cLA==} engines: {node: '>= 14'} @@ -5239,9 +4986,6 @@ packages: resolution: {integrity: sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==} engines: {node: '>= 0.4'} - async-sema@3.1.1: - resolution: {integrity: sha512-tLRNUXati5MFePdAk8dw7Qt7DpxPB60ofAgn8WRhW6a2rcimZnYBP9oxHiv0OHy+Wz7kPMG+t4LGdt31+4EmGg==} - async-validator@4.2.5: resolution: {integrity: sha512-7HhHjtERjqlNbZtqNqy2rckN/SpOOlmDliet+lP7k+eKZEjPk3DgyeU9lIXLdeLz0uBbbVp+9Qdow9wJWgwwfg==} @@ -5353,9 +5097,6 @@ packages: bignumber.js@9.3.1: resolution: {integrity: sha512-Ko0uX15oIUS7wJ3Rb30Fs6SkVbLmPBAKdlm7q9+ak9bbIeFf0MwuBsQV6z7+X768/cHsfg+WlysDWJcmthjsjQ==} - bindings@1.5.0: - resolution: {integrity: sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==} - birpc@2.9.0: resolution: {integrity: sha512-KrayHS5pBi69Xi9JmvoqrIgYGDkD6mcSe/i6YKi3w5kekCLzrX4+nawcXqrj2tIp50Kw/mT/s3p+GVK0A0sKxw==} @@ -5518,10 +5259,6 @@ packages: resolution: {integrity: sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw==} engines: {node: '>= 20.19.0'} - chownr@3.0.0: - resolution: {integrity: sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==} - engines: {node: '>=18'} - ci-info@4.4.0: resolution: {integrity: sha512-77PSwercCZU2Fc4sX94eF8k8Pxte6JAwL4/ICZLFjJLqegs7kCuAsqqj/70NQF6TvDpgFjkubQB2FW2ZZddvQg==} engines: {node: '>=8'} @@ -5571,10 +5308,6 @@ packages: clipboard@2.0.11: resolution: {integrity: sha512-C+0bbOqkezLIsmWSvlsXS0Q0bmkugu7jcfMIACB+RDEntIzQIkdr148we28AfSloQLRdZlYL/QYyrq05j/3Faw==} - clipboardy@4.0.0: - resolution: {integrity: sha512-5mOlNS0mhX0707P2I0aZ2V/cmHUEO/fL7VFLqszkhUsxt7RwnmrInf/eEQKlf5GzvYeHIjT+Ov1HRfNmymlG0w==} - engines: {node: '>=18'} - cliui@6.0.0: resolution: {integrity: sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==} @@ -5589,10 +5322,6 @@ packages: resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==} engines: {node: '>=6'} - cluster-key-slot@1.1.2: - resolution: {integrity: sha512-RMr0FhtfXemyinomL4hrWcYJxmX6deFdCxpJzhDttxgO1+bcCnkk+9drydLVDmAMG7NE6aN/fl4F7ucU/90gAA==} - engines: {node: '>=0.10.0'} - color-convert@2.0.1: resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} engines: {node: '>=7.0.0'} @@ -5643,15 +5372,9 @@ packages: resolution: {integrity: sha512-gk/Z852D2Wtb//0I+kRFNKKE9dIIVirjoqPoA1wJU+XePVXZfGeBpk45+A1rKO4Q43prqWBNY/MiIeRLbPWUaA==} engines: {node: '>=4.0.0'} - commondir@1.0.1: - resolution: {integrity: sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==} - compare-versions@6.1.1: resolution: {integrity: sha512-4hm4VPpIecmlg59CHXnRDnqGplJFrbLG4aFEl5vl6cK1u76ws3LLvX7ikFnTDl5vo39sjWD6AaDPYodJp/NNHg==} - compatx@0.2.0: - resolution: {integrity: sha512-6gLRNt4ygsi5NyMVhceOCFv14CIdDFN7fQjX1U4+47qVE/+kjPoXMK65KWK+dWxmFzMTuKazoQ9sch6pM0p5oA==} - compress-commons@6.0.2: resolution: {integrity: sha512-6FqVXeETqWPoGcfzrXb37E50NP0LXT8kAMu5ooZayhWWdgEY4lBEEcbQNXtkuKQsGduxiIcI4gOTsxTmuq/bSg==} engines: {node: '>= 14'} @@ -5696,12 +5419,6 @@ packages: convert-source-map@2.0.0: resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} - cookie-es@1.2.2: - resolution: {integrity: sha512-+W7VmiVINB+ywl1HGXJXmrqkOhpKrIiVZV6tQuV54ZyQC7MMuBt81Vc336GMLoHBq5hV/F9eXgt5Mnx0Rha5Fg==} - - cookie-es@2.0.0: - resolution: {integrity: sha512-RAj4E421UYRgqokKUmotqAwuplYw15qtdXfY+hGzgCJ/MBjCVZcSoHK/kH9kocfjRjcDME7IiDWR/1WX1TM2Pg==} - copy-anything@3.0.5: resolution: {integrity: sha512-yCEafptTtb4bk7GLEQoM8KVJpxAfdBJYaXyzQEgQQQgYrZiDp8SJmGKlYza6CYjEDNstAdNdKA3UuoULlEbS6w==} engines: {node: '>=12.13'} @@ -5744,10 +5461,6 @@ packages: resolution: {integrity: sha512-piICUB6ei4IlTv1+653yq5+KoqfBYmj9bw6LqXoOneTMDXk5nM1qt12mFW1caG3LlJXEKW1Bp0WggEmIfQB34g==} engines: {node: '>= 14'} - croner@10.0.1: - resolution: {integrity: sha512-ixNtAJndqh173VQ4KodSdJEI6nuioBWI0V1ITNKhZZsO0pEMoDxz539T4FTTbSZ/xIOSuDnzxLVRqBVSvPNE2g==} - engines: {node: '>=18.0'} - cross-env@10.1.0: resolution: {integrity: sha512-GsYosgnACZTADcmEyJctkJIoqAhHjttw7RsFrVoJNXbsWWqaq6Ym+7kZjq6mS45O0jij6vtiReppKQEtqWy6Dw==} engines: {node: '>=20'} @@ -5757,9 +5470,6 @@ packages: resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} engines: {node: '>= 8'} - crossws@0.3.5: - resolution: {integrity: sha512-ojKiDvcmByhwa8YYqbQI/hg7MEU0NC03+pSdEq4ZUnZR9xXpwk7E43SMNGkn+JxJGPFtNvQ48+vV2p+P1ml5PA==} - crypto-js@4.2.0: resolution: {integrity: sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q==} @@ -5874,29 +5584,6 @@ packages: dayjs@1.11.20: resolution: {integrity: sha512-YbwwqR/uYpeoP4pu043q+LTDLFBLApUP6VxRihdfNTqu4ubqMlGDLd6ErXhEgsyvY0K6nCs7nggYumAN+9uEuQ==} - db0@0.3.4: - resolution: {integrity: sha512-RiXXi4WaNzPTHEOu8UPQKMooIbqOEyqA1t7Z6MsdxSCeb8iUC9ko3LcmsLmeUt2SM5bctfArZKkRQggKZz7JNw==} - peerDependencies: - '@electric-sql/pglite': '*' - '@libsql/client': '*' - better-sqlite3: '*' - drizzle-orm: '*' - mysql2: '*' - sqlite3: '*' - peerDependenciesMeta: - '@electric-sql/pglite': - optional: true - '@libsql/client': - optional: true - better-sqlite3: - optional: true - drizzle-orm: - optional: true - mysql2: - optional: true - sqlite3: - optional: true - debug@2.6.9: resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==} peerDependencies: @@ -5971,19 +5658,11 @@ packages: delegate@3.2.0: resolution: {integrity: sha512-IofjkYBZaZivn0V8nnsMJGBr4jVLxHDheKSW88PyxS5QC4Vo9ZbZVvhzlSxY87fVq3STR6r+4cGepyHkcWOQSw==} - denque@2.1.0: - resolution: {integrity: sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw==} - engines: {node: '>=0.10'} - depcheck@1.4.7: resolution: {integrity: sha512-1lklS/bV5chOxwNKA/2XUUk/hPORp8zihZsXflr8x0kLwmcZ9Y9BsS6Hs3ssvA+2wUVbG0U2Ciqvm1SokNjPkA==} engines: {node: '>=10'} hasBin: true - depd@2.0.0: - resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==} - engines: {node: '>= 0.8'} - deps-regex@0.2.0: resolution: {integrity: sha512-PwuBojGMQAYbWkMXOY9Pd/NWCDNHVH12pnS7WHqZkTSeMESe4hwnKKRp0yR87g37113x4JPbo/oIvXY+s/f56Q==} @@ -6063,10 +5742,6 @@ packages: dot-case@3.0.4: resolution: {integrity: sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==} - dot-prop@10.1.0: - resolution: {integrity: sha512-MVUtAugQMOff5RnBy2d9N31iG0lNwg1qAoAOn7pOK5wf94WIaE3My2p3uwTQuvS2AcqchkcR3bHByjaM0mmi7Q==} - engines: {node: '>=20'} - dot-prop@9.0.0: resolution: {integrity: sha512-1gxPBJpI/pcjQhKgIU91II6Wkay+dLcN3M6rf2uwP8hRur3HtQXjVrdAK3sjC0piaEuxzMwjXChcETiJl47lAQ==} engines: {node: '>=18'} @@ -6100,9 +5775,6 @@ packages: resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} engines: {node: '>= 0.4'} - duplexer@0.1.2: - resolution: {integrity: sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==} - eastasianwidth@0.2.0: resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} @@ -6141,10 +5813,6 @@ packages: resolution: {integrity: sha512-i6UzDscO/XfAcNYD75CfICkmfLedpyPDdozrLMmQc5ORaQcdMoc21OnlEylMIqI7U8eniKrPMxxtj8k0vhmJhA==} engines: {node: '>=14'} - encodeurl@2.0.0: - resolution: {integrity: sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==} - engines: {node: '>= 0.8'} - encoding-sniffer@0.2.1: resolution: {integrity: sha512-5gvq20T6vfpekVtqrYQsSCFZ1wEg5+wW0/QaZMWkFr6BqD3NfKs0rLCx4rrVlSWJeZb5NBJgVLswK/w2MWU+Gw==} @@ -6435,10 +6103,6 @@ packages: resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} engines: {node: '>=0.10.0'} - etag@1.8.1: - resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==} - engines: {node: '>= 0.6'} - event-emitter@0.3.5: resolution: {integrity: sha512-D9rRn9y7kLPnJ+hMq7S/nhvoKwwvVJahBi2BPmx3bvbsEdK3W9ii8cBSGjP+72/LnM4n6fo3+dkCX5FeTQruXA==} @@ -6460,10 +6124,6 @@ packages: resolution: {integrity: sha512-IzUmBGPR3+oUG9dUeXynyNmf91/3zUSJg1lCktzKw47OXuhco54U3r9B7O4XX+Rb1Itm9OZ2b0RkTs10bICOxA==} engines: {node: '>=12.0.0'} - execa@8.0.1: - resolution: {integrity: sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==} - engines: {node: '>=16.17'} - execa@9.6.1: resolution: {integrity: sha512-9Be3ZoN4LmYR90tUoVu2te2BsbzHfhJyfEiAVfz7N5/zv+jduIfLrV2xdQXOHbaD6KgpGdO9PRPM1Y4Q9QkPkA==} engines: {node: ^18.19.0 || >=20.5.0} @@ -6550,9 +6210,6 @@ packages: resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==} engines: {node: '>=16.0.0'} - file-uri-to-path@1.0.0: - resolution: {integrity: sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==} - filelist@1.0.6: resolution: {integrity: sha512-5giy2PkLYY1cP39p17Ech+2xlpTRL9HLspOfEgm0L6CwBXBTgsK5ou0JtzYuepxkaQ/tvhCFIJ5uXo0OrM2DxA==} @@ -6628,10 +6285,6 @@ packages: framesync@6.1.2: resolution: {integrity: sha512-jBTqhX6KaQVDyus8muwZbBeGGP0XgujBRbQ7gM7BRdS3CadCZIHiawyzYLnafYcvZIh5j8WE7cxZKFn7dXhu9g==} - fresh@2.0.0: - resolution: {integrity: sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==} - engines: {node: '>= 0.8'} - fs-extra@10.1.0: resolution: {integrity: sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==} engines: {node: '>=12'} @@ -6652,11 +6305,6 @@ packages: resolution: {integrity: sha512-XUBA9XClHbnJWSfBzjkm6RvPsyg3sryZt06BEQoXcF7EK/xpGaQYJgQKDJSUH5SGZ76Y7pFx1QBnXz09rU5Fbw==} engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} - fsevents@2.3.2: - resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==} - engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} - os: [darwin] - fsevents@2.3.3: resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} @@ -6699,13 +6347,6 @@ packages: get-own-enumerable-property-symbols@3.0.2: resolution: {integrity: sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g==} - get-port-please@3.2.0: - resolution: {integrity: sha512-I9QVvBw5U/hw3RmWpYKRumUeaDgxTPd401x364rLmWBJcOQ753eov1eTgzDqRG9bqFIfDc7gfzcQEWrUri3o1A==} - - get-port@7.2.0: - resolution: {integrity: sha512-afP4W205ONCuMoPBqcR6PSXnzX35KTcJygfJfcp+QY+uwm3p20p1YczWXhlICIzGMCxYBQcySEcOgsJcrkyobg==} - engines: {node: '>=16'} - get-proto@1.0.1: resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==} engines: {node: '>= 0.4'} @@ -6713,10 +6354,6 @@ packages: get-ready@1.0.0: resolution: {integrity: sha512-mFXCZPJIlcYcth+N8267+mghfYN9h3EhsDa6JSnbA3Wrhh/XFpuowviFcsDeYZtKspQyWyJqfs4O6P8CHeTwzw==} - get-stream@8.0.1: - resolution: {integrity: sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==} - engines: {node: '>=16'} - get-stream@9.0.1: resolution: {integrity: sha512-kVCxPF3vQM/N0B1PmoqVUqgHP+EeVjmZSQn+1oCRPxd2P21P2F19lIgbR3HBosbB1PUhOAoctJnfEn2GbN2eZA==} engines: {node: '>=18'} @@ -6828,13 +6465,6 @@ packages: resolution: {integrity: sha512-5v6yZd4JK3eMI3FqqCouswVqwugaA9r4dNZB1wwcmrD02QkV5H0y7XBQW8QwQqEaZY1pM9aqORSORhJRdNK44Q==} engines: {node: '>=6.0'} - gzip-size@7.0.0: - resolution: {integrity: sha512-O1Ld7Dr+nqPnmGpdhzLmMTQ4vAsD+rHwMm1NLUmoUFFymBOMKxCCrtDxqdBRYXdeEPEi3SyoR4TizJLQrnKBNA==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - - h3@1.15.10: - resolution: {integrity: sha512-YzJeWSkDZxAhvmp8dexjRK5hxziRO7I9m0N53WhvYL5NiWfkUkzssVzY9jvGu0HBoLFW6+duYmNSn6MaZBCCtg==} - happy-dom@20.8.4: resolution: {integrity: sha512-GKhjq4OQCYB4VLFBzv8mmccUadwlAusOZOI7hC1D9xDIT5HhzkJK17c4el2f6R6C715P9xB4uiMxeKUa2nHMwQ==} engines: {node: '>=20.0.0'} @@ -6926,32 +6556,13 @@ packages: htmlparser2@8.0.2: resolution: {integrity: sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==} - http-errors@2.0.1: - resolution: {integrity: sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==} - engines: {node: '>= 0.8'} - http-parser-js@0.5.10: resolution: {integrity: sha512-Pysuw9XpUq5dVc/2SMHpuTY01RFl8fttgcyunjL7eEMhGM3cI4eOmiCycJDVCo/7O7ClfQD3SaI6ftDzqOXYMA==} - http-shutdown@1.2.2: - resolution: {integrity: sha512-S9wWkJ/VSY9/k4qcjG318bqJNruzE4HySUhFYknwmu6LBP97KLLfwNf+n4V1BHurvFNkSKLFnK/RsuUnRTf9Vw==} - engines: {iojs: '>= 1.0.0', node: '>= 0.12.0'} - - https-proxy-agent@7.0.6: - resolution: {integrity: sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==} - engines: {node: '>= 14'} - - httpxy@0.3.1: - resolution: {integrity: sha512-XjG/CEoofEisMrnFr0D6U6xOZ4mRfnwcYQ9qvvnT4lvnX8BoeA3x3WofB75D+vZwpaobFVkBIHrZzoK40w8XSw==} - human-id@4.1.3: resolution: {integrity: sha512-tsYlhAYpjCKa//8rXZ9DqKEawhPoSytweBC2eNvcaDK+57RZLHGqNs3PZTQO6yekLFSuvA6AlnAfrw1uBvtb+Q==} hasBin: true - human-signals@5.0.0: - resolution: {integrity: sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==} - engines: {node: '>=16.17.0'} - human-signals@8.0.1: resolution: {integrity: sha512-eKCa6bwnJhvxj14kZk5NCPc6Hb6BdsU9DZcOnmQKSnO1VKrfV0zCvtttPZUsBvjmNDn8rpcJfpwSYnHBjc95MQ==} engines: {node: '>=18.18.0'} @@ -7026,13 +6637,6 @@ packages: resolution: {integrity: sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==} engines: {node: '>= 0.4'} - ioredis@5.10.1: - resolution: {integrity: sha512-HuEDBTI70aYdx1v6U97SbNx9F1+svQKBDo30o0b9fw055LMepzpOOd0Ccg9Q6tbqmBSJaMuY0fB7yw9/vjBYCA==} - engines: {node: '>=12.22.0'} - - iron-webcrypto@1.2.1: - resolution: {integrity: sha512-feOM6FaSr6rEABp/eDfVseKyTMDt+KGpeB35SkVn9Tyn0CqvVsY3EwI0v5i8nMHyJnzCIQf7nsy3p41TPkJZhg==} - is-array-buffer@3.0.5: resolution: {integrity: sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==} engines: {node: '>= 0.4'} @@ -7177,9 +6781,6 @@ packages: resolution: {integrity: sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==} engines: {node: '>=0.10.0'} - is-reference@1.2.1: - resolution: {integrity: sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ==} - is-regex@1.2.1: resolution: {integrity: sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==} engines: {node: '>= 0.4'} @@ -7204,10 +6805,6 @@ packages: resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} engines: {node: '>=8'} - is-stream@3.0.0: - resolution: {integrity: sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - is-stream@4.0.1: resolution: {integrity: sha512-Dnz92NInDqYckGEUJv689RbRiTSEHCQ7wOVeALbkOz999YpqT46yMRIGtSNl2iCL1waAZSx40+h59NV/EwzV/A==} engines: {node: '>=18'} @@ -7266,10 +6863,6 @@ packages: resolution: {integrity: sha512-e6rvdUCiQCAuumZslxRJWR/Doq4VpPR82kqclvcS0efgt430SlGIk05vdCN58+VrzgtIcfNODjozVielycD4Sw==} engines: {node: '>=16'} - is64bit@2.0.0: - resolution: {integrity: sha512-jv+8jaWCl0g2lSBkNSVXdzfBA0npK1HGC2KtWM9FumFRoGS94g3NbCCLVnCYHLjp4GrW2KZeeSTMo5ddtznmGw==} - engines: {node: '>=18'} - isarray@1.0.0: resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==} @@ -7389,10 +6982,6 @@ packages: resolution: {integrity: sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==} engines: {node: '>=0.10.0'} - kleur@4.1.5: - resolution: {integrity: sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==} - engines: {node: '>=6'} - klona@2.0.6: resolution: {integrity: sha512-dhG34DXATL5hSxJbIexCft8FChFXtmskoZYnoPWjXQuebWYCNkVeV3KkGegCK9CP1oswI/vQibS2GY7Em/sJJA==} engines: {node: '>= 8'} @@ -7512,10 +7101,6 @@ packages: lines-and-columns@1.2.4: resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} - listhen@1.9.0: - resolution: {integrity: sha512-I8oW2+QL5KJo8zXNWX046M134WchxsXC7SawLPvRQpogCbkyQIaFxPE89A2HiwR7vAK2Dm2ERBAmyjTYGYEpBg==} - hasBin: true - listr2@9.0.5: resolution: {integrity: sha512-ME4Fb83LgEgwNw96RKNvKV4VTLuXfoKudAmm2lP8Kk87KaMK0/Xrx/aAkMWmT8mDb+3MlFDspfbCs7adjRxA2g==} engines: {node: '>=20.0.0'} @@ -7548,12 +7133,6 @@ packages: lodash.debounce@4.0.8: resolution: {integrity: sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==} - lodash.defaults@4.2.0: - resolution: {integrity: sha512-qjxPLHd3r5DnsdGacqOMU6pb/avJzdh9tFX2ymgoZE27BmjXrNy/y4LoaiTeAb+O3gL8AfpJGtqfX/ae2leYYQ==} - - lodash.isarguments@3.1.0: - resolution: {integrity: sha512-chi4NHZlZqZD18a0imDHnZPrDeBbTtVN7GXMwuGdRH9qotxAjYs3aVLKc7zNOG9eddR5Ksd8rvFEBc9SsggPpg==} - lodash.sortby@4.7.0: resolution: {integrity: sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==} @@ -7646,9 +7225,6 @@ packages: merge-descriptors@1.0.3: resolution: {integrity: sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==} - merge-stream@2.0.0: - resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} - merge2@1.4.1: resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} engines: {node: '>= 8'} @@ -7676,18 +7252,10 @@ packages: resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} engines: {node: '>= 0.6'} - mime-db@1.54.0: - resolution: {integrity: sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==} - engines: {node: '>= 0.6'} - mime-types@2.1.35: resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} engines: {node: '>= 0.6'} - mime-types@3.0.2: - resolution: {integrity: sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==} - engines: {node: '>=18'} - mime@1.6.0: resolution: {integrity: sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==} engines: {node: '>=4'} @@ -7698,15 +7266,6 @@ packages: engines: {node: '>=4.0.0'} hasBin: true - mime@4.1.0: - resolution: {integrity: sha512-X5ju04+cAzsojXKes0B/S4tcYtFAJ6tTMuSPBEn9CPGlrWr8Fiw7qYeLT0XyH80HSoAoqWCaz+MWKh22P7G1cw==} - engines: {node: '>=16'} - hasBin: true - - mimic-fn@4.0.0: - resolution: {integrity: sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==} - engines: {node: '>=12'} - mimic-function@5.0.1: resolution: {integrity: sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA==} engines: {node: '>=18'} @@ -7756,10 +7315,6 @@ packages: minisearch@7.2.0: resolution: {integrity: sha512-dqT2XBYUOZOiC5t2HRnwADjhNS2cecp9u+TJRiJ1Qp/f5qjkeT5APcGPjHw+bz89Ms8Jp+cG4AlE+QZ/QnDglg==} - minizlib@3.1.0: - resolution: {integrity: sha512-KZxYo1BUkWD2TVFLr0MQoM8vUUigWD3LlD83a/75BqC+4qE0Hb1Vo5v1FgcfaNXvfXzr+5EhQ6ing/CaBijTlw==} - engines: {node: '>= 18'} - mitt@3.0.1: resolution: {integrity: sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==} @@ -7821,16 +7376,6 @@ packages: next-tick@1.1.0: resolution: {integrity: sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==} - nitropack@2.13.2: - resolution: {integrity: sha512-R5TMzSBoTDG4gi6Y+pvvyCNnooShHePHsHxMLP9EXDGdrlR5RvNdSd4e5k8z0/EzP9Ske7ABRMDWg6O7Dm2OYw==} - engines: {node: ^20.19.0 || >=22.12.0} - hasBin: true - peerDependencies: - xml2js: ^0.6.2 - peerDependenciesMeta: - xml2js: - optional: true - no-case@3.0.4: resolution: {integrity: sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==} @@ -7865,10 +7410,6 @@ packages: resolution: {integrity: sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - node-forge@1.3.3: - resolution: {integrity: sha512-rLvcdSyRCyouf6jcOIPe/BgwG/d7hKjzMKOas33/pHEr6gbq18IK9zV7DiPvzsz0oBJPme6qr6H6kGZuI9/DZg==} - engines: {node: '>= 6.13.0'} - node-gyp-build@4.8.4: resolution: {integrity: sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==} hasBin: true @@ -7880,9 +7421,6 @@ packages: node-html-parser@5.4.2: resolution: {integrity: sha512-RaBPP3+51hPne/OolXxcz89iYvQvKOydaqoePpOgXcrOKZhjVIzmpKZz+Hd/RBO2/zN2q6CNJhQzucVz+u3Jyw==} - node-mock-http@1.0.4: - resolution: {integrity: sha512-8DY+kFsDkNXy1sJglUfuODx1/opAGJGyrTuFqEoN90oRc2Vk0ZbD4K2qmKXBBEhZQzdKHIVfEJpDU8Ak2NJEvQ==} - node-releases@2.0.36: resolution: {integrity: sha512-TdC8FSgHz8Mwtw9g5L4gR/Sh9XhSP/0DEkQxfEFXOpiul5IiHgHan2VhYYb6agDSfp4KuvltmGApc8HMgUrIkA==} @@ -7891,19 +7429,10 @@ packages: engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} hasBin: true - nopt@8.1.0: - resolution: {integrity: sha512-ieGu42u/Qsa4TFktmaKEwM6MQH0pOWnaB3htzh0JRtx84+Mebc0cbZYN5bC+6WTZ4+77xrL9Pn5m7CV6VIkV7A==} - engines: {node: ^18.17.0 || >=20.5.0} - hasBin: true - normalize-path@3.0.0: resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} engines: {node: '>=0.10.0'} - npm-run-path@5.3.0: - resolution: {integrity: sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - npm-run-path@6.0.0: resolution: {integrity: sha512-9qny7Z9DsQU8Ou39ERsPU4OZQlSTP47ShQzuKZ6PRXpYLtIFgl/DEBYEXKlvcEa+9tHVcK8CF81Y2V72qaZhWA==} engines: {node: '>=18'} @@ -7938,23 +7467,12 @@ packages: obug@2.1.1: resolution: {integrity: sha512-uTqF9MuPraAQ+IsnPf366RG4cP9RtUi7MLO1N3KEc+wb0a6yKpeL0lmk2IB1jY5KHPAlTc6T/JRdC/YqxHNwkQ==} - ofetch@1.5.1: - resolution: {integrity: sha512-2W4oUZlVaqAPAil6FUg/difl6YhqhUR7x2eZY4bQCko22UXg3hptq9KLQdqFClV+Wu85UX7hNtdGTngi/1BxcA==} - ohash@2.0.11: resolution: {integrity: sha512-RdR9FQrFwNBNXAr4GixM8YaRZRJ5PUWbKYbE5eOsrwAjJW0q2REGcf79oYPsLyskQCZG1PLN+S/K1V00joZAoQ==} - on-finished@2.4.1: - resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==} - engines: {node: '>= 0.8'} - once@1.4.0: resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} - onetime@6.0.0: - resolution: {integrity: sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==} - engines: {node: '>=12'} - onetime@7.0.0: resolution: {integrity: sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ==} engines: {node: '>=18'} @@ -8087,10 +7605,6 @@ packages: parse5@7.3.0: resolution: {integrity: sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==} - parseurl@1.3.3: - resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==} - engines: {node: '>= 0.8'} - pascal-case@3.1.2: resolution: {integrity: sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==} @@ -8131,9 +7645,6 @@ packages: pathe@0.2.0: resolution: {integrity: sha512-sTitTPYnn23esFR3RlqYBWn4c45WGeLcsKzQiUpXJAyfcWkolvlYpV8FLo7JishK946oQwMFUCHXQ9AjGPKExw==} - pathe@1.1.2: - resolution: {integrity: sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==} - pathe@2.0.3: resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==} @@ -8193,16 +7704,6 @@ packages: platform@1.3.6: resolution: {integrity: sha512-fnWVljUchTro6RiCFvCXBbNhJc2NijN7oIQxbwsyL0buWJPG85v81ehlHI9fXrJsMNgTofEoWIQeClKpgxFLrg==} - playwright-core@1.58.2: - resolution: {integrity: sha512-yZkEtftgwS8CsfYo7nm0KE8jsvm6i/PTgVtB8DL726wNf6H2IMsDuxCpJj59KDaxCtSnrWan2AeDqM7JBaultg==} - engines: {node: '>=18'} - hasBin: true - - playwright@1.58.2: - resolution: {integrity: sha512-vA30H8Nvkq/cPBnNw4Q8TWz1EJyqgpuinBcHET0YVJVFldr8JDNiU9LaWAE1KqSkRYazuaBhTpB5ZzShOezQ6A==} - engines: {node: '>=18'} - hasBin: true - please-upgrade-node@3.2.0: resolution: {integrity: sha512-gQR3WpIgNIKwBMVLkpMUeR3e1/E1y42bqDQZfql+kDeXd8COYfM8PQA4X6y7a8u9Ua9FHmsrrmirW2vHs45hWg==} @@ -8314,10 +7815,6 @@ packages: resolution: {integrity: sha512-mQUvGU6aUFQ+rNvTIAcZuWGRT9a6f6Yrg9bHs4ImKF+HZCEK+plBvnAZYSIQztknZF2qnzNtr6F8s0+IuptdlQ==} engines: {node: ^14.13.1 || >=16.0.0} - pretty-bytes@7.1.0: - resolution: {integrity: sha512-nODzvTiYVRGRqAOvE84Vk5JDPyyxsVk0/fbA/bq7RqlnhksGpset09XTxbpvLTIjoaF7K8Z8DG8yHtKGTPSYRw==} - engines: {node: '>=20'} - pretty-ms@9.3.0: resolution: {integrity: sha512-gjVS5hOP+M3wMm5nmNOucbIrqudzs9v/57bWRHQWLYklXqoXKrVfYW2W9+glfGsqtPgpiz5WwyEEB+ksXIx3gQ==} engines: {node: '>=18'} @@ -8382,16 +7879,9 @@ packages: queue-microtask@1.2.3: resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} - radix3@1.1.2: - resolution: {integrity: sha512-b484I/7b8rDEdSDKckSSBA8knMpcdsXudlE/LNL639wFoHKwLbEkQFZHWEYwDC0wa0FKUcCY+GAF73Z7wxNVFA==} - randombytes@2.1.0: resolution: {integrity: sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==} - range-parser@1.2.1: - resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==} - engines: {node: '>= 0.6'} - rc9@2.1.2: resolution: {integrity: sha512-btXCnMmRIBINM2LDZoEmOogIZU7Qe7zn4BpomSKZ/ykbLObuBdvG+mFq11DL6fjH1DRwHhrlgtYWG96bJiC7Cg==} @@ -8432,14 +7922,6 @@ packages: resolution: {integrity: sha512-9u/XQ1pvrQtYyMpZe7DXKv2p5CNvyVwzUB6uhLAnQwHMSgKMBR62lc7AHljaeteeHXn11XTAaLLUVZYVZyuRBQ==} engines: {node: '>= 20.19.0'} - redis-errors@1.2.0: - resolution: {integrity: sha512-1qny3OExCf0UvUV/5wpYKf2YwPcOqXzkwKKSmKHiE6ZMQs5heeE/c8eXK+PNllPvmjgAbfnsbpkGZWy8cBpn9w==} - engines: {node: '>=4'} - - redis-parser@3.0.0: - resolution: {integrity: sha512-DJnGAeenTdpMEH6uAJRK/uiyEIH9WVsUmoLwzudwGJUwZPp80PDBWPHXSAGNPwNvIXAbe7MSUB1zQFugFml66A==} - engines: {node: '>=4'} - reflect.getprototypeof@1.0.10: resolution: {integrity: sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==} engines: {node: '>= 0.4'} @@ -8496,9 +7978,6 @@ packages: resolution: {integrity: sha512-G08Dxvm4iDN3MLM0EsP62EDV9IuhXPR6blNz6Utcp7zyV3tr4HVNINt6MpaRWbxoOHT3Q7YN2P+jaHX8vUbgog==} engines: {node: '>= 0.10'} - remove-accents@0.5.0: - resolution: {integrity: sha512-8g3/Otx1eJaVD12e31UbJj1YzdtVvzH85HV7t+9MJYk/u3XmkOUJ5Ys9wQrf9PCPK8+xn4ymzqYCiZl6QWKn+A==} - require-directory@2.1.1: resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} engines: {node: '>=0.10.0'} @@ -8814,24 +8293,9 @@ packages: engines: {node: '>=10'} hasBin: true - send@1.2.1: - resolution: {integrity: sha512-1gnZf7DFcoIcajTjTwjwuDjzuz4PPcY2StKPlsGAQ1+YH20IRVrBaXSWmdjowTJ6u8Rc01PoYOGHXfP1mYcZNQ==} - engines: {node: '>= 18'} - serialize-javascript@6.0.2: resolution: {integrity: sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==} - serialize-javascript@7.0.4: - resolution: {integrity: sha512-DuGdB+Po43Q5Jxwpzt1lhyFSYKryqoNjQSA9M92tyw0lyHIOur+XCalOUe0KTJpyqzT8+fQ5A0Jf7vCx/NKmIg==} - engines: {node: '>=20.0.0'} - - serve-placeholder@2.0.2: - resolution: {integrity: sha512-/TMG8SboeiQbZJWRlfTCqMs2DD3SZgWp0kDQePz9yUuCnDfDh/92gf7/PxGhzXTKBIPASIHxFcZndoNbp6QOLQ==} - - serve-static@2.2.1: - resolution: {integrity: sha512-xRXBn0pPqQTVQiC8wyQrKs2MOlX24zQ0POGaj0kultvoOCstBQM5yvOhAVSUwOMjQtTvsPWoNCHfPGwaaQJhTw==} - engines: {node: '>= 18'} - set-blocking@2.0.0: resolution: {integrity: sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==} @@ -8847,9 +8311,6 @@ packages: resolution: {integrity: sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==} engines: {node: '>= 0.4'} - setprototypeof@1.2.0: - resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==} - shallow-equal@1.2.1: resolution: {integrity: sha512-S4vJDjHHMBaiZuT9NPb616CSmLf618jawtv3sufLl6ivK8WocjAo58cXwbRV1cgqxH0Qbv+iUt6m05eqEa2IRA==} @@ -8973,20 +8434,10 @@ packages: stackback@0.0.2: resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} - standard-as-callback@2.1.0: - resolution: {integrity: sha512-qoRRSyROncaz1z0mvYqIE4lCd9p2R90i6GxW3uZv5ucSu8tU7B5HXUP1gG8pVZsYNVaXjk8ClXHPttLyxAL48A==} - statuses@1.5.0: resolution: {integrity: sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==} engines: {node: '>= 0.6'} - statuses@2.0.2: - resolution: {integrity: sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==} - engines: {node: '>= 0.8'} - - std-env@3.10.0: - resolution: {integrity: sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg==} - std-env@4.0.0: resolution: {integrity: sha512-zUMPtQ/HBY3/50VbpkupYHbRroTRZJPRLvreamgErJVys0ceuzMkD44J/QjqhHjOzK42GQ3QZIeFG1OYfOtKqQ==} @@ -9080,10 +8531,6 @@ packages: resolution: {integrity: sha512-ZprKx+bBLXv067WTCALv8SSz5l2+XhpYCsVtSqlMnkAXMWDq+/ekVbl1ghqP9rUHTzv6sm/DwCOiYutU/yp1fw==} engines: {node: '>=10'} - strip-final-newline@3.0.0: - resolution: {integrity: sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==} - engines: {node: '>=12'} - strip-final-newline@4.0.0: resolution: {integrity: sha512-aulFJcD6YK8V1G7iRB5tigAP4TsHBZZrOV8pjV++zdUwmeV8uzbY7yn6h9MswN62adStNZFuCIx4haBnRuMDaw==} engines: {node: '>=18'} @@ -9096,9 +8543,6 @@ packages: resolution: {integrity: sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==} engines: {node: '>=0.10.0'} - strip-literal@3.1.0: - resolution: {integrity: sha512-8r3mkIM/2+PpjHoOtiAW8Rg3jJLHaV7xPwG+YRGrv6FP0wwk/toTpATxWYOW0BKdWwl82VT2tFYi5DlROa0Mxg==} - stubborn-fs@2.0.0: resolution: {integrity: sha512-Y0AvSwDw8y+nlSNFXMm2g6L51rBGdAQT20J3YSOqxC53Lo3bjWRtr2BKcfYoAf352WYpsZSTURrA0tqhfgudPA==} @@ -9220,10 +8664,6 @@ packages: resolution: {integrity: sha512-Bh7QjT8/SuKUIfObSXNHNSK6WHo6J1tHCqJsuaFDP7gP0fkzSfTxI8y85JrppZ0h8l0maIgc2tfuZQ6/t3GtnQ==} engines: {node: ^14.18.0 || >=16.0.0} - system-architecture@0.1.0: - resolution: {integrity: sha512-ulAk51I9UVUyJgxlv9M6lFot2WP3e7t8Kz9+IS6D4rVba1tR9kON+Ey69f+1R4Q8cd45Lod6a4IcJIxnzGc/zA==} - engines: {node: '>=18'} - tabbable@6.4.0: resolution: {integrity: sha512-05PUHKSNE8ou2dwIxTngl4EzcnsCDZGJ/iCLtDflR/SHB/ny14rXc+qU5P4mG9JkusiV7EivzY9Mhm55AzAvCg==} @@ -9231,10 +8671,6 @@ packages: resolution: {integrity: sha512-9kY+CygyYM6j02t5YFHbNz2FN5QmYGv9zAjVp4lCDjlCw7amdckXlEt/bjMhUIfj4ThGRE4gCUH5+yGnNuPo5A==} engines: {node: '>=10.0.0'} - tagged-tag@1.0.0: - resolution: {integrity: sha512-yEFYrVhod+hdNyx7g5Bnkkb0G6si8HJurOoOEgC8B/O0uXLHlaey/65KRv6cuWBNhBgHKAROVpc7QyYqE5gFng==} - engines: {node: '>=20'} - tailwind-merge@3.5.0: resolution: {integrity: sha512-I8K9wewnVDkL1NTGoqWmVEIlUcB9gFriAEkXkfCjX5ib8ezGxtR3xD7iZIxrfArjEsH7F1CHD4RFUtxefdqV/A==} @@ -9248,10 +8684,6 @@ packages: tar-stream@3.1.8: resolution: {integrity: sha512-U6QpVRyCGHva435KoNWy9PRoi2IFYCgtEhq9nmrPPpbRacPs9IH4aJ3gbrFC8dPcXvdSZ4XXfXT5Fshbp2MtlQ==} - tar@7.5.12: - resolution: {integrity: sha512-9TsuLcdhOn4XztcQqhNyq1KOwOOED/3k58JAvtULiYqbO8B/0IBAAIE1hj0Svmm58k27TmcigyDI0deMlgG3uw==} - engines: {node: '>=18'} - teex@1.0.1: resolution: {integrity: sha512-eYE6iEI62Ni1H8oIa7KlDU6uQBtqr4Eajni3wX7rpfXD8ysFx8z0+dri+KWEPWpBsxXfxu58x/0jvTVT1ekOSg==} @@ -9320,10 +8752,6 @@ packages: resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} engines: {node: '>=8.0'} - toidentifier@1.0.1: - resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==} - engines: {node: '>=0.6'} - totalist@3.0.1: resolution: {integrity: sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==} engines: {node: '>=6'} @@ -9408,10 +8836,6 @@ packages: resolution: {integrity: sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==} engines: {node: '>=16'} - type-fest@5.5.0: - resolution: {integrity: sha512-PlBfpQwiUvGViBNX84Yxwjsdhd1TUlXr6zjX7eoirtCPIr08NAmxwa+fcYBTeRQxHo9YC9wwF3m9i700sHma8g==} - engines: {node: '>=20'} - type@2.7.3: resolution: {integrity: sha512-8j+1QmAbPvLZow5Qpi6NCaN8FB60p/6x8/vfNqOk/hC+HuvFZhL4+WfekuhQLiqFZXOgQdrs3B+XxEmCc6b3FQ==} @@ -9442,9 +8866,6 @@ packages: ufo@1.6.3: resolution: {integrity: sha512-yDJTmhydvl5lJzBmy/hyOAA0d+aqCBuwl818haVdYCRrWV84o7YyeVm4QlVHStqNrrJSTb6jKuFAVqAFsr+K3Q==} - ultrahtml@1.6.0: - resolution: {integrity: sha512-R9fBn90VTJrqqLDwyMph+HGne8eqY1iPfYhPzZrvKpIfwkWZbcYlfpsb8B9dTvBfpy1/hqAD7Wi8EKfP9e8zdw==} - unbox-primitive@1.1.0: resolution: {integrity: sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==} engines: {node: '>= 0.4'} @@ -9465,9 +8886,6 @@ packages: resolution: {integrity: sha512-3IWdCpjgxp15CbJnsi/Y9TCDE7HWVN19j1hmzVhoAkY/+CJx449tVxT5wZc1Gwg8J+P0LWvzlBzxYRnHJ+1i7Q==} engines: {node: '>=20.18.1'} - unenv@2.0.0-rc.24: - resolution: {integrity: sha512-i7qRCmY42zmCwnYlh9H2SvLEypEFGye5iRmEMKjcGi7zk9UquigRjFtTLz0TYqr0ZGLZhaMHl/foy1bZR+Cwlw==} - unescape@1.0.1: resolution: {integrity: sha512-O0+af1Gs50lyH1nUu3ZyYS1cRh01Q/kUKatTOkSs7jukXE6/NebucDVxyiDsA9AQ4JC1V1jUH9EO8JX2nMDgGQ==} engines: {node: '>=0.10.0'} @@ -9496,10 +8914,6 @@ packages: resolution: {integrity: sha512-wH590V9VNgYH9g3lH9wWjTrUoKsjLF6sGLjhR4sH1LWpLmCOH0Zf7PukhDA8BiS7KHe4oPNkcTHqYkj7SOGUOw==} engines: {node: '>=20'} - unimport@6.0.2: - resolution: {integrity: sha512-ZSOkrDw380w+KIPniY3smyXh2h7H9v2MNr9zejDuh239o5sdea44DRAYrv+rfUi2QGT186P2h0GPGKvy8avQ5g==} - engines: {node: '>=18.12.0'} - unique-string@2.0.0: resolution: {integrity: sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==} engines: {node: '>=8'} @@ -9585,79 +8999,10 @@ packages: synckit: optional: true - unstorage@1.17.4: - resolution: {integrity: sha512-fHK0yNg38tBiJKp/Vgsq4j0JEsCmgqH58HAn707S7zGkArbZsVr/CwINoi+nh3h98BRCwKvx1K3Xg9u3VV83sw==} - peerDependencies: - '@azure/app-configuration': ^1.8.0 - '@azure/cosmos': ^4.2.0 - '@azure/data-tables': ^13.3.0 - '@azure/identity': ^4.6.0 - '@azure/keyvault-secrets': ^4.9.0 - '@azure/storage-blob': ^12.26.0 - '@capacitor/preferences': ^6 || ^7 || ^8 - '@deno/kv': '>=0.9.0' - '@netlify/blobs': ^6.5.0 || ^7.0.0 || ^8.1.0 || ^9.0.0 || ^10.0.0 - '@planetscale/database': ^1.19.0 - '@upstash/redis': ^1.34.3 - '@vercel/blob': '>=0.27.1' - '@vercel/functions': ^2.2.12 || ^3.0.0 - '@vercel/kv': ^1 || ^2 || ^3 - aws4fetch: ^1.0.20 - db0: '>=0.2.1' - idb-keyval: ^6.2.1 - ioredis: ^5.4.2 - uploadthing: ^7.4.4 - peerDependenciesMeta: - '@azure/app-configuration': - optional: true - '@azure/cosmos': - optional: true - '@azure/data-tables': - optional: true - '@azure/identity': - optional: true - '@azure/keyvault-secrets': - optional: true - '@azure/storage-blob': - optional: true - '@capacitor/preferences': - optional: true - '@deno/kv': - optional: true - '@netlify/blobs': - optional: true - '@planetscale/database': - optional: true - '@upstash/redis': - optional: true - '@vercel/blob': - optional: true - '@vercel/functions': - optional: true - '@vercel/kv': - optional: true - aws4fetch: - optional: true - db0: - optional: true - idb-keyval: - optional: true - ioredis: - optional: true - uploadthing: - optional: true - - untun@0.1.3: - resolution: {integrity: sha512-4luGP9LMYszMRZwsvyUd9MrxgEGZdZuZgpVQHEEX0lCYFESasVRvZd0EYpCkOIbJKHMuv0LskpXc/8Un+MJzEQ==} - hasBin: true - untyped@2.0.0: resolution: {integrity: sha512-nwNCjxJTjNuLCgFr42fEak5OcLuB3ecca+9ksPFNvtfYSLpjf+iJqSIaSnIile6ZPbKYxI5k2AfXqeopGudK/g==} hasBin: true - unwasm@0.5.3: - resolution: {integrity: sha512-keBgTSfp3r6+s9ZcSma+0chwxQdmLbB5+dAD9vjtB21UTMYuKAxHXCU1K2CbCtnP09EaWeRvACnXk0EJtUx+hw==} - upath@1.2.0: resolution: {integrity: sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==} engines: {node: '>=4'} @@ -9672,9 +9017,6 @@ packages: resolution: {integrity: sha512-+dwUY4L35XFYEzE+OAL3sarJdUioVovq+8f7lcIJ7wnmnYQV5UD1Y/lcwaMSyaQ6Bj3JMj1XSTjZbNLHn/19yA==} engines: {node: '>=18'} - uqr@0.1.2: - resolution: {integrity: sha512-MJu7ypHq6QasgF5YRTjqscSzQp/W11zoUk6kvmlH+fmWEs63Y0Eib13hYFwAzagRJcVY8WVnlV+eBDUGMJ5IbA==} - uri-js@4.4.1: resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} @@ -10216,10 +9558,6 @@ packages: yallist@4.0.0: resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} - yallist@5.0.0: - resolution: {integrity: sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==} - engines: {node: '>=18'} - yaml-eslint-parser@1.3.2: resolution: {integrity: sha512-odxVsHAkZYYglR30aPYRY4nUGJnoJ2y1ww2HDvZALo0BDETv9kWbi16J52eHs+PWRNmF4ub6nZqfVOeesOvntg==} engines: {node: ^14.17.0 || >=16.0.0} @@ -10273,12 +9611,6 @@ packages: resolution: {integrity: sha512-CzhO+pFNo8ajLM2d2IW/R93ipy99LWjtwblvC1RsoSUMZgyLbYFr221TnSNT7GjGdYui6P459mw9JH/g/zW2ug==} engines: {node: '>=18'} - youch-core@0.3.3: - resolution: {integrity: sha512-ho7XuGjLaJ2hWHoK8yFnsUGy2Y5uDpqSTq1FkHLK4/oqKtyUU1AFbOOxY4IpC9f0fTLjwYbslUz0Po5BpD1wrA==} - - youch@4.1.0: - resolution: {integrity: sha512-cYekNh2tUoU+voS11X0D0UQntVCSO6LQ1h10VriQGmfbpf0mnGTruwZICts23UUNiZCXm8H8hQBtRrdsbhuNNg==} - zip-stream@6.0.1: resolution: {integrity: sha512-zK7YHHz4ZXpW89AHXUPbQVGKI7uvkd3hzusTdotCg1UxyaVtg0zFJSTfW/Dq5f7OBBVnq6cZIaC8Ti4hb6dtCA==} engines: {node: '>= 14'} @@ -11413,8 +10745,6 @@ snapshots: '@clack/core': 1.1.0 sisteransi: 1.0.5 - '@cloudflare/kv-asset-handler@0.4.2': {} - '@cspell/cspell-bundled-dicts@9.7.0': dependencies: '@cspell/dict-ada': 4.1.1 @@ -12142,8 +11472,6 @@ snapshots: vue: 3.5.30(typescript@5.9.3) vue-i18n: 11.3.0(vue@3.5.30(typescript@5.9.3)) - '@ioredis/commands@1.5.1': {} - '@isaacs/cliui@8.0.2': dependencies: string-width: 5.1.2 @@ -12155,10 +11483,6 @@ snapshots: '@isaacs/cliui@9.0.0': {} - '@isaacs/fs-minipass@4.0.1': - dependencies: - minipass: 7.1.3 - '@jridgewell/gen-mapping@0.3.13': dependencies: '@jridgewell/sourcemap-codec': 1.5.5 @@ -12242,19 +11566,6 @@ snapshots: js-yaml: 4.1.1 tinyglobby: 0.2.15 - '@mapbox/node-pre-gyp@2.0.3': - dependencies: - consola: 3.4.2 - detect-libc: 2.1.2 - https-proxy-agent: 7.0.6 - node-fetch: 2.7.0 - nopt: 8.1.0 - semver: 7.7.4 - tar: 7.5.12 - transitivePeerDependencies: - - encoding - - supports-color - '@napi-rs/wasm-runtime@1.1.1': dependencies: '@emnapi/core': 1.9.1 @@ -12393,11 +11704,6 @@ snapshots: '@parcel/watcher-linux-x64-musl@2.5.6': optional: true - '@parcel/watcher-wasm@2.5.6': - dependencies: - is-glob: 4.0.3 - picomatch: 4.0.3 - '@parcel/watcher-win32-arm64@2.5.6': optional: true @@ -12427,16 +11733,13 @@ snapshots: '@parcel/watcher-win32-arm64': 2.5.6 '@parcel/watcher-win32-ia32': 2.5.6 '@parcel/watcher-win32-x64': 2.5.6 + optional: true '@pkgjs/parseargs@0.11.0': optional: true '@pkgr/core@0.2.9': {} - '@playwright/test@1.58.2': - dependencies: - playwright: 1.58.2 - '@pnpm/config.env-replace@1.1.0': {} '@pnpm/constants@1001.3.1': {} @@ -12468,18 +11771,6 @@ snapshots: '@popperjs/core@2.11.8': {} - '@poppinss/colors@4.1.6': - dependencies: - kleur: 4.1.5 - - '@poppinss/dumper@0.7.0': - dependencies: - '@poppinss/colors': 4.1.6 - '@sindresorhus/is': 7.2.0 - supports-color: 10.2.2 - - '@poppinss/exception@1.2.3': {} - '@publint/pack@0.1.4': {} '@quansync/fs@1.0.0': @@ -12586,10 +11877,6 @@ snapshots: '@rolldown/pluginutils@1.0.0-rc.9': {} - '@rollup/plugin-alias@6.0.0(rollup@4.60.0)': - optionalDependencies: - rollup: 4.60.0 - '@rollup/plugin-babel@5.3.1(@babel/core@7.29.0)(rollup@2.80.0)': dependencies: '@babel/core': 7.29.0 @@ -12599,32 +11886,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@rollup/plugin-commonjs@29.0.2(rollup@4.60.0)': - dependencies: - '@rollup/pluginutils': 5.3.0(rollup@4.60.0) - commondir: 1.0.1 - estree-walker: 2.0.2 - fdir: 6.5.0(picomatch@4.0.3) - is-reference: 1.2.1 - magic-string: 0.30.21 - picomatch: 4.0.3 - optionalDependencies: - rollup: 4.60.0 - - '@rollup/plugin-inject@5.0.5(rollup@4.60.0)': - dependencies: - '@rollup/pluginutils': 5.3.0(rollup@4.60.0) - estree-walker: 2.0.2 - magic-string: 0.30.21 - optionalDependencies: - rollup: 4.60.0 - - '@rollup/plugin-json@6.1.0(rollup@4.60.0)': - dependencies: - '@rollup/pluginutils': 5.3.0(rollup@4.60.0) - optionalDependencies: - rollup: 4.60.0 - '@rollup/plugin-node-resolve@15.3.1(rollup@2.80.0)': dependencies: '@rollup/pluginutils': 5.3.0(rollup@2.80.0) @@ -12635,29 +11896,12 @@ snapshots: optionalDependencies: rollup: 2.80.0 - '@rollup/plugin-node-resolve@16.0.3(rollup@4.60.0)': - dependencies: - '@rollup/pluginutils': 5.3.0(rollup@4.60.0) - '@types/resolve': 1.20.2 - deepmerge: 4.3.1 - is-module: 1.0.0 - resolve: 1.22.11 - optionalDependencies: - rollup: 4.60.0 - '@rollup/plugin-replace@2.4.2(rollup@2.80.0)': dependencies: '@rollup/pluginutils': 3.1.0(rollup@2.80.0) magic-string: 0.25.9 rollup: 2.80.0 - '@rollup/plugin-replace@6.0.3(rollup@4.60.0)': - dependencies: - '@rollup/pluginutils': 5.3.0(rollup@4.60.0) - magic-string: 0.30.21 - optionalDependencies: - rollup: 4.60.0 - '@rollup/plugin-terser@0.4.4(rollup@2.80.0)': dependencies: serialize-javascript: 6.0.2 @@ -12666,14 +11910,6 @@ snapshots: optionalDependencies: rollup: 2.80.0 - '@rollup/plugin-terser@1.0.0(rollup@4.60.0)': - dependencies: - serialize-javascript: 7.0.4 - smob: 1.6.1 - terser: 5.46.1 - optionalDependencies: - rollup: 4.60.0 - '@rollup/pluginutils@3.1.0(rollup@2.80.0)': dependencies: '@types/estree': 0.0.39 @@ -12824,14 +12060,10 @@ snapshots: core-js: 3.49.0 nanopop: 2.4.2 - '@sindresorhus/is@7.2.0': {} - '@sindresorhus/merge-streams@2.3.0': {} '@sindresorhus/merge-streams@4.0.0': {} - '@speed-highlight/core@1.2.15': {} - '@standard-schema/spec@1.1.0': {} '@stylistic/stylelint-plugin@5.0.1(stylelint@17.5.0(typescript@5.9.3))': @@ -12929,24 +12161,10 @@ snapshots: tailwindcss: 4.2.2 vite: 8.0.1(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(less@4.6.4)(sass-embedded@1.98.0)(sass@1.98.0)(terser@5.46.1)(yaml@2.8.3) - '@tanstack/match-sorter-utils@8.19.4': - dependencies: - remove-accents: 0.5.0 - - '@tanstack/query-core@5.95.0': {} - '@tanstack/store@0.9.2': {} '@tanstack/virtual-core@3.13.23': {} - '@tanstack/vue-query@5.95.0(vue@3.5.30(typescript@5.9.3))': - dependencies: - '@tanstack/match-sorter-utils': 8.19.4 - '@tanstack/query-core': 5.95.0 - '@vue/devtools-api': 6.6.4 - vue: 3.5.30(typescript@5.9.3) - vue-demi: 0.14.10(vue@3.5.30(typescript@5.9.3)) - '@tanstack/vue-store@0.9.2(vue@3.5.30(typescript@5.9.3))': dependencies: '@tanstack/store': 0.9.2 @@ -13426,25 +12644,6 @@ snapshots: transitivePeerDependencies: - vue - '@vercel/nft@1.5.0(rollup@4.60.0)': - dependencies: - '@mapbox/node-pre-gyp': 2.0.3 - '@rollup/pluginutils': 5.3.0(rollup@4.60.0) - acorn: 8.16.0 - acorn-import-attributes: 1.9.5(acorn@8.16.0) - async-sema: 3.1.1 - bindings: 1.5.0 - estree-walker: 2.0.2 - glob: 13.0.6 - graceful-fs: 4.2.11 - node-gyp-build: 4.8.4 - picomatch: 4.0.3 - resolve-from: 5.0.0 - transitivePeerDependencies: - - encoding - - rollup - - supports-color - '@vite-pwa/vitepress@1.1.0(vite-plugin-pwa@1.2.0(vite@8.0.1(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(less@4.6.4)(sass-embedded@1.98.0)(sass@1.98.0)(terser@5.46.1)(yaml@2.8.3))(workbox-build@7.4.0)(workbox-window@7.4.0))': dependencies: vite-plugin-pwa: 1.2.0(vite@8.0.1(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(less@4.6.4)(sass-embedded@1.98.0)(sass@1.98.0)(terser@5.46.1)(yaml@2.8.3))(workbox-build@7.4.0)(workbox-window@7.4.0) @@ -13796,16 +12995,10 @@ snapshots: abbrev@2.0.0: {} - abbrev@3.0.1: {} - abort-controller@3.0.0: dependencies: event-target-shim: 5.0.1 - acorn-import-attributes@1.9.5(acorn@8.16.0): - dependencies: - acorn: 8.16.0 - acorn-jsx@5.3.2(acorn@8.16.0): dependencies: acorn: 8.16.0 @@ -13814,8 +13007,6 @@ snapshots: address@1.2.2: {} - agent-base@7.1.4: {} - agentkeepalive@3.5.3: dependencies: humanize-ms: 1.2.1 @@ -13989,11 +13180,6 @@ snapshots: any-promise@1.3.0: {} - anymatch@3.1.3: - dependencies: - normalize-path: 3.0.0 - picomatch: 2.3.1 - archiver-utils@5.0.2: dependencies: glob: 10.4.5 @@ -14075,8 +13261,6 @@ snapshots: async-function@1.0.0: {} - async-sema@3.1.1: {} - async-validator@4.2.5: {} async@3.2.6: {} @@ -14181,10 +13365,6 @@ snapshots: bignumber.js@9.3.1: {} - bindings@1.5.0: - dependencies: - file-uri-to-path: 1.0.0 - birpc@2.9.0: {} birpc@4.0.0: {} @@ -14267,6 +13447,7 @@ snapshots: rc9: 2.1.2 optionalDependencies: magicast: 0.5.2 + optional: true cac@7.0.0: {} @@ -14379,8 +13560,6 @@ snapshots: dependencies: readdirp: 5.0.0 - chownr@3.0.0: {} - ci-info@4.4.0: {} circular-dependency-scanner@3.0.1: @@ -14399,8 +13578,10 @@ snapshots: citty@0.1.6: dependencies: consola: 3.4.2 + optional: true - citty@0.2.1: {} + citty@0.2.1: + optional: true class-variance-authority@0.7.1: dependencies: @@ -14438,12 +13619,6 @@ snapshots: select: 1.1.2 tiny-emitter: 2.1.0 - clipboardy@4.0.0: - dependencies: - execa: 8.0.1 - is-wsl: 3.1.1 - is64bit: 2.0.0 - cliui@6.0.0: dependencies: string-width: 4.2.3 @@ -14464,8 +13639,6 @@ snapshots: clsx@2.1.1: {} - cluster-key-slot@1.1.2: {} - color-convert@2.0.1: dependencies: color-name: 1.1.4 @@ -14501,12 +13674,8 @@ snapshots: common-tags@1.8.2: {} - commondir@1.0.1: {} - compare-versions@6.1.1: {} - compatx@0.2.0: {} - compress-commons@6.0.2: dependencies: crc-32: 1.2.2 @@ -14547,10 +13716,6 @@ snapshots: convert-source-map@2.0.0: {} - cookie-es@1.2.2: {} - - cookie-es@2.0.0: {} - copy-anything@3.0.5: dependencies: is-what: 4.1.16 @@ -14593,8 +13758,6 @@ snapshots: crc-32: 1.2.2 readable-stream: 4.7.0 - croner@10.0.1: {} - cross-env@10.1.0: dependencies: '@epic-web/invariant': 1.0.0 @@ -14606,10 +13769,6 @@ snapshots: shebang-command: 2.0.0 which: 2.0.2 - crossws@0.3.5: - dependencies: - uncrypto: 0.1.3 - crypto-js@4.2.0: {} crypto-random-string@2.0.0: {} @@ -14777,8 +13936,6 @@ snapshots: dayjs@1.11.20: {} - db0@0.3.4: {} - debug@2.6.9: dependencies: ms: 2.0.0 @@ -14831,8 +13988,6 @@ snapshots: delegate@3.2.0: {} - denque@2.1.0: {} - depcheck@1.4.7: dependencies: '@babel/parser': 7.29.2 @@ -14861,13 +14016,12 @@ snapshots: transitivePeerDependencies: - supports-color - depd@2.0.0: {} - deps-regex@0.2.0: {} dequal@2.0.3: {} - destr@2.0.5: {} + destr@2.0.5: + optional: true destroy@1.2.0: {} @@ -14936,10 +14090,6 @@ snapshots: no-case: 3.0.4 tslib: 2.8.1 - dot-prop@10.1.0: - dependencies: - type-fest: 5.5.0 - dot-prop@9.0.0: dependencies: type-fest: 4.41.0 @@ -14960,8 +14110,6 @@ snapshots: es-errors: 1.3.0 gopd: 1.2.0 - duplexer@0.1.2: {} - eastasianwidth@0.2.0: {} echarts@6.0.0: @@ -14994,8 +14142,6 @@ snapshots: empathic@2.0.0: {} - encodeurl@2.0.0: {} - encoding-sniffer@0.2.1: dependencies: iconv-lite: 0.6.3 @@ -15235,6 +14381,7 @@ snapshots: '@esbuild/win32-arm64': 0.27.4 '@esbuild/win32-ia32': 0.27.4 '@esbuild/win32-x64': 0.27.4 + optional: true escalade@3.2.0: {} @@ -15467,8 +14614,6 @@ snapshots: esutils@2.0.3: {} - etag@1.8.1: {} - event-emitter@0.3.5: dependencies: d: 1.0.2 @@ -15489,18 +14634,6 @@ snapshots: eventsource@2.0.2: {} - execa@8.0.1: - dependencies: - cross-spawn: 7.0.6 - get-stream: 8.0.1 - human-signals: 5.0.0 - is-stream: 3.0.0 - merge-stream: 2.0.0 - npm-run-path: 5.3.0 - onetime: 6.0.0 - signal-exit: 4.1.0 - strip-final-newline: 3.0.0 - execa@9.6.1: dependencies: '@sindresorhus/merge-streams': 4.0.0 @@ -15588,8 +14721,6 @@ snapshots: dependencies: flat-cache: 4.0.1 - file-uri-to-path@1.0.0: {} - filelist@1.0.6: dependencies: minimatch: 5.1.9 @@ -15675,8 +14806,6 @@ snapshots: dependencies: tslib: 2.4.0 - fresh@2.0.0: {} - fs-extra@10.1.0: dependencies: graceful-fs: 4.2.11 @@ -15706,9 +14835,6 @@ snapshots: dependencies: minipass: 7.1.3 - fsevents@2.3.2: - optional: true - fsevents@2.3.3: optional: true @@ -15750,10 +14876,6 @@ snapshots: get-own-enumerable-property-symbols@3.0.2: {} - get-port-please@3.2.0: {} - - get-port@7.2.0: {} - get-proto@1.0.1: dependencies: dunder-proto: 1.0.1 @@ -15761,8 +14883,6 @@ snapshots: get-ready@1.0.0: {} - get-stream@8.0.1: {} - get-stream@9.0.1: dependencies: '@sec-ant/readable-stream': 0.4.1 @@ -15786,6 +14906,7 @@ snapshots: node-fetch-native: 1.6.7 nypm: 0.6.5 pathe: 2.0.3 + optional: true glob-parent@5.1.2: dependencies: @@ -15910,22 +15031,6 @@ snapshots: section-matter: 1.0.0 strip-bom-string: 1.0.0 - gzip-size@7.0.0: - dependencies: - duplexer: 0.1.2 - - h3@1.15.10: - dependencies: - cookie-es: 1.2.2 - crossws: 0.3.5 - defu: 6.1.4 - destr: 2.0.5 - iron-webcrypto: 1.2.1 - node-mock-http: 1.0.4 - radix3: 1.1.2 - ufo: 1.6.3 - uncrypto: 0.1.3 - happy-dom@20.8.4(bufferutil@4.1.0)(utf-8-validate@5.0.10): dependencies: '@types/node': 25.5.0 @@ -16038,31 +15143,10 @@ snapshots: domutils: 3.2.2 entities: 4.5.0 - http-errors@2.0.1: - dependencies: - depd: 2.0.0 - inherits: 2.0.4 - setprototypeof: 1.2.0 - statuses: 2.0.2 - toidentifier: 1.0.1 - http-parser-js@0.5.10: {} - http-shutdown@1.2.2: {} - - https-proxy-agent@7.0.6: - dependencies: - agent-base: 7.1.4 - debug: 4.4.3 - transitivePeerDependencies: - - supports-color - - httpxy@0.3.1: {} - human-id@4.1.3: {} - human-signals@5.0.0: {} - human-signals@8.0.1: {} humanize-ms@1.2.1: @@ -16117,22 +15201,6 @@ snapshots: hasown: 2.0.2 side-channel: 1.1.0 - ioredis@5.10.1: - dependencies: - '@ioredis/commands': 1.5.1 - cluster-key-slot: 1.1.2 - debug: 4.4.3 - denque: 2.1.0 - lodash.defaults: 4.2.0 - lodash.isarguments: 3.1.0 - redis-errors: 1.2.0 - redis-parser: 3.0.0 - standard-as-callback: 2.1.0 - transitivePeerDependencies: - - supports-color - - iron-webcrypto@1.2.1: {} - is-array-buffer@3.0.5: dependencies: call-bind: 1.0.8 @@ -16251,10 +15319,6 @@ snapshots: is-plain-object@5.0.0: {} - is-reference@1.2.1: - dependencies: - '@types/estree': 1.0.8 - is-regex@1.2.1: dependencies: call-bound: 1.0.4 @@ -16274,8 +15338,6 @@ snapshots: is-stream@2.0.1: {} - is-stream@3.0.0: {} - is-stream@4.0.1: {} is-string@1.1.1: @@ -16329,10 +15391,6 @@ snapshots: dependencies: is-inside-container: 1.0.0 - is64bit@2.0.0: - dependencies: - system-architecture: 0.1.0 - isarray@1.0.0: {} isarray@2.0.5: {} @@ -16443,11 +15501,11 @@ snapshots: kind-of@6.0.3: {} - kleur@4.1.5: {} + klona@2.0.6: + optional: true - klona@2.0.6: {} - - knitwork@1.3.0: {} + knitwork@1.3.0: + optional: true known-css-properties@0.37.0: {} @@ -16536,27 +15594,6 @@ snapshots: lines-and-columns@1.2.4: {} - listhen@1.9.0: - dependencies: - '@parcel/watcher': 2.5.6 - '@parcel/watcher-wasm': 2.5.6 - citty: 0.1.6 - clipboardy: 4.0.0 - consola: 3.4.2 - crossws: 0.3.5 - defu: 6.1.4 - get-port-please: 3.2.0 - h3: 1.15.10 - http-shutdown: 1.2.2 - jiti: 2.6.1 - mlly: 1.8.2 - node-forge: 1.3.3 - pathe: 1.1.2 - std-env: 3.10.0 - ufo: 1.6.3 - untun: 0.1.3 - uqr: 0.1.2 - listr2@9.0.5: dependencies: cli-truncate: 5.2.0 @@ -16592,10 +15629,6 @@ snapshots: lodash.debounce@4.0.8: {} - lodash.defaults@4.2.0: {} - - lodash.isarguments@3.1.0: {} - lodash.sortby@4.7.0: {} lodash.startcase@4.4.0: {} @@ -16656,6 +15689,7 @@ snapshots: '@babel/parser': 7.29.2 '@babel/types': 7.29.0 source-map-js: 1.2.1 + optional: true make-dir@2.1.0: dependencies: @@ -16691,8 +15725,6 @@ snapshots: merge-descriptors@1.0.3: {} - merge-stream@2.0.0: {} - merge2@1.4.1: {} micromark-util-character@2.1.1: @@ -16719,25 +15751,15 @@ snapshots: mime-db@1.52.0: {} - mime-db@1.54.0: {} - mime-types@2.1.35: dependencies: mime-db: 1.52.0 - mime-types@3.0.2: - dependencies: - mime-db: 1.54.0 - mime@1.6.0: optional: true mime@2.6.0: {} - mime@4.1.0: {} - - mimic-fn@4.0.0: {} - mimic-function@5.0.1: {} minimatch@10.2.4: @@ -16782,10 +15804,6 @@ snapshots: minisearch@7.2.0: {} - minizlib@3.1.0: - dependencies: - minipass: 7.1.3 - mitt@3.0.1: {} mkdirp@0.5.6: @@ -16843,117 +15861,13 @@ snapshots: next-tick@1.1.0: optional: true - nitropack@2.13.2(rolldown@1.0.0-rc.10)(xml2js@0.6.2): - dependencies: - '@cloudflare/kv-asset-handler': 0.4.2 - '@rollup/plugin-alias': 6.0.0(rollup@4.60.0) - '@rollup/plugin-commonjs': 29.0.2(rollup@4.60.0) - '@rollup/plugin-inject': 5.0.5(rollup@4.60.0) - '@rollup/plugin-json': 6.1.0(rollup@4.60.0) - '@rollup/plugin-node-resolve': 16.0.3(rollup@4.60.0) - '@rollup/plugin-replace': 6.0.3(rollup@4.60.0) - '@rollup/plugin-terser': 1.0.0(rollup@4.60.0) - '@vercel/nft': 1.5.0(rollup@4.60.0) - archiver: 7.0.1 - c12: 3.3.3(magicast@0.5.2) - chokidar: 5.0.0 - citty: 0.2.1 - compatx: 0.2.0 - confbox: 0.2.4 - consola: 3.4.2 - cookie-es: 2.0.0 - croner: 10.0.1 - crossws: 0.3.5 - db0: 0.3.4 - defu: 6.1.4 - destr: 2.0.5 - dot-prop: 10.1.0 - esbuild: 0.27.4 - escape-string-regexp: 5.0.0 - etag: 1.8.1 - exsolve: 1.0.8 - globby: 16.1.1 - gzip-size: 7.0.0 - h3: 1.15.10 - hookable: 5.5.3 - httpxy: 0.3.1 - ioredis: 5.10.1 - jiti: 2.6.1 - klona: 2.0.6 - knitwork: 1.3.0 - listhen: 1.9.0 - magic-string: 0.30.21 - magicast: 0.5.2 - mime: 4.1.0 - mlly: 1.8.2 - node-fetch-native: 1.6.7 - node-mock-http: 1.0.4 - ofetch: 1.5.1 - ohash: 2.0.11 - pathe: 2.0.3 - perfect-debounce: 2.1.0 - pkg-types: 2.3.0 - pretty-bytes: 7.1.0 - radix3: 1.1.2 - rollup: 4.60.0 - rollup-plugin-visualizer: 7.0.1(rolldown@1.0.0-rc.10)(rollup@4.60.0) - scule: 1.3.0 - semver: 7.7.4 - serve-placeholder: 2.0.2 - serve-static: 2.2.1 - source-map: 0.7.6 - std-env: 4.0.0 - ufo: 1.6.3 - ultrahtml: 1.6.0 - uncrypto: 0.1.3 - unctx: 2.5.0 - unenv: 2.0.0-rc.24 - unimport: 6.0.2 - unplugin-utils: 0.3.1 - unstorage: 1.17.4(db0@0.3.4)(ioredis@5.10.1) - untyped: 2.0.0 - unwasm: 0.5.3 - youch: 4.1.0 - youch-core: 0.3.3 - optionalDependencies: - xml2js: 0.6.2 - transitivePeerDependencies: - - '@azure/app-configuration' - - '@azure/cosmos' - - '@azure/data-tables' - - '@azure/identity' - - '@azure/keyvault-secrets' - - '@azure/storage-blob' - - '@capacitor/preferences' - - '@deno/kv' - - '@electric-sql/pglite' - - '@libsql/client' - - '@netlify/blobs' - - '@planetscale/database' - - '@upstash/redis' - - '@vercel/blob' - - '@vercel/functions' - - '@vercel/kv' - - aws4fetch - - bare-abort-controller - - bare-buffer - - better-sqlite3 - - drizzle-orm - - encoding - - idb-keyval - - mysql2 - - react-native-b4a - - rolldown - - sqlite3 - - supports-color - - uploadthing - no-case@3.0.4: dependencies: lower-case: 2.0.2 tslib: 2.8.1 - node-addon-api@7.1.1: {} + node-addon-api@7.1.1: + optional: true node-cleanup@2.1.2: {} @@ -16966,7 +15880,8 @@ snapshots: locko: 1.1.0 node-fetch: 3.3.2 - node-fetch-native@1.6.7: {} + node-fetch-native@1.6.7: + optional: true node-fetch@2.7.0: dependencies: @@ -16978,9 +15893,8 @@ snapshots: fetch-blob: 3.2.0 formdata-polyfill: 4.0.10 - node-forge@1.3.3: {} - - node-gyp-build@4.8.4: {} + node-gyp-build@4.8.4: + optional: true node-hex@1.0.1: {} @@ -16989,24 +15903,14 @@ snapshots: css-select: 4.3.0 he: 1.2.0 - node-mock-http@1.0.4: {} - node-releases@2.0.36: {} nopt@7.2.1: dependencies: abbrev: 2.0.0 - nopt@8.1.0: - dependencies: - abbrev: 3.0.1 - normalize-path@3.0.0: {} - npm-run-path@5.3.0: - dependencies: - path-key: 4.0.0 - npm-run-path@6.0.0: dependencies: path-key: 4.0.0 @@ -17023,6 +15927,7 @@ snapshots: citty: 0.2.1 pathe: 2.0.3 tinyexec: 1.0.4 + optional: true object-assign@4.1.1: {} @@ -17041,26 +15946,12 @@ snapshots: obug@2.1.1: {} - ofetch@1.5.1: - dependencies: - destr: 2.0.5 - node-fetch-native: 1.6.7 - ufo: 1.6.3 - ohash@2.0.11: {} - on-finished@2.4.1: - dependencies: - ee-first: 1.1.1 - once@1.4.0: dependencies: wrappy: 1.0.2 - onetime@6.0.0: - dependencies: - mimic-fn: 4.0.0 - onetime@7.0.0: dependencies: mimic-function: 5.0.1 @@ -17214,8 +16105,6 @@ snapshots: dependencies: entities: 6.0.1 - parseurl@1.3.3: {} - pascal-case@3.1.2: dependencies: no-case: 3.0.4 @@ -17247,8 +16136,6 @@ snapshots: pathe@0.2.0: {} - pathe@1.1.2: {} - pathe@2.0.3: {} pause-stream@0.0.11: @@ -17295,14 +16182,6 @@ snapshots: platform@1.3.6: {} - playwright-core@1.58.2: {} - - playwright@1.58.2: - dependencies: - playwright-core: 1.58.2 - optionalDependencies: - fsevents: 2.3.2 - please-upgrade-node@3.2.0: dependencies: semver-compare: 1.0.0 @@ -17389,8 +16268,6 @@ snapshots: pretty-bytes@6.1.1: {} - pretty-bytes@7.1.0: {} - pretty-ms@9.3.0: dependencies: parse-ms: 4.0.0 @@ -17448,18 +16325,15 @@ snapshots: queue-microtask@1.2.3: {} - radix3@1.1.2: {} - randombytes@2.1.0: dependencies: safe-buffer: 5.2.1 - range-parser@1.2.1: {} - rc9@2.1.2: dependencies: defu: 6.1.4 destr: 2.0.5 + optional: true rc9@3.0.0: dependencies: @@ -17516,12 +16390,6 @@ snapshots: readdirp@5.0.0: {} - redis-errors@1.2.0: {} - - redis-parser@3.0.0: - dependencies: - redis-errors: 1.2.0 - reflect.getprototypeof@1.0.10: dependencies: call-bind: 1.0.8 @@ -17601,8 +16469,6 @@ snapshots: relateurl@0.2.7: {} - remove-accents@0.5.0: {} - require-directory@2.1.1: {} require-from-string@2.0.2: {} @@ -17925,41 +16791,10 @@ snapshots: semver@7.7.4: {} - send@1.2.1: - dependencies: - debug: 4.4.3 - encodeurl: 2.0.0 - escape-html: 1.0.3 - etag: 1.8.1 - fresh: 2.0.0 - http-errors: 2.0.1 - mime-types: 3.0.2 - ms: 2.1.3 - on-finished: 2.4.1 - range-parser: 1.2.1 - statuses: 2.0.2 - transitivePeerDependencies: - - supports-color - serialize-javascript@6.0.2: dependencies: randombytes: 2.1.0 - serialize-javascript@7.0.4: {} - - serve-placeholder@2.0.2: - dependencies: - defu: 6.1.4 - - serve-static@2.2.1: - dependencies: - encodeurl: 2.0.0 - escape-html: 1.0.3 - parseurl: 1.3.3 - send: 1.2.1 - transitivePeerDependencies: - - supports-color - set-blocking@2.0.0: {} set-function-length@1.2.2: @@ -17984,8 +16819,6 @@ snapshots: es-errors: 1.3.0 es-object-atoms: 1.1.1 - setprototypeof@1.2.0: {} - shallow-equal@1.2.1: {} shebang-command@2.0.0: @@ -18115,14 +16948,8 @@ snapshots: stackback@0.0.2: {} - standard-as-callback@2.1.0: {} - statuses@1.5.0: {} - statuses@2.0.2: {} - - std-env@3.10.0: {} - std-env@4.0.0: {} stdin-discarder@0.3.1: {} @@ -18254,18 +17081,12 @@ snapshots: strip-comments@2.0.1: {} - strip-final-newline@3.0.0: {} - strip-final-newline@4.0.0: {} strip-indent@4.1.1: {} strip-json-comments@2.0.1: {} - strip-literal@3.1.0: - dependencies: - js-tokens: 9.0.1 - stubborn-fs@2.0.0: dependencies: stubborn-utils: 1.0.2 @@ -18423,8 +17244,6 @@ snapshots: dependencies: '@pkgr/core': 0.2.9 - system-architecture@0.1.0: {} - tabbable@6.4.0: {} table@6.9.0: @@ -18435,8 +17254,6 @@ snapshots: string-width: 4.2.3 strip-ansi: 6.0.1 - tagged-tag@1.0.0: {} - tailwind-merge@3.5.0: {} tailwindcss@4.2.2: {} @@ -18454,14 +17271,6 @@ snapshots: - bare-buffer - react-native-b4a - tar@7.5.12: - dependencies: - '@isaacs/fs-minipass': 4.0.1 - chownr: 3.0.0 - minipass: 7.1.3 - minizlib: 3.1.0 - yallist: 5.0.0 - teex@1.0.1: dependencies: streamx: 2.25.0 @@ -18530,8 +17339,6 @@ snapshots: dependencies: is-number: 7.0.0 - toidentifier@1.0.1: {} - totalist@3.0.1: {} tr46@0.0.3: {} @@ -18607,10 +17414,6 @@ snapshots: type-fest@4.41.0: {} - type-fest@5.5.0: - dependencies: - tagged-tag: 1.0.0 - type@2.7.3: optional: true @@ -18656,8 +17459,6 @@ snapshots: ufo@1.6.3: {} - ultrahtml@1.6.0: {} - unbox-primitive@1.1.0: dependencies: call-bound: 1.0.4 @@ -18678,15 +17479,12 @@ snapshots: estree-walker: 3.0.3 magic-string: 0.30.21 unplugin: 2.3.11 + optional: true undici-types@7.18.2: {} undici@7.24.5: {} - unenv@2.0.0-rc.24: - dependencies: - pathe: 2.0.3 - unescape@1.0.1: dependencies: extend-shallow: 2.0.1 @@ -18706,23 +17504,6 @@ snapshots: unicorn-magic@0.4.0: {} - unimport@6.0.2: - dependencies: - acorn: 8.16.0 - escape-string-regexp: 5.0.0 - estree-walker: 3.0.3 - local-pkg: 1.1.2 - magic-string: 0.30.21 - mlly: 1.8.2 - pathe: 2.0.3 - picomatch: 4.0.3 - pkg-types: 2.3.0 - scule: 1.3.0 - strip-literal: 3.1.0 - tinyglobby: 0.2.15 - unplugin: 3.0.0 - unplugin-utils: 0.3.1 - unique-string@2.0.0: dependencies: crypto-random-string: 2.0.0 @@ -18820,26 +17601,6 @@ snapshots: optionalDependencies: synckit: 0.11.12 - unstorage@1.17.4(db0@0.3.4)(ioredis@5.10.1): - dependencies: - anymatch: 3.1.3 - chokidar: 5.0.0 - destr: 2.0.5 - h3: 1.15.10 - lru-cache: 11.2.7 - node-fetch-native: 1.6.7 - ofetch: 1.5.1 - ufo: 1.6.3 - optionalDependencies: - db0: 0.3.4 - ioredis: 5.10.1 - - untun@0.1.3: - dependencies: - citty: 0.1.6 - consola: 3.4.2 - pathe: 1.1.2 - untyped@2.0.0: dependencies: citty: 0.1.6 @@ -18847,15 +17608,7 @@ snapshots: jiti: 2.6.1 knitwork: 1.3.0 scule: 1.3.0 - - unwasm@0.5.3: - dependencies: - exsolve: 1.0.8 - knitwork: 1.3.0 - magic-string: 0.30.21 - mlly: 1.8.2 - pathe: 2.0.3 - pkg-types: 2.3.0 + optional: true upath@1.2.0: {} @@ -18878,8 +17631,6 @@ snapshots: semver: 7.7.4 xdg-basedir: 5.1.0 - uqr@0.1.2: {} - uri-js@4.4.1: dependencies: punycode: 2.3.1 @@ -19554,8 +18305,6 @@ snapshots: yallist@4.0.0: {} - yallist@5.0.0: {} - yaml-eslint-parser@1.3.2: dependencies: eslint-visitor-keys: 3.4.3 @@ -19618,19 +18367,6 @@ snapshots: yoctocolors@2.1.2: {} - youch-core@0.3.3: - dependencies: - '@poppinss/exception': 1.2.3 - error-stack-parser-es: 1.0.5 - - youch@4.1.0: - dependencies: - '@poppinss/colors': 4.1.6 - '@poppinss/dumper': 0.7.0 - '@speed-highlight/core': 1.2.15 - cookie-es: 2.0.0 - youch-core: 0.3.3 - zip-stream@6.0.1: dependencies: archiver-utils: 5.0.2 diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index db14b9c..8f2b850 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -11,7 +11,6 @@ packages: - apps - scripts/* - docs - - playground overrides: '@ast-grep/napi': 'catalog:' diff --git a/scripts/deploy/Dockerfile b/scripts/deploy/Dockerfile index 862673c..aed70a4 100644 --- a/scripts/deploy/Dockerfile +++ b/scripts/deploy/Dockerfile @@ -27,7 +27,7 @@ RUN echo "types { application/javascript js mjs; }" > /etc/nginx/conf.d/mjs.conf && rm -rf /etc/nginx/conf.d/default.conf # 复制构建产物 -COPY --from=builder /app/playground/dist /usr/share/nginx/html +COPY --from=builder /app/apps/dist /usr/share/nginx/html # 复制 nginx 配置 COPY --from=builder /app/scripts/deploy/nginx.conf /etc/nginx/nginx.conf diff --git a/turbo.json b/turbo.json index ff3070b..2c746a1 100644 --- a/turbo.json +++ b/turbo.json @@ -30,7 +30,6 @@ "dependsOn": ["^build"], "outputs": ["dist/**"] }, - "test:e2e": {}, "dev": { "dependsOn": [], "outputs": [], diff --git a/vben-admin.code-workspace b/vben-admin.code-workspace index 9fac3c6..8091dd8 100644 --- a/vben-admin.code-workspace +++ b/vben-admin.code-workspace @@ -136,10 +136,6 @@ "name": "@vben/utils", "path": "packages/utils" }, - { - "name": "@vben/playground", - "path": "playground" - }, { "name": "@vben/turbo-run", "path": "scripts/turbo-run"