mirror of
https://github.com/clash-verge-rev/clash-verge-rev.git
synced 2026-01-28 07:14:40 +08:00
fix: update fallback (#5115)
* fix: update fallback * test: introduce Vitest and add semver helper tests * chore: merge vitest config into vite
This commit is contained in:
@@ -60,6 +60,7 @@
|
||||
- 修复 macOS 连接界面显示异常
|
||||
- 修复规则配置项在不同配置文件间全局共享导致切换被重置的问题
|
||||
- 修复 Linux Wayland 下部分 GPU 可能出现的 UI 渲染问题
|
||||
- 修复自动更新使版本回退的问题
|
||||
|
||||
## v2.4.2
|
||||
|
||||
|
||||
11
package.json
11
package.json
@@ -30,7 +30,8 @@
|
||||
"lint:fix": "eslint -c eslint.config.ts --cache --cache-location .eslintcache --fix src",
|
||||
"format": "prettier --write .",
|
||||
"format:check": "prettier --check .",
|
||||
"typecheck": "tsc --noEmit"
|
||||
"typecheck": "tsc --noEmit",
|
||||
"test": "vitest run"
|
||||
},
|
||||
"dependencies": {
|
||||
"@dnd-kit/core": "^6.3.1",
|
||||
@@ -73,9 +74,9 @@
|
||||
"react-router-dom": "7.9.4",
|
||||
"react-virtuoso": "^4.14.1",
|
||||
"swr": "^2.3.6",
|
||||
"tauri-plugin-mihomo-api": "git+https://github.com/clash-verge-rev/tauri-plugin-mihomo",
|
||||
"types-pac": "^1.0.3",
|
||||
"zustand": "^5.0.8",
|
||||
"tauri-plugin-mihomo-api": "git+https://github.com/clash-verge-rev/tauri-plugin-mihomo"
|
||||
"zustand": "^5.0.8"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@actions/github": "^6.0.1",
|
||||
@@ -84,6 +85,7 @@
|
||||
"@tauri-apps/cli": "2.8.4",
|
||||
"@types/js-yaml": "^4.0.9",
|
||||
"@types/lodash-es": "^4.17.12",
|
||||
"@types/node": "^24.8.1",
|
||||
"@types/react": "19.2.2",
|
||||
"@types/react-dom": "19.2.2",
|
||||
"@vitejs/plugin-legacy": "^7.2.1",
|
||||
@@ -116,7 +118,8 @@
|
||||
"typescript-eslint": "^8.46.1",
|
||||
"vite": "^7.1.10",
|
||||
"vite-plugin-monaco-editor": "^1.1.0",
|
||||
"vite-plugin-svgr": "^4.5.0"
|
||||
"vite-plugin-svgr": "^4.5.0",
|
||||
"vitest": "^3.2.4"
|
||||
},
|
||||
"lint-staged": {
|
||||
"*.{ts,tsx,js,jsx}": [
|
||||
|
||||
355
pnpm-lock.yaml
generated
355
pnpm-lock.yaml
generated
@@ -156,6 +156,9 @@ importers:
|
||||
'@types/lodash-es':
|
||||
specifier: ^4.17.12
|
||||
version: 4.17.12
|
||||
'@types/node':
|
||||
specifier: ^24.8.1
|
||||
version: 24.8.1
|
||||
'@types/react':
|
||||
specifier: 19.2.2
|
||||
version: 19.2.2
|
||||
@@ -164,10 +167,10 @@ importers:
|
||||
version: 19.2.2(@types/react@19.2.2)
|
||||
'@vitejs/plugin-legacy':
|
||||
specifier: ^7.2.1
|
||||
version: 7.2.1(terser@5.44.0)(vite@7.1.10(jiti@2.6.1)(sass@1.93.2)(terser@5.44.0)(yaml@2.8.1))
|
||||
version: 7.2.1(terser@5.44.0)(vite@7.1.10(@types/node@24.8.1)(jiti@2.6.1)(sass@1.93.2)(terser@5.44.0)(yaml@2.8.1))
|
||||
'@vitejs/plugin-react':
|
||||
specifier: 5.0.4
|
||||
version: 5.0.4(vite@7.1.10(jiti@2.6.1)(sass@1.93.2)(terser@5.44.0)(yaml@2.8.1))
|
||||
version: 5.0.4(vite@7.1.10(@types/node@24.8.1)(jiti@2.6.1)(sass@1.93.2)(terser@5.44.0)(yaml@2.8.1))
|
||||
adm-zip:
|
||||
specifier: ^0.5.16
|
||||
version: 0.5.16
|
||||
@@ -248,13 +251,16 @@ importers:
|
||||
version: 8.46.1(eslint@9.38.0(jiti@2.6.1))(typescript@5.9.3)
|
||||
vite:
|
||||
specifier: ^7.1.10
|
||||
version: 7.1.10(jiti@2.6.1)(sass@1.93.2)(terser@5.44.0)(yaml@2.8.1)
|
||||
version: 7.1.10(@types/node@24.8.1)(jiti@2.6.1)(sass@1.93.2)(terser@5.44.0)(yaml@2.8.1)
|
||||
vite-plugin-monaco-editor:
|
||||
specifier: ^1.1.0
|
||||
version: 1.1.0(monaco-editor@0.54.0)
|
||||
vite-plugin-svgr:
|
||||
specifier: ^4.5.0
|
||||
version: 4.5.0(rollup@4.46.2)(typescript@5.9.3)(vite@7.1.10(jiti@2.6.1)(sass@1.93.2)(terser@5.44.0)(yaml@2.8.1))
|
||||
version: 4.5.0(rollup@4.46.2)(typescript@5.9.3)(vite@7.1.10(@types/node@24.8.1)(jiti@2.6.1)(sass@1.93.2)(terser@5.44.0)(yaml@2.8.1))
|
||||
vitest:
|
||||
specifier: ^3.2.4
|
||||
version: 3.2.4(@types/debug@4.1.12)(@types/node@24.8.1)(jiti@2.6.1)(sass@1.93.2)(terser@5.44.0)(yaml@2.8.1)
|
||||
|
||||
packages:
|
||||
|
||||
@@ -1722,9 +1728,15 @@ packages:
|
||||
'@types/babel__traverse@7.20.7':
|
||||
resolution: {integrity: sha512-dkO5fhS7+/oos4ciWxyEyjWe48zmG6wbCheo/G2ZnHx4fs3EU6YC6UM8rk56gAjNJ9P3MTH2jo5jb92/K6wbng==}
|
||||
|
||||
'@types/chai@5.2.2':
|
||||
resolution: {integrity: sha512-8kB30R7Hwqf40JPiKhVzodJs2Qc1ZJ5zuT3uzw5Hq/dhNCl3G3l83jfpdI1e20BP348+fV7VIL/+FxaXkqBmWg==}
|
||||
|
||||
'@types/debug@4.1.12':
|
||||
resolution: {integrity: sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==}
|
||||
|
||||
'@types/deep-eql@4.0.2':
|
||||
resolution: {integrity: sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==}
|
||||
|
||||
'@types/estree-jsx@1.0.5':
|
||||
resolution: {integrity: sha512-52CcUVNFyfb1A2ALocQw/Dd1BQFNmSdkuC3BkZ6iqhdMfQz7JWOFRuJFloOzjk+6WijU56m9oKXFAXc7o3Towg==}
|
||||
|
||||
@@ -1758,6 +1770,9 @@ packages:
|
||||
'@types/ms@2.1.0':
|
||||
resolution: {integrity: sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==}
|
||||
|
||||
'@types/node@24.8.1':
|
||||
resolution: {integrity: sha512-alv65KGRadQVfVcG69MuB4IzdYVpRwMG/mq8KWOaoOdyY617P5ivaDiMCGOFDWD2sAn5Q0mR3mRtUOgm99hL9Q==}
|
||||
|
||||
'@types/parse-json@4.0.2':
|
||||
resolution: {integrity: sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==}
|
||||
|
||||
@@ -1953,6 +1968,35 @@ packages:
|
||||
peerDependencies:
|
||||
vite: ^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0
|
||||
|
||||
'@vitest/expect@3.2.4':
|
||||
resolution: {integrity: sha512-Io0yyORnB6sikFlt8QW5K7slY4OjqNX9jmJQ02QDda8lyM6B5oNgVWoSoKPac8/kgnCUzuHQKrSLtu/uOqqrig==}
|
||||
|
||||
'@vitest/mocker@3.2.4':
|
||||
resolution: {integrity: sha512-46ryTE9RZO/rfDd7pEqFl7etuyzekzEhUbTW3BvmeO/BcCMEgq59BKhek3dXDWgAj4oMK6OZi+vRr1wPW6qjEQ==}
|
||||
peerDependencies:
|
||||
msw: ^2.4.9
|
||||
vite: ^5.0.0 || ^6.0.0 || ^7.0.0-0
|
||||
peerDependenciesMeta:
|
||||
msw:
|
||||
optional: true
|
||||
vite:
|
||||
optional: true
|
||||
|
||||
'@vitest/pretty-format@3.2.4':
|
||||
resolution: {integrity: sha512-IVNZik8IVRJRTr9fxlitMKeJeXFFFN0JaB9PHPGQ8NKQbGpfjlTx9zO4RefN8gp7eqjNy8nyK3NZmBzOPeIxtA==}
|
||||
|
||||
'@vitest/runner@3.2.4':
|
||||
resolution: {integrity: sha512-oukfKT9Mk41LreEW09vt45f8wx7DordoWUZMYdY/cyAk7w5TWkTRCNZYF7sX7n2wB7jyGAl74OxgwhPgKaqDMQ==}
|
||||
|
||||
'@vitest/snapshot@3.2.4':
|
||||
resolution: {integrity: sha512-dEYtS7qQP2CjU27QBC5oUOxLE/v5eLkGqPE0ZKEIDGMs4vKWe7IjgLOeauHsR0D5YuuycGRO5oSRXnwnmA78fQ==}
|
||||
|
||||
'@vitest/spy@3.2.4':
|
||||
resolution: {integrity: sha512-vAfasCOe6AIK70iP5UD11Ac4siNUNJ9i/9PZ3NKx07sG6sUxeag1LWdNrMWeKKYBLlzuK+Gn65Yd5nyL6ds+nw==}
|
||||
|
||||
'@vitest/utils@3.2.4':
|
||||
resolution: {integrity: sha512-fB2V0JFrQSMsCo9HiSq3Ezpdv4iYaXRG1Sx8edX3MwxfyNn83mKiGzOcH+Fkxt4MHxr3y42fQi1oeAInqgX2QA==}
|
||||
|
||||
acorn-jsx@5.3.2:
|
||||
resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==}
|
||||
peerDependencies:
|
||||
@@ -2028,6 +2072,10 @@ packages:
|
||||
resolution: {integrity: sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
assertion-error@2.0.1:
|
||||
resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==}
|
||||
engines: {node: '>=12'}
|
||||
|
||||
async-function@1.0.0:
|
||||
resolution: {integrity: sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==}
|
||||
engines: {node: '>= 0.4'}
|
||||
@@ -2098,6 +2146,10 @@ packages:
|
||||
buffer-from@1.1.2:
|
||||
resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==}
|
||||
|
||||
cac@6.7.14:
|
||||
resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
call-bind-apply-helpers@1.0.2:
|
||||
resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==}
|
||||
engines: {node: '>= 0.4'}
|
||||
@@ -2124,6 +2176,10 @@ packages:
|
||||
ccount@2.0.1:
|
||||
resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==}
|
||||
|
||||
chai@5.3.3:
|
||||
resolution: {integrity: sha512-4zNhdJD/iOjSH0A05ea+Ke6MU5mmpQcbQsSOkgdaUMJ9zTlDTD/GYlwohmIE2u0gaxHYiVHEn1Fw9mZ/ktJWgw==}
|
||||
engines: {node: '>=18'}
|
||||
|
||||
chalk@4.1.2:
|
||||
resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==}
|
||||
engines: {node: '>=10'}
|
||||
@@ -2140,6 +2196,10 @@ packages:
|
||||
character-reference-invalid@2.0.1:
|
||||
resolution: {integrity: sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==}
|
||||
|
||||
check-error@2.1.1:
|
||||
resolution: {integrity: sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==}
|
||||
engines: {node: '>= 16'}
|
||||
|
||||
chokidar@4.0.3:
|
||||
resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==}
|
||||
engines: {node: '>= 14.16.0'}
|
||||
@@ -2285,6 +2345,10 @@ packages:
|
||||
decode-named-character-reference@1.1.0:
|
||||
resolution: {integrity: sha512-Wy+JTSbFThEOXQIR2L6mxJvEs+veIzpmqD7ynWxMXGpnk3smkHQOp6forLdHsKpAMW9iJpaBBIxz285t1n1C3w==}
|
||||
|
||||
deep-eql@5.0.2:
|
||||
resolution: {integrity: sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==}
|
||||
engines: {node: '>=6'}
|
||||
|
||||
deep-is@0.1.4:
|
||||
resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==}
|
||||
|
||||
@@ -2370,6 +2434,9 @@ packages:
|
||||
resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
es-module-lexer@1.7.0:
|
||||
resolution: {integrity: sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==}
|
||||
|
||||
es-object-atoms@1.1.1:
|
||||
resolution: {integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==}
|
||||
engines: {node: '>= 0.4'}
|
||||
@@ -2605,6 +2672,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'}
|
||||
@@ -2615,6 +2685,10 @@ packages:
|
||||
eventemitter3@5.0.1:
|
||||
resolution: {integrity: sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==}
|
||||
|
||||
expect-type@1.2.2:
|
||||
resolution: {integrity: sha512-JhFGDVJ7tmDJItKhYgJCGLOWjuK9vPxiXoUFLwLDc99NlmklilbiQJwoctZtt13+xMw91MCk/REan6MWHqDjyA==}
|
||||
engines: {node: '>=12.0.0'}
|
||||
|
||||
ext@1.7.0:
|
||||
resolution: {integrity: sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw==}
|
||||
|
||||
@@ -3032,6 +3106,9 @@ packages:
|
||||
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.0:
|
||||
resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==}
|
||||
hasBin: true
|
||||
@@ -3119,6 +3196,9 @@ packages:
|
||||
resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==}
|
||||
hasBin: true
|
||||
|
||||
loupe@3.2.1:
|
||||
resolution: {integrity: sha512-CdzqowRJCeLU72bHvWqwRBBlLcMEtIvGrlvef74kMnV2AolS9Y8xUv1I0U/MNAWMhBlKIoyuEgoJ0t/bbwHbLQ==}
|
||||
|
||||
lower-case@2.0.2:
|
||||
resolution: {integrity: sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==}
|
||||
|
||||
@@ -3440,6 +3520,13 @@ packages:
|
||||
resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
pathe@2.0.3:
|
||||
resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==}
|
||||
|
||||
pathval@2.0.1:
|
||||
resolution: {integrity: sha512-//nshmD55c46FuFw26xV/xFAaB5HF9Xdap7HJBBnrKdAd6/GxDBaNA1870O79+9ueg61cZLSVc+OaFlfmObYVQ==}
|
||||
engines: {node: '>= 14.16'}
|
||||
|
||||
picocolors@1.1.1:
|
||||
resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==}
|
||||
|
||||
@@ -3735,6 +3822,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@4.1.0:
|
||||
resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==}
|
||||
engines: {node: '>=14'}
|
||||
@@ -3768,6 +3858,12 @@ packages:
|
||||
resolution: {integrity: sha512-o3yWv49B/o4QZk5ZcsALc6t0+eCelPc44zZsLtCQnZPDwFpDYSWcDnrv2TtMmMbQ7uKo3J0HTURCqckw23czNQ==}
|
||||
engines: {node: '>=12.0.0'}
|
||||
|
||||
stackback@0.0.2:
|
||||
resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==}
|
||||
|
||||
std-env@3.10.0:
|
||||
resolution: {integrity: sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg==}
|
||||
|
||||
stop-iteration-iterator@1.1.0:
|
||||
resolution: {integrity: sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==}
|
||||
engines: {node: '>= 0.4'}
|
||||
@@ -3826,6 +3922,9 @@ packages:
|
||||
resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
strip-literal@3.1.0:
|
||||
resolution: {integrity: sha512-8r3mkIM/2+PpjHoOtiAW8Rg3jJLHaV7xPwG+YRGrv6FP0wwk/toTpATxWYOW0BKdWwl82VT2tFYi5DlROa0Mxg==}
|
||||
|
||||
style-to-js@1.1.16:
|
||||
resolution: {integrity: sha512-/Q6ld50hKYPH3d/r6nr117TZkHR0w0kGGIVfpG9N6D8NymRPM9RqCUv4pRpJ62E5DqOYx2AFpbZMyCPnjQCnOw==}
|
||||
|
||||
@@ -3875,10 +3974,28 @@ packages:
|
||||
resolution: {integrity: sha512-wFH7+SEAcKfJpfLPkrgMPvvwnEtj8W4IurvEyrKsDleXnKLCDw71w8jltvfLa8Rm4qQxxT4jmDBYbJG/z7qoww==}
|
||||
engines: {node: '>=0.12'}
|
||||
|
||||
tinybench@2.9.0:
|
||||
resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==}
|
||||
|
||||
tinyexec@0.3.2:
|
||||
resolution: {integrity: sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==}
|
||||
|
||||
tinyglobby@0.2.15:
|
||||
resolution: {integrity: sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==}
|
||||
engines: {node: '>=12.0.0'}
|
||||
|
||||
tinypool@1.1.1:
|
||||
resolution: {integrity: sha512-Zba82s87IFq9A9XmjiX5uZA/ARWDrB03OHlq+Vw1fSdt0I+4/Kutwy8BP4Y/y/aORMo61FQ0vIb5j44vSo5Pkg==}
|
||||
engines: {node: ^18.0.0 || >=20.0.0}
|
||||
|
||||
tinyrainbow@2.0.0:
|
||||
resolution: {integrity: sha512-op4nsTR47R6p0vMUUoYl/a+ljLFVtlfaXkLQmqfLR1qHma1h/ysYk4hEXZ880bf2CYgTskvTa/e196Vd5dDQXw==}
|
||||
engines: {node: '>=14.0.0'}
|
||||
|
||||
tinyspy@4.0.4:
|
||||
resolution: {integrity: sha512-azl+t0z7pw/z958Gy9svOTuzqIk6xq+NSheJzn5MMWtWTFywIacg2wUlzKFGtt3cthx0r2SxMK0yzJOR0IES7Q==}
|
||||
engines: {node: '>=14.0.0'}
|
||||
|
||||
to-regex-range@5.0.1:
|
||||
resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==}
|
||||
engines: {node: '>=8.0'}
|
||||
@@ -3955,6 +4072,9 @@ packages:
|
||||
resolution: {integrity: sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
undici-types@7.14.0:
|
||||
resolution: {integrity: sha512-QQiYxHuyZ9gQUIrmPo3IA+hUl4KYk8uSA7cHrcKd/l3p1OTpZcM0Tbp9x7FAtXdAYhlasd60ncPpgu6ihG6TOA==}
|
||||
|
||||
undici@5.29.0:
|
||||
resolution: {integrity: sha512-raqeBD6NQK4SkWhQzeYKd1KmIG6dllBOTt55Rmkt4HtI9mwdWtJljnrXjAFUBLTSN67HWrOIZ3EPF4kjUw80Bg==}
|
||||
engines: {node: '>=14.0'}
|
||||
@@ -4019,6 +4139,11 @@ packages:
|
||||
vfile@6.0.3:
|
||||
resolution: {integrity: sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==}
|
||||
|
||||
vite-node@3.2.4:
|
||||
resolution: {integrity: sha512-EbKSKh+bh1E1IFxeO0pg1n4dvoOTt0UDiXMd/qn++r98+jPO1xtJilvXldeuQ8giIB5IkpjCgMleHMNEsGH6pg==}
|
||||
engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0}
|
||||
hasBin: true
|
||||
|
||||
vite-plugin-monaco-editor@1.1.0:
|
||||
resolution: {integrity: sha512-IvtUqZotrRoVqwT0PBBDIZPNraya3BxN/bfcNfnxZ5rkJiGcNtO5eAOWWSgT7zullIAEqQwxMU83yL9J5k7gww==}
|
||||
peerDependencies:
|
||||
@@ -4069,6 +4194,34 @@ packages:
|
||||
yaml:
|
||||
optional: true
|
||||
|
||||
vitest@3.2.4:
|
||||
resolution: {integrity: sha512-LUCP5ev3GURDysTWiP47wRRUpLKMOfPh+yKTx3kVIEiu5KOMeqzpnYNsKyOoVrULivR8tLcks4+lga33Whn90A==}
|
||||
engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0}
|
||||
hasBin: true
|
||||
peerDependencies:
|
||||
'@edge-runtime/vm': '*'
|
||||
'@types/debug': ^4.1.12
|
||||
'@types/node': ^18.0.0 || ^20.0.0 || >=22.0.0
|
||||
'@vitest/browser': 3.2.4
|
||||
'@vitest/ui': 3.2.4
|
||||
happy-dom: '*'
|
||||
jsdom: '*'
|
||||
peerDependenciesMeta:
|
||||
'@edge-runtime/vm':
|
||||
optional: true
|
||||
'@types/debug':
|
||||
optional: true
|
||||
'@types/node':
|
||||
optional: true
|
||||
'@vitest/browser':
|
||||
optional: true
|
||||
'@vitest/ui':
|
||||
optional: true
|
||||
happy-dom:
|
||||
optional: true
|
||||
jsdom:
|
||||
optional: true
|
||||
|
||||
void-elements@3.1.0:
|
||||
resolution: {integrity: sha512-Dhxzh5HZuiHQhbvTW9AMetFfBHDMYpo23Uo9btPXgdYP+3T5S+p+jgNy7spra+veYhBP2dCSgxR/i2Y02h5/6w==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
@@ -4114,6 +4267,11 @@ packages:
|
||||
engines: {node: '>= 8'}
|
||||
hasBin: true
|
||||
|
||||
why-is-node-running@2.3.0:
|
||||
resolution: {integrity: sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==}
|
||||
engines: {node: '>=8'}
|
||||
hasBin: true
|
||||
|
||||
word-wrap@1.2.5:
|
||||
resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
@@ -5774,10 +5932,16 @@ snapshots:
|
||||
dependencies:
|
||||
'@babel/types': 7.28.4
|
||||
|
||||
'@types/chai@5.2.2':
|
||||
dependencies:
|
||||
'@types/deep-eql': 4.0.2
|
||||
|
||||
'@types/debug@4.1.12':
|
||||
dependencies:
|
||||
'@types/ms': 2.1.0
|
||||
|
||||
'@types/deep-eql@4.0.2': {}
|
||||
|
||||
'@types/estree-jsx@1.0.5':
|
||||
dependencies:
|
||||
'@types/estree': 1.0.8
|
||||
@@ -5809,6 +5973,10 @@ snapshots:
|
||||
|
||||
'@types/ms@2.1.0': {}
|
||||
|
||||
'@types/node@24.8.1':
|
||||
dependencies:
|
||||
undici-types: 7.14.0
|
||||
|
||||
'@types/parse-json@4.0.2': {}
|
||||
|
||||
'@types/prop-types@15.7.15': {}
|
||||
@@ -5983,7 +6151,7 @@ snapshots:
|
||||
'@unrs/resolver-binding-win32-x64-msvc@1.11.1':
|
||||
optional: true
|
||||
|
||||
'@vitejs/plugin-legacy@7.2.1(terser@5.44.0)(vite@7.1.10(jiti@2.6.1)(sass@1.93.2)(terser@5.44.0)(yaml@2.8.1))':
|
||||
'@vitejs/plugin-legacy@7.2.1(terser@5.44.0)(vite@7.1.10(@types/node@24.8.1)(jiti@2.6.1)(sass@1.93.2)(terser@5.44.0)(yaml@2.8.1))':
|
||||
dependencies:
|
||||
'@babel/core': 7.28.4
|
||||
'@babel/plugin-transform-dynamic-import': 7.27.1(@babel/core@7.28.4)
|
||||
@@ -5998,11 +6166,11 @@ snapshots:
|
||||
regenerator-runtime: 0.14.1
|
||||
systemjs: 6.15.1
|
||||
terser: 5.44.0
|
||||
vite: 7.1.10(jiti@2.6.1)(sass@1.93.2)(terser@5.44.0)(yaml@2.8.1)
|
||||
vite: 7.1.10(@types/node@24.8.1)(jiti@2.6.1)(sass@1.93.2)(terser@5.44.0)(yaml@2.8.1)
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@vitejs/plugin-react@5.0.4(vite@7.1.10(jiti@2.6.1)(sass@1.93.2)(terser@5.44.0)(yaml@2.8.1))':
|
||||
'@vitejs/plugin-react@5.0.4(vite@7.1.10(@types/node@24.8.1)(jiti@2.6.1)(sass@1.93.2)(terser@5.44.0)(yaml@2.8.1))':
|
||||
dependencies:
|
||||
'@babel/core': 7.28.4
|
||||
'@babel/plugin-transform-react-jsx-self': 7.27.1(@babel/core@7.28.4)
|
||||
@@ -6010,10 +6178,52 @@ snapshots:
|
||||
'@rolldown/pluginutils': 1.0.0-beta.38
|
||||
'@types/babel__core': 7.20.5
|
||||
react-refresh: 0.17.0
|
||||
vite: 7.1.10(jiti@2.6.1)(sass@1.93.2)(terser@5.44.0)(yaml@2.8.1)
|
||||
vite: 7.1.10(@types/node@24.8.1)(jiti@2.6.1)(sass@1.93.2)(terser@5.44.0)(yaml@2.8.1)
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@vitest/expect@3.2.4':
|
||||
dependencies:
|
||||
'@types/chai': 5.2.2
|
||||
'@vitest/spy': 3.2.4
|
||||
'@vitest/utils': 3.2.4
|
||||
chai: 5.3.3
|
||||
tinyrainbow: 2.0.0
|
||||
|
||||
'@vitest/mocker@3.2.4(vite@7.1.10(@types/node@24.8.1)(jiti@2.6.1)(sass@1.93.2)(terser@5.44.0)(yaml@2.8.1))':
|
||||
dependencies:
|
||||
'@vitest/spy': 3.2.4
|
||||
estree-walker: 3.0.3
|
||||
magic-string: 0.30.17
|
||||
optionalDependencies:
|
||||
vite: 7.1.10(@types/node@24.8.1)(jiti@2.6.1)(sass@1.93.2)(terser@5.44.0)(yaml@2.8.1)
|
||||
|
||||
'@vitest/pretty-format@3.2.4':
|
||||
dependencies:
|
||||
tinyrainbow: 2.0.0
|
||||
|
||||
'@vitest/runner@3.2.4':
|
||||
dependencies:
|
||||
'@vitest/utils': 3.2.4
|
||||
pathe: 2.0.3
|
||||
strip-literal: 3.1.0
|
||||
|
||||
'@vitest/snapshot@3.2.4':
|
||||
dependencies:
|
||||
'@vitest/pretty-format': 3.2.4
|
||||
magic-string: 0.30.17
|
||||
pathe: 2.0.3
|
||||
|
||||
'@vitest/spy@3.2.4':
|
||||
dependencies:
|
||||
tinyspy: 4.0.4
|
||||
|
||||
'@vitest/utils@3.2.4':
|
||||
dependencies:
|
||||
'@vitest/pretty-format': 3.2.4
|
||||
loupe: 3.2.1
|
||||
tinyrainbow: 2.0.0
|
||||
|
||||
acorn-jsx@5.3.2(acorn@8.15.0):
|
||||
dependencies:
|
||||
acorn: 8.15.0
|
||||
@@ -6118,6 +6328,8 @@ snapshots:
|
||||
is-array-buffer: 3.0.5
|
||||
optional: true
|
||||
|
||||
assertion-error@2.0.1: {}
|
||||
|
||||
async-function@1.0.0:
|
||||
optional: true
|
||||
|
||||
@@ -6201,6 +6413,8 @@ snapshots:
|
||||
|
||||
buffer-from@1.1.2: {}
|
||||
|
||||
cac@6.7.14: {}
|
||||
|
||||
call-bind-apply-helpers@1.0.2:
|
||||
dependencies:
|
||||
es-errors: 1.3.0
|
||||
@@ -6228,6 +6442,14 @@ snapshots:
|
||||
|
||||
ccount@2.0.1: {}
|
||||
|
||||
chai@5.3.3:
|
||||
dependencies:
|
||||
assertion-error: 2.0.1
|
||||
check-error: 2.1.1
|
||||
deep-eql: 5.0.2
|
||||
loupe: 3.2.1
|
||||
pathval: 2.0.1
|
||||
|
||||
chalk@4.1.2:
|
||||
dependencies:
|
||||
ansi-styles: 4.3.0
|
||||
@@ -6241,6 +6463,8 @@ snapshots:
|
||||
|
||||
character-reference-invalid@2.0.1: {}
|
||||
|
||||
check-error@2.1.1: {}
|
||||
|
||||
chokidar@4.0.3:
|
||||
dependencies:
|
||||
readdirp: 4.1.2
|
||||
@@ -6377,6 +6601,8 @@ snapshots:
|
||||
dependencies:
|
||||
character-entities: 2.0.2
|
||||
|
||||
deep-eql@5.0.2: {}
|
||||
|
||||
deep-is@0.1.4: {}
|
||||
|
||||
define-data-property@1.1.4:
|
||||
@@ -6509,6 +6735,8 @@ snapshots:
|
||||
|
||||
es-errors@1.3.0: {}
|
||||
|
||||
es-module-lexer@1.7.0: {}
|
||||
|
||||
es-object-atoms@1.1.1:
|
||||
dependencies:
|
||||
es-errors: 1.3.0
|
||||
@@ -6884,6 +7112,10 @@ snapshots:
|
||||
|
||||
estree-walker@2.0.2: {}
|
||||
|
||||
estree-walker@3.0.3:
|
||||
dependencies:
|
||||
'@types/estree': 1.0.8
|
||||
|
||||
esutils@2.0.3: {}
|
||||
|
||||
event-emitter@0.3.5:
|
||||
@@ -6893,6 +7125,8 @@ snapshots:
|
||||
|
||||
eventemitter3@5.0.1: {}
|
||||
|
||||
expect-type@1.2.2: {}
|
||||
|
||||
ext@1.7.0:
|
||||
dependencies:
|
||||
type: 2.7.3
|
||||
@@ -7347,6 +7581,8 @@ snapshots:
|
||||
|
||||
js-tokens@4.0.0: {}
|
||||
|
||||
js-tokens@9.0.1: {}
|
||||
|
||||
js-yaml@4.1.0:
|
||||
dependencies:
|
||||
argparse: 2.0.1
|
||||
@@ -7430,6 +7666,8 @@ snapshots:
|
||||
dependencies:
|
||||
js-tokens: 4.0.0
|
||||
|
||||
loupe@3.2.1: {}
|
||||
|
||||
lower-case@2.0.2:
|
||||
dependencies:
|
||||
tslib: 2.8.1
|
||||
@@ -7904,6 +8142,10 @@ snapshots:
|
||||
|
||||
path-type@4.0.0: {}
|
||||
|
||||
pathe@2.0.3: {}
|
||||
|
||||
pathval@2.0.1: {}
|
||||
|
||||
picocolors@1.1.1: {}
|
||||
|
||||
picomatch@2.3.1: {}
|
||||
@@ -8251,6 +8493,8 @@ snapshots:
|
||||
side-channel-weakmap: 1.0.2
|
||||
optional: true
|
||||
|
||||
siginfo@2.0.0: {}
|
||||
|
||||
signal-exit@4.1.0: {}
|
||||
|
||||
slice-ansi@7.1.2:
|
||||
@@ -8278,6 +8522,10 @@ snapshots:
|
||||
|
||||
stable-hash-x@0.2.0: {}
|
||||
|
||||
stackback@0.0.2: {}
|
||||
|
||||
std-env@3.10.0: {}
|
||||
|
||||
stop-iteration-iterator@1.1.0:
|
||||
dependencies:
|
||||
es-errors: 1.3.0
|
||||
@@ -8355,6 +8603,10 @@ snapshots:
|
||||
|
||||
strip-json-comments@3.1.1: {}
|
||||
|
||||
strip-literal@3.1.0:
|
||||
dependencies:
|
||||
js-tokens: 9.0.1
|
||||
|
||||
style-to-js@1.1.16:
|
||||
dependencies:
|
||||
style-to-object: 1.0.8
|
||||
@@ -8409,11 +8661,21 @@ snapshots:
|
||||
es5-ext: 0.10.64
|
||||
next-tick: 1.1.0
|
||||
|
||||
tinybench@2.9.0: {}
|
||||
|
||||
tinyexec@0.3.2: {}
|
||||
|
||||
tinyglobby@0.2.15:
|
||||
dependencies:
|
||||
fdir: 6.5.0(picomatch@4.0.3)
|
||||
picomatch: 4.0.3
|
||||
|
||||
tinypool@1.1.1: {}
|
||||
|
||||
tinyrainbow@2.0.0: {}
|
||||
|
||||
tinyspy@4.0.4: {}
|
||||
|
||||
to-regex-range@5.0.1:
|
||||
dependencies:
|
||||
is-number: 7.0.0
|
||||
@@ -8511,6 +8773,8 @@ snapshots:
|
||||
which-boxed-primitive: 1.1.1
|
||||
optional: true
|
||||
|
||||
undici-types@7.14.0: {}
|
||||
|
||||
undici@5.29.0:
|
||||
dependencies:
|
||||
'@fastify/busboy': 2.1.1
|
||||
@@ -8609,22 +8873,43 @@ snapshots:
|
||||
'@types/unist': 3.0.3
|
||||
vfile-message: 4.0.2
|
||||
|
||||
vite-node@3.2.4(@types/node@24.8.1)(jiti@2.6.1)(sass@1.93.2)(terser@5.44.0)(yaml@2.8.1):
|
||||
dependencies:
|
||||
cac: 6.7.14
|
||||
debug: 4.4.1
|
||||
es-module-lexer: 1.7.0
|
||||
pathe: 2.0.3
|
||||
vite: 7.1.10(@types/node@24.8.1)(jiti@2.6.1)(sass@1.93.2)(terser@5.44.0)(yaml@2.8.1)
|
||||
transitivePeerDependencies:
|
||||
- '@types/node'
|
||||
- jiti
|
||||
- less
|
||||
- lightningcss
|
||||
- sass
|
||||
- sass-embedded
|
||||
- stylus
|
||||
- sugarss
|
||||
- supports-color
|
||||
- terser
|
||||
- tsx
|
||||
- yaml
|
||||
|
||||
vite-plugin-monaco-editor@1.1.0(monaco-editor@0.54.0):
|
||||
dependencies:
|
||||
monaco-editor: 0.54.0
|
||||
|
||||
vite-plugin-svgr@4.5.0(rollup@4.46.2)(typescript@5.9.3)(vite@7.1.10(jiti@2.6.1)(sass@1.93.2)(terser@5.44.0)(yaml@2.8.1)):
|
||||
vite-plugin-svgr@4.5.0(rollup@4.46.2)(typescript@5.9.3)(vite@7.1.10(@types/node@24.8.1)(jiti@2.6.1)(sass@1.93.2)(terser@5.44.0)(yaml@2.8.1)):
|
||||
dependencies:
|
||||
'@rollup/pluginutils': 5.2.0(rollup@4.46.2)
|
||||
'@svgr/core': 8.1.0(typescript@5.9.3)
|
||||
'@svgr/plugin-jsx': 8.1.0(@svgr/core@8.1.0(typescript@5.9.3))
|
||||
vite: 7.1.10(jiti@2.6.1)(sass@1.93.2)(terser@5.44.0)(yaml@2.8.1)
|
||||
vite: 7.1.10(@types/node@24.8.1)(jiti@2.6.1)(sass@1.93.2)(terser@5.44.0)(yaml@2.8.1)
|
||||
transitivePeerDependencies:
|
||||
- rollup
|
||||
- supports-color
|
||||
- typescript
|
||||
|
||||
vite@7.1.10(jiti@2.6.1)(sass@1.93.2)(terser@5.44.0)(yaml@2.8.1):
|
||||
vite@7.1.10(@types/node@24.8.1)(jiti@2.6.1)(sass@1.93.2)(terser@5.44.0)(yaml@2.8.1):
|
||||
dependencies:
|
||||
esbuild: 0.25.4
|
||||
fdir: 6.5.0(picomatch@4.0.3)
|
||||
@@ -8633,12 +8918,55 @@ snapshots:
|
||||
rollup: 4.46.2
|
||||
tinyglobby: 0.2.15
|
||||
optionalDependencies:
|
||||
'@types/node': 24.8.1
|
||||
fsevents: 2.3.3
|
||||
jiti: 2.6.1
|
||||
sass: 1.93.2
|
||||
terser: 5.44.0
|
||||
yaml: 2.8.1
|
||||
|
||||
vitest@3.2.4(@types/debug@4.1.12)(@types/node@24.8.1)(jiti@2.6.1)(sass@1.93.2)(terser@5.44.0)(yaml@2.8.1):
|
||||
dependencies:
|
||||
'@types/chai': 5.2.2
|
||||
'@vitest/expect': 3.2.4
|
||||
'@vitest/mocker': 3.2.4(vite@7.1.10(@types/node@24.8.1)(jiti@2.6.1)(sass@1.93.2)(terser@5.44.0)(yaml@2.8.1))
|
||||
'@vitest/pretty-format': 3.2.4
|
||||
'@vitest/runner': 3.2.4
|
||||
'@vitest/snapshot': 3.2.4
|
||||
'@vitest/spy': 3.2.4
|
||||
'@vitest/utils': 3.2.4
|
||||
chai: 5.3.3
|
||||
debug: 4.4.1
|
||||
expect-type: 1.2.2
|
||||
magic-string: 0.30.17
|
||||
pathe: 2.0.3
|
||||
picomatch: 4.0.3
|
||||
std-env: 3.10.0
|
||||
tinybench: 2.9.0
|
||||
tinyexec: 0.3.2
|
||||
tinyglobby: 0.2.15
|
||||
tinypool: 1.1.1
|
||||
tinyrainbow: 2.0.0
|
||||
vite: 7.1.10(@types/node@24.8.1)(jiti@2.6.1)(sass@1.93.2)(terser@5.44.0)(yaml@2.8.1)
|
||||
vite-node: 3.2.4(@types/node@24.8.1)(jiti@2.6.1)(sass@1.93.2)(terser@5.44.0)(yaml@2.8.1)
|
||||
why-is-node-running: 2.3.0
|
||||
optionalDependencies:
|
||||
'@types/debug': 4.1.12
|
||||
'@types/node': 24.8.1
|
||||
transitivePeerDependencies:
|
||||
- jiti
|
||||
- less
|
||||
- lightningcss
|
||||
- msw
|
||||
- sass
|
||||
- sass-embedded
|
||||
- stylus
|
||||
- sugarss
|
||||
- supports-color
|
||||
- terser
|
||||
- tsx
|
||||
- yaml
|
||||
|
||||
void-elements@3.1.0: {}
|
||||
|
||||
vscode-jsonrpc@8.2.0: {}
|
||||
@@ -8705,6 +9033,11 @@ snapshots:
|
||||
dependencies:
|
||||
isexe: 2.0.0
|
||||
|
||||
why-is-node-running@2.3.0:
|
||||
dependencies:
|
||||
siginfo: 2.0.0
|
||||
stackback: 0.0.2
|
||||
|
||||
word-wrap@1.2.5: {}
|
||||
|
||||
wrap-ansi@7.0.0:
|
||||
|
||||
@@ -14,7 +14,6 @@ import {
|
||||
IconButton,
|
||||
Tooltip,
|
||||
} from "@mui/material";
|
||||
import { check as checkUpdate } from "@tauri-apps/plugin-updater";
|
||||
import { useLockFn } from "ahooks";
|
||||
import { useCallback, useEffect, useMemo, useReducer } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
@@ -26,6 +25,7 @@ import { useVerge } from "@/hooks/use-verge";
|
||||
import { useServiceInstaller } from "@/hooks/useServiceInstaller";
|
||||
import { getSystemInfo } from "@/services/cmds";
|
||||
import { showNotice } from "@/services/noticeService";
|
||||
import { checkUpdateSafe as checkUpdate } from "@/services/update";
|
||||
import { version as appVersion } from "@root/package.json";
|
||||
|
||||
import { EnhancedCard } from "./enhanced-card";
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { Button } from "@mui/material";
|
||||
import { check } from "@tauri-apps/plugin-updater";
|
||||
import { useRef } from "react";
|
||||
import useSWR from "swr";
|
||||
|
||||
import { useVerge } from "@/hooks/use-verge";
|
||||
import { checkUpdateSafe } from "@/services/update";
|
||||
|
||||
import { DialogRef } from "../base";
|
||||
import { UpdateViewer } from "../setting/mods/update-viewer";
|
||||
@@ -21,7 +21,7 @@ export const UpdateButton = (props: Props) => {
|
||||
|
||||
const { data: updateInfo } = useSWR(
|
||||
auto_check_update || auto_check_update === null ? "checkUpdate" : null,
|
||||
check,
|
||||
checkUpdateSafe,
|
||||
{
|
||||
errorRetryCount: 2,
|
||||
revalidateIfStale: false,
|
||||
|
||||
@@ -2,7 +2,6 @@ import { Box, Button, LinearProgress } from "@mui/material";
|
||||
import { Event, UnlistenFn } from "@tauri-apps/api/event";
|
||||
import { relaunch } from "@tauri-apps/plugin-process";
|
||||
import { open as openUrl } from "@tauri-apps/plugin-shell";
|
||||
import { check as checkUpdate } from "@tauri-apps/plugin-updater";
|
||||
import { useLockFn } from "ahooks";
|
||||
import type { Ref } from "react";
|
||||
import { useEffect, useImperativeHandle, useMemo, useState } from "react";
|
||||
@@ -15,6 +14,7 @@ import { useListen } from "@/hooks/use-listen";
|
||||
import { portableFlag } from "@/pages/_layout";
|
||||
import { showNotice } from "@/services/noticeService";
|
||||
import { useSetUpdateState, useUpdateState } from "@/services/states";
|
||||
import { checkUpdateSafe as checkUpdate } from "@/services/update";
|
||||
|
||||
export function UpdateViewer({ ref }: { ref?: Ref<DialogRef> }) {
|
||||
const { t } = useTranslation();
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { ContentCopyRounded } from "@mui/icons-material";
|
||||
import { Typography } from "@mui/material";
|
||||
import { check as checkUpdate } from "@tauri-apps/plugin-updater";
|
||||
import { useCallback, useRef } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
@@ -15,6 +14,7 @@ import {
|
||||
openLogsDir,
|
||||
} from "@/services/cmds";
|
||||
import { showNotice } from "@/services/noticeService";
|
||||
import { checkUpdateSafe as checkUpdate } from "@/services/update";
|
||||
import { version } from "@root/package.json";
|
||||
|
||||
import { BackupViewer } from "./mods/backup-viewer";
|
||||
|
||||
140
src/services/update.test.ts
Normal file
140
src/services/update.test.ts
Normal file
@@ -0,0 +1,140 @@
|
||||
import type { Update } from "@tauri-apps/plugin-updater";
|
||||
import { describe, expect, it } from "vitest";
|
||||
|
||||
import {
|
||||
compareVersions,
|
||||
ensureSemver,
|
||||
extractSemver,
|
||||
normalizeVersion,
|
||||
resolveRemoteVersion,
|
||||
splitVersion,
|
||||
} from "@/services/update";
|
||||
import type { VersionParts } from "@/services/update";
|
||||
|
||||
const makeUpdate = (data: {
|
||||
version?: string | null;
|
||||
rawJson?: Record<string, unknown> | null;
|
||||
}): Update =>
|
||||
({
|
||||
version: data.version ?? "",
|
||||
rawJson: data.rawJson ?? {},
|
||||
}) as unknown as Update;
|
||||
|
||||
describe("normalizeVersion", () => {
|
||||
it("strips optional v prefix and trims whitespace", () => {
|
||||
expect(normalizeVersion(" v1.2.3 ")).toBe("1.2.3");
|
||||
expect(normalizeVersion("V2.0.0-beta")).toBe("2.0.0-beta");
|
||||
});
|
||||
|
||||
it("returns null for empty or non-string input", () => {
|
||||
expect(normalizeVersion(null)).toBeNull();
|
||||
expect(normalizeVersion(" ")).toBeNull();
|
||||
});
|
||||
});
|
||||
|
||||
describe("ensureSemver", () => {
|
||||
it("returns normalized semver when input is valid", () => {
|
||||
expect(ensureSemver("1.2.3")).toBe("1.2.3");
|
||||
expect(ensureSemver("v3.4.5-alpha.1+build.7")).toBe(
|
||||
"3.4.5-alpha.1+build.7",
|
||||
);
|
||||
});
|
||||
|
||||
it("returns null for invalid versions", () => {
|
||||
expect(ensureSemver("1")).toBeNull();
|
||||
expect(ensureSemver("1.2.3.4")).toBeNull();
|
||||
expect(ensureSemver("release-candidate")).toBeNull();
|
||||
});
|
||||
});
|
||||
|
||||
describe("extractSemver", () => {
|
||||
it("finds the first semver-like string and normalizes it", () => {
|
||||
expect(extractSemver("Release v1.2.3 (latest)")).toBe("1.2.3");
|
||||
expect(extractSemver("tag:V2.0.0-beta+exp.sha")).toBe("2.0.0-beta+exp.sha");
|
||||
});
|
||||
|
||||
it("returns null when no semver-like string is present", () => {
|
||||
expect(extractSemver("no version available")).toBeNull();
|
||||
});
|
||||
});
|
||||
|
||||
describe("splitVersion", () => {
|
||||
it("splits version into numeric main and typed prerelease parts", () => {
|
||||
const parts = splitVersion("1.2.3-alpha.4.beta") as VersionParts;
|
||||
expect(parts.main).toEqual([1, 2, 3]);
|
||||
expect(parts.pre).toEqual(["alpha", 4, "beta"]);
|
||||
});
|
||||
|
||||
it("returns null when version is missing", () => {
|
||||
expect(splitVersion(null)).toBeNull();
|
||||
});
|
||||
});
|
||||
|
||||
describe("compareVersions", () => {
|
||||
it("orders versions by numeric components", () => {
|
||||
expect(compareVersions("1.2.3", "1.2.4")).toBe(-1);
|
||||
expect(compareVersions("2.0.0", "1.9.9")).toBe(1);
|
||||
});
|
||||
|
||||
it("treats release versions as newer than prereleases", () => {
|
||||
expect(compareVersions("1.0.0", "1.0.0-beta")).toBe(1);
|
||||
expect(compareVersions("1.0.0-beta", "1.0.0")).toBe(-1);
|
||||
});
|
||||
|
||||
it("resolves prerelease precedence correctly", () => {
|
||||
expect(compareVersions("1.0.0-beta", "1.0.0-alpha")).toBe(1);
|
||||
expect(compareVersions("1.0.0-alpha.1", "1.0.0-alpha.beta")).toBe(-1);
|
||||
});
|
||||
|
||||
it("returns null when comparison cannot be made", () => {
|
||||
expect(compareVersions(null, "1.0.0")).toBeNull();
|
||||
});
|
||||
});
|
||||
|
||||
describe("resolveRemoteVersion", () => {
|
||||
it("prefers direct semver value on the update object", () => {
|
||||
const update = makeUpdate({ version: "v1.2.3" });
|
||||
expect(resolveRemoteVersion(update)).toBe("1.2.3");
|
||||
});
|
||||
|
||||
it("falls back through rawJson fields when primary version is missing", () => {
|
||||
const update = makeUpdate({
|
||||
version: "See release notes",
|
||||
rawJson: {
|
||||
version: "v2.3.4",
|
||||
tag_name: "ignore-me",
|
||||
name: "v0.0.1",
|
||||
},
|
||||
});
|
||||
expect(resolveRemoteVersion(update)).toBe("2.3.4");
|
||||
});
|
||||
|
||||
it("rescues version from tag_name or name when needed", () => {
|
||||
const update = makeUpdate({
|
||||
version: "no version here",
|
||||
rawJson: {
|
||||
tag_name: "release-v3.1.0",
|
||||
name: "build-should-not-override",
|
||||
},
|
||||
});
|
||||
expect(resolveRemoteVersion(update)).toBe("3.1.0");
|
||||
|
||||
const nameOnly = makeUpdate({
|
||||
version: "invalid",
|
||||
rawJson: {
|
||||
name: "release v4.0.0-beta.1",
|
||||
},
|
||||
});
|
||||
expect(resolveRemoteVersion(nameOnly)).toBe("4.0.0-beta.1");
|
||||
});
|
||||
|
||||
it("returns null when no semver-like data is present", () => {
|
||||
const update = makeUpdate({
|
||||
version: "not-a-version",
|
||||
rawJson: {
|
||||
name: "nope",
|
||||
},
|
||||
});
|
||||
expect(resolveRemoteVersion(update)).toBeNull();
|
||||
});
|
||||
});
|
||||
155
src/services/update.ts
Normal file
155
src/services/update.ts
Normal file
@@ -0,0 +1,155 @@
|
||||
import {
|
||||
check,
|
||||
type CheckOptions,
|
||||
type Update,
|
||||
} from "@tauri-apps/plugin-updater";
|
||||
|
||||
import { version as appVersion } from "@root/package.json";
|
||||
|
||||
export type VersionParts = {
|
||||
main: number[];
|
||||
pre: (number | string)[];
|
||||
};
|
||||
|
||||
const SEMVER_FULL_REGEX =
|
||||
/^\d+(?:\.\d+){1,2}(?:-[0-9A-Za-z.-]+)?(?:\+[0-9A-Za-z.-]+)?$/;
|
||||
const SEMVER_SEARCH_REGEX =
|
||||
/v?\d+(?:\.\d+){1,2}(?:-[0-9A-Za-z.-]+)?(?:\+[0-9A-Za-z.-]+)?/i;
|
||||
|
||||
export const normalizeVersion = (
|
||||
input: string | null | undefined,
|
||||
): string | null => {
|
||||
if (typeof input !== "string") return null;
|
||||
const trimmed = input.trim();
|
||||
if (!trimmed) return null;
|
||||
return trimmed.replace(/^v/i, "");
|
||||
};
|
||||
|
||||
export const ensureSemver = (
|
||||
input: string | null | undefined,
|
||||
): string | null => {
|
||||
const normalized = normalizeVersion(input);
|
||||
if (!normalized) return null;
|
||||
return SEMVER_FULL_REGEX.test(normalized) ? normalized : null;
|
||||
};
|
||||
|
||||
export const extractSemver = (
|
||||
input: string | null | undefined,
|
||||
): string | null => {
|
||||
if (typeof input !== "string") return null;
|
||||
const match = input.match(SEMVER_SEARCH_REGEX);
|
||||
if (!match) return null;
|
||||
return normalizeVersion(match[0]);
|
||||
};
|
||||
|
||||
export const splitVersion = (version: string | null): VersionParts | null => {
|
||||
if (!version) return null;
|
||||
const [mainPart, preRelease] = version.split("-");
|
||||
const main = mainPart
|
||||
.split(".")
|
||||
.map((part) => Number.parseInt(part, 10))
|
||||
.map((num) => (Number.isNaN(num) ? 0 : num));
|
||||
|
||||
const pre =
|
||||
preRelease?.split(".").map((token) => {
|
||||
const numeric = Number.parseInt(token, 10);
|
||||
return Number.isNaN(numeric) ? token : numeric;
|
||||
}) ?? [];
|
||||
|
||||
return { main, pre };
|
||||
};
|
||||
|
||||
const compareVersionParts = (a: VersionParts, b: VersionParts): number => {
|
||||
const length = Math.max(a.main.length, b.main.length);
|
||||
for (let i = 0; i < length; i += 1) {
|
||||
const diff = (a.main[i] ?? 0) - (b.main[i] ?? 0);
|
||||
if (diff !== 0) return diff > 0 ? 1 : -1;
|
||||
}
|
||||
|
||||
if (a.pre.length === 0 && b.pre.length === 0) return 0;
|
||||
if (a.pre.length === 0) return 1;
|
||||
if (b.pre.length === 0) return -1;
|
||||
|
||||
const preLen = Math.max(a.pre.length, b.pre.length);
|
||||
for (let i = 0; i < preLen; i += 1) {
|
||||
const aToken = a.pre[i];
|
||||
const bToken = b.pre[i];
|
||||
if (aToken === undefined) return -1;
|
||||
if (bToken === undefined) return 1;
|
||||
|
||||
if (typeof aToken === "number" && typeof bToken === "number") {
|
||||
if (aToken > bToken) return 1;
|
||||
if (aToken < bToken) return -1;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (typeof aToken === "number") return -1;
|
||||
if (typeof bToken === "number") return 1;
|
||||
|
||||
if (aToken > bToken) return 1;
|
||||
if (aToken < bToken) return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
};
|
||||
|
||||
export const compareVersions = (
|
||||
a: string | null,
|
||||
b: string | null,
|
||||
): number | null => {
|
||||
const partsA = splitVersion(a);
|
||||
const partsB = splitVersion(b);
|
||||
if (!partsA || !partsB) return null;
|
||||
return compareVersionParts(partsA, partsB);
|
||||
};
|
||||
|
||||
export const resolveRemoteVersion = (update: Update): string | null => {
|
||||
const primary = ensureSemver(update.version);
|
||||
if (primary) return primary;
|
||||
|
||||
const fallbackPrimary = extractSemver(update.version);
|
||||
if (fallbackPrimary) return fallbackPrimary;
|
||||
|
||||
const raw = update.rawJson ?? {};
|
||||
const rawVersion = ensureSemver(
|
||||
typeof raw.version === "string" ? raw.version : null,
|
||||
);
|
||||
if (rawVersion) return rawVersion;
|
||||
|
||||
const tagVersion = extractSemver(
|
||||
typeof raw.tag_name === "string" ? raw.tag_name : null,
|
||||
);
|
||||
if (tagVersion) return tagVersion;
|
||||
|
||||
const nameVersion = extractSemver(
|
||||
typeof raw.name === "string" ? raw.name : null,
|
||||
);
|
||||
if (nameVersion) return nameVersion;
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
const localVersionNormalized = normalizeVersion(appVersion);
|
||||
|
||||
export const checkUpdateSafe = async (
|
||||
options?: CheckOptions,
|
||||
): Promise<Update | null> => {
|
||||
const result = await check({ ...(options ?? {}), allowDowngrades: false });
|
||||
if (!result) return null;
|
||||
|
||||
const remoteVersion = resolveRemoteVersion(result);
|
||||
const comparison = compareVersions(remoteVersion, localVersionNormalized);
|
||||
|
||||
if (comparison !== null && comparison <= 0) {
|
||||
try {
|
||||
await result.close();
|
||||
} catch (err) {
|
||||
console.warn("[updater] failed to close stale update resource", err);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
export type { CheckOptions };
|
||||
@@ -1,11 +1,12 @@
|
||||
import { defineConfig } from "vite";
|
||||
import path from "path";
|
||||
import svgr from "vite-plugin-svgr";
|
||||
import react from "@vitejs/plugin-react";
|
||||
import path from "node:path";
|
||||
|
||||
import legacy from "@vitejs/plugin-legacy";
|
||||
import react from "@vitejs/plugin-react";
|
||||
import { defineConfig } from "vitest/config";
|
||||
import monacoEditorPlugin, {
|
||||
type IMonacoEditorOpts,
|
||||
} from "vite-plugin-monaco-editor";
|
||||
import svgr from "vite-plugin-svgr";
|
||||
const monacoEditorPluginDefault = (monacoEditorPlugin as any).default as (
|
||||
options: IMonacoEditorOpts,
|
||||
) => any;
|
||||
@@ -159,6 +160,10 @@ export default defineConfig({
|
||||
"@root": path.resolve("."),
|
||||
},
|
||||
},
|
||||
test: {
|
||||
environment: "node",
|
||||
include: ["**/*.{test,spec}.{ts,tsx}"],
|
||||
},
|
||||
|
||||
define: {
|
||||
OS_PLATFORM: `"${process.platform}"`,
|
||||
|
||||
Reference in New Issue
Block a user