新增自动换源下载功能

pull/495/head
lyswhut 2021-04-22 16:01:47 +08:00
parent cd1a55652f
commit 3efd6867d8
10 changed files with 284 additions and 121 deletions

240
package-lock.json generated
View File

@ -26,20 +26,20 @@
"dev": true
},
"@babel/core": {
"version": "7.13.15",
"resolved": "https://registry.npmjs.org/@babel/core/-/core-7.13.15.tgz",
"integrity": "sha512-6GXmNYeNjS2Uz+uls5jalOemgIhnTMeaXo+yBUA72kC2uX/8VW6XyhVIo2L8/q0goKQA3EVKx0KOQpVKSeWadQ==",
"version": "7.13.16",
"resolved": "https://registry.npmjs.org/@babel/core/-/core-7.13.16.tgz",
"integrity": "sha512-sXHpixBiWWFti0AV2Zq7avpTasr6sIAu7Y396c608541qAU2ui4a193m0KSQmfPSKFZLnQ3cvlKDOm3XkuXm3Q==",
"dev": true,
"requires": {
"@babel/code-frame": "^7.12.13",
"@babel/generator": "^7.13.9",
"@babel/helper-compilation-targets": "^7.13.13",
"@babel/generator": "^7.13.16",
"@babel/helper-compilation-targets": "^7.13.16",
"@babel/helper-module-transforms": "^7.13.14",
"@babel/helpers": "^7.13.10",
"@babel/parser": "^7.13.15",
"@babel/helpers": "^7.13.16",
"@babel/parser": "^7.13.16",
"@babel/template": "^7.12.13",
"@babel/traverse": "^7.13.15",
"@babel/types": "^7.13.14",
"@babel/types": "^7.13.16",
"convert-source-map": "^1.7.0",
"debug": "^4.1.0",
"gensync": "^1.0.0-beta.2",
@ -58,16 +58,28 @@
}
},
"@babel/generator": {
"version": "7.13.9",
"resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.13.9.tgz",
"integrity": "sha512-mHOOmY0Axl/JCTkxTU6Lf5sWOg/v8nUa+Xkt4zMTftX0wqmb6Sh7J8gvcehBw7q0AhrhAR+FDacKjCZ2X8K+Sw==",
"version": "7.13.16",
"resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.13.16.tgz",
"integrity": "sha512-grBBR75UnKOcUWMp8WoDxNsWCFl//XCK6HWTrBQKTr5SV9f5g0pNOjdyzi/DTBv12S9GnYPInIXQBTky7OXEMg==",
"dev": true,
"requires": {
"@babel/types": "^7.13.0",
"@babel/types": "^7.13.16",
"jsesc": "^2.5.1",
"source-map": "^0.5.0"
}
},
"@babel/helper-compilation-targets": {
"version": "7.13.16",
"resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.13.16.tgz",
"integrity": "sha512-3gmkYIrpqsLlieFwjkGgLaSHmhnvlAYzZLlYVjlW+QwI+1zE17kGxuJGmIqDQdYp56XdmGeD+Bswx0UTyG18xA==",
"dev": true,
"requires": {
"@babel/compat-data": "^7.13.15",
"@babel/helper-validator-option": "^7.12.17",
"browserslist": "^4.14.5",
"semver": "^6.3.0"
}
},
"@babel/helper-function-name": {
"version": "7.12.13",
"resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.12.13.tgz",
@ -170,9 +182,9 @@
}
},
"@babel/parser": {
"version": "7.13.15",
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.13.15.tgz",
"integrity": "sha512-b9COtcAlVEQljy/9fbcMHpG+UIW9ReF+gpaxDHTlZd0c6/UU9ng8zdySAW9sRTzpvcdCHn6bUcbuYUgGzLAWVQ==",
"version": "7.13.16",
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.13.16.tgz",
"integrity": "sha512-6bAg36mCwuqLO0hbR+z7PHuqWiCeP7Dzg73OpQwsAB1Eb8HnGEz5xYBzCfbu+YjoaJsJs+qheDxVAuqbt3ILEw==",
"dev": true
},
"@babel/template": {
@ -187,32 +199,50 @@
}
},
"@babel/traverse": {
"version": "7.13.15",
"resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.13.15.tgz",
"integrity": "sha512-/mpZMNvj6bce59Qzl09fHEs8Bt8NnpEDQYleHUPZQ3wXUMvXi+HJPLars68oAbmp839fGoOkv2pSL2z9ajCIaQ==",
"version": "7.13.17",
"resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.13.17.tgz",
"integrity": "sha512-BMnZn0R+X6ayqm3C3To7o1j7Q020gWdqdyP50KEoVqaCO2c/Im7sYZSmVgvefp8TTMQ+9CtwuBp0Z1CZ8V3Pvg==",
"dev": true,
"requires": {
"@babel/code-frame": "^7.12.13",
"@babel/generator": "^7.13.9",
"@babel/generator": "^7.13.16",
"@babel/helper-function-name": "^7.12.13",
"@babel/helper-split-export-declaration": "^7.12.13",
"@babel/parser": "^7.13.15",
"@babel/types": "^7.13.14",
"@babel/parser": "^7.13.16",
"@babel/types": "^7.13.17",
"debug": "^4.1.0",
"globals": "^11.1.0"
}
},
"@babel/types": {
"version": "7.13.14",
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.13.14.tgz",
"integrity": "sha512-A2aa3QTkWoyqsZZFl56MLUsfmh7O0gN41IPvXAE/++8ojpbz12SszD7JEGYVdn4f9Kt4amIei07swF1h4AqmmQ==",
"version": "7.13.17",
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.13.17.tgz",
"integrity": "sha512-RawydLgxbOPDlTLJNtoIypwdmAy//uQIzlKt2+iBiJaRlVuI6QLUxVAyWGNfOzp8Yu4L4lLIacoCyTNtpb4wiA==",
"dev": true,
"requires": {
"@babel/helper-validator-identifier": "^7.12.11",
"lodash": "^4.17.19",
"to-fast-properties": "^2.0.0"
}
},
"browserslist": {
"version": "4.16.4",
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.4.tgz",
"integrity": "sha512-d7rCxYV8I9kj41RH8UKYnvDYCRENUlHRgyXy/Rhr/1BaeLGfiCptEdFE8MIrvGfWbBFNjVYx76SQWvNX1j+/cQ==",
"dev": true,
"requires": {
"caniuse-lite": "^1.0.30001208",
"colorette": "^1.2.2",
"electron-to-chromium": "^1.3.712",
"escalade": "^3.1.1",
"node-releases": "^1.1.71"
}
},
"caniuse-lite": {
"version": "1.0.30001214",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001214.tgz",
"integrity": "sha512-O2/SCpuaU3eASWVaesQirZv1MSjUNOvmugaD8zNSJqw6Vv5SGwoOpA9LJs3pNPfM745nxqPvfZY3MQKY4AKHYg==",
"dev": true
},
"chalk": {
"version": "2.4.2",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
@ -223,6 +253,24 @@
"escape-string-regexp": "^1.0.5",
"supports-color": "^5.3.0"
}
},
"electron-to-chromium": {
"version": "1.3.718",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.718.tgz",
"integrity": "sha512-CikzdUSShGXwjq1pcW740wK8j+KbazgHZiwzlHICejDaczM6OVsPcrZmBHPwzj9i2rj5twg20MBwp+cYZwldYA==",
"dev": true
},
"escalade": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz",
"integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==",
"dev": true
},
"node-releases": {
"version": "1.1.71",
"resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.71.tgz",
"integrity": "sha512-zR6HoT6LrLCRBwukmrVbHv0EpEQjksO6GmFcZQQuCAy139BEsoVKPYnf3jongYW83fAa1torLGYwxxky/p28sg==",
"dev": true
}
}
},
@ -1401,14 +1449,14 @@
}
},
"@babel/helpers": {
"version": "7.13.10",
"resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.13.10.tgz",
"integrity": "sha512-4VO883+MWPDUVRF3PhiLBUFHoX/bsLTGFpFK/HqvvfBZz2D57u9XzPVNFVBTc0PW/CWR9BXTOKt8NF4DInUHcQ==",
"version": "7.13.17",
"resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.13.17.tgz",
"integrity": "sha512-Eal4Gce4kGijo1/TGJdqp3WuhllaMLSrW6XcL0ulyUAQOuxHcCafZE8KHg9857gcTehsm/v7RcOx2+jp0Ryjsg==",
"dev": true,
"requires": {
"@babel/template": "^7.12.13",
"@babel/traverse": "^7.13.0",
"@babel/types": "^7.13.0"
"@babel/traverse": "^7.13.17",
"@babel/types": "^7.13.17"
},
"dependencies": {
"@babel/code-frame": {
@ -1421,12 +1469,12 @@
}
},
"@babel/generator": {
"version": "7.13.9",
"resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.13.9.tgz",
"integrity": "sha512-mHOOmY0Axl/JCTkxTU6Lf5sWOg/v8nUa+Xkt4zMTftX0wqmb6Sh7J8gvcehBw7q0AhrhAR+FDacKjCZ2X8K+Sw==",
"version": "7.13.16",
"resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.13.16.tgz",
"integrity": "sha512-grBBR75UnKOcUWMp8WoDxNsWCFl//XCK6HWTrBQKTr5SV9f5g0pNOjdyzi/DTBv12S9GnYPInIXQBTky7OXEMg==",
"dev": true,
"requires": {
"@babel/types": "^7.13.0",
"@babel/types": "^7.13.16",
"jsesc": "^2.5.1",
"source-map": "^0.5.0"
}
@ -1478,9 +1526,9 @@
}
},
"@babel/parser": {
"version": "7.13.15",
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.13.15.tgz",
"integrity": "sha512-b9COtcAlVEQljy/9fbcMHpG+UIW9ReF+gpaxDHTlZd0c6/UU9ng8zdySAW9sRTzpvcdCHn6bUcbuYUgGzLAWVQ==",
"version": "7.13.16",
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.13.16.tgz",
"integrity": "sha512-6bAg36mCwuqLO0hbR+z7PHuqWiCeP7Dzg73OpQwsAB1Eb8HnGEz5xYBzCfbu+YjoaJsJs+qheDxVAuqbt3ILEw==",
"dev": true
},
"@babel/template": {
@ -1495,29 +1543,28 @@
}
},
"@babel/traverse": {
"version": "7.13.15",
"resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.13.15.tgz",
"integrity": "sha512-/mpZMNvj6bce59Qzl09fHEs8Bt8NnpEDQYleHUPZQ3wXUMvXi+HJPLars68oAbmp839fGoOkv2pSL2z9ajCIaQ==",
"version": "7.13.17",
"resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.13.17.tgz",
"integrity": "sha512-BMnZn0R+X6ayqm3C3To7o1j7Q020gWdqdyP50KEoVqaCO2c/Im7sYZSmVgvefp8TTMQ+9CtwuBp0Z1CZ8V3Pvg==",
"dev": true,
"requires": {
"@babel/code-frame": "^7.12.13",
"@babel/generator": "^7.13.9",
"@babel/generator": "^7.13.16",
"@babel/helper-function-name": "^7.12.13",
"@babel/helper-split-export-declaration": "^7.12.13",
"@babel/parser": "^7.13.15",
"@babel/types": "^7.13.14",
"@babel/parser": "^7.13.16",
"@babel/types": "^7.13.17",
"debug": "^4.1.0",
"globals": "^11.1.0"
}
},
"@babel/types": {
"version": "7.13.14",
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.13.14.tgz",
"integrity": "sha512-A2aa3QTkWoyqsZZFl56MLUsfmh7O0gN41IPvXAE/++8ojpbz12SszD7JEGYVdn4f9Kt4amIei07swF1h4AqmmQ==",
"version": "7.13.17",
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.13.17.tgz",
"integrity": "sha512-RawydLgxbOPDlTLJNtoIypwdmAy//uQIzlKt2+iBiJaRlVuI6QLUxVAyWGNfOzp8Yu4L4lLIacoCyTNtpb4wiA==",
"dev": true,
"requires": {
"@babel/helper-validator-identifier": "^7.12.11",
"lodash": "^4.17.19",
"to-fast-properties": "^2.0.0"
}
},
@ -3170,9 +3217,9 @@
}
},
"@types/estree": {
"version": "0.0.46",
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.46.tgz",
"integrity": "sha512-laIjwTQaD+5DukBZaygQ79K1Z0jb1bPEMRrkXSLjtCcZm+abyp5YbrqpSLzD42FwWW6gK/aS4NYpJ804nG2brg==",
"version": "0.0.47",
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.47.tgz",
"integrity": "sha512-c5ciR06jK8u9BstrmJyO97m+klJrrhCf9u3rLu3DEAJBirxRqSCvDQoYKmxuYwQI5SZChAWu+tq9oVlGRuzPAg==",
"dev": true
},
"@types/fs-extra": {
@ -6094,9 +6141,9 @@
}
},
"core-js": {
"version": "3.10.1",
"resolved": "https://registry.npmjs.org/core-js/-/core-js-3.10.1.tgz",
"integrity": "sha512-pwCxEXnj27XG47mu7SXAwhLP3L5CrlvCB91ANUkIz40P27kUcvNfSdvyZJ9CLHiVoKSp+TTChMQMSKQEH/IQxA==",
"version": "3.10.2",
"resolved": "https://registry.npmjs.org/core-js/-/core-js-3.10.2.tgz",
"integrity": "sha512-W+2oVYeNghuBr3yTzZFQ5rfmjZtYB/Ubg87R5YOmlGrIb+Uw9f7qjUbhsj+/EkXhcV7eOD3jiM4+sgraX3FZUw==",
"dev": true
},
"core-js-compat": {
@ -6340,23 +6387,22 @@
}
},
"css-loader": {
"version": "5.2.1",
"resolved": "https://registry.npmjs.org/css-loader/-/css-loader-5.2.1.tgz",
"integrity": "sha512-YCyRzlt/jgG1xanXZDG/DHqAueOtXFHeusP9TS478oP1J++JSKOyEgGW1GHVoCj/rkS+GWOlBwqQJBr9yajQ9w==",
"version": "5.2.4",
"resolved": "https://registry.npmjs.org/css-loader/-/css-loader-5.2.4.tgz",
"integrity": "sha512-OFYGyINCKkdQsTrSYxzGSFnGS4gNjcXkKkQgWxK138jgnPt+lepxdjSZNc8sHAl5vP3DhsJUxufWIjOwI8PMMw==",
"dev": true,
"requires": {
"camelcase": "^6.2.0",
"cssesc": "^3.0.0",
"icss-utils": "^5.1.0",
"loader-utils": "^2.0.0",
"postcss": "^8.2.8",
"postcss": "^8.2.10",
"postcss-modules-extract-imports": "^3.0.0",
"postcss-modules-local-by-default": "^4.0.0",
"postcss-modules-scope": "^3.0.0",
"postcss-modules-values": "^4.0.0",
"postcss-value-parser": "^4.1.0",
"schema-utils": "^3.0.0",
"semver": "^7.3.4"
"semver": "^7.3.5"
},
"dependencies": {
"ajv": {
@ -7291,20 +7337,30 @@
}
},
"electron-devtools-installer": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/electron-devtools-installer/-/electron-devtools-installer-3.1.1.tgz",
"integrity": "sha512-g2D4J6APbpsiIcnLkFMyKZ6bOpEJ0Ltcc2m66F7oKUymyGAt628OWeU9nRZoh1cNmUs/a6Cls2UfOmsZtE496Q==",
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/electron-devtools-installer/-/electron-devtools-installer-3.2.0.tgz",
"integrity": "sha512-t3UczsYugm4OAbqvdImMCImIMVdFzJAHgbwHpkl5jmfu1izVgUcP/mnrPqJIpEeCK1uZGpt+yHgWEN+9EwoYhQ==",
"dev": true,
"requires": {
"rimraf": "^3.0.2",
"semver": "^7.2.1",
"tslib": "^2.1.0",
"unzip-crx-3": "^0.2.0"
},
"dependencies": {
"semver": {
"version": "7.3.2",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz",
"integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==",
"version": "7.3.5",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz",
"integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==",
"dev": true,
"requires": {
"lru-cache": "^6.0.0"
}
},
"tslib": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.2.0.tgz",
"integrity": "sha512-gS9GVHRU+RGn5KQM2rllAlR3dU6m7AcpJKdtH8gFvQiC4Otgk98XnmMU+nZenHt/+VhnBPWwgrJsyrdcw6i23w==",
"dev": true
}
}
@ -7495,9 +7551,9 @@
}
},
"enhanced-resolve": {
"version": "5.7.0",
"resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.7.0.tgz",
"integrity": "sha512-6njwt/NsZFUKhM6j9U8hzVyD4E4r0x7NQzhTCbcWOJ0IQjNSAoalWmb0AE51Wn+fwan5qVESWi7t2ToBxs9vrw==",
"version": "5.8.0",
"resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.8.0.tgz",
"integrity": "sha512-Sl3KRpJA8OpprrtaIswVki3cWPiPKxXuFxJXBp+zNb6s6VwNWwFRUdtmzd2ReUut8n+sCPx7QCtQ7w5wfJhSgQ==",
"dev": true,
"requires": {
"graceful-fs": "^4.2.4",
@ -10355,9 +10411,9 @@
}
},
"jszip": {
"version": "3.5.0",
"resolved": "https://registry.npmjs.org/jszip/-/jszip-3.5.0.tgz",
"integrity": "sha512-WRtu7TPCmYePR1nazfrtuF216cIVon/3GWOvHS9QR5bIwSbnxtdpma6un3jyGGNhHsKCSzn5Ypk+EkDRvTGiFA==",
"version": "3.6.0",
"resolved": "https://registry.npmjs.org/jszip/-/jszip-3.6.0.tgz",
"integrity": "sha512-jgnQoG9LKnWO3mnVNBnfhkh0QknICd1FGSrXcgrl67zioyJ4wgx25o9ZqwNtrROSflGBCGYnJfjrIyRIby1OoQ==",
"dev": true,
"requires": {
"lie": "~3.3.0",
@ -10773,9 +10829,9 @@
}
},
"markdown-it": {
"version": "12.0.5",
"resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-12.0.5.tgz",
"integrity": "sha512-9KB992Yy2TedaoKETgZPL2n3bmqqZxzUsZ4fxe2ho+/AYuQUz+iDKpfjLgKbg/lHcG6cGOj+L3gDrn9S2CxoRg==",
"version": "12.0.6",
"resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-12.0.6.tgz",
"integrity": "sha512-qv3sVLl4lMT96LLtR7xeRJX11OUFjsaD5oVat2/SNBIb21bJXwal2+SklcRbTwGwqWpWH/HRtYavOoJE+seL8w==",
"dev": true,
"requires": {
"argparse": "^2.0.1",
@ -10928,9 +10984,9 @@
"dev": true
},
"mini-css-extract-plugin": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-1.4.1.tgz",
"integrity": "sha512-COAGbpAsU0ioFzj+/RRfO5Qv177L1Z/XAx2EmCF33b8GDDqKygMffBTws2lit8iaPdrbKEY5P+zsseBUCREZWQ==",
"version": "1.5.0",
"resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-1.5.0.tgz",
"integrity": "sha512-SIbuLMv6jsk1FnLIU5OUG/+VMGUprEjM1+o2trOAx8i5KOKMrhyezb1dJ4Ugsykb8Jgq8/w5NEopy6escV9G7g==",
"dev": true,
"requires": {
"loader-utils": "^2.0.0",
@ -12757,14 +12813,12 @@
},
"dependencies": {
"postcss-selector-parser": {
"version": "6.0.4",
"resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.4.tgz",
"integrity": "sha512-gjMeXBempyInaBqpp8gODmwZ52WaYsVOsfr4L4lDQ7n3ncD6mEyySiDtgzCT+NYC0mmeOLvtsF8iaEf0YT6dBw==",
"version": "6.0.5",
"resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.5.tgz",
"integrity": "sha512-aFYPoYmXbZ1V6HZaSvat08M97A8HqO6Pjz+PiNpw/DhuRrC72XWAdp3hL6wusDCN31sSmcZyMGa2hZEuX+Xfhg==",
"dev": true,
"requires": {
"cssesc": "^3.0.0",
"indexes-of": "^1.0.1",
"uniq": "^1.0.1",
"util-deprecate": "^1.0.2"
}
}
@ -16709,20 +16763,20 @@
}
},
"webpack": {
"version": "5.33.2",
"resolved": "https://registry.npmjs.org/webpack/-/webpack-5.33.2.tgz",
"integrity": "sha512-X4b7F1sYBmJx8mlh2B7mV5szEkE0jYNJ2y3akgAP0ERi0vLCG1VvdsIxt8lFd4st6SUy0lf7W0CCQS566MBpJg==",
"version": "5.35.0",
"resolved": "https://registry.npmjs.org/webpack/-/webpack-5.35.0.tgz",
"integrity": "sha512-au3gu55yYF/h6NXFr0KZPZAYxS6Nlc595BzYPke8n0CSff5WXcoixtjh5LC/8mXunkRKxhymhXmBY0+kEbR6jg==",
"dev": true,
"requires": {
"@types/eslint-scope": "^3.7.0",
"@types/estree": "^0.0.46",
"@types/estree": "^0.0.47",
"@webassemblyjs/ast": "1.11.0",
"@webassemblyjs/wasm-edit": "1.11.0",
"@webassemblyjs/wasm-parser": "1.11.0",
"acorn": "^8.0.4",
"browserslist": "^4.14.5",
"chrome-trace-event": "^1.0.2",
"enhanced-resolve": "^5.7.0",
"enhanced-resolve": "^5.8.0",
"es-module-lexer": "^0.4.0",
"eslint-scope": "^5.1.1",
"events": "^3.2.0",
@ -16777,15 +16831,15 @@
}
},
"caniuse-lite": {
"version": "1.0.30001208",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001208.tgz",
"integrity": "sha512-OE5UE4+nBOro8Dyvv0lfx+SRtfVIOM9uhKqFmJeUbGriqhhStgp1A0OyBpgy3OUF8AhYCT+PVwPC1gMl2ZcQMA==",
"version": "1.0.30001214",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001214.tgz",
"integrity": "sha512-O2/SCpuaU3eASWVaesQirZv1MSjUNOvmugaD8zNSJqw6Vv5SGwoOpA9LJs3pNPfM745nxqPvfZY3MQKY4AKHYg==",
"dev": true
},
"electron-to-chromium": {
"version": "1.3.717",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.717.tgz",
"integrity": "sha512-OfzVPIqD1MkJ7fX+yTl2nKyOE4FReeVfMCzzxQS+Kp43hZYwHwThlGP+EGIZRXJsxCM7dqo8Y65NOX/HP12iXQ==",
"version": "1.3.718",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.718.tgz",
"integrity": "sha512-CikzdUSShGXwjq1pcW740wK8j+KbazgHZiwzlHICejDaczM6OVsPcrZmBHPwzj9i2rj5twg20MBwp+cYZwldYA==",
"dev": true
},
"escalade": {

View File

@ -155,7 +155,7 @@
},
"homepage": "https://github.com/lyswhut/lx-music-desktop#readme",
"devDependencies": {
"@babel/core": "^7.13.15",
"@babel/core": "^7.13.16",
"@babel/plugin-proposal-class-properties": "^7.13.0",
"@babel/plugin-syntax-dynamic-import": "^7.8.3",
"@babel/plugin-transform-modules-umd": "^7.13.0",
@ -170,14 +170,14 @@
"chalk": "^4.1.0",
"changelog-parser": "^2.8.0",
"copy-webpack-plugin": "^8.1.1",
"core-js": "^3.10.1",
"core-js": "^3.10.2",
"cross-env": "^7.0.3",
"css-loader": "^5.2.1",
"css-loader": "^5.2.4",
"del": "^6.0.0",
"electron": "^9.4.4",
"electron-builder": "^22.10.5",
"electron-debug": "^3.2.0",
"electron-devtools-installer": "^3.1.1",
"electron-devtools-installer": "^3.2.0",
"eslint": "^7.24.0",
"eslint-config-standard": "^14.1.1",
"eslint-formatter-friendly": "^7.0.0",
@ -193,8 +193,8 @@
"less": "^4.1.1",
"less-loader": "^8.1.1",
"less-plugin-clean-css": "^1.5.1",
"markdown-it": "^12.0.5",
"mini-css-extract-plugin": "^1.4.1",
"markdown-it": "^12.0.6",
"mini-css-extract-plugin": "^1.5.0",
"optimize-css-assets-webpack-plugin": "^5.0.4",
"postcss": "^8.2.10",
"postcss-loader": "^5.2.0",
@ -211,7 +211,7 @@
"url-loader": "^4.1.1",
"vue-loader": "^15.9.6",
"vue-template-compiler": "^2.6.12",
"webpack": "^5.33.2",
"webpack": "^5.35.0",
"webpack-cli": "^4.6.0",
"webpack-dev-server": "^3.11.2",
"webpack-hot-middleware": "^2.25.0",

View File

@ -3,6 +3,7 @@
- 新增启动参数`-dhmkh`此参数将禁用Chromium的Hardware Media Key Handling特性用于解决漫步者部分型号耳机与本程序冲突导致耳机意外关机的问题
- 新增Windows arm64位免安装版的构建
- 新增黑色皮肤“黑灯瞎火”,有关于皮肤配色的建议欢迎反馈
- 新增自动换源下载功能默认关闭当无法从歌曲的原始源下载时将尝试切换到其他源下载此功能不100%保证换源后的歌曲版本与原版一致
### 优化

View File

@ -2,7 +2,7 @@ const path = require('path')
const os = require('os')
const defaultSetting = {
version: '1.0.40',
version: '1.0.41',
player: {
togglePlayMethod: 'listLoop',
highQuality: false,
@ -45,6 +45,7 @@ const defaultSetting = {
isDownloadLrc: false,
isEmbedPic: true,
isEmbedLyric: false,
isUseOtherSource: false,
},
leaderboard: {
source: 'kw',

View File

@ -73,6 +73,7 @@
"download_name1": "Title - Artist",
"download_name2": "Artist - Title",
"download_name3": "Title only",
"download_use_other_source": "Automatically change the source to download (when the song cannot be downloaded from the original source, try to switch to another source to download. Note: this function does not 100% guarantee that the version of the song after the source is changed is the same as the original version)",
"download_select_save_path": "Select the save path",
"hot_key": "Shortcut Key Settings",

View File

@ -73,6 +73,7 @@
"download_name1": "歌名 - 歌手",
"download_name2": "歌手 - 歌名",
"download_name3": "歌名",
"download_use_other_source": "自动换源下载当无法从歌曲的原始源下载时尝试切换到其他源下载此功能不100%保证换源后的歌曲版本与原版一致)",
"download_select_save_path": "选择歌曲保存路径",
"hot_key": "快捷键设置",

View File

@ -73,6 +73,7 @@
"download_name1": "歌名 - 歌手",
"download_name2": "歌手 - 歌名",
"download_name3": "歌名",
"download_use_other_source": "自動換源下載當無法從歌曲的原始源下載時嘗試切換到其他源下載此功能不100%保證換源後的歌曲版本與原版一致)",
"download_select_save_path": "選擇歌曲保存路徑",
"hot_key": "快捷鍵設置",

View File

@ -3,7 +3,15 @@ import fs from 'fs'
import path from 'path'
import music from '../../utils/music'
import { getMusicType } from '../../utils/music/utils'
import { setMeta, saveLrc, getLyric, setLyric, getMusicUrl, setMusicUrl } from '../../utils'
import {
setMeta,
saveLrc,
getLyric as getLyricFromStorage,
setLyric,
getMusicUrl as getMusicUrlFormStorage,
setMusicUrl,
assertApiSupport,
} from '../../utils'
// state
const state = {
@ -147,8 +155,33 @@ const pauseTasks = async(store, list, runs = []) => {
await pauseTasks(store, list, runs)
}
const getUrl = async(downloadInfo, isRefresh) => {
const cachedUrl = await getMusicUrl(downloadInfo.musicInfo, downloadInfo.type)
const handleGetMusicUrl = function(musicInfo, type, retryedSource = [], originMusic) {
// console.log(musicInfo.source)
if (!originMusic) originMusic = musicInfo
let reqPromise
try {
reqPromise = music[musicInfo.source].getMusicUrl(musicInfo, type).promise
} catch (err) {
reqPromise = Promise.reject(err)
}
return reqPromise.catch(err => {
if (!retryedSource.includes(musicInfo.source) || !assertApiSupport(musicInfo.source)) retryedSource.push(musicInfo.source)
return this.dispatch('list/getOtherSource', originMusic).then(otherSource => {
console.log('find otherSource', otherSource)
if (otherSource.length) {
for (const item of otherSource) {
if (retryedSource.includes(item.source)) continue
console.log('try toggle to: ', item.source, item.name, item.singer, item.interval)
return handleGetMusicUrl.call(this, item, type, retryedSource, originMusic)
}
}
return Promise.reject(err)
})
})
}
const getMusicUrl = async function(downloadInfo, isUseOtherSource, isRefresh) {
const cachedUrl = await getMusicUrlFormStorage(downloadInfo.musicInfo, downloadInfo.type)
if (!downloadInfo.musicInfo._types[downloadInfo.type]) {
// 兼容旧版酷我源搜索列表过滤128k音质的bug
if (!(downloadInfo.musicInfo.source == 'kw' && downloadInfo.type == '128k')) throw new Error('该歌曲没有可下载的音频')
@ -157,11 +190,62 @@ const getUrl = async(downloadInfo, isRefresh) => {
}
return cachedUrl && !isRefresh
? cachedUrl
: music[downloadInfo.musicInfo.source].getMusicUrl(downloadInfo.musicInfo, downloadInfo.type).promise.then(({ url }) => {
: (
isUseOtherSource
? handleGetMusicUrl.call(this, downloadInfo.musicInfo, downloadInfo.type)
: music[downloadInfo.musicInfo.source].getMusicUrl(downloadInfo.musicInfo, downloadInfo.type).promise
).then(({ url }) => {
setMusicUrl(downloadInfo.musicInfo, downloadInfo.type, url)
return url
})
}
const getPic = function(musicInfo, retryedSource = [], originMusic) {
// console.log(musicInfo.source)
if (!originMusic) originMusic = musicInfo
let reqPromise
try {
reqPromise = music[musicInfo.source].getPic(musicInfo).promise
} catch (err) {
reqPromise = Promise.reject(err)
}
return reqPromise.catch(err => {
if (!retryedSource.includes(musicInfo.source)) retryedSource.push(musicInfo.source)
return this.dispatch('list/getOtherSource', originMusic).then(otherSource => {
console.log('find otherSource', otherSource)
if (otherSource.length) {
for (const item of otherSource) {
if (retryedSource.includes(item.source)) continue
console.log('try toggle to: ', item.source, item.name, item.singer, item.interval)
return getPic.call(this, item, retryedSource, originMusic)
}
}
return Promise.reject(err)
})
})
}
const getLyric = function(musicInfo, retryedSource = [], originMusic) {
if (!originMusic) originMusic = musicInfo
let reqPromise
try {
reqPromise = music[musicInfo.source].getLyric(musicInfo).promise
} catch (err) {
reqPromise = Promise.reject(err)
}
return reqPromise.catch(err => {
if (!retryedSource.includes(musicInfo.source)) retryedSource.push(musicInfo.source)
return this.dispatch('list/getOtherSource', originMusic).then(otherSource => {
console.log('find otherSource', otherSource)
if (otherSource.length) {
for (const item of otherSource) {
if (retryedSource.includes(item.source)) continue
console.log('try toggle to: ', item.source, item.name, item.singer, item.interval)
return getLyric.call(this, item, retryedSource, originMusic)
}
}
return Promise.reject(err)
})
})
}
// 修复 1.1.x版本 酷狗源歌词格式
const fixKgLyric = lrc => /\[00:\d\d:\d\d.\d+\]/.test(lrc) ? lrc.replace(/(?:\[00:(\d\d:\d\d.\d+\]))/gm, '[$1') : lrc
@ -172,22 +256,30 @@ const fixKgLyric = lrc => /\[00:\d\d:\d\d.\d+\]/.test(lrc) ? lrc.replace(/(?:\[0
* @param {*} filePath
* @param {*} isEmbedPic // 是否嵌入图片
*/
const saveMeta = (downloadInfo, filePath, isEmbedPic, isEmbedLyric) => {
const saveMeta = function(downloadInfo, filePath, isUseOtherSource, isEmbedPic, isEmbedLyric) {
if (downloadInfo.type === 'ape') return
const tasks = [
isEmbedPic
? downloadInfo.musicInfo.img
? Promise.resolve(downloadInfo.musicInfo.img)
: music[downloadInfo.musicInfo.source].getPic(downloadInfo.musicInfo).promise.catch(err => {
: (
isUseOtherSource
? getPic.call(this, downloadInfo.musicInfo)
: music[downloadInfo.musicInfo.source].getPic(downloadInfo.musicInfo).promise
).catch(err => {
console.log(err)
return null
})
: Promise.resolve(),
isEmbedLyric
? getLyric(downloadInfo.musicInfo).then(lrcInfo => {
? getLyricFromStorage(downloadInfo.musicInfo).then(lrcInfo => {
return lrcInfo.lyric
? Promise.resolve({ lyric: lrcInfo.lyric, tlyric: lrcInfo.tlyric || '' })
: music[downloadInfo.musicInfo.source].getLyric(downloadInfo.musicInfo).promise.then(({ lyric, tlyric, lxlyric }) => {
: (
isUseOtherSource
? getLyric.call(this, downloadInfo.musicInfo)
: music[downloadInfo.musicInfo.source].getLyric(downloadInfo.musicInfo).promise
).then(({ lyric, tlyric, lxlyric }) => {
setLyric(downloadInfo.musicInfo, { lyric, tlyric, lxlyric })
return { lyric, tlyric, lxlyric }
}).catch(err => {
@ -231,9 +323,9 @@ const downloadLyric = (downloadInfo, filePath) => {
})
}
const refreshUrl = function(commit, downloadInfo) {
const refreshUrl = function(commit, downloadInfo, isUseOtherSource) {
commit('setStatusText', { downloadInfo, text: '链接失效,正在刷新链接' })
getUrl(downloadInfo, true).then(url => {
getMusicUrl.call(this, downloadInfo, isUseOtherSource, true).then(url => {
commit('updateUrl', { downloadInfo, url })
commit('setStatusText', { downloadInfo, text: '链接刷新成功' })
const dl = dls[downloadInfo.key]
@ -341,7 +433,7 @@ const actions = {
commit('onCompleted', downloadInfo)
dispatch('startTask')
saveMeta(downloadInfo, downloadInfo.filePath, rootState.setting.download.isEmbedPic, rootState.setting.download.isEmbedLyric)
saveMeta.call(_this, downloadInfo, downloadInfo.filePath, rootState.setting.download.isUseOtherSource, rootState.setting.download.isEmbedPic, rootState.setting.download.isEmbedLyric)
if (rootState.setting.download.isDownloadLrc) downloadLyric(downloadInfo, downloadInfo.filePath)
console.log('on complate')
},
@ -358,7 +450,8 @@ const actions = {
return
}
if (err.code == 'ENOTFOUND') {
refreshUrl.call(_this, commit, downloadInfo)
commit('onError', { downloadInfo, errorMsg: '链接失效' })
refreshUrl.call(_this, commit, downloadInfo, rootState.setting.download.isUseOtherSource)
} else {
console.log('Download failed, Attempting Retry')
dls[downloadInfo.key].start()
@ -375,7 +468,13 @@ const actions = {
case 401:
case 403:
case 410:
refreshUrl.call(_this, commit, downloadInfo)
commit('onError', { downloadInfo, errorMsg: '链接失效' })
refreshUrl.call(_this, commit, downloadInfo, rootState.setting.download.isUseOtherSource)
break
default:
dls[downloadInfo.key].start()
commit('setStatusText', { downloadInfo, text: '正在重试' })
break
}
},
onStart() {
@ -394,7 +493,7 @@ const actions = {
commit('setStatusText', { downloadInfo, text: '获取URL中...' })
let p = options.url
? Promise.resolve()
: getUrl(downloadInfo).then(url => {
: getMusicUrl.call(this, downloadInfo, rootState.setting.download.isUseOtherSource).then(url => {
commit('updateUrl', { downloadInfo, url })
if (!url) return Promise.reject(new Error('获取URL失败'))
options.url = url

View File

@ -68,16 +68,16 @@ const filterList = async({ playedList, listInfo, savePath, commit }) => {
const getPic = function(musicInfo, retryedSource = [], originMusic) {
// console.log(musicInfo.source)
if (!originMusic) originMusic = musicInfo
let reqPromise
try {
reqPromise = music[musicInfo.source].getPic(musicInfo).promise
} catch (err) {
reqPromise = Promise.reject(err)
}
return reqPromise.promise.catch(err => {
return reqPromise.catch(err => {
if (!retryedSource.includes(musicInfo.source)) retryedSource.push(musicInfo.source)
return this.dispatch('list/getOtherSource', musicInfo).then(otherSource => {
if (!originMusic) originMusic = musicInfo
return this.dispatch('list/getOtherSource', originMusic).then(otherSource => {
console.log('find otherSource', otherSource)
if (otherSource.length) {
for (const item of otherSource) {
@ -91,16 +91,16 @@ const getPic = function(musicInfo, retryedSource = [], originMusic) {
})
}
const getLyric = function(musicInfo, retryedSource = [], originMusic) {
if (!originMusic) originMusic = musicInfo
let reqPromise
try {
reqPromise = music[musicInfo.source].getLyric(musicInfo).promise
} catch (err) {
reqPromise = Promise.reject(err)
}
return reqPromise.promise.catch(err => {
return reqPromise.catch(err => {
if (!retryedSource.includes(musicInfo.source)) retryedSource.push(musicInfo.source)
return this.dispatch('list/getOtherSource', musicInfo).then(otherSource => {
if (!originMusic) originMusic = musicInfo
return this.dispatch('list/getOtherSource', originMusic).then(otherSource => {
console.log('find otherSource', otherSource)
if (otherSource.length) {
for (const item of otherSource) {

View File

@ -122,6 +122,11 @@ div(:class="$style.main")
span.auto-hidden.hover(:tips="$t('view.setting.download_path_open_label')" :class="$style.savePath" @click="handleOpenDir(current_setting.download.savePath)") {{current_setting.download.savePath}}
p
material-btn(:class="$style.btn" min @click="handleChangeSavePath") {{$t('view.setting.download_path_change_btn')}}
dd
h3#download_name {{$t('view.setting.download_use_other_source')}}
div
material-checkbox(id="setting_download_isUseOtherSource" v-model="current_setting.download.isUseOtherSource" :label="$t('view.setting.is_enable')")
div
dd(:tips="$t('view.setting.download_name_title')")
h3#download_name {{$t('view.setting.download_name')}}
div