build(release): 加固 v0.1.0 桌面发布链路 (#3)
Client Quality Gates / Shared client and Web (push) Has been cancelled
Client Quality Gates / macOS Desktop (push) Has been cancelled

This commit is contained in:
chengchengzhou7
2026-07-17 09:36:16 +08:00
committed by GitHub
parent 1837ceff58
commit 4863ade45b
16 changed files with 895 additions and 323 deletions
+316 -187
View File
@@ -1001,9 +1001,9 @@
"license": "MIT"
},
"node_modules/@rollup/rollup-android-arm-eabi": {
"version": "4.53.5",
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.53.5.tgz",
"integrity": "sha512-iDGS/h7D8t7tvZ1t6+WPK04KD0MwzLZrG0se1hzBjSi5fyxlsiggoJHwh18PCFNn7tG43OWb6pdZ6Y+rMlmyNQ==",
"version": "4.62.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.62.2.tgz",
"integrity": "sha512-6o7ZLZK+BeenkZCFNDXqpbjw9bD6nuWonvS/lwQJp7NoVVxm6p3qE7qQ5jGuBjiFsgvqjD8mZAU5oWxTmbOeOg==",
"cpu": [
"arm"
],
@@ -1015,9 +1015,9 @@
]
},
"node_modules/@rollup/rollup-android-arm64": {
"version": "4.53.5",
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.53.5.tgz",
"integrity": "sha512-wrSAViWvZHBMMlWk6EJhvg8/rjxzyEhEdgfMMjREHEq11EtJ6IP6yfcCH57YAEca2Oe3FNCE9DSTgU70EIGmVw==",
"version": "4.62.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.62.2.tgz",
"integrity": "sha512-BaH7BllCACHoH1LguOU56UItGfUWjujlO65kS9LAodViaN4bwIKd7oeW/ZHJ/4ljr/7MIiENnNy3HJ0zXv8Zkw==",
"cpu": [
"arm64"
],
@@ -1028,10 +1028,24 @@
"android"
]
},
"node_modules/@rollup/rollup-darwin-arm64": {
"version": "4.62.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.62.2.tgz",
"integrity": "sha512-v39RCCvj4He82I9sFmk+M1VZ0PLM9sfsLVikjfx2hYBNALhrrOR2D3JjQA6AhlaSOgcR+RzrKY7e1+bT6SUO/A==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"darwin"
]
},
"node_modules/@rollup/rollup-darwin-x64": {
"version": "4.53.5",
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.53.5.tgz",
"integrity": "sha512-YTbnsAaHo6VrAczISxgpTva8EkfQus0VPEVJCEaboHtZRIb6h6j0BNxRBOwnDciFTZLDPW5r+ZBmhL/+YpTZgA==",
"version": "4.62.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.62.2.tgz",
"integrity": "sha512-yl0y2vq3S3lHeuXhEdss6TWfKW8vkujImO12tn4ZkG/4oghr09LvdYm2RElVjokTQiUvDUGXLGsYeLqUMCKpGA==",
"cpu": [
"x64"
],
@@ -1043,9 +1057,9 @@
]
},
"node_modules/@rollup/rollup-freebsd-arm64": {
"version": "4.53.5",
"resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.53.5.tgz",
"integrity": "sha512-1T8eY2J8rKJWzaznV7zedfdhD1BqVs1iqILhmHDq/bqCUZsrMt+j8VCTHhP0vdfbHK3e1IQ7VYx3jlKqwlf+vw==",
"version": "4.62.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.62.2.tgz",
"integrity": "sha512-tT4pvt4qXD+vEoezupCWi+a1F0vvDiksiHc+PxRlYTOH1I6/X4id9jPxTP+Fg+545euaFT1jJVs4CEdHZAU1vw==",
"cpu": [
"arm64"
],
@@ -1057,9 +1071,9 @@
]
},
"node_modules/@rollup/rollup-freebsd-x64": {
"version": "4.53.5",
"resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.53.5.tgz",
"integrity": "sha512-sHTiuXyBJApxRn+VFMaw1U+Qsz4kcNlxQ742snICYPrY+DDL8/ZbaC4DVIB7vgZmp3jiDaKA0WpBdP0aqPJoBQ==",
"version": "4.62.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.62.2.tgz",
"integrity": "sha512-6nU5F2wCW+qvCBhTn1pdIU3bzsIoF7EUwsCDRxilWGprQR6yd508YnH9+OKFCwpfS8pjZqDUmnCAr7exax0XCg==",
"cpu": [
"x64"
],
@@ -1071,13 +1085,16 @@
]
},
"node_modules/@rollup/rollup-linux-arm-gnueabihf": {
"version": "4.53.5",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.53.5.tgz",
"integrity": "sha512-dV3T9MyAf0w8zPVLVBptVlzaXxka6xg1f16VAQmjg+4KMSTWDvhimI/Y6mp8oHwNrmnmVl9XxJ/w/mO4uIQONA==",
"version": "4.62.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.62.2.tgz",
"integrity": "sha512-n1GJHPOvpIfhi3TmrCeh6S6URt9BFCt0KQE3qvexyGCTAKpR4Lg+eWvNZEqu7epxwus/8ElT3hacYEucm49SZg==",
"cpu": [
"arm"
],
"dev": true,
"libc": [
"glibc"
],
"license": "MIT",
"optional": true,
"os": [
@@ -1085,13 +1102,16 @@
]
},
"node_modules/@rollup/rollup-linux-arm-musleabihf": {
"version": "4.53.5",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.53.5.tgz",
"integrity": "sha512-wIGYC1x/hyjP+KAu9+ewDI+fi5XSNiUi9Bvg6KGAh2TsNMA3tSEs+Sh6jJ/r4BV/bx/CyWu2ue9kDnIdRyafcQ==",
"version": "4.62.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.62.2.tgz",
"integrity": "sha512-JqgflS8wEB+UXV/vS1RpRbifGBeN4D5lz8D8oOFbFZw4vedvdOgCFAjfBmIMdW3yL10XpQQ0Ambepw6MXrhOnA==",
"cpu": [
"arm"
],
"dev": true,
"libc": [
"musl"
],
"license": "MIT",
"optional": true,
"os": [
@@ -1099,13 +1119,16 @@
]
},
"node_modules/@rollup/rollup-linux-arm64-gnu": {
"version": "4.53.5",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.53.5.tgz",
"integrity": "sha512-Y+qVA0D9d0y2FRNiG9oM3Hut/DgODZbU9I8pLLPwAsU0tUKZ49cyV1tzmB/qRbSzGvY8lpgGkJuMyuhH7Ma+Vg==",
"version": "4.62.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.62.2.tgz",
"integrity": "sha512-wnFJkogWvN4jm/hQRF2UBaeUmk20j5+DmHvoyWii2b8HJDyvz1MF2OU/6ynXt2KR63rbZLWkFpoytpdc/yBuSA==",
"cpu": [
"arm64"
],
"dev": true,
"libc": [
"glibc"
],
"license": "MIT",
"optional": true,
"os": [
@@ -1113,11 +1136,16 @@
]
},
"node_modules/@rollup/rollup-linux-arm64-musl": {
"version": "4.53.5",
"version": "4.62.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.62.2.tgz",
"integrity": "sha512-HVu2bp0zhvJ8xHEV9+UUs7S90VadmBSY3LcIMvozbPo4AuMGDWlz3ymHLHZPX4hR67TKTt8Qp5PJ5RBg/i+RMQ==",
"cpu": [
"arm64"
],
"dev": true,
"libc": [
"musl"
],
"license": "MIT",
"optional": true,
"os": [
@@ -1125,13 +1153,33 @@
]
},
"node_modules/@rollup/rollup-linux-loong64-gnu": {
"version": "4.53.5",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.53.5.tgz",
"integrity": "sha512-rIEC0hZ17A42iXtHX+EPJVL/CakHo+tT7W0pbzdAGuWOt2jxDFh7A/lRhsNHBcqL4T36+UiAgwO8pbmn3dE8wA==",
"version": "4.62.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.62.2.tgz",
"integrity": "sha512-mQqqAV8QaoSgr9I2fKDLY2BAVvmKjWoGiu/cSYQonsLvtqwEn1E4QYfnCOcp5zoEqNhsDYin1s6jx/VJmrxlZg==",
"cpu": [
"loong64"
],
"dev": true,
"libc": [
"glibc"
],
"license": "MIT",
"optional": true,
"os": [
"linux"
]
},
"node_modules/@rollup/rollup-linux-loong64-musl": {
"version": "4.62.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.62.2.tgz",
"integrity": "sha512-IxKLoxCQ2IWi6bT2akyDUBGsOImDKB+sPp4EsTmwFQ/fMwpCKm8uLSSgP/Kx/QYUgKis6SEZ5/Nlhup0DIA0PQ==",
"cpu": [
"loong64"
],
"dev": true,
"libc": [
"musl"
],
"license": "MIT",
"optional": true,
"os": [
@@ -1139,13 +1187,33 @@
]
},
"node_modules/@rollup/rollup-linux-ppc64-gnu": {
"version": "4.53.5",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.53.5.tgz",
"integrity": "sha512-T7l409NhUE552RcAOcmJHj3xyZ2h7vMWzcwQI0hvn5tqHh3oSoclf9WgTl+0QqffWFG8MEVZZP1/OBglKZx52Q==",
"version": "4.62.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.62.2.tgz",
"integrity": "sha512-Mk5ha2RQSgyFfmYYLkBpPnUk8D8FriBxesO1u9O75X0mHgXL1UQcH5Itl2lurWL2tj0RxV9b9tJgipac0hRY9A==",
"cpu": [
"ppc64"
],
"dev": true,
"libc": [
"glibc"
],
"license": "MIT",
"optional": true,
"os": [
"linux"
]
},
"node_modules/@rollup/rollup-linux-ppc64-musl": {
"version": "4.62.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.62.2.tgz",
"integrity": "sha512-CjvEnqJL/0/TQ3TXX3OPIJ/kmBellrWd4heXUmHeJlTnmwjKpSJzoehLaL6Xk0ZnMHBu9dZuFADNOrtjF4v+2w==",
"cpu": [
"ppc64"
],
"dev": true,
"libc": [
"musl"
],
"license": "MIT",
"optional": true,
"os": [
@@ -1153,13 +1221,16 @@
]
},
"node_modules/@rollup/rollup-linux-riscv64-gnu": {
"version": "4.53.5",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.53.5.tgz",
"integrity": "sha512-7OK5/GhxbnrMcxIFoYfhV/TkknarkYC1hqUw1wU2xUN3TVRLNT5FmBv4KkheSG2xZ6IEbRAhTooTV2+R5Tk0lQ==",
"version": "4.62.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.62.2.tgz",
"integrity": "sha512-1SiZbzwdkaDURsew/tSOrooKiYy7EQGT6m8ufavAi9NEyQb/6VuIxFXAL1fqa4iZe3g4NbNk4P7J32z2tw5Mgg==",
"cpu": [
"riscv64"
],
"dev": true,
"libc": [
"glibc"
],
"license": "MIT",
"optional": true,
"os": [
@@ -1167,13 +1238,16 @@
]
},
"node_modules/@rollup/rollup-linux-riscv64-musl": {
"version": "4.53.5",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.53.5.tgz",
"integrity": "sha512-GwuDBE/PsXaTa76lO5eLJTyr2k8QkPipAyOrs4V/KJufHCZBJ495VCGJol35grx9xryk4V+2zd3Ri+3v7NPh+w==",
"version": "4.62.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.62.2.tgz",
"integrity": "sha512-nQts12zJ3NQRoE6uYljOH89v7szzLDvG2JD/vsX+vGXU8w/At1GowTZ5/7qeFQ8m7L55rpR8Okugnuo5bgjy2Q==",
"cpu": [
"riscv64"
],
"dev": true,
"libc": [
"musl"
],
"license": "MIT",
"optional": true,
"os": [
@@ -1181,13 +1255,16 @@
]
},
"node_modules/@rollup/rollup-linux-s390x-gnu": {
"version": "4.53.5",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.53.5.tgz",
"integrity": "sha512-IAE1Ziyr1qNfnmiQLHBURAD+eh/zH1pIeJjeShleII7Vj8kyEm2PF77o+lf3WTHDpNJcu4IXJxNO0Zluro8bOw==",
"version": "4.62.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.62.2.tgz",
"integrity": "sha512-E9/ll019jhPIJgpzfZoIkBGhcz+kKNgVWYRY0zr9srBdPPFVpvOKW8VaJKUbeK+eZXyQF9ltME+Kk6affeaPgg==",
"cpu": [
"s390x"
],
"dev": true,
"libc": [
"glibc"
],
"license": "MIT",
"optional": true,
"os": [
@@ -1195,13 +1272,16 @@
]
},
"node_modules/@rollup/rollup-linux-x64-gnu": {
"version": "4.53.5",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.53.5.tgz",
"integrity": "sha512-Pg6E+oP7GvZ4XwgRJBuSXZjcqpIW3yCBhK4BcsANvb47qMvAbCjR6E+1a/U2WXz1JJxp9/4Dno3/iSJLcm5auw==",
"version": "4.62.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.62.2.tgz",
"integrity": "sha512-5BqxR/pshjey51iliyzTD5Xi3EN0aLmQ2lZ3lvefVV9c82BvrLo2/6OT55iifpWBufs6kdwWbuOKS841DrmK9A==",
"cpu": [
"x64"
],
"dev": true,
"libc": [
"glibc"
],
"license": "MIT",
"optional": true,
"os": [
@@ -1209,9 +1289,26 @@
]
},
"node_modules/@rollup/rollup-linux-x64-musl": {
"version": "4.53.5",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.53.5.tgz",
"integrity": "sha512-txGtluxDKTxaMDzUduGP0wdfng24y1rygUMnmlUJ88fzCCULCLn7oE5kb2+tRB+MWq1QDZT6ObT5RrR8HFRKqg==",
"version": "4.62.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.62.2.tgz",
"integrity": "sha512-uNN83XxQrRAh/w0/pmAfibcwyb6YWt4gP+dpnQKPVJshAloQ785ii8CT8ZCIxkGg9opVsvAlGhFitSm6D1Jjpg==",
"cpu": [
"x64"
],
"dev": true,
"libc": [
"musl"
],
"license": "MIT",
"optional": true,
"os": [
"linux"
]
},
"node_modules/@rollup/rollup-openbsd-x64": {
"version": "4.62.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.62.2.tgz",
"integrity": "sha512-srjEIxSH3LRnJN6THczDHWQplqEMFiAJrTab0msUryh9kwNpkICf3Ea6q6MN/2cZwRFUNx5w+h6Hpi4QuHS6Zg==",
"cpu": [
"x64"
],
@@ -1219,13 +1316,13 @@
"license": "MIT",
"optional": true,
"os": [
"linux"
"openbsd"
]
},
"node_modules/@rollup/rollup-openharmony-arm64": {
"version": "4.53.5",
"resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.53.5.tgz",
"integrity": "sha512-3DFiLPnTxiOQV993fMc+KO8zXHTcIjgaInrqlG8zDp1TlhYl6WgrOHuJkJQ6M8zHEcntSJsUp1XFZSY8C1DYbg==",
"version": "4.62.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.62.2.tgz",
"integrity": "sha512-8hOJnxgbyObnCm5AlRA3A931xX19xq80RjVTKgJOvEKWqJruP/Uf12IbAOaDjjEXYRewwHLfmF0YRIdK3OwKWA==",
"cpu": [
"arm64"
],
@@ -1237,9 +1334,9 @@
]
},
"node_modules/@rollup/rollup-win32-arm64-msvc": {
"version": "4.53.5",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.53.5.tgz",
"integrity": "sha512-nggc/wPpNTgjGg75hu+Q/3i32R00Lq1B6N1DO7MCU340MRKL3WZJMjA9U4K4gzy3dkZPXm9E1Nc81FItBVGRlA==",
"version": "4.62.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.62.2.tgz",
"integrity": "sha512-mmF4AY1i0hG/bLWUctUq59gtmgaSIRa3cu/A3JFRp/sCNEme2bgDEiDS22P9FbnJB8NJNF4jPJiSP5RHQpUTDg==",
"cpu": [
"arm64"
],
@@ -1251,9 +1348,9 @@
]
},
"node_modules/@rollup/rollup-win32-ia32-msvc": {
"version": "4.53.5",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.53.5.tgz",
"integrity": "sha512-U/54pTbdQpPLBdEzCT6NBCFAfSZMvmjr0twhnD9f4EIvlm9wy3jjQ38yQj1AGznrNO65EWQMgm/QUjuIVrYF9w==",
"version": "4.62.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.62.2.tgz",
"integrity": "sha512-DZgkknc6jhHrk46V25vbAM0zZkyP0nSDkJB8/dRkLTxv470dOmWDqGoEJl/9A0dFfS7yE3REOwNDxpHwSLSt0Q==",
"cpu": [
"ia32"
],
@@ -1265,9 +1362,9 @@
]
},
"node_modules/@rollup/rollup-win32-x64-gnu": {
"version": "4.53.5",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.53.5.tgz",
"integrity": "sha512-2NqKgZSuLH9SXBBV2dWNRCZmocgSOx8OJSdpRaEcRlIfX8YrKxUT6z0F1NpvDVhOsl190UFTRh2F2WDWWCYp3A==",
"version": "4.62.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.62.2.tgz",
"integrity": "sha512-T6xr6ucWSFto+VGajA8YH26LdpHRuP4YLHEKAtCWvJDOlnmWcDZVCI2Jmjr+IFHDlt2zRaTAKE4tfjTaWLgJBg==",
"cpu": [
"x64"
],
@@ -1279,9 +1376,9 @@
]
},
"node_modules/@rollup/rollup-win32-x64-msvc": {
"version": "4.53.5",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.53.5.tgz",
"integrity": "sha512-JRpZUhCfhZ4keB5v0fe02gQJy05GqboPOaxvjugW04RLSYYoB/9t2lx2u/tMs/Na/1NXfY8QYjgRljRpN+MjTQ==",
"version": "4.62.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.62.2.tgz",
"integrity": "sha512-BfzEnDJOt9T8M989/lA37EcJgat01wLRnoi5dQf3QzOH7jzpqTAzdDbVfRljVr5r+jzKqpbHeyOfAaXxAd0PAA==",
"cpu": [
"x64"
],
@@ -1589,7 +1686,9 @@
"license": "MIT"
},
"node_modules/@types/estree": {
"version": "1.0.8",
"version": "1.0.9",
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.9.tgz",
"integrity": "sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==",
"dev": true,
"license": "MIT"
},
@@ -1634,15 +1733,15 @@
}
},
"node_modules/@vitest/expect": {
"version": "3.2.4",
"resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-3.2.4.tgz",
"integrity": "sha512-Io0yyORnB6sikFlt8QW5K7slY4OjqNX9jmJQ02QDda8lyM6B5oNgVWoSoKPac8/kgnCUzuHQKrSLtu/uOqqrig==",
"version": "3.2.7",
"resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-3.2.7.tgz",
"integrity": "sha512-E8eBXaKibuvH2pSZErOjdVb5vF4PbKYcrnluBTYxEk1l/VhhwZg1kZQsdtjq+CsF5CFydf2Rdkz7jDHKSisi3w==",
"dev": true,
"license": "MIT",
"dependencies": {
"@types/chai": "^5.2.2",
"@vitest/spy": "3.2.4",
"@vitest/utils": "3.2.4",
"@vitest/spy": "3.2.7",
"@vitest/utils": "3.2.7",
"chai": "^5.2.0",
"tinyrainbow": "^2.0.0"
},
@@ -1651,13 +1750,13 @@
}
},
"node_modules/@vitest/mocker": {
"version": "3.2.4",
"resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-3.2.4.tgz",
"integrity": "sha512-46ryTE9RZO/rfDd7pEqFl7etuyzekzEhUbTW3BvmeO/BcCMEgq59BKhek3dXDWgAj4oMK6OZi+vRr1wPW6qjEQ==",
"version": "3.2.7",
"resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-3.2.7.tgz",
"integrity": "sha512-Trr0hYO9CM3Wj6ksWHRhK9IZpIY6wTMO5u/MqXurMxT57sWBaOPEtP3Oq60ihZuh5JsiagKfz95OcxdEP6dBrA==",
"dev": true,
"license": "MIT",
"dependencies": {
"@vitest/spy": "3.2.4",
"@vitest/spy": "3.2.7",
"estree-walker": "^3.0.3",
"magic-string": "^0.30.17"
},
@@ -1688,9 +1787,9 @@
}
},
"node_modules/@vitest/pretty-format": {
"version": "3.2.4",
"resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-3.2.4.tgz",
"integrity": "sha512-IVNZik8IVRJRTr9fxlitMKeJeXFFFN0JaB9PHPGQ8NKQbGpfjlTx9zO4RefN8gp7eqjNy8nyK3NZmBzOPeIxtA==",
"version": "3.2.7",
"resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-3.2.7.tgz",
"integrity": "sha512-KUHlwqVu0sRlhCdyPdQ/wBoTfRahjUky1MubOmYw9fWfIZy1gNoHpuaaQBPAaMaVYdQYHJLurzj8ECCj5OwTqA==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -1701,13 +1800,13 @@
}
},
"node_modules/@vitest/runner": {
"version": "3.2.4",
"resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-3.2.4.tgz",
"integrity": "sha512-oukfKT9Mk41LreEW09vt45f8wx7DordoWUZMYdY/cyAk7w5TWkTRCNZYF7sX7n2wB7jyGAl74OxgwhPgKaqDMQ==",
"version": "3.2.7",
"resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-3.2.7.tgz",
"integrity": "sha512-sB9y4ovltoQP+WaUPwmSxO9WIg9Ig694Di5PalVPsYHklAdE027mehpWF2SQSVq+k6sFgaivbTjTJwZLSHbedA==",
"dev": true,
"license": "MIT",
"dependencies": {
"@vitest/utils": "3.2.4",
"@vitest/utils": "3.2.7",
"pathe": "^2.0.3",
"strip-literal": "^3.0.0"
},
@@ -1716,13 +1815,13 @@
}
},
"node_modules/@vitest/snapshot": {
"version": "3.2.4",
"resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-3.2.4.tgz",
"integrity": "sha512-dEYtS7qQP2CjU27QBC5oUOxLE/v5eLkGqPE0ZKEIDGMs4vKWe7IjgLOeauHsR0D5YuuycGRO5oSRXnwnmA78fQ==",
"version": "3.2.7",
"resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-3.2.7.tgz",
"integrity": "sha512-7C+MwShwtBSI5Buwoyg3s/iY1eHL9PKAf+O1wVh/TdnjXUtkoL/9YQtre90i4MtNXM6edP1wJ2zOBpfCyhIS7g==",
"dev": true,
"license": "MIT",
"dependencies": {
"@vitest/pretty-format": "3.2.4",
"@vitest/pretty-format": "3.2.7",
"magic-string": "^0.30.17",
"pathe": "^2.0.3"
},
@@ -1731,9 +1830,9 @@
}
},
"node_modules/@vitest/spy": {
"version": "3.2.4",
"resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-3.2.4.tgz",
"integrity": "sha512-vAfasCOe6AIK70iP5UD11Ac4siNUNJ9i/9PZ3NKx07sG6sUxeag1LWdNrMWeKKYBLlzuK+Gn65Yd5nyL6ds+nw==",
"version": "3.2.7",
"resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-3.2.7.tgz",
"integrity": "sha512-Q2eQGI6d2L/hBtZ0qNuKcAGid68XK6cv1xsoaIma6PaJhHPoqcEJhYpXZ/5myCMqkNgtP6UKuBhbc0nHKnrkuQ==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -1744,13 +1843,13 @@
}
},
"node_modules/@vitest/utils": {
"version": "3.2.4",
"resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-3.2.4.tgz",
"integrity": "sha512-fB2V0JFrQSMsCo9HiSq3Ezpdv4iYaXRG1Sx8edX3MwxfyNn83mKiGzOcH+Fkxt4MHxr3y42fQi1oeAInqgX2QA==",
"version": "3.2.7",
"resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-3.2.7.tgz",
"integrity": "sha512-x6BDOd7dyo3PFLY3I9/HJ25X/6OurhGXk2/B9gOZNPF7XDVjeBK4k01lQE5uvDpbuheErh91qYuE1E2OEjK3Rw==",
"dev": true,
"license": "MIT",
"dependencies": {
"@vitest/pretty-format": "3.2.4",
"@vitest/pretty-format": "3.2.7",
"loupe": "^3.1.4",
"tinyrainbow": "^2.0.0"
},
@@ -2002,12 +2101,40 @@
"license": "MIT"
},
"node_modules/axios": {
"version": "1.13.2",
"version": "1.18.1",
"resolved": "https://registry.npmjs.org/axios/-/axios-1.18.1.tgz",
"integrity": "sha512-3nTvFlvpn9Zu/RkHUqtc7/+al4UpRW5az71ap5zccp6e8RAYEzhMTecX8Dz1wWDYrPpUoB1HAQEGEAEvUr7S9g==",
"license": "MIT",
"dependencies": {
"follow-redirects": "^1.15.6",
"form-data": "^4.0.4",
"proxy-from-env": "^1.1.0"
"follow-redirects": "^1.16.0",
"form-data": "^4.0.5",
"https-proxy-agent": "^5.0.1",
"proxy-from-env": "^2.1.0"
}
},
"node_modules/axios/node_modules/agent-base": {
"version": "6.0.2",
"resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz",
"integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==",
"license": "MIT",
"dependencies": {
"debug": "4"
},
"engines": {
"node": ">= 6.0.0"
}
},
"node_modules/axios/node_modules/https-proxy-agent": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz",
"integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==",
"license": "MIT",
"dependencies": {
"agent-base": "6",
"debug": "4"
},
"engines": {
"node": ">= 6"
}
},
"node_modules/balanced-match": {
@@ -2181,7 +2308,6 @@
"version": "4.4.3",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz",
"integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==",
"dev": true,
"license": "MIT",
"dependencies": {
"ms": "^2.1.3"
@@ -2239,21 +2365,15 @@
"license": "MIT"
},
"node_modules/echarts": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/echarts/-/echarts-6.0.0.tgz",
"integrity": "sha512-Tte/grDQRiETQP4xz3iZWSvoHrkCQtwqd6hs+mifXcjrCuo2iKWbajFObuLJVBlDIJlOzgQPd1hsaKt/3+OMkQ==",
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/echarts/-/echarts-6.1.0.tgz",
"integrity": "sha512-q0yaFPggC9FUdsWH4blavRWFmxdrIodbkoKNAjJudAI6CA9gNPxHtV2RcZNEepZVlk4yvBYkOkbk6HIVpIyHZA==",
"license": "Apache-2.0",
"dependencies": {
"tslib": "2.3.0",
"zrender": "6.0.0"
"zrender": "6.1.0"
}
},
"node_modules/echarts/node_modules/tslib": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.0.tgz",
"integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==",
"license": "0BSD"
},
"node_modules/editorconfig": {
"version": "1.0.7",
"resolved": "https://registry.npmjs.org/editorconfig/-/editorconfig-1.0.7.tgz",
@@ -2432,7 +2552,9 @@
}
},
"node_modules/follow-redirects": {
"version": "1.15.11",
"version": "1.16.0",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.16.0.tgz",
"integrity": "sha512-y5rN/uOsadFT/JfYwhxRS5R7Qce+g3zG97+JrtFZlC9klX/W5hD7iiLzScI4nZqUS7DNUdhPgw4xI8W2LuXlUw==",
"funding": [
{
"type": "individual",
@@ -2467,14 +2589,16 @@
}
},
"node_modules/form-data": {
"version": "4.0.5",
"version": "4.0.6",
"resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.6.tgz",
"integrity": "sha512-vKatAh4SlVfgbv+YtmhiRjhEMJsYpsG1Y2rMQtR+SVSbytsSD1YGzDIcrAJmdFec88u/+VoGmxnl+80gL1tRCQ==",
"license": "MIT",
"dependencies": {
"asynckit": "^0.4.0",
"combined-stream": "^1.0.8",
"es-set-tostringtag": "^2.1.0",
"hasown": "^2.0.2",
"mime-types": "^2.1.12"
"hasown": "^2.0.4",
"mime-types": "^2.1.35"
},
"engines": {
"node": ">= 6"
@@ -2591,7 +2715,9 @@
}
},
"node_modules/hasown": {
"version": "2.0.2",
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.4.tgz",
"integrity": "sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A==",
"license": "MIT",
"dependencies": {
"function-bind": "^1.1.2"
@@ -2781,11 +2907,15 @@
}
},
"node_modules/lodash": {
"version": "4.17.21",
"version": "4.18.1",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.18.1.tgz",
"integrity": "sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q==",
"license": "MIT"
},
"node_modules/lodash-es": {
"version": "4.17.21",
"version": "4.18.1",
"resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.18.1.tgz",
"integrity": "sha512-J8xewKD/Gk22OZbhpOVSwcs60zhd95ESDwezOFuA3/099925PdHJ7OFHNTGtajL3AlZkykD32HykiMo+BIBI8A==",
"license": "MIT"
},
"node_modules/lodash-unified": {
@@ -2876,7 +3006,6 @@
"version": "2.1.3",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
"dev": true,
"license": "MIT"
},
"node_modules/muggle-string": {
@@ -2887,7 +3016,9 @@
"license": "MIT"
},
"node_modules/nanoid": {
"version": "3.3.11",
"version": "3.3.16",
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.16.tgz",
"integrity": "sha512-bzlKTyNJ7+LdGIIwy8ijFpIqEQIvafahV7eYykJ8Cvh42EdJeODoJ6gUJXpQJvej1BddH8OqTXZNE/KfbWAu8Q==",
"funding": [
{
"type": "github",
@@ -3030,9 +3161,9 @@
"license": "ISC"
},
"node_modules/picomatch": {
"version": "4.0.3",
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz",
"integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
"version": "4.0.5",
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.5.tgz",
"integrity": "sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A==",
"dev": true,
"license": "MIT",
"engines": {
@@ -3063,7 +3194,9 @@
}
},
"node_modules/postcss": {
"version": "8.5.6",
"version": "8.5.19",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.19.tgz",
"integrity": "sha512-Mz8SaolMd8nB+G13WkORcxQKHZ/NE4xXevtkJHVuG+guo9/wYKlIMTKAqGdEmYOXR2ijPjTYNHssizdaVSUNdQ==",
"funding": [
{
"type": "opencollective",
@@ -3080,7 +3213,7 @@
],
"license": "MIT",
"dependencies": {
"nanoid": "^3.3.11",
"nanoid": "^3.3.12",
"picocolors": "^1.1.1",
"source-map-js": "^1.2.1"
},
@@ -3096,8 +3229,13 @@
"license": "ISC"
},
"node_modules/proxy-from-env": {
"version": "1.1.0",
"license": "MIT"
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-2.1.0.tgz",
"integrity": "sha512-cJ+oHTW1VAEa8cJslgmUZrc+sjRKgAKl3Zyse6+PV38hZe/V6Z14TbCuXcan9F9ghlz4QrFr2c92TNF82UkYHA==",
"license": "MIT",
"engines": {
"node": ">=10"
}
},
"node_modules/punycode": {
"version": "2.3.1",
@@ -3110,11 +3248,13 @@
}
},
"node_modules/rollup": {
"version": "4.53.5",
"version": "4.62.2",
"resolved": "https://registry.npmjs.org/rollup/-/rollup-4.62.2.tgz",
"integrity": "sha512-RFnrW4lhXA3s3eqHDZvN654g8OTjzRfqpIRJYczCGB6HzphckVAi/Qh4tbPUbRuDi7s1Llv8g/NspLkttY3gTA==",
"dev": true,
"license": "MIT",
"dependencies": {
"@types/estree": "1.0.8"
"@types/estree": "1.0.9"
},
"bin": {
"rollup": "dist/bin/rollup"
@@ -3124,45 +3264,34 @@
"npm": ">=8.0.0"
},
"optionalDependencies": {
"@rollup/rollup-android-arm-eabi": "4.53.5",
"@rollup/rollup-android-arm64": "4.53.5",
"@rollup/rollup-darwin-arm64": "4.53.5",
"@rollup/rollup-darwin-x64": "4.53.5",
"@rollup/rollup-freebsd-arm64": "4.53.5",
"@rollup/rollup-freebsd-x64": "4.53.5",
"@rollup/rollup-linux-arm-gnueabihf": "4.53.5",
"@rollup/rollup-linux-arm-musleabihf": "4.53.5",
"@rollup/rollup-linux-arm64-gnu": "4.53.5",
"@rollup/rollup-linux-arm64-musl": "4.53.5",
"@rollup/rollup-linux-loong64-gnu": "4.53.5",
"@rollup/rollup-linux-ppc64-gnu": "4.53.5",
"@rollup/rollup-linux-riscv64-gnu": "4.53.5",
"@rollup/rollup-linux-riscv64-musl": "4.53.5",
"@rollup/rollup-linux-s390x-gnu": "4.53.5",
"@rollup/rollup-linux-x64-gnu": "4.53.5",
"@rollup/rollup-linux-x64-musl": "4.53.5",
"@rollup/rollup-openharmony-arm64": "4.53.5",
"@rollup/rollup-win32-arm64-msvc": "4.53.5",
"@rollup/rollup-win32-ia32-msvc": "4.53.5",
"@rollup/rollup-win32-x64-gnu": "4.53.5",
"@rollup/rollup-win32-x64-msvc": "4.53.5",
"@rollup/rollup-android-arm-eabi": "4.62.2",
"@rollup/rollup-android-arm64": "4.62.2",
"@rollup/rollup-darwin-arm64": "4.62.2",
"@rollup/rollup-darwin-x64": "4.62.2",
"@rollup/rollup-freebsd-arm64": "4.62.2",
"@rollup/rollup-freebsd-x64": "4.62.2",
"@rollup/rollup-linux-arm-gnueabihf": "4.62.2",
"@rollup/rollup-linux-arm-musleabihf": "4.62.2",
"@rollup/rollup-linux-arm64-gnu": "4.62.2",
"@rollup/rollup-linux-arm64-musl": "4.62.2",
"@rollup/rollup-linux-loong64-gnu": "4.62.2",
"@rollup/rollup-linux-loong64-musl": "4.62.2",
"@rollup/rollup-linux-ppc64-gnu": "4.62.2",
"@rollup/rollup-linux-ppc64-musl": "4.62.2",
"@rollup/rollup-linux-riscv64-gnu": "4.62.2",
"@rollup/rollup-linux-riscv64-musl": "4.62.2",
"@rollup/rollup-linux-s390x-gnu": "4.62.2",
"@rollup/rollup-linux-x64-gnu": "4.62.2",
"@rollup/rollup-linux-x64-musl": "4.62.2",
"@rollup/rollup-openbsd-x64": "4.62.2",
"@rollup/rollup-openharmony-arm64": "4.62.2",
"@rollup/rollup-win32-arm64-msvc": "4.62.2",
"@rollup/rollup-win32-ia32-msvc": "4.62.2",
"@rollup/rollup-win32-x64-gnu": "4.62.2",
"@rollup/rollup-win32-x64-msvc": "4.62.2",
"fsevents": "~2.3.2"
}
},
"node_modules/rollup/node_modules/@rollup/rollup-darwin-arm64": {
"version": "4.53.5",
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.53.5.tgz",
"integrity": "sha512-S87zZPBmRO6u1YXQLwpveZm4JfPpAa6oHBX7/ghSiGH3rz/KDgAu1rKdGutV+WUI6tKDMbaBJomhnT30Y2t4VQ==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"darwin"
]
},
"node_modules/rrweb-cssom": {
"version": "0.8.0",
"resolved": "https://registry.npmjs.org/rrweb-cssom/-/rrweb-cssom-0.8.0.tgz",
@@ -3498,6 +3627,12 @@
"node": ">=18"
}
},
"node_modules/tslib": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.0.tgz",
"integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==",
"license": "0BSD"
},
"node_modules/typescript": {
"version": "5.9.3",
"devOptional": true,
@@ -3516,13 +3651,13 @@
"license": "MIT"
},
"node_modules/vite": {
"version": "7.3.1",
"resolved": "https://registry.npmjs.org/vite/-/vite-7.3.1.tgz",
"integrity": "sha512-w+N7Hifpc3gRjZ63vYBXA56dvvRlNWRczTdmCBBa+CotUzAPf5b7YMdMR/8CQoeYE5LX3W4wj6RYTgonm1b9DA==",
"version": "7.3.6",
"resolved": "https://registry.npmjs.org/vite/-/vite-7.3.6.tgz",
"integrity": "sha512-4XP60spRGjSZFf1qYH+dJIkK2znL3zQfl9KkOV9MkkRR/3Dls0dxaBsQPTloEc5BLXWPL9vsOxopxyKoMmDueg==",
"dev": true,
"license": "MIT",
"dependencies": {
"esbuild": "^0.27.0",
"esbuild": "^0.27.0 || ^0.28.0",
"fdir": "^6.5.0",
"picomatch": "^4.0.3",
"postcss": "^8.5.6",
@@ -3614,20 +3749,20 @@
}
},
"node_modules/vitest": {
"version": "3.2.4",
"resolved": "https://registry.npmjs.org/vitest/-/vitest-3.2.4.tgz",
"integrity": "sha512-LUCP5ev3GURDysTWiP47wRRUpLKMOfPh+yKTx3kVIEiu5KOMeqzpnYNsKyOoVrULivR8tLcks4+lga33Whn90A==",
"version": "3.2.7",
"resolved": "https://registry.npmjs.org/vitest/-/vitest-3.2.7.tgz",
"integrity": "sha512-KrxIJ62Fd89gfysR4WotlgZABiz2dqFPgqGzX7s+CwsqLFomRH7777ZcrOD6+WVAh7khPQP41A+BKbpcJFrdEg==",
"dev": true,
"license": "MIT",
"dependencies": {
"@types/chai": "^5.2.2",
"@vitest/expect": "3.2.4",
"@vitest/mocker": "3.2.4",
"@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",
"@vitest/expect": "3.2.7",
"@vitest/mocker": "3.2.7",
"@vitest/pretty-format": "^3.2.7",
"@vitest/runner": "3.2.7",
"@vitest/snapshot": "3.2.7",
"@vitest/spy": "3.2.7",
"@vitest/utils": "3.2.7",
"chai": "^5.2.0",
"debug": "^4.4.1",
"expect-type": "^1.2.1",
@@ -3657,8 +3792,8 @@
"@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",
"@vitest/browser": "3.2.7",
"@vitest/ui": "3.2.7",
"happy-dom": "*",
"jsdom": "*"
},
@@ -3976,9 +4111,9 @@
}
},
"node_modules/ws": {
"version": "8.19.0",
"resolved": "https://registry.npmjs.org/ws/-/ws-8.19.0.tgz",
"integrity": "sha512-blAT2mjOEIi0ZzruJfIhb3nps74PRWTCz1IjglWEEpQl5XS/UNama6u2/rjFkDDouqr4L67ry+1aGIALViWjDg==",
"version": "8.21.1",
"resolved": "https://registry.npmjs.org/ws/-/ws-8.21.1.tgz",
"integrity": "sha512-+0NTnW77fFN/DjQi6k/Sq/Yvk4Sgajw7urW8V+asjXnRgDs9gyGkdb7EzgfhA4goXsRIZKE28fzIXBHEzhuiWw==",
"dev": true,
"license": "MIT",
"engines": {
@@ -4015,19 +4150,13 @@
"license": "MIT"
},
"node_modules/zrender": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/zrender/-/zrender-6.0.0.tgz",
"integrity": "sha512-41dFXEEXuJpNecuUQq6JlbybmnHaqqpGlbH1yxnA5V9MMP4SbohSVZsJIwz+zdjQXSSlR1Vc34EgH1zxyTDvhg==",
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/zrender/-/zrender-6.1.0.tgz",
"integrity": "sha512-oEGMDB6pOP2S6OwRR4PdVv610zrjnA3Bh+JnSG12fYJlBKjtNAoEb5fSUoCOOINlH96I2fU38/A2UpRKs67xYQ==",
"license": "BSD-3-Clause",
"dependencies": {
"tslib": "2.3.0"
}
},
"node_modules/zrender/node_modules/tslib": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.0.tgz",
"integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==",
"license": "0BSD"
}
}
}
+1
View File
@@ -15,6 +15,7 @@
"desktop:build": "tauri build",
"desktop:build:app": "tauri build --config '{\"bundle\":{\"createUpdaterArtifacts\":false}}' --bundles app",
"desktop:build:macos-release": "tauri build --target universal-apple-darwin --bundles app,dmg",
"desktop:build:windows-release": "tauri build --bundles nsis",
"desktop:update-feed:create": "node scripts/create-desktop-update-feed.mjs",
"desktop:bundle:dmg": "tauri build --bundles dmg",
"desktop:update-feed:check": "node scripts/verify-desktop-update-feed.mjs",
+81 -44
View File
@@ -1,6 +1,6 @@
import { createHash } from "node:crypto";
import { copyFile, mkdir, readFile, stat, writeFile } from "node:fs/promises";
import { basename, resolve } from "node:path";
import { createHash } from "node:crypto";
import { fileURLToPath } from "node:url";
const frontendDir = fileURLToPath(new URL("../", import.meta.url));
@@ -25,7 +25,7 @@ const assert = (condition, message) => {
if (!condition) fail(message);
};
const artifactPath = value("--artifact") || process.env.DESKTOP_UPDATE_ARTIFACT;
const macosArtifactPath = value("--artifact") || process.env.DESKTOP_UPDATE_ARTIFACT;
const outputDir = resolve(
frontendDir,
value("--output-dir") || process.env.DESKTOP_UPDATE_OUTPUT_DIR || "src-tauri/target/release/desktop-update-feed",
@@ -34,18 +34,40 @@ const baseUrlRaw = value("--base-url") || process.env.DESKTOP_UPDATE_BASE_URL;
const pubDate = value("--date") || process.env.DESKTOP_UPDATE_PUB_DATE || new Date().toISOString();
const notes = value("--notes") || process.env.DESKTOP_UPDATE_NOTES;
const includes = values("--include").map((path) => resolve(frontendDir, path));
const platformArtifactSpecs = values("--platform-artifact");
const platformPattern = /^(?:darwin|windows|linux)-(?:x86_64|aarch64|i686|armv7)$/;
assert(Boolean(artifactPath), "--artifact or DESKTOP_UPDATE_ARTIFACT is required.");
assert(Boolean(macosArtifactPath), "--artifact or DESKTOP_UPDATE_ARTIFACT is required for the Universal macOS updater artifact.");
assert(Boolean(baseUrlRaw), "--base-url or DESKTOP_UPDATE_BASE_URL is required.");
const resolvedArtifactPath = artifactPath ? resolve(frontendDir, artifactPath) : undefined;
const artifactName = resolvedArtifactPath ? basename(resolvedArtifactPath) : undefined;
const signaturePath = resolvedArtifactPath ? `${resolvedArtifactPath}.sig` : undefined;
const uploadFiles = [];
const platformArtifacts = new Map();
if (macosArtifactPath) {
const resolvedMacosArtifact = resolve(frontendDir, macosArtifactPath);
platformArtifacts.set("darwin-aarch64", resolvedMacosArtifact);
platformArtifacts.set("darwin-x86_64", resolvedMacosArtifact);
}
for (const spec of platformArtifactSpecs) {
const separator = spec.indexOf("=");
if (separator <= 0 || separator === spec.length - 1) {
fail(`--platform-artifact must use <os>-<arch>=<path>: ${spec}`);
continue;
}
const platform = spec.slice(0, separator);
const path = spec.slice(separator + 1);
assert(platformPattern.test(platform), `Unsupported updater platform key: ${platform}`);
assert(!platformArtifacts.has(platform), `Updater platform is configured more than once: ${platform}`);
if (platformPattern.test(platform) && !platformArtifacts.has(platform)) {
platformArtifacts.set(platform, resolve(frontendDir, path));
}
}
const readRequiredFile = async (path, description) => {
try {
return await readFile(path);
const data = await readFile(path);
assert(data.length > 0, `${description} must not be empty: ${path}`);
return data;
} catch (error) {
fail(`${description} cannot be read: ${path} (${error.message})`);
return undefined;
@@ -72,20 +94,16 @@ const normalizedBaseUrl = () => {
}
};
const copyIntoOutput = async (sourcePath) => {
const destination = resolve(outputDir, basename(sourcePath));
if (sourcePath !== destination) {
await copyFile(sourcePath, destination);
}
return destination;
};
if (resolvedArtifactPath && signaturePath) {
await readRequiredFile(resolvedArtifactPath, "Updater artifact");
const artifactSignatures = new Map();
const uniqueArtifactPaths = [...new Set(platformArtifacts.values())];
for (const artifactPath of uniqueArtifactPaths) {
const signaturePath = `${artifactPath}.sig`;
await readRequiredFile(artifactPath, "Updater artifact");
const signature = await readRequiredFile(signaturePath, "Updater artifact signature");
if (signature) {
const signatureText = signature.toString("utf8").trim();
assert(signatureText.length > 80, "Updater artifact signature is unexpectedly short.");
assert(signatureText.length > 80, `Updater artifact signature is unexpectedly short: ${signaturePath}`);
artifactSignatures.set(artifactPath, signatureText);
}
}
@@ -98,56 +116,75 @@ for (const includePath of includes) {
}
}
for (const [platform, artifactPath] of platformArtifacts) {
if (platform.startsWith("darwin-")) {
assert(artifactPath.endsWith(".app.tar.gz"), `${platform} must use a macOS .app.tar.gz updater artifact.`);
}
if (platform === "windows-x86_64") {
assert(artifactPath.endsWith(".nsis.zip"), "windows-x86_64 must use an NSIS .nsis.zip updater artifact.");
}
}
const uploadSources = [
...uniqueArtifactPaths.flatMap((path) => [path, `${path}.sig`]),
...includes,
];
const sourceByName = new Map();
for (const sourcePath of uploadSources) {
const name = basename(sourcePath);
const existing = sourceByName.get(name);
assert(!existing || existing === sourcePath, `Release files must have unique basenames: ${name}`);
sourceByName.set(name, sourcePath);
}
const baseUrl = normalizedBaseUrl();
if (failures.length === 0 && resolvedArtifactPath && signaturePath && artifactName && baseUrl) {
if (failures.length === 0 && baseUrl) {
await mkdir(outputDir, { recursive: true });
const artifactUrl = new URL(artifactName, baseUrl).toString();
assert(!artifactUrl.endsWith("/latest.json"), "Updater artifact URL must not point at latest.json.");
assert(!/[?&]token=/i.test(new URL(artifactUrl).search), "Updater artifact URL must not include token query parameters.");
const platforms = {};
for (const [platform, artifactPath] of platformArtifacts) {
const artifactUrl = new URL(basename(artifactPath), baseUrl).toString();
assert(!artifactUrl.endsWith("/latest.json"), "Updater artifact URL must not point at latest.json.");
assert(!/[?&]token=/i.test(new URL(artifactUrl).search), "Updater artifact URL must not include token query parameters.");
platforms[platform] = {
signature: artifactSignatures.get(artifactPath),
url: artifactUrl,
};
}
const signature = (await readFile(signaturePath, "utf8")).trim();
const latest = {
version: packageInfo.version,
pub_date: pubDate,
platforms: {
"darwin-aarch64": {
signature,
url: artifactUrl,
},
"darwin-x86_64": {
signature,
url: artifactUrl,
},
},
platforms,
};
if (notes) {
latest.notes = notes;
}
uploadFiles.push(await copyIntoOutput(resolvedArtifactPath));
uploadFiles.push(await copyIntoOutput(signaturePath));
for (const includePath of includes) {
uploadFiles.push(await copyIntoOutput(includePath));
const copiedFiles = [];
for (const sourcePath of sourceByName.values()) {
const destination = resolve(outputDir, basename(sourcePath));
if (sourcePath !== destination) {
await copyFile(sourcePath, destination);
}
copiedFiles.push(destination);
}
const latestPath = resolve(outputDir, "latest.json");
await writeFile(latestPath, `${JSON.stringify(latest, null, 2)}\n`);
uploadFiles.push(latestPath);
copiedFiles.push(latestPath);
const uniqueFiles = [...new Map(uploadFiles.map((path) => [basename(path), path])).values()];
const checksumLines = [];
for (const filePath of uniqueFiles) {
for (const filePath of copiedFiles) {
checksumLines.push(`${await sha256(filePath)} ${basename(filePath)}`);
}
const checksumPath = resolve(outputDir, "SHA256SUMS.txt");
await writeFile(checksumPath, `${checksumLines.join("\n")}\n`);
console.log(`Desktop update feed created in ${outputDir}`);
console.log(` - ${uniqueFiles.map((path) => basename(path)).join("\n - ")}`);
console.log(` - SHA256SUMS.txt`);
console.log(` - ${copiedFiles.map((path) => basename(path)).join("\n - ")}`);
console.log(" - SHA256SUMS.txt");
}
if (failures.length > 0) {
@@ -11,13 +11,11 @@ const failures = [];
const env = process.env;
const fullShaPattern = /^[0-9a-f]{40}$/i;
const expectedTag = `v${packageInfo.version}`;
const requiredSecretLikeEnv = [
"TAURI_SIGNING_PRIVATE_KEY",
"TAURI_SIGNING_PRIVATE_KEY_PASSWORD",
"APPLE_ID",
"APPLE_PASSWORD",
"APPLE_TEAM_ID",
];
const requiresMacosSigning = env.REQUIRE_DESKTOP_SIGNING === "true";
const requiresWindowsSigning = env.REQUIRE_WINDOWS_SIGNING === "true";
const requiredUpdaterEnv = ["TAURI_SIGNING_PRIVATE_KEY", "TAURI_SIGNING_PRIVATE_KEY_PASSWORD"];
const requiredMacosEnv = ["APPLE_ID", "APPLE_PASSWORD", "APPLE_TEAM_ID"];
const requiredWindowsEnv = ["WINDOWS_CERTIFICATE", "WINDOWS_CERTIFICATE_PASSWORD"];
const fail = (message) => failures.push(message);
const assert = (condition, message) => {
@@ -65,6 +63,24 @@ const validateBaseUrl = () => {
);
};
const validateWindowsTimestampUrl = () => {
const raw = env.WINDOWS_TIMESTAMP_URL;
requireEnv("WINDOWS_TIMESTAMP_URL");
if (!raw) return;
let url;
try {
url = new URL(raw);
} catch (error) {
fail(`WINDOWS_TIMESTAMP_URL is invalid: ${error.message}`);
return;
}
assert(["http:", "https:"].includes(url.protocol), "WINDOWS_TIMESTAMP_URL must use HTTP or HTTPS.");
assert(url.username === "" && url.password === "", "WINDOWS_TIMESTAMP_URL must not include credentials.");
assert(!/[?&]token=/i.test(url.search), "WINDOWS_TIMESTAMP_URL must not include token query parameters.");
};
const headSha = gitMaybe(["rev-parse", "HEAD"]);
const exactTag = gitMaybe(["describe", "--tags", "--exact-match", "HEAD"]);
const status = gitMaybe(["status", "--porcelain"]);
@@ -79,16 +95,39 @@ if (headSha && env.VITE_BUILD_COMMIT) {
assert(env.VITE_BUILD_COMMIT === headSha, "VITE_BUILD_COMMIT must match the current release commit.");
}
for (const name of requiredSecretLikeEnv) {
assert(
requiresMacosSigning || requiresWindowsSigning,
"Release readiness requires REQUIRE_DESKTOP_SIGNING=true or REQUIRE_WINDOWS_SIGNING=true.",
);
assert(
!(requiresMacosSigning && requiresWindowsSigning),
"macOS and Windows signing readiness must be checked in their native jobs.",
);
for (const name of requiredUpdaterEnv) {
requireEnv(name);
}
assert(
Boolean(env.APPLE_CERTIFICATE || env.APPLE_SIGNING_IDENTITY),
"APPLE_CERTIFICATE or APPLE_SIGNING_IDENTITY must be configured for macOS signing.",
);
if (env.APPLE_CERTIFICATE) {
requireEnv("APPLE_CERTIFICATE_PASSWORD");
if (requiresMacosSigning) {
assert(process.platform === "darwin", "Signed macOS desktop release readiness must run on macOS.");
for (const name of requiredMacosEnv) {
requireEnv(name);
}
assert(
Boolean(env.APPLE_CERTIFICATE || env.APPLE_SIGNING_IDENTITY),
"APPLE_CERTIFICATE or APPLE_SIGNING_IDENTITY must be configured for macOS signing.",
);
if (env.APPLE_CERTIFICATE) {
requireEnv("APPLE_CERTIFICATE_PASSWORD");
}
}
if (requiresWindowsSigning) {
assert(process.platform === "win32", "Signed Windows desktop release readiness must run on Windows.");
for (const name of requiredWindowsEnv) {
requireEnv(name);
}
validateWindowsTimestampUrl();
}
validateBaseUrl();
@@ -392,6 +392,7 @@ const verifyWorkflowGates = async () => {
assert(packageInfo.engines?.node === ">=22.13.0", "package.json must require Node.js >=22.13.0.");
const requiredScripts = [
"desktop:build:macos-release",
"desktop:build:windows-release",
"desktop:update-feed:create",
"desktop:update-feed:check",
"desktop:release-readiness:check",
@@ -424,15 +425,30 @@ const verifyWorkflowGates = async () => {
const releaseWorkflow = await readFile(resolve(rootDir, ".github/workflows/desktop-release-candidate.yml"), "utf8");
const requiredReleaseWorkflowTokens = [
"runs-on: macos-latest",
"runs-on: windows-latest",
"REQUIRE_DESKTOP_SIGNING",
"REQUIRE_WINDOWS_SIGNING",
"TAURI_SIGNING_PRIVATE_KEY",
"APPLE_ID",
"APPLE_PASSWORD",
"APPLE_TEAM_ID",
"WINDOWS_CERTIFICATE",
"WINDOWS_CERTIFICATE_PASSWORD",
"WINDOWS_TIMESTAMP_URL",
"npm audit",
"npm run desktop:build:macos-release",
"npm run desktop:build:windows-release",
"Get-AuthenticodeSignature",
"EnhancedKeyUsageList",
"TimeStamperCertificate",
".nsis.zip",
"npm run desktop:update-feed:create",
"--platform-artifact",
"npm run desktop:update-feed:check",
"--require-platform windows-x86_64",
"npm run desktop:release-readiness:check",
"actions/download-artifact",
"actions/upload-artifact",
];
@@ -12,6 +12,8 @@ const optionValue = (name) => {
const index = args.indexOf(name);
return index >= 0 ? args[index + 1] : undefined;
};
const optionValues = (name) =>
args.reduce((result, argument, index) => (argument === name && args[index + 1] ? [...result, args[index + 1]] : result), []);
const feedPath = resolve(
frontendDir,
@@ -19,6 +21,12 @@ const feedPath = resolve(
);
const artifactDir = optionValue("--artifacts-dir") || process.env.DESKTOP_UPDATE_ARTIFACTS_DIR;
const expectedBaseUrl = optionValue("--base-url") || process.env.DESKTOP_UPDATE_BASE_URL;
const requiredPlatforms = new Set([
"darwin-aarch64",
"darwin-x86_64",
...optionValues("--require-platform"),
]);
const platformPattern = /^(?:darwin|windows|linux)-(?:x86_64|aarch64|i686|armv7)$/;
const checksumManifestPath =
optionValue("--checksum-manifest") ||
process.env.DESKTOP_UPDATE_CHECKSUM_MANIFEST ||
@@ -103,15 +111,16 @@ if (feed) {
assert(normalizedFeedVersion === packageInfo.version, `latest.json version must match package version ${packageInfo.version}.`);
assert(Boolean(feed.pub_date || feed.pubDate), "latest.json must include a publication date.");
assert(Boolean(darwinArm), "latest.json must include darwin-aarch64.");
assert(Boolean(darwinIntel), "latest.json must include darwin-x86_64.");
for (const platform of requiredPlatforms) {
assert(platformPattern.test(platform), `Required updater platform key is unsupported: ${platform}.`);
assert(Boolean(platforms[platform]), `latest.json must include ${platform}.`);
}
const entries = [
["darwin-aarch64", darwinArm],
["darwin-x86_64", darwinIntel],
];
const entries = Object.entries(platforms);
assert(entries.length > 0, "latest.json must include at least one platform entry.");
for (const [platform, entry] of entries) {
assert(platformPattern.test(platform), `latest.json contains an unsupported platform key: ${platform}.`);
const rawUrl = entry?.url;
const signature = entry?.signature;
assert(typeof signature === "string" && signature.length > 80, `${platform} must include an updater signature.`);
@@ -133,6 +142,12 @@ if (feed) {
if (expectedBaseUrl) {
assert(rawUrl.startsWith(expectedBaseUrl), `${platform} artifact URL must start with ${expectedBaseUrl}.`);
}
if (platform.startsWith("darwin-")) {
assert(url.pathname.endsWith(".app.tar.gz"), `${platform} must point to a macOS .app.tar.gz updater artifact.`);
}
if (platform === "windows-x86_64") {
assert(url.pathname.endsWith(".nsis.zip"), "windows-x86_64 must point to an NSIS .nsis.zip updater artifact.");
}
if (artifactDir) {
const artifactPath = resolve(artifactDir, basename(url.pathname));
+42 -1
View File
@@ -1,8 +1,10 @@
import { execFileSync } from "node:child_process";
import { readFile } from "node:fs/promises";
import { resolve } from "node:path";
import { fileURLToPath } from "node:url";
const frontendDir = fileURLToPath(new URL("../", import.meta.url));
const rootDir = resolve(frontendDir, "..");
const packageInfo = JSON.parse(await readFile(resolve(frontendDir, "package.json"), "utf8"));
const failures = [];
@@ -16,6 +18,8 @@ const commit = env.VITE_BUILD_COMMIT || "local";
const isCi = env.CI === "true" || env.GITHUB_ACTIONS === "true";
const isTagBuild = env.GITHUB_REF_TYPE === "tag";
const isReleaseBuild = env.RELEASE_BUILD === "true" || isTagBuild || channel === "release";
const requiresMacosSigning = env.REQUIRE_DESKTOP_SIGNING === "true";
const requiresWindowsSigning = env.REQUIRE_WINDOWS_SIGNING === "true";
const fail = (message) => failures.push(message);
const assert = (condition, message) => {
@@ -26,6 +30,18 @@ const requireEnv = (name) => {
assert(Boolean(env[name]), `${name} must be configured for signed desktop release builds.`);
};
const gitHead = () => {
try {
return execFileSync("git", ["rev-parse", "HEAD"], {
cwd: rootDir,
encoding: "utf8",
stdio: ["ignore", "pipe", "ignore"],
}).trim();
} catch {
return undefined;
}
};
assert(allowedChannels.has(channel), `VITE_BUILD_CHANNEL must be one of ${[...allowedChannels].join(", ")}.`);
if (isCi || isReleaseBuild) {
@@ -40,12 +56,25 @@ if (env.GITHUB_SHA) {
);
}
if (isReleaseBuild && fullShaPattern.test(commit)) {
const headSha = gitHead();
assert(Boolean(headSha), "Release builds must be able to resolve the current Git commit.");
if (headSha) {
assert(commit === headSha, "VITE_BUILD_COMMIT must match the current Git HEAD for release builds.");
}
}
if (isTagBuild) {
assert(env.GITHUB_REF_NAME === semverTag, `Release tag must be ${semverTag}; found ${env.GITHUB_REF_NAME || "<missing>"}.`);
assert(channel === "release", "Release tag builds must set VITE_BUILD_CHANNEL=release.");
}
if (env.REQUIRE_DESKTOP_SIGNING === "true") {
assert(
!(requiresMacosSigning && requiresWindowsSigning),
"macOS and Windows signing requirements must be checked in their native jobs.",
);
if (requiresMacosSigning) {
assert(process.platform === "darwin", "Signed macOS desktop release builds must run on macOS.");
if (isCi) {
assert(isTagBuild, "Signed desktop release candidate builds in CI must run from a release tag.");
@@ -64,6 +93,18 @@ if (env.REQUIRE_DESKTOP_SIGNING === "true") {
}
}
if (requiresWindowsSigning) {
assert(process.platform === "win32", "Signed Windows desktop release builds must run on Windows.");
if (isCi) {
assert(isTagBuild, "Signed Windows desktop release candidate builds in CI must run from a release tag.");
}
requireEnv("TAURI_SIGNING_PRIVATE_KEY");
requireEnv("TAURI_SIGNING_PRIVATE_KEY_PASSWORD");
requireEnv("WINDOWS_CERTIFICATE");
requireEnv("WINDOWS_CERTIFICATE_PASSWORD");
requireEnv("WINDOWS_TIMESTAMP_URL");
}
if (failures.length > 0) {
console.error(`Release build environment check failed:\n${failures.map((item) => ` - ${item}`).join("\n")}`);
process.exitCode = 1;
+14 -1
View File
@@ -1,5 +1,18 @@
import { describe, expect, it } from "vitest";
import { getContentDispositionFilename } from "./contentDisposition";
import { getContentDispositionFilename, getHttpHeaderString } from "./contentDisposition";
describe("getHttpHeaderString", () => {
it("keeps string header values and joins string arrays", () => {
expect(getHttpHeaderString("application/pdf")).toBe("application/pdf");
expect(getHttpHeaderString(["attachment", "filename=protocol.pdf"])).toBe("attachment, filename=protocol.pdf");
});
it("rejects non-string Axios header values", () => {
expect(getHttpHeaderString(200)).toBeUndefined();
expect(getHttpHeaderString(true)).toBeUndefined();
expect(getHttpHeaderString({ value: "application/pdf" })).toBeUndefined();
});
});
describe("getContentDispositionFilename", () => {
it("prefers the UTF-8 filename even when the ASCII fallback appears first", () => {
+8
View File
@@ -1,3 +1,11 @@
export const getHttpHeaderString = (value: unknown): string | undefined => {
if (typeof value === "string") return value;
if (Array.isArray(value) && value.every((item) => typeof item === "string")) {
return value.join(", ");
}
return undefined;
};
export const getContentDispositionFilename = (header?: string | null): string | null => {
if (!header) return null;
const encoded = /filename\*\s*=\s*UTF-8''([^;]+)/i.exec(header)?.[1];
@@ -381,7 +381,7 @@ import StateLoading from "../../components/StateLoading.vue";
import { onDesktopRefreshCurrentView } from "../../composables/useDesktopRefresh";
import { openFileWithFeedback, pickFilesWithFeedback, saveFileWithFeedback } from "../../utils/fileTaskFeedback";
import { getApiErrorMessage } from "../../utils/apiErrorMessage";
import { getContentDispositionFilename } from "../../utils/contentDisposition";
import { getContentDispositionFilename, getHttpHeaderString } from "../../utils/contentDisposition";
import { prepareSaveFile } from "../../runtime";
import { detectFilePreviewKind, ONLYOFFICE_FILE_EXTENSIONS } from "../../utils/officePreview";
@@ -803,7 +803,8 @@ const previewVersion = async (version: DocumentVersion) => {
previewLoading.value = true;
try {
const response = await downloadDocumentVersion(version.id);
const contentType = response.headers?.["content-type"] || version.mime_type || "application/octet-stream";
const contentType =
getHttpHeaderString(response.headers?.["content-type"]) || version.mime_type || "application/octet-stream";
const blob = new Blob([response.data], { type: contentType });
previewObjectUrl.value = URL.createObjectURL(blob);
previewUrl.value = previewObjectUrl.value;
@@ -823,8 +824,9 @@ const downloadVersion = async (version: DocumentVersion) => {
return;
}
const response = await downloadDocumentVersion(version.id);
const contentType = response.headers?.["content-type"] || "application/octet-stream";
const filename = getContentDispositionFilename(response.headers?.["content-disposition"]) || suggestedName;
const contentType = getHttpHeaderString(response.headers?.["content-type"]) || "application/octet-stream";
const filename =
getContentDispositionFilename(getHttpHeaderString(response.headers?.["content-disposition"])) || suggestedName;
const blob = new Blob([response.data], { type: contentType });
await saveFileWithFeedback({ suggestedName: filename, mimeType: contentType, data: blob }, {}, destination);
} catch (e: any) { ElMessage.error(await getApiErrorMessage(e, TEXT.common.messages.downloadFailed)); }
@@ -840,10 +842,11 @@ const openVersion = async (version: DocumentVersion) => {
}
try {
const contentType = response.headers?.["content-type"] || "application/octet-stream";
const filename = getContentDispositionFilename(response.headers?.["content-disposition"])
|| getVersionFileName(version)
|| `document-${version.version_no || version.id}.bin`;
const contentType = getHttpHeaderString(response.headers?.["content-type"]) || "application/octet-stream";
const filename =
getContentDispositionFilename(getHttpHeaderString(response.headers?.["content-disposition"])) ||
getVersionFileName(version) ||
`document-${version.version_no || version.id}.bin`;
await openFileWithFeedback({
suggestedName: filename,
mimeType: contentType,
@@ -474,6 +474,7 @@ import { isApiPermissionAllowed } from "../../utils/apiPermissionValue";
import { displayDateTime } from "../../utils/display";
import { getProjectRole, isSystemAdmin } from "../../utils/roles";
import { useDrawerDirtyGuard } from "../../utils/drawerDirtyGuard";
import { getContentDispositionFilename, getHttpHeaderString } from "../../utils/contentDisposition";
interface MonitoringIssueRow {
id: string;
@@ -937,13 +938,6 @@ const removeIssue = async (row: MonitoringIssueRow) => {
}
};
const getFilename = (header?: string | null) => {
if (!header) return null;
const match = /filename\*=UTF-8''([^;]+)|filename="?([^\";]+)"?/i.exec(header);
if (!match) return null;
return decodeURIComponent(match[1] || match[2] || "");
};
const handleExportExcel = async () => {
const studyId = study.currentStudy?.id;
if (!studyId || !canListIssues.value) return;
@@ -975,8 +969,9 @@ const handleExportExcel = async () => {
}
const response = await exportMonitoringVisitIssues(studyId, params);
const contentType = response.headers?.["content-type"] || "application/octet-stream";
const filename = getFilename(response.headers?.["content-disposition"]) || "监查访视问题.xlsx";
const contentType = getHttpHeaderString(response.headers?.["content-type"]) || "application/octet-stream";
const filename =
getContentDispositionFilename(getHttpHeaderString(response.headers?.["content-disposition"])) || "监查访视问题.xlsx";
const blob = new Blob([response.data], { type: contentType });
await saveFileWithFeedback(
{ suggestedName: filename, mimeType: contentType, data: blob },