hookehuyr

chore: 添加测试框架和更新项目文档

- 配置 Vitest 测试框架
- 添加 search/index.test.js 测试套件
- 更新 README.md 和 MaterialCard 组件文档
- 更新 pnpm 依赖

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
......@@ -45,6 +45,13 @@ pnpm lint
-**组件复用** - "第 3 次出现原则"抽取 Composables
-**可复用组件** - TabBar、NavHeader、IconFont
## 🆕 最新更新(2026-02-13)
### 权限与测试
-**资料查看权限** - 资料查看入口增加登录校验,支持动作级权限扩展
-**回跳路径统一** - 统一保存登录回跳路径,确保权限拦截后可恢复
-**搜索页测试** - 搜索页测试对齐当前实现并补充接口 Mock
## 🆕 最新更新(2026-02-12)
### 计划书功能优化
......
......@@ -28,6 +28,7 @@
"dev:quickapp": "NODE_ENV=development taro build --type quickapp --watch",
"postinstall": "weapp-tw patch",
"lint": "eslint --ext .js,.vue src",
"test": "vitest run",
"api:generate": "node scripts/generateApiFromOpenAPI.js",
"changelog:check": "bash scripts/check-changelog.sh 7",
"changelog:check:30": "bash scripts/check-changelog.sh 30",
......@@ -77,8 +78,10 @@
"@tarojs/taro-loader": "4.1.11",
"@tarojs/webpack5-runner": "4.1.11",
"@types/webpack-env": "^1.13.6",
"@vitejs/plugin-vue": "^5.2.4",
"@vue/babel-plugin-jsx": "^1.0.6",
"@vue/compiler-sfc": "^3.0.0",
"@vue/test-utils": "^2.4.6",
"autoprefixer": "^10.4.21",
"babel-preset-taro": "4.1.11",
"css-loader": "3.4.2",
......@@ -87,6 +90,7 @@
"eslint-plugin-react": "^7.33.2",
"eslint-plugin-react-hooks": "^4.4.0",
"eslint-plugin-vue": "^8.0.0",
"happy-dom": "^14.12.0",
"husky": "^9.1.7",
"js-yaml": "^4.1.1",
"less": "^4.2.0",
......@@ -99,7 +103,8 @@
"vue-eslint-parser": "^9.0.0",
"vue-loader": "^17.0.0",
"weapp-tailwindcss": "^4.1.10",
"webpack": "5.91.0"
"webpack": "5.91.0",
"vitest": "^1.6.0"
},
"pnpm": {
"onlyBuiltDependencies": [
......
......@@ -28,7 +28,7 @@ importers:
version: 4.1.11
'@tarojs/plugin-framework-vue3':
specifier: 4.1.11
version: 4.1.11(@tarojs/helper@4.1.11)(@tarojs/runner-utils@4.1.11)(@tarojs/runtime@4.1.11)(@tarojs/shared@4.1.11)(vue-loader@17.4.2(@vue/compiler-sfc@3.5.27)(vue@3.5.27(typescript@5.9.3))(webpack@5.91.0(@swc/core@1.3.96)))(vue@3.5.27(typescript@5.9.3))(webpack@5.91.0(@swc/core@1.3.96))
version: 4.1.11(@tarojs/helper@4.1.11)(@tarojs/runner-utils@4.1.11)(@tarojs/runtime@4.1.11)(@tarojs/shared@4.1.11)(@vitejs/plugin-vue@5.2.4(vue@3.5.27(typescript@5.9.3)))(vue-loader@17.4.2(@vue/compiler-sfc@3.5.27)(vue@3.5.27(typescript@5.9.3))(webpack@5.91.0(@swc/core@1.3.96)))(vue@3.5.27(typescript@5.9.3))(webpack@5.91.0(@swc/core@1.3.96))
'@tarojs/plugin-html':
specifier: 4.1.11
version: 4.1.11(@tarojs/helper@4.1.11)(@tarojs/runtime@4.1.11)(@tarojs/shared@4.1.11)
......@@ -108,12 +108,18 @@ importers:
'@types/webpack-env':
specifier: ^1.13.6
version: 1.18.8
'@vitejs/plugin-vue':
specifier: ^5.2.4
version: 5.2.4(vue@3.5.27(typescript@5.9.3))
'@vue/babel-plugin-jsx':
specifier: ^1.0.6
version: 1.5.0(@babel/core@7.28.6)
'@vue/compiler-sfc':
specifier: ^3.0.0
version: 3.5.27
'@vue/test-utils':
specifier: ^2.4.6
version: 2.4.6
autoprefixer:
specifier: ^10.4.21
version: 10.4.23(postcss@8.5.6)
......@@ -138,6 +144,9 @@ importers:
eslint-plugin-vue:
specifier: ^8.0.0
version: 8.7.1(eslint@8.57.1)
happy-dom:
specifier: ^14.12.0
version: 14.12.3
husky:
specifier: ^9.1.7
version: 9.1.7
......@@ -165,6 +174,9 @@ importers:
unplugin-vue-components:
specifier: ^0.26.0
version: 0.26.0(@babel/parser@7.29.0)(rollup@3.29.5)(vue@3.5.27(typescript@5.9.3))
vitest:
specifier: ^1.6.0
version: 1.6.1(@types/node@25.2.2)(happy-dom@14.12.3)(jsdom@24.1.3)(less@4.5.1)(lightningcss@1.31.1)(sass@1.97.3)(stylus@0.64.0)(terser@5.46.0)
vue-eslint-parser:
specifier: ^9.0.0
version: 9.4.3(eslint@8.57.1)
......@@ -1504,6 +1516,9 @@ packages:
unplugin-vue-components:
optional: true
'@one-ini/wasm@0.1.1':
resolution: {integrity: sha512-XuySG1E38YScSJoMlqovLru4KTUNSjgVTIjyh7qMX6aNN5HY5Ct5LhRJdxO79JtTzKfzV/bnWpz+zquYrISsvw==}
'@parcel/watcher-android-arm64@2.5.6':
resolution: {integrity: sha512-YQxSS34tPF/6ZG7r/Ih9xy+kP/WwediEUsqmtf0cuCV5TPPKw/PQHRhueUo6JdeFJaqV3pyjm0GdYjZotbRt/A==}
engines: {node: '>= 10.0.0'}
......@@ -1624,6 +1639,144 @@ packages:
rollup:
optional: true
'@rollup/rollup-android-arm-eabi@4.57.1':
resolution: {integrity: sha512-A6ehUVSiSaaliTxai040ZpZ2zTevHYbvu/lDoeAteHI8QnaosIzm4qwtezfRg1jOYaUmnzLX1AOD6Z+UJjtifg==}
cpu: [arm]
os: [android]
'@rollup/rollup-android-arm64@4.57.1':
resolution: {integrity: sha512-dQaAddCY9YgkFHZcFNS/606Exo8vcLHwArFZ7vxXq4rigo2bb494/xKMMwRRQW6ug7Js6yXmBZhSBRuBvCCQ3w==}
cpu: [arm64]
os: [android]
'@rollup/rollup-darwin-arm64@4.57.1':
resolution: {integrity: sha512-crNPrwJOrRxagUYeMn/DZwqN88SDmwaJ8Cvi/TN1HnWBU7GwknckyosC2gd0IqYRsHDEnXf328o9/HC6OkPgOg==}
cpu: [arm64]
os: [darwin]
'@rollup/rollup-darwin-x64@4.57.1':
resolution: {integrity: sha512-Ji8g8ChVbKrhFtig5QBV7iMaJrGtpHelkB3lsaKzadFBe58gmjfGXAOfI5FV0lYMH8wiqsxKQ1C9B0YTRXVy4w==}
cpu: [x64]
os: [darwin]
'@rollup/rollup-freebsd-arm64@4.57.1':
resolution: {integrity: sha512-R+/WwhsjmwodAcz65guCGFRkMb4gKWTcIeLy60JJQbXrJ97BOXHxnkPFrP+YwFlaS0m+uWJTstrUA9o+UchFug==}
cpu: [arm64]
os: [freebsd]
'@rollup/rollup-freebsd-x64@4.57.1':
resolution: {integrity: sha512-IEQTCHeiTOnAUC3IDQdzRAGj3jOAYNr9kBguI7MQAAZK3caezRrg0GxAb6Hchg4lxdZEI5Oq3iov/w/hnFWY9Q==}
cpu: [x64]
os: [freebsd]
'@rollup/rollup-linux-arm-gnueabihf@4.57.1':
resolution: {integrity: sha512-F8sWbhZ7tyuEfsmOxwc2giKDQzN3+kuBLPwwZGyVkLlKGdV1nvnNwYD0fKQ8+XS6hp9nY7B+ZeK01EBUE7aHaw==}
cpu: [arm]
os: [linux]
libc: [glibc]
'@rollup/rollup-linux-arm-musleabihf@4.57.1':
resolution: {integrity: sha512-rGfNUfn0GIeXtBP1wL5MnzSj98+PZe/AXaGBCRmT0ts80lU5CATYGxXukeTX39XBKsxzFpEeK+Mrp9faXOlmrw==}
cpu: [arm]
os: [linux]
libc: [musl]
'@rollup/rollup-linux-arm64-gnu@4.57.1':
resolution: {integrity: sha512-MMtej3YHWeg/0klK2Qodf3yrNzz6CGjo2UntLvk2RSPlhzgLvYEB3frRvbEF2wRKh1Z2fDIg9KRPe1fawv7C+g==}
cpu: [arm64]
os: [linux]
libc: [glibc]
'@rollup/rollup-linux-arm64-musl@4.57.1':
resolution: {integrity: sha512-1a/qhaaOXhqXGpMFMET9VqwZakkljWHLmZOX48R0I/YLbhdxr1m4gtG1Hq7++VhVUmf+L3sTAf9op4JlhQ5u1Q==}
cpu: [arm64]
os: [linux]
libc: [musl]
'@rollup/rollup-linux-loong64-gnu@4.57.1':
resolution: {integrity: sha512-QWO6RQTZ/cqYtJMtxhkRkidoNGXc7ERPbZN7dVW5SdURuLeVU7lwKMpo18XdcmpWYd0qsP1bwKPf7DNSUinhvA==}
cpu: [loong64]
os: [linux]
libc: [glibc]
'@rollup/rollup-linux-loong64-musl@4.57.1':
resolution: {integrity: sha512-xpObYIf+8gprgWaPP32xiN5RVTi/s5FCR+XMXSKmhfoJjrpRAjCuuqQXyxUa/eJTdAE6eJ+KDKaoEqjZQxh3Gw==}
cpu: [loong64]
os: [linux]
libc: [musl]
'@rollup/rollup-linux-ppc64-gnu@4.57.1':
resolution: {integrity: sha512-4BrCgrpZo4hvzMDKRqEaW1zeecScDCR+2nZ86ATLhAoJ5FQ+lbHVD3ttKe74/c7tNT9c6F2viwB3ufwp01Oh2w==}
cpu: [ppc64]
os: [linux]
libc: [glibc]
'@rollup/rollup-linux-ppc64-musl@4.57.1':
resolution: {integrity: sha512-NOlUuzesGauESAyEYFSe3QTUguL+lvrN1HtwEEsU2rOwdUDeTMJdO5dUYl/2hKf9jWydJrO9OL/XSSf65R5+Xw==}
cpu: [ppc64]
os: [linux]
libc: [musl]
'@rollup/rollup-linux-riscv64-gnu@4.57.1':
resolution: {integrity: sha512-ptA88htVp0AwUUqhVghwDIKlvJMD/fmL/wrQj99PRHFRAG6Z5nbWoWG4o81Nt9FT+IuqUQi+L31ZKAFeJ5Is+A==}
cpu: [riscv64]
os: [linux]
libc: [glibc]
'@rollup/rollup-linux-riscv64-musl@4.57.1':
resolution: {integrity: sha512-S51t7aMMTNdmAMPpBg7OOsTdn4tySRQvklmL3RpDRyknk87+Sp3xaumlatU+ppQ+5raY7sSTcC2beGgvhENfuw==}
cpu: [riscv64]
os: [linux]
libc: [musl]
'@rollup/rollup-linux-s390x-gnu@4.57.1':
resolution: {integrity: sha512-Bl00OFnVFkL82FHbEqy3k5CUCKH6OEJL54KCyx2oqsmZnFTR8IoNqBF+mjQVcRCT5sB6yOvK8A37LNm/kPJiZg==}
cpu: [s390x]
os: [linux]
libc: [glibc]
'@rollup/rollup-linux-x64-gnu@4.57.1':
resolution: {integrity: sha512-ABca4ceT4N+Tv/GtotnWAeXZUZuM/9AQyCyKYyKnpk4yoA7QIAuBt6Hkgpw8kActYlew2mvckXkvx0FfoInnLg==}
cpu: [x64]
os: [linux]
libc: [glibc]
'@rollup/rollup-linux-x64-musl@4.57.1':
resolution: {integrity: sha512-HFps0JeGtuOR2convgRRkHCekD7j+gdAuXM+/i6kGzQtFhlCtQkpwtNzkNj6QhCDp7DRJ7+qC/1Vg2jt5iSOFw==}
cpu: [x64]
os: [linux]
libc: [musl]
'@rollup/rollup-openbsd-x64@4.57.1':
resolution: {integrity: sha512-H+hXEv9gdVQuDTgnqD+SQffoWoc0Of59AStSzTEj/feWTBAnSfSD3+Dql1ZruJQxmykT/JVY0dE8Ka7z0DH1hw==}
cpu: [x64]
os: [openbsd]
'@rollup/rollup-openharmony-arm64@4.57.1':
resolution: {integrity: sha512-4wYoDpNg6o/oPximyc/NG+mYUejZrCU2q+2w6YZqrAs2UcNUChIZXjtafAiiZSUc7On8v5NyNj34Kzj/Ltk6dQ==}
cpu: [arm64]
os: [openharmony]
'@rollup/rollup-win32-arm64-msvc@4.57.1':
resolution: {integrity: sha512-O54mtsV/6LW3P8qdTcamQmuC990HDfR71lo44oZMZlXU4tzLrbvTii87Ni9opq60ds0YzuAlEr/GNwuNluZyMQ==}
cpu: [arm64]
os: [win32]
'@rollup/rollup-win32-ia32-msvc@4.57.1':
resolution: {integrity: sha512-P3dLS+IerxCT/7D2q2FYcRdWRl22dNbrbBEtxdWhXrfIMPP9lQhb5h4Du04mdl5Woq05jVCDPCMF7Ub0NAjIew==}
cpu: [ia32]
os: [win32]
'@rollup/rollup-win32-x64-gnu@4.57.1':
resolution: {integrity: sha512-VMBH2eOOaKGtIJYleXsi2B8CPVADrh+TyNxJ4mWPnKfLB/DBUmzW+5m1xUrcwWoMfSLagIRpjUFeW5CO5hyciQ==}
cpu: [x64]
os: [win32]
'@rollup/rollup-win32-x64-msvc@4.57.1':
resolution: {integrity: sha512-mxRFDdHIWRxg3UfIIAwCm6NzvxG0jDX/wBN6KsQFTvKFqqg9vTrWUE68qEjHt19A5wwx5X5aUi2zuZT7YR0jrA==}
cpu: [x64]
os: [win32]
'@rtsao/scc@1.1.0':
resolution: {integrity: sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==}
......@@ -2268,6 +2421,28 @@ packages:
'@ungap/structured-clone@1.3.0':
resolution: {integrity: sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==}
'@vitejs/plugin-vue@5.2.4':
resolution: {integrity: sha512-7Yx/SXSOcQq5HiiV3orevHUFn+pmMB4cgbEkDYgnkUWb0WfeQ/wa2yFv6D5ICiCQOVpjA7vYDXrC7AGO8yjDHA==}
engines: {node: ^18.0.0 || >=20.0.0}
peerDependencies:
vite: ^5.0.0 || ^6.0.0
vue: ^3.2.25
'@vitest/expect@1.6.1':
resolution: {integrity: sha512-jXL+9+ZNIJKruofqXuuTClf44eSpcHlgj3CiuNihUF3Ioujtmc0zIa3UJOW5RjDK1YLBJZnWBlPuqhYycLioog==}
'@vitest/runner@1.6.1':
resolution: {integrity: sha512-3nSnYXkVkf3mXFfE7vVyPmi3Sazhb/2cfZGGs0JRzFsPFvAMBEcrweV1V1GsrstdXeKCTXlJbvnQwGWgEIHmOA==}
'@vitest/snapshot@1.6.1':
resolution: {integrity: sha512-WvidQuWAzU2p95u8GAKlRMqMyN1yOJkGHnx3M1PL9Raf7AQ1kwLKg04ADlCa3+OXUZE7BceOhVZiuWAbzCKcUQ==}
'@vitest/spy@1.6.1':
resolution: {integrity: sha512-MGcMmpGkZebsMZhbQKkAf9CX5zGvjkBTqf8Zx3ApYWXr3wG+QvEu2eXWfnIIWYSJExIp4V9FCKDEeygzkYrXMw==}
'@vitest/utils@1.6.1':
resolution: {integrity: sha512-jOrrUvXM4Av9ZWiG1EajNto0u96kWAhJ1LmPmJhXXQx/32MecEKd10pOLYgS2BQx1TgkGhloPU1ArDW2vvaY6g==}
'@vue/babel-helper-vue-transform-on@1.5.0':
resolution: {integrity: sha512-0dAYkerNhhHutHZ34JtTl2czVQHUNWv6xEbkdF5W+Yrv5pCWsqjeORdOgbtW2I9gWlt+wBmVn+ttqN9ZxR5tzA==}
......@@ -2322,6 +2497,9 @@ packages:
'@vue/shared@3.5.27':
resolution: {integrity: sha512-dXr/3CgqXsJkZ0n9F3I4elY8wM9jMJpP3pvRG52r6m0tu/MsAFIe6JpXVGeNMd/D9F4hQynWT8Rfuj0bdm9kFQ==}
'@vue/test-utils@2.4.6':
resolution: {integrity: sha512-FMxEjOpYNYiFe0GkaHsnJPXFHxQ6m4t8vI/ElPGpMWxZKpmRvQ33OIrvRXemy6yha03RxhOlQuy+gZMC3CQSow==}
'@weapp-core/escape@7.0.0':
resolution: {integrity: sha512-xMiRT/54YCuyXGXC6ozxmoF+wmnnPJNbouRaAhGLl1jBKsLqtkeILYU5/tGDtfJPxwKcQEFeDuaSmnMHaU3myg==}
......@@ -2396,6 +2574,10 @@ packages:
'@xtuc/long@4.2.2':
resolution: {integrity: sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==}
abbrev@2.0.0:
resolution: {integrity: sha512-6/mh1E2u2YgEsCHdY0Yx5oW+61gZU+1vXaoiHHrpKeuRNNgFvS+/jrwHiQhB5apAf5oB7UB7E19ol2R2LKH8hQ==}
engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0}
abortcontroller-polyfill@1.7.8:
resolution: {integrity: sha512-9f1iZ2uWh92VcrU9Y8x+LdM4DLj75VE0MJB8zuF1iUnroEptStw+DQ8EQPMUdfe5k+PkB1uUfDQfWbhstH8LrQ==}
......@@ -2488,6 +2670,10 @@ packages:
resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==}
engines: {node: '>=8'}
ansi-styles@5.2.0:
resolution: {integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==}
engines: {node: '>=10'}
ansi-styles@6.2.3:
resolution: {integrity: sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==}
engines: {node: '>=12'}
......@@ -2551,6 +2737,9 @@ packages:
resolution: {integrity: sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==}
engines: {node: '>= 0.4'}
assertion-error@1.1.0:
resolution: {integrity: sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==}
async-function@1.0.0:
resolution: {integrity: sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==}
engines: {node: '>= 0.4'}
......@@ -2788,6 +2977,10 @@ packages:
resolution: {integrity: sha512-Cg8/ZSBEa8ZVY9HspcGUYaK63d/bN7rqS3CYCzEGUxuYv6UlmcjzDUz2fCFFHyTvUW5Pk0I+3hkA3iXlIj6guA==}
engines: {node: '>=4'}
chai@4.5.0:
resolution: {integrity: sha512-RITGBfijLkBddZvnn8jdqoTypxvqbOLYQkGGxXzeFjVHvudaPw0HNFD9x928/eUwYWd2dPCugVqspGALTZZQKw==}
engines: {node: '>=4'}
chalk@3.0.0:
resolution: {integrity: sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==}
engines: {node: '>=8'}
......@@ -2805,6 +2998,9 @@ packages:
charenc@0.0.2:
resolution: {integrity: sha512-yrLQ/yVUFXkzg7EDQsPieE/53+0RlaWTs+wBrvW36cyilJ2SaDWfl4Yj7MtLTXleV9uEKefbAGUPv2/iWSooRA==}
check-error@1.0.3:
resolution: {integrity: sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==}
chokidar@3.6.0:
resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==}
engines: {node: '>= 8.10.0'}
......@@ -2904,6 +3100,10 @@ packages:
resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==}
engines: {node: '>= 0.8'}
commander@10.0.1:
resolution: {integrity: sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==}
engines: {node: '>=14'}
commander@14.0.3:
resolution: {integrity: sha512-H+y0Jo/T1RZ9qPP4Eh1pkcQcLRglraJaSLoyOtHxu6AapkjWVCy2Sit1QQ4x3Dng8qDlSsZEet7g5Pq06MvTgw==}
engines: {node: '>=20'}
......@@ -3238,6 +3438,10 @@ packages:
resolution: {integrity: sha512-e48kc2IjU+2Zw8cTb6VZcJQ3lgVbS4uuB1TfCHbiZIP/haNXm+SVyhu+87jts5/3ROpd82GSVCoNs/z8l4ZOaQ==}
engines: {node: '>=4'}
deep-eql@4.1.4:
resolution: {integrity: sha512-SUwdGfqdKOwxCPeVYjwSyRpJ7Z+fhpwIAtmCUdZIWZ/YP5R9WAsyuSgpLVDi9bjWoN2LXHNss/dk3urXtdQxGg==}
engines: {node: '>=6'}
deep-extend@0.6.0:
resolution: {integrity: sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==}
engines: {node: '>=4.0.0'}
......@@ -3308,6 +3512,10 @@ packages:
didyoumean@1.2.2:
resolution: {integrity: sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==}
diff-sequences@29.6.3:
resolution: {integrity: sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
dijkstrajs@1.0.3:
resolution: {integrity: sha512-qiSlmBq9+BCdCA/L46dw8Uy93mloxsPSbwnm5yrKn2vMPiy8KyAskTF6zuV/j5BMsmOGZDPs7KjU+mjb670kfA==}
......@@ -3391,6 +3599,11 @@ packages:
eastasianwidth@0.2.0:
resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==}
editorconfig@1.0.4:
resolution: {integrity: sha512-L9Qe08KWTlqYMVvMcTIvMAdl1cDUubzRNYL+WfA4bLDMHe4nemKkpmYzkznE1FwLKu0EEmy6obgQKzMJrg4x9Q==}
engines: {node: '>=14'}
hasBin: true
ee-first@1.1.1:
resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==}
......@@ -3653,6 +3866,9 @@ packages:
estree-walker@2.0.2:
resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==}
estree-walker@3.0.3:
resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==}
esutils@2.0.3:
resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==}
engines: {node: '>=0.10.0'}
......@@ -3675,6 +3891,10 @@ packages:
resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==}
engines: {node: '>=10'}
execa@8.0.1:
resolution: {integrity: sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==}
engines: {node: '>=16.17'}
expr-parser@1.0.0:
resolution: {integrity: sha512-ncuWTCWH0M5KbaYikXxZ3FG3Q+FTYIEXeXAbxYscdZLFNnR5Le5gRU2r/a/JUZHnxwBDZcxWEWzCoPQlW9Engg==}
......@@ -3889,6 +4109,9 @@ packages:
resolution: {integrity: sha512-QZjmEOC+IT1uk6Rx0sX22V6uHWVwbdbxf1faPqJ1QhLdGgsRGCZoyaQBm/piRdJy/D2um6hM1UP7ZEeQ4EkP+Q==}
engines: {node: '>=18'}
get-func-name@2.0.2:
resolution: {integrity: sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==}
get-intrinsic@1.3.0:
resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==}
engines: {node: '>= 0.4'}
......@@ -3921,6 +4144,10 @@ packages:
resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==}
engines: {node: '>=10'}
get-stream@8.0.1:
resolution: {integrity: sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==}
engines: {node: '>=16'}
get-symbol-description@1.1.0:
resolution: {integrity: sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==}
engines: {node: '>= 0.4'}
......@@ -4005,6 +4232,10 @@ packages:
handle-thing@2.0.1:
resolution: {integrity: sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg==}
happy-dom@14.12.3:
resolution: {integrity: sha512-vsYlEs3E9gLwA1Hp+w3qzu+RUDFf4VTT8cyKqVICoZ2k7WM++Qyd2LwzyTi5bqMJFiIC/vNpTDYuxdreENRK/g==}
engines: {node: '>=16.0.0'}
harmony-reflect@1.6.2:
resolution: {integrity: sha512-HIp/n38R9kQjDEziXyDTuW3vvoxxyxjxFzXLrBr18uB47GnSt+G9D29fqrpM5ZkspMcPICud3XsBJQ4Y2URg8g==}
......@@ -4149,6 +4380,10 @@ packages:
resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==}
engines: {node: '>=10.17.0'}
human-signals@5.0.0:
resolution: {integrity: sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==}
engines: {node: '>=16.17.0'}
husky@9.1.7:
resolution: {integrity: sha512-5gs5ytaNjBrh5Ow3zrvdUUY+0VxIuWVL4i9irt6friV+BqdCfmV11CQTWMiBYWHbXhco+J1kHfTOUkePhCDvMA==}
engines: {node: '>=18'}
......@@ -4390,6 +4625,10 @@ 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-string@1.1.1:
resolution: {integrity: sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==}
engines: {node: '>= 0.4'}
......@@ -4486,9 +4725,21 @@ packages:
joi@17.13.3:
resolution: {integrity: sha512-otDA4ldcIx+ZXsKHWmp0YizCweVRZG96J10b0FevjfuncLO1oX59THoAmHkNubYJ+9gWsYsp5k8v4ib6oDv1fA==}
js-beautify@1.15.4:
resolution: {integrity: sha512-9/KXeZUKKJwqCXUdBxFJ3vPh467OCckSBmYDwSK/EtV090K+iMJ7zx2S3HLVDIWFQdqMIsZWbnaGiba18aWhaA==}
engines: {node: '>=14'}
hasBin: true
js-cookie@3.0.5:
resolution: {integrity: sha512-cEiJEAEoIbWfCZYKWhVwFuvPX1gETRYPw6LlaTKoxD3s2AkXzkCjnp6h0V77ozyqj0jakteJ4YqDJT830+lVGw==}
engines: {node: '>=14'}
js-tokens@4.0.0:
resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==}
js-tokens@9.0.1:
resolution: {integrity: sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==}
js-yaml@4.1.1:
resolution: {integrity: sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==}
hasBin: true
......@@ -4782,6 +5033,10 @@ packages:
resolution: {integrity: sha512-SFppqq5p42fe2qcZQqqEOiVRXl+WCP1MdT6k7BDEW1j++sp5fIY+/fdRQitvKgB5BrBcmrs5m/L0v2FrU5MY1g==}
engines: {node: '>=14'}
local-pkg@0.5.1:
resolution: {integrity: sha512-9rrA30MRRP3gBD3HTGnC6cDFpaE1kVDWxWgqWJUN0RvDNAo+Nz/9GxB+nHOH0ifbVFy0hSA1V6vFDvnx54lTEQ==}
engines: {node: '>=14'}
local-pkg@1.1.2:
resolution: {integrity: sha512-arhlxbFRmoQHl33a0Zkle/YWlmNwoyt6QNZEIJcqNbdrsix5Lvc4HyyI3EnwxTYlZYc32EbYrQ8SzEZ7dqgg9A==}
engines: {node: '>=14'}
......@@ -4841,6 +5096,9 @@ packages:
resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==}
hasBin: true
loupe@2.3.7:
resolution: {integrity: sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==}
lower-case@1.1.4:
resolution: {integrity: sha512-2Fgx1Ycm599x+WGpIYwJOvsjmXFzTSc34IwDWALRA/8AopUKAVPwfJ+h5+f85BCp0PWmmJcWzEpxOpoXycMpdA==}
......@@ -4948,6 +5206,10 @@ packages:
resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==}
engines: {node: '>=6'}
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'}
......@@ -4975,6 +5237,10 @@ packages:
minimatch@3.1.2:
resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==}
minimatch@9.0.1:
resolution: {integrity: sha512-0jWhJpD/MdhPXwPuiRkCbfYfSKp2qnn2eOc279qI7f+osl/l+prKSrvhg157zSYvx/1nmgn2NqdT6k2Z7zSH9w==}
engines: {node: '>=16 || 14 >=14.17'}
minimatch@9.0.3:
resolution: {integrity: sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==}
engines: {node: '>=16 || 14 >=14.17'}
......@@ -5081,6 +5347,11 @@ packages:
node-releases@2.0.27:
resolution: {integrity: sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==}
nopt@7.2.1:
resolution: {integrity: sha512-taM24ViiimT/XntxbPyJQzCG+p4EKOpgD3mxFwW38mGjVUrfERQOeY4EDHjdnptttfHuHQXFx+lTP08Q+mLa/w==}
engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0}
hasBin: true
normalize-path@3.0.0:
resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==}
engines: {node: '>=0.10.0'}
......@@ -5101,6 +5372,10 @@ packages:
resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==}
engines: {node: '>=8'}
npm-run-path@5.3.0:
resolution: {integrity: sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==}
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
nth-check@2.1.1:
resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==}
......@@ -5169,6 +5444,10 @@ packages:
resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==}
engines: {node: '>=6'}
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'}
......@@ -5217,6 +5496,10 @@ packages:
resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==}
engines: {node: '>=10'}
p-limit@5.0.0:
resolution: {integrity: sha512-/Eaoq+QyLSiXQ4lyYV23f14mZRQcXnxfHrN0vCai+ak9G0pp9iEQukIIZq5NccEvwRB8PUnZT0KsOoDCINS1qQ==}
engines: {node: '>=18'}
p-locate@3.0.0:
resolution: {integrity: sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==}
engines: {node: '>=6'}
......@@ -5304,6 +5587,10 @@ packages:
resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==}
engines: {node: '>=8'}
path-key@4.0.0:
resolution: {integrity: sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==}
engines: {node: '>=12'}
path-parse@1.0.7:
resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==}
......@@ -5325,9 +5612,15 @@ packages:
resolution: {integrity: sha512-Vj7sf++t5pBD637NSfkxpHSMfWaeig5+DKWLhcqIYx6mWQz5hdJTGDVMQiJcw1ZYkhs7AazKDGpRVji1LJCZUQ==}
engines: {node: '>=18'}
pathe@1.1.2:
resolution: {integrity: sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==}
pathe@2.0.3:
resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==}
pathval@1.1.1:
resolution: {integrity: sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==}
pend@1.2.0:
resolution: {integrity: sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==}
......@@ -5897,6 +6190,10 @@ packages:
resolution: {integrity: sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==}
engines: {node: '>= 10'}
pretty-format@29.7.0:
resolution: {integrity: sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
pretty-time@1.1.0:
resolution: {integrity: sha512-28iF6xPQrP8Oa6uxE6a1biz+lWeTOAPKggvjB8HAs6nVMKZwf5bG++632Dx614hIWgUPkgivRfG+a8uAXGTIbA==}
engines: {node: '>=4'}
......@@ -5986,6 +6283,9 @@ packages:
react-is@17.0.2:
resolution: {integrity: sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==}
react-is@18.3.1:
resolution: {integrity: sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==}
react@19.2.4:
resolution: {integrity: sha512-9nfp2hYpCwOjAN+8TZFGhtWEwgvWHXqESH8qT89AT/lWklpLON22Lc8pEtnpsZz7VmawabSU0gCjnj8aC0euHQ==}
engines: {node: '>=0.10.0'}
......@@ -6128,6 +6428,11 @@ packages:
engines: {node: '>=14.18.0', npm: '>=8.0.0'}
hasBin: true
rollup@4.57.1:
resolution: {integrity: sha512-oQL6lgK3e2QZeQ7gcgIkS2YZPg5slw37hYufJ3edKlfQSGGm8ICoxswK15ntSzF/a8+h7ekRy7k7oWc3BQ7y8A==}
engines: {node: '>=18.0.0', npm: '>=8.0.0'}
hasBin: true
rrweb-cssom@0.7.1:
resolution: {integrity: sha512-TrEMa7JGdVm0UThDJSx7ddw5nVm3UJS9o9CCIZ72B1vSyEZoziDqBYP3XIoi/12lKrJR8rE3jeFHMok2F/Mnsg==}
......@@ -6328,6 +6633,9 @@ packages:
resolution: {integrity: sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==}
engines: {node: '>= 0.4'}
siginfo@2.0.0:
resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==}
signal-exit@3.0.7:
resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==}
......@@ -6405,6 +6713,9 @@ packages:
resolution: {integrity: sha512-qxQJTx2ryR0Dw0ITYyekNQWpz6f8dGd7vffGNflQQ3Iqj9NJ6qiZ7ELpZsJ/QBhIVAiDfXdag3+Gp8RvWa62AA==}
engines: {node: '>=12'}
stackback@0.0.2:
resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==}
statuses@1.5.0:
resolution: {integrity: sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==}
engines: {node: '>= 0.6'}
......@@ -6491,6 +6802,10 @@ packages:
resolution: {integrity: sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==}
engines: {node: '>=6'}
strip-final-newline@3.0.0:
resolution: {integrity: sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==}
engines: {node: '>=12'}
strip-json-comments@2.0.1:
resolution: {integrity: sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==}
engines: {node: '>=0.10.0'}
......@@ -6499,6 +6814,9 @@ packages:
resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==}
engines: {node: '>=8'}
strip-literal@2.1.1:
resolution: {integrity: sha512-631UJ6O00eNGfMiWG78ck80dfBab8X6IVFB51jZK5Icd7XAs60Z5y7QdSd/wGIklnWvRbUNloVzhOKKmutxQ6Q==}
strip-outer@1.0.1:
resolution: {integrity: sha512-k55yxKHwaXnpYGsOzg4Vl8+tDrWylxDEpknGjhTiZB8dFRU5rTo9CAzeycivxV3s+zlTKwrs6WxMxR95n26kwg==}
engines: {node: '>=0.10.0'}
......@@ -6652,6 +6970,9 @@ packages:
tiny-case@1.0.3:
resolution: {integrity: sha512-Eet/eeMhkO6TX8mnUteS9zgPbUMQa4I6Kkp5ORiBD5476/m+PIRiumP5tmh5ioJpH7k51Kehawy2UDfsnxxY8Q==}
tinybench@2.9.0:
resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==}
tinyexec@1.0.2:
resolution: {integrity: sha512-W/KYk+NFhkmsYpuHq5JykngiOCnxeVL8v8dFnqxSD8qEEdRfXk1SDM6JzNqcERbcGYj9tMrDQBYV9cjgnunFIg==}
engines: {node: '>=18'}
......@@ -6660,6 +6981,14 @@ packages:
resolution: {integrity: sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==}
engines: {node: '>=12.0.0'}
tinypool@0.8.4:
resolution: {integrity: sha512-i11VH5gS6IFeLY3gMBQ00/MmLncVP7JLXOw1vlgkytLmJK7QnEr7NXf0LBdxfmNPAeyetukOk0bOYrJrFGjYJQ==}
engines: {node: '>=14.0.0'}
tinyspy@2.2.1:
resolution: {integrity: sha512-KYad6Vy5VDWV4GH3fjpseMQ/XU2BhIYP7Vzd0LG44qRWm/Yt2WCOTicFdvmgo6gWaqooMQCawTtILVQJupKu7A==}
engines: {node: '>=14.0.0'}
to-buffer@1.2.2:
resolution: {integrity: sha512-db0E3UJjcFhpDhAF4tLo03oli3pwl3dbnzXOUIlRKrp+ldk/VUxzpWYZENsw2SZiuBjHAk7DfB0VU7NKdpb6sw==}
engines: {node: '>= 0.4'}
......@@ -6719,6 +7048,10 @@ packages:
resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==}
engines: {node: '>= 0.8.0'}
type-detect@4.1.0:
resolution: {integrity: sha512-Acylog8/luQ8L7il+geoSxhEkazvkslg7PSNKOX59mbB9cOveP5aq9h74Y7YU8yDpJwetzQQrfIwtf4Wp4LKcw==}
engines: {node: '>=4'}
type-fest@0.20.2:
resolution: {integrity: sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==}
engines: {node: '>=10'}
......@@ -6887,11 +7220,75 @@ packages:
resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==}
engines: {node: '>= 0.8'}
vite-node@1.6.1:
resolution: {integrity: sha512-YAXkfvGtuTzwWbDSACdJSg4A4DZiAqckWe90Zapc/sEX3XvHcw1NdurM/6od8J207tSDqNbSsgdCacBgvJKFuA==}
engines: {node: ^18.0.0 || >=20.0.0}
hasBin: true
vite@5.4.21:
resolution: {integrity: sha512-o5a9xKjbtuhY6Bi5S3+HvbRERmouabWbyUcpXXUA1u+GNUKoROi9byOJ8M0nHbHYHkYICiMlqxkg1KkYmm25Sw==}
engines: {node: ^18.0.0 || >=20.0.0}
hasBin: true
peerDependencies:
'@types/node': ^18.0.0 || >=20.0.0
less: '*'
lightningcss: ^1.21.0
sass: '*'
sass-embedded: '*'
stylus: '*'
sugarss: '*'
terser: ^5.4.0
peerDependenciesMeta:
'@types/node':
optional: true
less:
optional: true
lightningcss:
optional: true
sass:
optional: true
sass-embedded:
optional: true
stylus:
optional: true
sugarss:
optional: true
terser:
optional: true
vitest@1.6.1:
resolution: {integrity: sha512-Ljb1cnSJSivGN0LqXd/zmDbWEM0RNNg2t1QW/XUhYl/qPqyu7CsqeWtqQXHVaJsecLPuDoak2oJcZN2QoRIOag==}
engines: {node: ^18.0.0 || >=20.0.0}
hasBin: true
peerDependencies:
'@edge-runtime/vm': '*'
'@types/node': ^18.0.0 || >=20.0.0
'@vitest/browser': 1.6.1
'@vitest/ui': 1.6.1
happy-dom: '*'
jsdom: '*'
peerDependenciesMeta:
'@edge-runtime/vm':
optional: true
'@types/node':
optional: true
'@vitest/browser':
optional: true
'@vitest/ui':
optional: true
happy-dom:
optional: true
jsdom:
optional: true
vm2@3.10.4:
resolution: {integrity: sha512-Gl6r7MN3mkawGurFdp467yDJQ7HdragK2QVVWFbOCd3LPJXJLE2xZFwLCNhp04MTkHruPqLIOs3pYbJQJw/1aA==}
engines: {node: '>=6.0'}
hasBin: true
vue-component-type-helpers@2.2.12:
resolution: {integrity: sha512-YbGqHZ5/eW4SnkPNR44mKVc6ZKQoRs/Rux1sxC6rdwXb4qpbOSYfDr9DsTHolOTGmIKgM9j141mZbBeg05R1pw==}
vue-eslint-parser@8.3.0:
resolution: {integrity: sha512-dzHGG3+sYwSf6zFBa0Gi9ZDshD7+ad14DGOdTLjruRVgZXe2J+DcZ9iUhyR48z5g1PqRa20yt3Njna/veLJL/g==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
......@@ -7021,6 +7418,10 @@ packages:
whatwg-fetch@3.6.20:
resolution: {integrity: sha512-EqhiFU6daOA8kpjOWTL0olhVOF3i7OrFzSYiGsEMB8GcXS+RrzauAERX65xMeNWVqxA6HXH2m69Z9LaKKdisfg==}
whatwg-mimetype@3.0.0:
resolution: {integrity: sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q==}
engines: {node: '>=12'}
whatwg-mimetype@4.0.0:
resolution: {integrity: sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==}
engines: {node: '>=18'}
......@@ -7053,6 +7454,11 @@ packages:
engines: {node: '>= 8'}
hasBin: true
why-is-node-running@2.3.0:
resolution: {integrity: sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==}
engines: {node: '>=8'}
hasBin: true
wildcard@2.0.1:
resolution: {integrity: sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==}
......@@ -7146,6 +7552,10 @@ packages:
resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==}
engines: {node: '>=10'}
yocto-queue@1.2.2:
resolution: {integrity: sha512-4LCcse/U2MHZ63HAJVE+v71o7yOdIe4cZ70Wpf8D/IyjDKYQLV5GD46B+hSTjJsvV5PztjvHoU580EftxjDZFQ==}
engines: {node: '>=12.20'}
yup@1.7.1:
resolution: {integrity: sha512-GKHFX2nXul2/4Dtfxhozv701jLQHdf6J34YDh2cEkpqoo8le5Mg6/LrdseVLrFarmFygZTlfIhHx/QKfb/QWXw==}
......@@ -8545,6 +8955,8 @@ snapshots:
optionalDependencies:
unplugin-vue-components: 0.26.0(@babel/parser@7.29.0)(rollup@3.29.5)(vue@3.5.27(typescript@5.9.3))
'@one-ini/wasm@0.1.1': {}
'@parcel/watcher-android-arm64@2.5.6':
optional: true
......@@ -8630,6 +9042,81 @@ snapshots:
optionalDependencies:
rollup: 3.29.5
'@rollup/rollup-android-arm-eabi@4.57.1':
optional: true
'@rollup/rollup-android-arm64@4.57.1':
optional: true
'@rollup/rollup-darwin-arm64@4.57.1':
optional: true
'@rollup/rollup-darwin-x64@4.57.1':
optional: true
'@rollup/rollup-freebsd-arm64@4.57.1':
optional: true
'@rollup/rollup-freebsd-x64@4.57.1':
optional: true
'@rollup/rollup-linux-arm-gnueabihf@4.57.1':
optional: true
'@rollup/rollup-linux-arm-musleabihf@4.57.1':
optional: true
'@rollup/rollup-linux-arm64-gnu@4.57.1':
optional: true
'@rollup/rollup-linux-arm64-musl@4.57.1':
optional: true
'@rollup/rollup-linux-loong64-gnu@4.57.1':
optional: true
'@rollup/rollup-linux-loong64-musl@4.57.1':
optional: true
'@rollup/rollup-linux-ppc64-gnu@4.57.1':
optional: true
'@rollup/rollup-linux-ppc64-musl@4.57.1':
optional: true
'@rollup/rollup-linux-riscv64-gnu@4.57.1':
optional: true
'@rollup/rollup-linux-riscv64-musl@4.57.1':
optional: true
'@rollup/rollup-linux-s390x-gnu@4.57.1':
optional: true
'@rollup/rollup-linux-x64-gnu@4.57.1':
optional: true
'@rollup/rollup-linux-x64-musl@4.57.1':
optional: true
'@rollup/rollup-openbsd-x64@4.57.1':
optional: true
'@rollup/rollup-openharmony-arm64@4.57.1':
optional: true
'@rollup/rollup-win32-arm64-msvc@4.57.1':
optional: true
'@rollup/rollup-win32-ia32-msvc@4.57.1':
optional: true
'@rollup/rollup-win32-x64-gnu@4.57.1':
optional: true
'@rollup/rollup-win32-x64-msvc@4.57.1':
optional: true
'@rtsao/scc@1.1.0': {}
'@sideway/address@4.1.5':
......@@ -8910,7 +9397,7 @@ snapshots:
transitivePeerDependencies:
- supports-color
'@tarojs/plugin-framework-vue3@4.1.11(@tarojs/helper@4.1.11)(@tarojs/runner-utils@4.1.11)(@tarojs/runtime@4.1.11)(@tarojs/shared@4.1.11)(vue-loader@17.4.2(@vue/compiler-sfc@3.5.27)(vue@3.5.27(typescript@5.9.3))(webpack@5.91.0(@swc/core@1.3.96)))(vue@3.5.27(typescript@5.9.3))(webpack@5.91.0(@swc/core@1.3.96))':
'@tarojs/plugin-framework-vue3@4.1.11(@tarojs/helper@4.1.11)(@tarojs/runner-utils@4.1.11)(@tarojs/runtime@4.1.11)(@tarojs/shared@4.1.11)(@vitejs/plugin-vue@5.2.4(vue@3.5.27(typescript@5.9.3)))(vue-loader@17.4.2(@vue/compiler-sfc@3.5.27)(vue@3.5.27(typescript@5.9.3))(webpack@5.91.0(@swc/core@1.3.96)))(vue@3.5.27(typescript@5.9.3))(webpack@5.91.0(@swc/core@1.3.96))':
dependencies:
'@tarojs/helper': 4.1.11
'@tarojs/runner-utils': 4.1.11
......@@ -8921,6 +9408,8 @@ snapshots:
vue: 3.5.27(typescript@5.9.3)
vue-loader: 17.4.2(@vue/compiler-sfc@3.5.27)(vue@3.5.27(typescript@5.9.3))(webpack@5.91.0(@swc/core@1.3.96))
webpack: 5.91.0(@swc/core@1.3.96)
optionalDependencies:
'@vitejs/plugin-vue': 5.2.4(vue@3.5.27(typescript@5.9.3))
'@tarojs/plugin-html@4.1.11(@tarojs/helper@4.1.11)(@tarojs/runtime@4.1.11)(@tarojs/shared@4.1.11)':
dependencies:
......@@ -9433,6 +9922,39 @@ snapshots:
'@ungap/structured-clone@1.3.0': {}
'@vitejs/plugin-vue@5.2.4(vue@3.5.27(typescript@5.9.3))':
dependencies:
vue: 3.5.27(typescript@5.9.3)
'@vitest/expect@1.6.1':
dependencies:
'@vitest/spy': 1.6.1
'@vitest/utils': 1.6.1
chai: 4.5.0
'@vitest/runner@1.6.1':
dependencies:
'@vitest/utils': 1.6.1
p-limit: 5.0.0
pathe: 1.1.2
'@vitest/snapshot@1.6.1':
dependencies:
magic-string: 0.30.21
pathe: 1.1.2
pretty-format: 29.7.0
'@vitest/spy@1.6.1':
dependencies:
tinyspy: 2.2.1
'@vitest/utils@1.6.1':
dependencies:
diff-sequences: 29.6.3
estree-walker: 3.0.3
loupe: 2.3.7
pretty-format: 29.7.0
'@vue/babel-helper-vue-transform-on@1.5.0': {}
'@vue/babel-plugin-jsx@1.5.0(@babel/core@7.28.6)':
......@@ -9534,6 +10056,11 @@ snapshots:
'@vue/shared@3.5.27': {}
'@vue/test-utils@2.4.6':
dependencies:
js-beautify: 1.15.4
vue-component-type-helpers: 2.2.12
'@weapp-core/escape@7.0.0': {}
'@weapp-core/regex@1.0.1': {}
......@@ -9645,6 +10172,8 @@ snapshots:
'@xtuc/long@4.2.2': {}
abbrev@2.0.0: {}
abortcontroller-polyfill@1.7.8: {}
accepts@1.3.8:
......@@ -9722,6 +10251,8 @@ snapshots:
dependencies:
color-convert: 2.0.1
ansi-styles@5.2.0: {}
ansi-styles@6.2.3: {}
any-promise@1.3.0: {}
......@@ -9812,6 +10343,8 @@ snapshots:
get-intrinsic: 1.3.0
is-array-buffer: 3.0.5
assertion-error@1.1.0: {}
async-function@1.0.0: {}
asynckit@0.4.0: {}
......@@ -10122,6 +10655,16 @@ snapshots:
tunnel-agent: 0.6.0
url-to-options: 1.0.1
chai@4.5.0:
dependencies:
assertion-error: 1.1.0
check-error: 1.0.3
deep-eql: 4.1.4
get-func-name: 2.0.2
loupe: 2.3.7
pathval: 1.1.1
type-detect: 4.1.0
chalk@3.0.0:
dependencies:
ansi-styles: 4.3.0
......@@ -10151,6 +10694,10 @@ snapshots:
charenc@0.0.2: {}
check-error@1.0.3:
dependencies:
get-func-name: 2.0.2
chokidar@3.6.0:
dependencies:
anymatch: 3.1.3
......@@ -10259,6 +10806,8 @@ snapshots:
dependencies:
delayed-stream: 1.0.0
commander@10.0.1: {}
commander@14.0.3: {}
commander@2.20.3: {}
......@@ -10616,6 +11165,10 @@ snapshots:
pify: 2.3.0
strip-dirs: 2.1.0
deep-eql@4.1.4:
dependencies:
type-detect: 4.1.0
deep-extend@0.6.0: {}
deep-is@0.1.4: {}
......@@ -10671,6 +11224,8 @@ snapshots:
didyoumean@1.2.2: {}
diff-sequences@29.6.3: {}
dijkstrajs@1.0.3: {}
dingtalk-jsapi@2.15.6:
......@@ -10777,6 +11332,13 @@ snapshots:
eastasianwidth@0.2.0: {}
editorconfig@1.0.4:
dependencies:
'@one-ini/wasm': 0.1.1
commander: 10.0.1
minimatch: 9.0.1
semver: 7.7.4
ee-first@1.1.1: {}
electron-to-chromium@1.5.279: {}
......@@ -11233,6 +11795,10 @@ snapshots:
estree-walker@2.0.2: {}
estree-walker@3.0.3:
dependencies:
'@types/estree': 1.0.8
esutils@2.0.3: {}
etag@1.8.1: {}
......@@ -11255,6 +11821,18 @@ snapshots:
signal-exit: 3.0.7
strip-final-newline: 2.0.0
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
expr-parser@1.0.0: {}
express@4.22.1:
......@@ -11486,6 +12064,8 @@ snapshots:
get-east-asian-width@1.4.0: {}
get-func-name@2.0.2: {}
get-intrinsic@1.3.0:
dependencies:
call-bind-apply-helpers: 1.0.2
......@@ -11525,6 +12105,8 @@ snapshots:
get-stream@6.0.1: {}
get-stream@8.0.1: {}
get-symbol-description@1.1.0:
dependencies:
call-bound: 1.0.4
......@@ -11661,6 +12243,12 @@ snapshots:
handle-thing@2.0.1: {}
happy-dom@14.12.3:
dependencies:
entities: 4.5.0
webidl-conversions: 7.0.0
whatwg-mimetype: 3.0.0
harmony-reflect@1.6.2: {}
has-bigints@1.1.0: {}
......@@ -11829,6 +12417,8 @@ snapshots:
human-signals@2.1.0: {}
human-signals@5.0.0: {}
husky@9.1.7: {}
iconv-lite@0.4.24:
......@@ -12051,6 +12641,8 @@ snapshots:
is-stream@2.0.1: {}
is-stream@3.0.0: {}
is-string@1.1.1:
dependencies:
call-bound: 1.0.4
......@@ -12163,8 +12755,20 @@ snapshots:
'@sideway/formula': 3.0.1
'@sideway/pinpoint': 2.0.0
js-beautify@1.15.4:
dependencies:
config-chain: 1.1.13
editorconfig: 1.0.4
glob: 10.5.0
js-cookie: 3.0.5
nopt: 7.2.1
js-cookie@3.0.5: {}
js-tokens@4.0.0: {}
js-tokens@9.0.1: {}
js-yaml@4.1.1:
dependencies:
argparse: 2.0.1
......@@ -12440,6 +13044,11 @@ snapshots:
local-pkg@0.4.3: {}
local-pkg@0.5.1:
dependencies:
mlly: 1.8.0
pkg-types: 1.3.1
local-pkg@1.1.2:
dependencies:
mlly: 1.8.0
......@@ -12496,6 +13105,10 @@ snapshots:
dependencies:
js-tokens: 4.0.0
loupe@2.3.7:
dependencies:
get-func-name: 2.0.2
lower-case@1.1.4: {}
lower-case@2.0.2:
......@@ -12578,6 +13191,8 @@ snapshots:
mimic-fn@2.1.0: {}
mimic-fn@4.0.0: {}
mimic-function@5.0.1: {}
mimic-response@1.0.1: {}
......@@ -12602,6 +13217,10 @@ snapshots:
dependencies:
brace-expansion: 1.1.12
minimatch@9.0.1:
dependencies:
brace-expansion: 2.0.2
minimatch@9.0.3:
dependencies:
brace-expansion: 2.0.2
......@@ -12701,6 +13320,10 @@ snapshots:
node-releases@2.0.27: {}
nopt@7.2.1:
dependencies:
abbrev: 2.0.0
normalize-path@3.0.0: {}
normalize-url@2.0.1:
......@@ -12720,6 +13343,10 @@ snapshots:
dependencies:
path-key: 3.1.1
npm-run-path@5.3.0:
dependencies:
path-key: 4.0.0
nth-check@2.1.1:
dependencies:
boolbase: 1.0.0
......@@ -12794,6 +13421,10 @@ snapshots:
dependencies:
mimic-fn: 2.1.0
onetime@6.0.0:
dependencies:
mimic-fn: 4.0.0
onetime@7.0.0:
dependencies:
mimic-function: 5.0.1
......@@ -12851,6 +13482,10 @@ snapshots:
dependencies:
yocto-queue: 0.1.0
p-limit@5.0.0:
dependencies:
yocto-queue: 1.2.2
p-locate@3.0.0:
dependencies:
p-limit: 2.3.0
......@@ -12937,6 +13572,8 @@ snapshots:
path-key@3.1.1: {}
path-key@4.0.0: {}
path-parse@1.0.7: {}
path-scurry@1.11.1:
......@@ -12952,8 +13589,12 @@ snapshots:
path-type@6.0.0: {}
pathe@1.1.2: {}
pathe@2.0.3: {}
pathval@1.1.1: {}
pend@1.2.0: {}
perfect-debounce@1.0.0: {}
......@@ -13541,6 +14182,12 @@ snapshots:
ansi-styles: 4.3.0
react-is: 17.0.2
pretty-format@29.7.0:
dependencies:
'@jest/schemas': 29.6.3
ansi-styles: 5.2.0
react-is: 18.3.1
pretty-time@1.1.0: {}
process-nextick-args@2.0.1: {}
......@@ -13635,6 +14282,8 @@ snapshots:
react-is@17.0.2: {}
react-is@18.3.1: {}
react@19.2.4: {}
read-cache@1.0.0:
......@@ -13790,6 +14439,37 @@ snapshots:
optionalDependencies:
fsevents: 2.3.3
rollup@4.57.1:
dependencies:
'@types/estree': 1.0.8
optionalDependencies:
'@rollup/rollup-android-arm-eabi': 4.57.1
'@rollup/rollup-android-arm64': 4.57.1
'@rollup/rollup-darwin-arm64': 4.57.1
'@rollup/rollup-darwin-x64': 4.57.1
'@rollup/rollup-freebsd-arm64': 4.57.1
'@rollup/rollup-freebsd-x64': 4.57.1
'@rollup/rollup-linux-arm-gnueabihf': 4.57.1
'@rollup/rollup-linux-arm-musleabihf': 4.57.1
'@rollup/rollup-linux-arm64-gnu': 4.57.1
'@rollup/rollup-linux-arm64-musl': 4.57.1
'@rollup/rollup-linux-loong64-gnu': 4.57.1
'@rollup/rollup-linux-loong64-musl': 4.57.1
'@rollup/rollup-linux-ppc64-gnu': 4.57.1
'@rollup/rollup-linux-ppc64-musl': 4.57.1
'@rollup/rollup-linux-riscv64-gnu': 4.57.1
'@rollup/rollup-linux-riscv64-musl': 4.57.1
'@rollup/rollup-linux-s390x-gnu': 4.57.1
'@rollup/rollup-linux-x64-gnu': 4.57.1
'@rollup/rollup-linux-x64-musl': 4.57.1
'@rollup/rollup-openbsd-x64': 4.57.1
'@rollup/rollup-openharmony-arm64': 4.57.1
'@rollup/rollup-win32-arm64-msvc': 4.57.1
'@rollup/rollup-win32-ia32-msvc': 4.57.1
'@rollup/rollup-win32-x64-gnu': 4.57.1
'@rollup/rollup-win32-x64-msvc': 4.57.1
fsevents: 2.3.3
rrweb-cssom@0.7.1: {}
rrweb-cssom@0.8.0: {}
......@@ -14034,6 +14714,8 @@ snapshots:
side-channel-map: 1.0.1
side-channel-weakmap: 1.0.2
siginfo@2.0.0: {}
signal-exit@3.0.7: {}
signal-exit@4.1.0: {}
......@@ -14116,6 +14798,8 @@ snapshots:
split-on-first@3.0.0: {}
stackback@0.0.2: {}
statuses@1.5.0: {}
statuses@2.0.2: {}
......@@ -14224,10 +14908,16 @@ snapshots:
strip-final-newline@2.0.0: {}
strip-final-newline@3.0.0: {}
strip-json-comments@2.0.1: {}
strip-json-comments@3.1.1: {}
strip-literal@2.1.1:
dependencies:
js-tokens: 9.0.1
strip-outer@1.0.1:
dependencies:
escape-string-regexp: 1.0.5
......@@ -14418,6 +15108,8 @@ snapshots:
tiny-case@1.0.3: {}
tinybench@2.9.0: {}
tinyexec@1.0.2: {}
tinyglobby@0.2.15:
......@@ -14425,6 +15117,10 @@ snapshots:
fdir: 6.5.0(picomatch@4.0.3)
picomatch: 4.0.3
tinypool@0.8.4: {}
tinyspy@2.2.1: {}
to-buffer@1.2.2:
dependencies:
isarray: 2.0.5
......@@ -14483,6 +15179,8 @@ snapshots:
dependencies:
prelude-ls: 1.2.1
type-detect@4.1.0: {}
type-fest@0.20.2: {}
type-fest@0.21.3: {}
......@@ -14645,11 +15343,81 @@ snapshots:
vary@1.1.2: {}
vite-node@1.6.1(@types/node@25.2.2)(less@4.5.1)(lightningcss@1.31.1)(sass@1.97.3)(stylus@0.64.0)(terser@5.46.0):
dependencies:
cac: 6.7.14
debug: 4.4.3
pathe: 1.1.2
picocolors: 1.1.1
vite: 5.4.21(@types/node@25.2.2)(less@4.5.1)(lightningcss@1.31.1)(sass@1.97.3)(stylus@0.64.0)(terser@5.46.0)
transitivePeerDependencies:
- '@types/node'
- less
- lightningcss
- sass
- sass-embedded
- stylus
- sugarss
- supports-color
- terser
vite@5.4.21(@types/node@25.2.2)(less@4.5.1)(lightningcss@1.31.1)(sass@1.97.3)(stylus@0.64.0)(terser@5.46.0):
dependencies:
esbuild: 0.21.5
postcss: 8.5.6
rollup: 4.57.1
optionalDependencies:
'@types/node': 25.2.2
fsevents: 2.3.3
less: 4.5.1
lightningcss: 1.31.1
sass: 1.97.3
stylus: 0.64.0
terser: 5.46.0
vitest@1.6.1(@types/node@25.2.2)(happy-dom@14.12.3)(jsdom@24.1.3)(less@4.5.1)(lightningcss@1.31.1)(sass@1.97.3)(stylus@0.64.0)(terser@5.46.0):
dependencies:
'@vitest/expect': 1.6.1
'@vitest/runner': 1.6.1
'@vitest/snapshot': 1.6.1
'@vitest/spy': 1.6.1
'@vitest/utils': 1.6.1
acorn-walk: 8.3.4
chai: 4.5.0
debug: 4.4.3
execa: 8.0.1
local-pkg: 0.5.1
magic-string: 0.30.21
pathe: 1.1.2
picocolors: 1.1.1
std-env: 3.10.0
strip-literal: 2.1.1
tinybench: 2.9.0
tinypool: 0.8.4
vite: 5.4.21(@types/node@25.2.2)(less@4.5.1)(lightningcss@1.31.1)(sass@1.97.3)(stylus@0.64.0)(terser@5.46.0)
vite-node: 1.6.1(@types/node@25.2.2)(less@4.5.1)(lightningcss@1.31.1)(sass@1.97.3)(stylus@0.64.0)(terser@5.46.0)
why-is-node-running: 2.3.0
optionalDependencies:
'@types/node': 25.2.2
happy-dom: 14.12.3
jsdom: 24.1.3
transitivePeerDependencies:
- less
- lightningcss
- sass
- sass-embedded
- stylus
- sugarss
- supports-color
- terser
vm2@3.10.4:
dependencies:
acorn: 8.15.0
acorn-walk: 8.3.4
vue-component-type-helpers@2.2.12: {}
vue-eslint-parser@8.3.0(eslint@8.57.1):
dependencies:
debug: 4.4.3
......@@ -14872,6 +15640,8 @@ snapshots:
whatwg-fetch@3.6.20: {}
whatwg-mimetype@3.0.0: {}
whatwg-mimetype@4.0.0: {}
whatwg-url@14.2.0:
......@@ -14926,6 +15696,11 @@ snapshots:
dependencies:
isexe: 2.0.0
why-is-node-running@2.3.0:
dependencies:
siginfo: 2.0.0
stackback: 0.0.2
wildcard@2.0.1: {}
word-wrap@1.2.5: {}
......@@ -15018,6 +15793,8 @@ snapshots:
yocto-queue@0.1.0: {}
yocto-queue@1.2.2: {}
yup@1.7.1:
dependencies:
property-expr: 2.0.6
......
......@@ -169,12 +169,13 @@ const { handleClick } = useListItemClick({
// 通知父组件查看完成
emit('viewed', item)
}
})
});
/**
* 处理查看点击
*
* @description 内部处理查看逻辑,调用 useListItemClick
* 注意:权限检查和埋点由 ListItemActions 组件内部处理
*/
const handleView = () => {
handleClick({
......
/**
* 搜索页面测试套件
* @description 测试搜索功能的各种场景,包括输入、返回、状态切换等
* @date 2026-01-31
* @description 测试搜索功能的各种场景,包括输入、状态切换等
* @date 2026-02-13
*/
import { describe, it, expect, beforeEach, vi } from 'vitest'
import { mount } from '@vue/test-utils'
import { createPinia, setActivePinia } from 'pinia'
import Taro from '@tarojs/taro'
import SearchPage from './index.vue'
import { searchAPI } from '@/api/search'
// Mock Taro
vi.mock('@tarojs/taro', () => ({
default: {
showToast: vi.fn()
}
showToast: vi.fn(),
getCurrentPages: vi.fn(() => [])
},
useDidShow: vi.fn(),
usePullDownRefresh: vi.fn(),
stopPullDownRefresh: vi.fn()
}))
// Mock hooks
vi.mock('@/hooks/useGo', () => ({
useGo: () => vi.fn()
}))
describe('搜索页面测试', () => {
let wrapper
vi.mock('@/api/search', () => ({
searchAPI: vi.fn()
}))
beforeEach(() => {
wrapper = mount(SearchPage, {
global: {
components: {
NavHeader: { template: '<div>NavHeader</div>' },
IconFont: { template: '<div>IconFont</div>' },
SearchBar: {
template: '<input :value="modelValue" @input="$emit(\'update:modelValue\', $event.target.value)" @search="$emit(\'search\')" @clear="$emit(\'clear\')" @blur="$emit(\'blur\')" />',
props: ['modelValue'],
emits: ['update:modelValue', 'search', 'clear', 'blur']
}
}
const create_wrapper = () => {
const pinia = createPinia()
setActivePinia(pinia)
return mount(SearchPage, {
global: {
plugins: [pinia],
components: {
NavHeader: { template: '<div />' },
IconFont: { template: '<div />' },
SearchBar: { template: '<input />' }
}
})
})
describe('初始化状态测试', () => {
it('应该正确初始化 mock 数据', () => {
// 验证是否生成了 100 条数据(50 产品 + 50 资料)
expect(wrapper.vm.allData.length).toBe(100)
})
it('应该正确初始化分类数据', () => {
// 验证 3 个分类(全部、产品、资料)
expect(wrapper.vm.tabsData.length).toBe(3)
expect(wrapper.vm.tabsData[0].name).toBe('全部')
expect(wrapper.vm.tabsData[1].name).toBe('产品')
expect(wrapper.vm.tabsData[2].name).toBe('资料')
})
it('应该默认选中"全部"分类', () => {
expect(wrapper.vm.activeTabId).toBe('')
})
it('初始状态 shouldSearched 应该为 false', () => {
expect(wrapper.vm.hasSearched).toBe(false)
})
it('初始状态搜索结果应该为空数组', () => {
expect(wrapper.vm.searchResults.length).toBe(0)
})
}
})
}
describe('搜索功能测试', () => {
it('输入搜索关键词后,hasSearched 应该变为 true', async () => {
wrapper.vm.searchKeyword = '保险'
await wrapper.vm.$nextTick()
await wrapper.vm.handleSearch()
expect(wrapper.vm.hasSearched).toBe(true)
expect(wrapper.vm.searchKeyword).toBe('保险')
})
it('应该能搜索到包含关键词的产品', async () => {
wrapper.vm.searchKeyword = '保险'
await wrapper.vm.$nextTick()
await wrapper.vm.handleSearch()
const results = wrapper.vm.searchResults
expect(results.length).toBeGreaterThan(0)
expect(results[0].title.toLowerCase()).toContain('保险')
})
it('应该能搜索到包含关键词的资料', async () => {
wrapper.vm.searchKeyword = '培训'
await wrapper.vm.$nextTick()
await wrapper.vm.handleSearch()
const results = wrapper.vm.searchResults
expect(results.length).toBeGreaterThan(0)
expect(results[0].title.toLowerCase()).toContain('培训')
})
it('搜索不存在的关键词应该返回空结果', async () => {
wrapper.vm.searchKeyword = '不存在的内容xyz123'
await wrapper.vm.$nextTick()
await wrapper.vm.handleSearch()
expect(wrapper.vm.hasSearched).toBe(true)
expect(wrapper.vm.searchResults.length).toBe(0)
})
it('清空搜索关键词后 hasSearched 应该保持为 true', async () => {
// 先执行搜索
wrapper.vm.searchKeyword = '保险'
await wrapper.vm.$nextTick()
await wrapper.vm.handleSearch()
expect(wrapper.vm.hasSearched).toBe(true)
// 清空搜索
await wrapper.vm.clearSearch()
expect(wrapper.vm.searchKeyword).toBe('')
// ✅ 修复后:hasSearched 应该保持 true
expect(wrapper.vm.hasSearched).toBe(true)
})
describe('搜索页面测试', () => {
beforeEach(() => {
searchAPI.mockReset()
Taro.showToast.mockReset()
})
describe('分类切换测试', () => {
beforeEach(async () => {
// 先执行一次搜索
wrapper.vm.searchKeyword = '保险'
await wrapper.vm.handleSearch()
})
it('切换到"产品"分类应该只显示产品', async () => {
await wrapper.vm.onTabClick('product')
expect(wrapper.vm.activeTabId).toBe('product')
const results = wrapper.vm.searchResults
results.forEach(item => {
expect(item.category).toBe('product')
})
})
it('切换到"资料"分类应该只显示资料', async () => {
await wrapper.vm.onTabClick('material')
expect(wrapper.vm.activeTabId).toBe('material')
const results = wrapper.vm.searchResults
results.forEach(item => {
expect(item.category).toBe('material')
})
})
it('切换到"全部"分类应该显示所有结果', async () => {
await wrapper.vm.onTabClick('')
expect(wrapper.vm.activeTabId).toBe('')
const results = wrapper.vm.searchResults
// 验证包含所有分类
const hasProduct = results.some(item => item.category === 'product')
const hasMaterial = results.some(item => item.category === 'material')
expect(hasProduct).toBe(true)
expect(hasMaterial).toBe(true)
})
it('切换分类后 listRenderKey 应该递增', async () => {
const oldKey = wrapper.vm.listRenderKey
await wrapper.vm.onTabClick('product')
expect(wrapper.vm.listRenderKey).toBe(oldKey + 1)
})
it('初始化状态正确', () => {
const wrapper = create_wrapper()
expect(wrapper.vm.activeTab).toBe('')
expect(wrapper.vm.hasSearched).toBe(false)
expect(wrapper.vm.currentList.length).toBe(0)
expect(wrapper.vm.currentTotal).toBe(0)
expect(wrapper.vm.shouldEnableScrollLoad).toBe(false)
expect(wrapper.vm.tabsData.length).toBe(2)
expect(wrapper.vm.tabsData[0].id).toBe('product')
expect(wrapper.vm.tabsData[1].id).toBe('file')
})
describe('实时搜索测试(watch searchKeyword)', () => {
it('输入关键词应该自动触发搜索', async () => {
wrapper.vm.searchKeyword = '医疗'
// 等待 watch 触发
await wrapper.vm.$nextTick()
expect(wrapper.vm.hasSearched).toBe(true)
expect(wrapper.vm.searchResults.length).toBeGreaterThan(0)
})
it('清空关键词应该自动重置搜索状态', async () => {
// 先输入
wrapper.vm.searchKeyword = '保险'
await wrapper.vm.$nextTick()
expect(wrapper.vm.hasSearched).toBe(true)
// 清空
wrapper.vm.searchKeyword = ''
await wrapper.vm.$nextTick()
it('空关键词时提示并保持未搜索状态', async () => {
const wrapper = create_wrapper()
wrapper.vm.searchKeyword = ''
await wrapper.vm.handleSearch()
expect(wrapper.vm.hasSearched).toBe(false)
expect(wrapper.vm.searchResults.length).toBe(0)
})
expect(Taro.showToast).toHaveBeenCalledTimes(1)
expect(wrapper.vm.hasSearched).toBe(false)
expect(wrapper.vm.activeTab).toBe('')
})
describe('边界情况测试', () => {
it('输入纯空格不应该触发搜索', async () => {
wrapper.vm.searchKeyword = ' '
await wrapper.vm.handleSearch()
expect(wrapper.vm.hasSearched).toBe(false)
})
it('输入特殊字符应该正常搜索', async () => {
wrapper.vm.searchKeyword = '!@#$%'
await wrapper.vm.handleSearch()
expect(wrapper.vm.hasSearched).toBe(true)
// 应该返回空结果,但不应该报错
expect(wrapper.vm.searchResults.length).toBe(0)
})
it('输入超长关键词应该正常处理', async () => {
const longKeyword = 'a'.repeat(1000)
wrapper.vm.searchKeyword = longKeyword
await wrapper.vm.handleSearch()
expect(wrapper.vm.hasSearched).toBe(true)
// 应该返回空结果,但不应该报错
expect(wrapper.vm.searchResults.length).toBe(0)
})
it('快速切换多次分类不应该出错', async () => {
wrapper.vm.searchKeyword = '保险'
await wrapper.vm.handleSearch()
// 快速切换分类
await wrapper.vm.onTabClick('product')
await wrapper.vm.onTabClick('material')
await wrapper.vm.onTabClick('')
await wrapper.vm.onTabClick('product')
// 不应该抛出错误
expect(wrapper.vm.activeTabId).toBe('product')
it('搜索成功后默认选中产品并展示列表', async () => {
const wrapper = create_wrapper()
searchAPI.mockResolvedValueOnce({
code: 1,
msg: 'ok',
data: {
products: {
list: [{ id: 1, product_name: '保险A', tags: [] }],
total: 1
},
files: {
list: [{ id: 10, name: '培训资料', value: 'url', size: '1MB', extension: 'pdf', is_favorite: 1 }],
total: 1
}
}
})
it('快速输入和删除关键词应该正常处理', async () => {
// 快速输入
wrapper.vm.searchKeyword = '保'
await wrapper.vm.$nextTick()
wrapper.vm.searchKeyword = '保险'
await wrapper.vm.$nextTick()
wrapper.vm.searchKeyword = '保险产品'
await wrapper.vm.$nextTick()
// 快速删除
wrapper.vm.searchKeyword = '保险'
await wrapper.vm.$nextTick()
wrapper.vm.searchKeyword = ''
await wrapper.vm.$nextTick()
wrapper.vm.searchKeyword = '保险'
await wrapper.vm.handleSearch()
// 最终状态应该是重置的
expect(wrapper.vm.hasSearched).toBe(false)
expect(wrapper.vm.searchResults.length).toBe(0)
})
expect(wrapper.vm.hasSearched).toBe(true)
expect(wrapper.vm.activeTab).toBe('product')
expect(wrapper.vm.currentList.length).toBe(1)
expect(wrapper.vm.currentTotal).toBe(1)
expect(wrapper.vm.hasMore).toBe(false)
})
describe('✅ 修复后的问题测试', () => {
it('问题1修复: 清空关键词后,应该显示"暂无搜索结果"而不是"初始状态"', async () => {
// 1. 先搜索一个关键词(有结果)
wrapper.vm.searchKeyword = '保险'
await wrapper.vm.handleSearch()
console.log('搜索"保险"后:')
console.log('- hasSearched:', wrapper.vm.hasSearched)
console.log('- results.length:', wrapper.vm.searchResults.length)
expect(wrapper.vm.hasSearched).toBe(true)
expect(wrapper.vm.searchResults.length).toBeGreaterThan(0)
// 2. 清空关键词
wrapper.vm.searchKeyword = ''
await wrapper.vm.$nextTick()
console.log('清空关键词后:')
console.log('- hasSearched:', wrapper.vm.hasSearched)
console.log('- results.length:', wrapper.vm.searchResults.length)
console.log('- isInitialState:', wrapper.vm.isInitialState)
// ✅ 修复后:hasSearched 保持 true
expect(wrapper.vm.hasSearched).toBe(true)
expect(wrapper.vm.isInitialState).toBe(false)
expect(wrapper.vm.searchResults.length).toBe(0)
console.log('✅ FIXED: 用户看到"暂无搜索结果"而不是"初始状态"')
it('切换 tab 时按当前关键词重新搜索', async () => {
const wrapper = create_wrapper()
searchAPI.mockResolvedValueOnce({
code: 1,
msg: 'ok',
data: {
products: {
list: [{ id: 1, product_name: '保险A', tags: [] }],
total: 1
},
files: {
list: [],
total: 0
}
}
})
it('问题2: 切换分类时,如果当前没有关键词,不应该显示结果', async () => {
// 不输入任何关键词,直接切换分类
await wrapper.vm.onTabClick('product')
// hasSearched 应该保持 false
expect(wrapper.vm.hasSearched).toBe(false)
// 结果应该为空
expect(wrapper.vm.searchResults.length).toBe(0)
wrapper.vm.searchKeyword = '保险'
await wrapper.vm.handleSearch()
searchAPI.mockResolvedValueOnce({
code: 1,
msg: 'ok',
data: {
products: {
list: [],
total: 0
},
files: {
list: [{ id: 10, name: '培训资料', value: 'url', size: '1MB', extension: 'pdf', is_favorite: 0 }],
total: 1
}
}
})
it('问题3: 搜索关键词后切换分类,结果应该正确更新', async () => {
// 1. 搜索"保险"
wrapper.vm.searchKeyword = '保险'
await wrapper.vm.handleSearch()
const allResults = wrapper.vm.searchResults.length
console.log('全部分类搜索"保险"结果数:', allResults)
// 2. 切换到"产品"分类
await wrapper.vm.onTabClick('product')
const productResults = wrapper.vm.searchResults.length
console.log('产品分类搜索"保险"结果数:', productResults)
await wrapper.vm.onTabClick('file')
// 3. 切换到"资料"分类
await wrapper.vm.onTabClick('material')
const materialResults = wrapper.vm.searchResults.length
console.log('资料分类搜索"保险"结果数:', materialResults)
// 验证结果正确性
expect(productResults + materialResults).toBe(allResults)
})
expect(wrapper.vm.activeTab).toBe('file')
expect(wrapper.vm.currentList.length).toBe(1)
expect(searchAPI).toHaveBeenCalledWith({ keyword: '保险', page: 0, limit: 20, type: 'file' })
})
})
describe('搜索结果 computed 属性详细测试', () => {
let wrapper
beforeEach(() => {
wrapper = mount(SearchPage, {
global: {
components: {
NavHeader: { template: '<div>NavHeader</div>' },
IconFont: { template: '<div>IconFont</div>' },
SearchBar: { template: '<div>SearchBar</div>' }
it('清空搜索后重置状态', async () => {
const wrapper = create_wrapper()
searchAPI.mockResolvedValueOnce({
code: 1,
msg: 'ok',
data: {
products: {
list: [{ id: 1, product_name: '保险A', tags: [] }],
total: 1
},
files: {
list: [],
total: 0
}
}
})
})
it('当 hasSearched 为 false 时,应该返回空数组', () => {
wrapper.vm.hasSearched = false
wrapper.vm.searchKeyword = '保险'
await wrapper.vm.handleSearch()
expect(wrapper.vm.searchResults.length).toBe(0)
})
wrapper.vm.clearSearch()
it('当 hasSearched 为 true 但关键词为空时,应该返回当前分类的所有数据', () => {
wrapper.vm.hasSearched = true
wrapper.vm.searchKeyword = ''
wrapper.vm.activeTabId = ''
// 应该返回所有 100 条数据
expect(wrapper.vm.searchResults.length).toBe(100)
expect(wrapper.vm.hasSearched).toBe(false)
expect(wrapper.vm.activeTab).toBe('')
expect(wrapper.vm.currentList.length).toBe(0)
})
it('当 hasSearched 为 true 且有关键词时,应该返回过滤后的结果', () => {
wrapper.vm.hasSearched = true
wrapper.vm.searchKeyword = '保险'
wrapper.vm.activeTabId = ''
const results = wrapper.vm.searchResults
expect(results.length).toBeGreaterThan(0)
// 验证所有结果都包含关键词
results.forEach(item => {
expect(item.title.toLowerCase()).toContain('保险')
})
})
it('搜索应该不区分大小写', () => {
wrapper.vm.hasSearched = true
wrapper.vm.searchKeyword = 'BAOXIAN'
wrapper.vm.activeTabId = ''
const results = wrapper.vm.searchResults
// 应该能搜索到包含"保险"的内容
expect(results.length).toBeGreaterThan(0)
it('未搜索或无关键词时不触发加载更多', async () => {
const wrapper = create_wrapper()
await wrapper.vm.handleLoadMore(1)
expect(searchAPI).not.toHaveBeenCalled()
})
})
......