Removed Conflict
This commit is contained in:
commit
2fd2181447
3
.github/updateUserAgents.js
vendored
3
.github/updateUserAgents.js
vendored
@ -9,7 +9,8 @@ for (let i = 0; i < 10; i++) {
|
||||
|
||||
// only use Windows and Linux user agents and exclude Internet Explorer ones
|
||||
while (!(userAgent.data.platform.startsWith('Win') || userAgent.data.platform.startsWith('Linux'))
|
||||
|| userAgent.data.userAgent.includes('; MSIE') || userAgent.data.userAgent.includes('Trident/')) {
|
||||
|| userAgent.data.userAgent.includes('; MSIE') || userAgent.data.userAgent.includes('Trident/')
|
||||
|| userAgents.includes(userAgent.toString())) {
|
||||
userAgent = generator.random();
|
||||
}
|
||||
|
||||
|
||||
512
package-lock.json
generated
512
package-lock.json
generated
@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "play-dl",
|
||||
"version": "1.9.3",
|
||||
"version": "1.9.4",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "play-dl",
|
||||
"version": "1.9.3",
|
||||
"version": "1.9.4",
|
||||
"license": "GPL-3.0",
|
||||
"dependencies": {
|
||||
"play-audio": "^0.5.2"
|
||||
@ -60,9 +60,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@types/node": {
|
||||
"version": "17.0.21",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.21.tgz",
|
||||
"integrity": "sha512-DBZCJbhII3r90XbQxI8Y9IjjiiOGlZ0Hr32omXIZvwwZ7p4DMMXGrKXVyPfuoBOri9XNtL0UK69jYIBIsRX3QQ==",
|
||||
"version": "17.0.23",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.23.tgz",
|
||||
"integrity": "sha512-UxDxWn7dl97rKVeVS61vErvw086aCYhDLyvRQZ5Rk65rZKepaFdm53GeqXaKBuOhED4e9uWq34IC3TdSdJJ2Gw==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/any-promise": {
|
||||
@ -234,9 +234,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/esbuild": {
|
||||
"version": "0.14.16",
|
||||
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.14.16.tgz",
|
||||
"integrity": "sha512-niiWy7nesZFGCiDr0NR9/JLEhtZPYHG/ABYTqveNWvocw/gGI5rKHOj3+5yUv3yH10/geTlZiyVaNvjJWL9Xbw==",
|
||||
"version": "0.14.29",
|
||||
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.14.29.tgz",
|
||||
"integrity": "sha512-SQS8cO8xFEqevYlrHt6exIhK853Me4nZ4aMW6ieysInLa0FMAL+AKs87HYNRtR2YWRcEIqoXAHh+Ytt5/66qpg==",
|
||||
"dev": true,
|
||||
"hasInstallScript": true,
|
||||
"bin": {
|
||||
@ -246,30 +246,48 @@
|
||||
"node": ">=12"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"esbuild-android-arm64": "0.14.16",
|
||||
"esbuild-darwin-64": "0.14.16",
|
||||
"esbuild-darwin-arm64": "0.14.16",
|
||||
"esbuild-freebsd-64": "0.14.16",
|
||||
"esbuild-freebsd-arm64": "0.14.16",
|
||||
"esbuild-linux-32": "0.14.16",
|
||||
"esbuild-linux-64": "0.14.16",
|
||||
"esbuild-linux-arm": "0.14.16",
|
||||
"esbuild-linux-arm64": "0.14.16",
|
||||
"esbuild-linux-mips64le": "0.14.16",
|
||||
"esbuild-linux-ppc64le": "0.14.16",
|
||||
"esbuild-linux-s390x": "0.14.16",
|
||||
"esbuild-netbsd-64": "0.14.16",
|
||||
"esbuild-openbsd-64": "0.14.16",
|
||||
"esbuild-sunos-64": "0.14.16",
|
||||
"esbuild-windows-32": "0.14.16",
|
||||
"esbuild-windows-64": "0.14.16",
|
||||
"esbuild-windows-arm64": "0.14.16"
|
||||
"esbuild-android-64": "0.14.29",
|
||||
"esbuild-android-arm64": "0.14.29",
|
||||
"esbuild-darwin-64": "0.14.29",
|
||||
"esbuild-darwin-arm64": "0.14.29",
|
||||
"esbuild-freebsd-64": "0.14.29",
|
||||
"esbuild-freebsd-arm64": "0.14.29",
|
||||
"esbuild-linux-32": "0.14.29",
|
||||
"esbuild-linux-64": "0.14.29",
|
||||
"esbuild-linux-arm": "0.14.29",
|
||||
"esbuild-linux-arm64": "0.14.29",
|
||||
"esbuild-linux-mips64le": "0.14.29",
|
||||
"esbuild-linux-ppc64le": "0.14.29",
|
||||
"esbuild-linux-riscv64": "0.14.29",
|
||||
"esbuild-linux-s390x": "0.14.29",
|
||||
"esbuild-netbsd-64": "0.14.29",
|
||||
"esbuild-openbsd-64": "0.14.29",
|
||||
"esbuild-sunos-64": "0.14.29",
|
||||
"esbuild-windows-32": "0.14.29",
|
||||
"esbuild-windows-64": "0.14.29",
|
||||
"esbuild-windows-arm64": "0.14.29"
|
||||
}
|
||||
},
|
||||
"node_modules/esbuild-android-64": {
|
||||
"version": "0.14.29",
|
||||
"resolved": "https://registry.npmjs.org/esbuild-android-64/-/esbuild-android-64-0.14.29.tgz",
|
||||
"integrity": "sha512-tJuaN33SVZyiHxRaVTo1pwW+rn3qetJX/SRuc/83rrKYtyZG0XfsQ1ao1nEudIt9w37ZSNXR236xEfm2C43sbw==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"android"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/esbuild-android-arm64": {
|
||||
"version": "0.14.16",
|
||||
"resolved": "https://registry.npmjs.org/esbuild-android-arm64/-/esbuild-android-arm64-0.14.16.tgz",
|
||||
"integrity": "sha512-9qRiUXiV0qIa4Dfv+GLKsk/HHOq3U9qh8yZK9iX0awlzLPFb38NJrNTGtb/TeI6AyyZqsGgwLm/JeJ1UtEN9Aw==",
|
||||
"version": "0.14.29",
|
||||
"resolved": "https://registry.npmjs.org/esbuild-android-arm64/-/esbuild-android-arm64-0.14.29.tgz",
|
||||
"integrity": "sha512-D74dCv6yYnMTlofVy1JKiLM5JdVSQd60/rQfJSDP9qvRAI0laPXIG/IXY1RG6jobmFMUfL38PbFnCqyI/6fPXg==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@ -283,9 +301,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/esbuild-darwin-64": {
|
||||
"version": "0.14.16",
|
||||
"resolved": "https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-0.14.16.tgz",
|
||||
"integrity": "sha512-1Xa86DpTJFRffA7go0pqUdC0ggxxGxjsrnrvA2nHBVHNf9Ix/cgGuPfxZwf3fRZxDDAT2RdqF5SRZzLYvUCtZQ==",
|
||||
"version": "0.14.29",
|
||||
"resolved": "https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-0.14.29.tgz",
|
||||
"integrity": "sha512-+CJaRvfTkzs9t+CjGa0Oa28WoXa7EeLutQhxus+fFcu0MHhsBhlmeWHac3Cc/Sf/xPi1b2ccDFfzGYJCfV0RrA==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
@ -299,9 +317,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/esbuild-darwin-arm64": {
|
||||
"version": "0.14.16",
|
||||
"resolved": "https://registry.npmjs.org/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.14.16.tgz",
|
||||
"integrity": "sha512-a0Tp0tec/s5hYT6OiJ2zvfH/6IfXFCH406yqFfXe5u8Nfo6l6IG33L7nqCYCEPnBLF7oYfZk6Re0VDwpgK18kQ==",
|
||||
"version": "0.14.29",
|
||||
"resolved": "https://registry.npmjs.org/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.14.29.tgz",
|
||||
"integrity": "sha512-5Wgz/+zK+8X2ZW7vIbwoZ613Vfr4A8HmIs1XdzRmdC1kG0n5EG5fvKk/jUxhNlrYPx1gSY7XadQ3l4xAManPSw==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@ -315,9 +333,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/esbuild-freebsd-64": {
|
||||
"version": "0.14.16",
|
||||
"resolved": "https://registry.npmjs.org/esbuild-freebsd-64/-/esbuild-freebsd-64-0.14.16.tgz",
|
||||
"integrity": "sha512-FqEdOphRS5kJ8MFqQ21Y0yducmwcFHmpkceLkup1kpsGChr3PGO7DfzXmF5fECNnMxRpk/jgk7e6nV4zXTau/A==",
|
||||
"version": "0.14.29",
|
||||
"resolved": "https://registry.npmjs.org/esbuild-freebsd-64/-/esbuild-freebsd-64-0.14.29.tgz",
|
||||
"integrity": "sha512-VTfS7Bm9QA12JK1YXF8+WyYOfvD7WMpbArtDj6bGJ5Sy5xp01c/q70Arkn596aGcGj0TvQRplaaCIrfBG1Wdtg==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
@ -331,9 +349,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/esbuild-freebsd-arm64": {
|
||||
"version": "0.14.16",
|
||||
"resolved": "https://registry.npmjs.org/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.14.16.tgz",
|
||||
"integrity": "sha512-4Au4zR0//Df1v6FuWJEMZFRzaF69FvxHgSmKjikq7x6Ect+h4TbJKkblC3eDrfTA8L6l5bB1vhh0dbKq4zBy5Q==",
|
||||
"version": "0.14.29",
|
||||
"resolved": "https://registry.npmjs.org/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.14.29.tgz",
|
||||
"integrity": "sha512-WP5L4ejwLWWvd3Fo2J5mlXvG3zQHaw5N1KxFGnUc4+2ZFZknP0ST63i0IQhpJLgEJwnQpXv2uZlU1iWZjFqEIg==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@ -347,9 +365,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/esbuild-linux-32": {
|
||||
"version": "0.14.16",
|
||||
"resolved": "https://registry.npmjs.org/esbuild-linux-32/-/esbuild-linux-32-0.14.16.tgz",
|
||||
"integrity": "sha512-HundAiQCa0ut7PXq3lmRZY7H3/OYh27wkJ97S7jjCgWmcd5To6Bs8UBVB7I4Qi9lNk/Yty0INnqq9on1WR8JUA==",
|
||||
"version": "0.14.29",
|
||||
"resolved": "https://registry.npmjs.org/esbuild-linux-32/-/esbuild-linux-32-0.14.29.tgz",
|
||||
"integrity": "sha512-4myeOvFmQBWdI2U1dEBe2DCSpaZyjdQtmjUY11Zu2eQg4ynqLb8Y5mNjNU9UN063aVsCYYfbs8jbken/PjyidA==",
|
||||
"cpu": [
|
||||
"ia32"
|
||||
],
|
||||
@ -363,9 +381,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/esbuild-linux-64": {
|
||||
"version": "0.14.16",
|
||||
"resolved": "https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-0.14.16.tgz",
|
||||
"integrity": "sha512-fG8MgVmQknIuYCHFOq+9iKLyygjPun+VkNH9ZIdRQrSzb3CFdEkNm+Suq5w8W+WjA/P0OIdrQ/mXXCoHCQTWSQ==",
|
||||
"version": "0.14.29",
|
||||
"resolved": "https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-0.14.29.tgz",
|
||||
"integrity": "sha512-iaEuLhssReAKE7HMwxwFJFn7D/EXEs43fFy5CJeA4DGmU6JHh0qVJD2p/UP46DvUXLRKXsXw0i+kv5TdJ1w5pg==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
@ -379,9 +397,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/esbuild-linux-arm": {
|
||||
"version": "0.14.16",
|
||||
"resolved": "https://registry.npmjs.org/esbuild-linux-arm/-/esbuild-linux-arm-0.14.16.tgz",
|
||||
"integrity": "sha512-0NDVeuvWska0d4Rd8R3+lWEyKaIbAxDuRAeeU6a2xaUXrTG2IPhGNLWc4NbVMbnkGqRqKB4PLdk/YaTUZjKFHQ==",
|
||||
"version": "0.14.29",
|
||||
"resolved": "https://registry.npmjs.org/esbuild-linux-arm/-/esbuild-linux-arm-0.14.29.tgz",
|
||||
"integrity": "sha512-OXa9D9QL1hwrAnYYAHt/cXAuSCmoSqYfTW/0CEY0LgJNyTxJKtqc5mlwjAZAvgyjmha0auS/sQ0bXfGf2wAokQ==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
@ -395,9 +413,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/esbuild-linux-arm64": {
|
||||
"version": "0.14.16",
|
||||
"resolved": "https://registry.npmjs.org/esbuild-linux-arm64/-/esbuild-linux-arm64-0.14.16.tgz",
|
||||
"integrity": "sha512-7WF1rHsPVXhme2B6ceZZABxFwCiZfMRIJO7yRiLahIdDkwfhSTR6M0a6OwO/NsLJH9fax5GdwBOIBoG5Hkz4gA==",
|
||||
"version": "0.14.29",
|
||||
"resolved": "https://registry.npmjs.org/esbuild-linux-arm64/-/esbuild-linux-arm64-0.14.29.tgz",
|
||||
"integrity": "sha512-KYf7s8wDfUy+kjKymW3twyGT14OABjGHRkm9gPJ0z4BuvqljfOOUbq9qT3JYFnZJHOgkr29atT//hcdD0Pi7Mw==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@ -411,9 +429,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/esbuild-linux-mips64le": {
|
||||
"version": "0.14.16",
|
||||
"resolved": "https://registry.npmjs.org/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.14.16.tgz",
|
||||
"integrity": "sha512-RLNaTRdcQ81QckeIjbk1hCrgmrL6VoZBsYT8ak9ObNQzXEJNMlxOBixaF6rhW8UUYRpTpFuoYHeNya8xY884/A==",
|
||||
"version": "0.14.29",
|
||||
"resolved": "https://registry.npmjs.org/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.14.29.tgz",
|
||||
"integrity": "sha512-05jPtWQMsZ1aMGfHOvnR5KrTvigPbU35BtuItSSWLI2sJu5VrM8Pr9Owym4wPvA4153DFcOJ1EPN/2ujcDt54g==",
|
||||
"cpu": [
|
||||
"mips64el"
|
||||
],
|
||||
@ -427,9 +445,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/esbuild-linux-ppc64le": {
|
||||
"version": "0.14.16",
|
||||
"resolved": "https://registry.npmjs.org/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.14.16.tgz",
|
||||
"integrity": "sha512-ky0Ii2Jmyc00FzGT2audU0UmnBVrVevYmKW10DXLPcHGhbhzJdFRemXLvvzhDM8WD9IMJK3uV6ifJzkKrv8IQA==",
|
||||
"version": "0.14.29",
|
||||
"resolved": "https://registry.npmjs.org/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.14.29.tgz",
|
||||
"integrity": "sha512-FYhBqn4Ir9xG+f6B5VIQVbRuM4S6qwy29dDNYFPoxLRnwTEKToIYIUESN1qHyUmIbfO0YB4phG2JDV2JDN9Kgw==",
|
||||
"cpu": [
|
||||
"ppc64"
|
||||
],
|
||||
@ -442,10 +460,26 @@
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/esbuild-linux-riscv64": {
|
||||
"version": "0.14.29",
|
||||
"resolved": "https://registry.npmjs.org/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.14.29.tgz",
|
||||
"integrity": "sha512-eqZMqPehkb4nZcffnuOpXJQdGURGd6GXQ4ZsDHSWyIUaA+V4FpMBe+5zMPtXRD2N4BtyzVvnBko6K8IWWr36ew==",
|
||||
"cpu": [
|
||||
"riscv64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/esbuild-linux-s390x": {
|
||||
"version": "0.14.16",
|
||||
"resolved": "https://registry.npmjs.org/esbuild-linux-s390x/-/esbuild-linux-s390x-0.14.16.tgz",
|
||||
"integrity": "sha512-DuW9MPGJAzUUBPI/olMkMMepCasTbPN1Xr2cKZZEEDIibcdRnuFrMYVk3G3I8/Qb6SZBNTSnZMAyhvYFrwAkqw==",
|
||||
"version": "0.14.29",
|
||||
"resolved": "https://registry.npmjs.org/esbuild-linux-s390x/-/esbuild-linux-s390x-0.14.29.tgz",
|
||||
"integrity": "sha512-o7EYajF1rC/4ho7kpSG3gENVx0o2SsHm7cJ5fvewWB/TEczWU7teDgusGSujxCYcMottE3zqa423VTglNTYhjg==",
|
||||
"cpu": [
|
||||
"s390x"
|
||||
],
|
||||
@ -459,9 +493,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/esbuild-netbsd-64": {
|
||||
"version": "0.14.16",
|
||||
"resolved": "https://registry.npmjs.org/esbuild-netbsd-64/-/esbuild-netbsd-64-0.14.16.tgz",
|
||||
"integrity": "sha512-l8+mnz8iVsV0iL5v5JCuP0UTv2LwO1ORdJ/scMkGUl8WrC6cBmUrrHhg+pwREqjbD8TxjfUJVM1Vvt5E8SaTsg==",
|
||||
"version": "0.14.29",
|
||||
"resolved": "https://registry.npmjs.org/esbuild-netbsd-64/-/esbuild-netbsd-64-0.14.29.tgz",
|
||||
"integrity": "sha512-/esN6tb6OBSot6+JxgeOZeBk6P8V/WdR3GKBFeFpSqhgw4wx7xWUqPrdx4XNpBVO7X4Ipw9SAqgBrWHlXfddww==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
@ -475,9 +509,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/esbuild-openbsd-64": {
|
||||
"version": "0.14.16",
|
||||
"resolved": "https://registry.npmjs.org/esbuild-openbsd-64/-/esbuild-openbsd-64-0.14.16.tgz",
|
||||
"integrity": "sha512-8SbZNAV902FmcGnc+j86HWY8PyTD1H7T39RsPXXS5IC1psi3yzFr2d8NoOxb6cQd5XUVHmHT1naJsbtEAyKIPA==",
|
||||
"version": "0.14.29",
|
||||
"resolved": "https://registry.npmjs.org/esbuild-openbsd-64/-/esbuild-openbsd-64-0.14.29.tgz",
|
||||
"integrity": "sha512-jUTdDzhEKrD0pLpjmk0UxwlfNJNg/D50vdwhrVcW/D26Vg0hVbthMfb19PJMatzclbK7cmgk1Nu0eNS+abzoHw==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
@ -491,9 +525,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/esbuild-sunos-64": {
|
||||
"version": "0.14.16",
|
||||
"resolved": "https://registry.npmjs.org/esbuild-sunos-64/-/esbuild-sunos-64-0.14.16.tgz",
|
||||
"integrity": "sha512-pMhe4uOaGjA/5YgeNoB0PRZi1V73D8sx876uFzuAxaZcYzLA5BsSbQeEccH182X6cBybE4Pm79kYedTSGOfwog==",
|
||||
"version": "0.14.29",
|
||||
"resolved": "https://registry.npmjs.org/esbuild-sunos-64/-/esbuild-sunos-64-0.14.29.tgz",
|
||||
"integrity": "sha512-EfhQN/XO+TBHTbkxwsxwA7EfiTHFe+MNDfxcf0nj97moCppD9JHPq48MLtOaDcuvrTYOcrMdJVeqmmeQ7doTcg==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
@ -507,9 +541,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/esbuild-windows-32": {
|
||||
"version": "0.14.16",
|
||||
"resolved": "https://registry.npmjs.org/esbuild-windows-32/-/esbuild-windows-32-0.14.16.tgz",
|
||||
"integrity": "sha512-M68/EFCgji0DI+DgULx2ytUUSxwwODJDpiVc0YsiWKdyB4umKTu1GGxFfdZhXrWtPxB4aZFoIgJyDhsFxnHC4g==",
|
||||
"version": "0.14.29",
|
||||
"resolved": "https://registry.npmjs.org/esbuild-windows-32/-/esbuild-windows-32-0.14.29.tgz",
|
||||
"integrity": "sha512-uoyb0YAJ6uWH4PYuYjfGNjvgLlb5t6b3zIaGmpWPOjgpr1Nb3SJtQiK4YCPGhONgfg2v6DcJgSbOteuKXhwqAw==",
|
||||
"cpu": [
|
||||
"ia32"
|
||||
],
|
||||
@ -523,9 +557,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/esbuild-windows-64": {
|
||||
"version": "0.14.16",
|
||||
"resolved": "https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-0.14.16.tgz",
|
||||
"integrity": "sha512-rmSal1Co749CXSNyFJ62J5Fz/nZiFWhwMfYN9SwZazutKZ6s0QDRIhnupa93bJmzMzz4C2dqUV/VL1tqOI3y9g==",
|
||||
"version": "0.14.29",
|
||||
"resolved": "https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-0.14.29.tgz",
|
||||
"integrity": "sha512-X9cW/Wl95QjsH8WUyr3NqbmfdU72jCp71cH3pwPvI4CgBM2IeOUDdbt6oIGljPu2bf5eGDIo8K3Y3vvXCCTd8A==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
@ -539,9 +573,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/esbuild-windows-arm64": {
|
||||
"version": "0.14.16",
|
||||
"resolved": "https://registry.npmjs.org/esbuild-windows-arm64/-/esbuild-windows-arm64-0.14.16.tgz",
|
||||
"integrity": "sha512-VMfEf+MDgO+rulAuSeu3HNebSHa1TDn0lJp+QRk7E2WVg9OCSwuXUEkSbqIbkif3ZjASy7h9sTCGyHcqgKQTrg==",
|
||||
"version": "0.14.29",
|
||||
"resolved": "https://registry.npmjs.org/esbuild-windows-arm64/-/esbuild-windows-arm64-0.14.29.tgz",
|
||||
"integrity": "sha512-+O/PI+68fbUZPpl3eXhqGHTGK7DjLcexNnyJqtLZXOFwoAjaXlS5UBCvVcR3o2va+AqZTj8o6URaz8D2K+yfQQ==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@ -862,9 +896,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/marked": {
|
||||
"version": "4.0.10",
|
||||
"resolved": "https://registry.npmjs.org/marked/-/marked-4.0.10.tgz",
|
||||
"integrity": "sha512-+QvuFj0nGgO970fySghXGmuw+Fd0gD2x3+MqCWLIPf5oxdv1Ka6b2q+z9RP01P/IaKPMEramy+7cNy/Lw8c3hw==",
|
||||
"version": "4.0.12",
|
||||
"resolved": "https://registry.npmjs.org/marked/-/marked-4.0.12.tgz",
|
||||
"integrity": "sha512-hgibXWrEDNBWgGiK18j/4lkS6ihTe9sxtV4Q1OQppb/0zzyPSzoFANBa5MfsG/zgsWklmNnhm0XACZOH/0HBiQ==",
|
||||
"dev": true,
|
||||
"bin": {
|
||||
"marked": "bin/marked.js"
|
||||
@ -1073,15 +1107,18 @@
|
||||
}
|
||||
},
|
||||
"node_modules/prettier": {
|
||||
"version": "2.5.1",
|
||||
"resolved": "https://registry.npmjs.org/prettier/-/prettier-2.5.1.tgz",
|
||||
"integrity": "sha512-vBZcPRUR5MZJwoyi3ZoyQlc1rXeEck8KgeC9AwwOn+exuxLxq5toTRDTSaVrXHxelDMHy9zlicw8u66yxoSUFg==",
|
||||
"version": "2.6.1",
|
||||
"resolved": "https://registry.npmjs.org/prettier/-/prettier-2.6.1.tgz",
|
||||
"integrity": "sha512-8UVbTBYGwN37Bs9LERmxCPjdvPxlEowx2urIL6urHzdb3SDq4B/Z6xLFCblrSnE4iKWcS6ziJ3aOYrc1kz/E2A==",
|
||||
"dev": true,
|
||||
"bin": {
|
||||
"prettier": "bin-prettier.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10.13.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/prettier/prettier?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/queue-microtask": {
|
||||
@ -1195,9 +1232,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/shiki": {
|
||||
"version": "0.10.0",
|
||||
"resolved": "https://registry.npmjs.org/shiki/-/shiki-0.10.0.tgz",
|
||||
"integrity": "sha512-iczxaIYeBFHTFrQPb9DVy2SKgYxC4Wo7Iucm7C17cCh2Ge/refnvHscUOxM85u57MfLoNOtjoEFUWt9gBexblA==",
|
||||
"version": "0.10.1",
|
||||
"resolved": "https://registry.npmjs.org/shiki/-/shiki-0.10.1.tgz",
|
||||
"integrity": "sha512-VsY7QJVzU51j5o1+DguUd+6vmCmZ5v/6gYu4vyYAhzjuNQU6P/vmSy4uQaOhvje031qQMiW0d2BwgMH52vqMng==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"jsonc-parser": "^3.0.0",
|
||||
@ -1328,16 +1365,16 @@
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/tsup": {
|
||||
"version": "5.11.13",
|
||||
"resolved": "https://registry.npmjs.org/tsup/-/tsup-5.11.13.tgz",
|
||||
"integrity": "sha512-NVMK01gVmojZn7+iZwxRK1CzW2BIabaVMyEjs7Nm9lm4DrSf7IAqs2F3fg0vT7rH72x1cIBsW9U/TlWrCvHVQQ==",
|
||||
"version": "5.12.2",
|
||||
"resolved": "https://registry.npmjs.org/tsup/-/tsup-5.12.2.tgz",
|
||||
"integrity": "sha512-CZcM4UGYlKcdQzDIJbrwgpn4sQe8zobnHRgAF6C8RpMGvfRov9ipSQY3mjjnZRAkEZQO1+Jr3cxeaQJjY/iVTg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"bundle-require": "^3.0.2",
|
||||
"cac": "^6.7.12",
|
||||
"chokidar": "^3.5.1",
|
||||
"debug": "^4.3.1",
|
||||
"esbuild": "^0.14.2",
|
||||
"esbuild": "^0.14.25",
|
||||
"execa": "^5.0.0",
|
||||
"globby": "^11.0.3",
|
||||
"joycon": "^3.0.1",
|
||||
@ -1362,16 +1399,16 @@
|
||||
}
|
||||
},
|
||||
"node_modules/typedoc": {
|
||||
"version": "0.22.12",
|
||||
"resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.22.12.tgz",
|
||||
"integrity": "sha512-FcyC+YuaOpr3rB9QwA1IHOi9KnU2m50sPJW5vcNRPCIdecp+3bFkh7Rq5hBU1Fyn29UR2h4h/H7twZHWDhL0sw==",
|
||||
"version": "0.22.13",
|
||||
"resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.22.13.tgz",
|
||||
"integrity": "sha512-NHNI7Dr6JHa/I3+c62gdRNXBIyX7P33O9TafGLd07ur3MqzcKgwTvpg18EtvCLHJyfeSthAtCLpM7WkStUmDuQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"glob": "^7.2.0",
|
||||
"lunr": "^2.3.9",
|
||||
"marked": "^4.0.10",
|
||||
"minimatch": "^3.0.4",
|
||||
"shiki": "^0.10.0"
|
||||
"marked": "^4.0.12",
|
||||
"minimatch": "^5.0.1",
|
||||
"shiki": "^0.10.1"
|
||||
},
|
||||
"bin": {
|
||||
"typedoc": "bin/typedoc"
|
||||
@ -1380,7 +1417,7 @@
|
||||
"node": ">= 12.10.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"typescript": "4.0.x || 4.1.x || 4.2.x || 4.3.x || 4.4.x || 4.5.x"
|
||||
"typescript": "4.0.x || 4.1.x || 4.2.x || 4.3.x || 4.4.x || 4.5.x || 4.6.x"
|
||||
}
|
||||
},
|
||||
"node_modules/typedoc-plugin-extras": {
|
||||
@ -1401,10 +1438,31 @@
|
||||
"typedoc": "0.22.x"
|
||||
}
|
||||
},
|
||||
"node_modules/typedoc/node_modules/brace-expansion": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
|
||||
"integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"balanced-match": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/typedoc/node_modules/minimatch": {
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.0.1.tgz",
|
||||
"integrity": "sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"brace-expansion": "^2.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/typescript": {
|
||||
"version": "4.6.2",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.6.2.tgz",
|
||||
"integrity": "sha512-HM/hFigTBHZhLXshn9sN37H085+hQGeJHJ/X7LpBWLID/fbc2acUMfU+lGD98X81sKP+pFa9f0DZmCwB9GnbAg==",
|
||||
"version": "4.6.3",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.6.3.tgz",
|
||||
"integrity": "sha512-yNIatDa5iaofVozS/uQJEl3JRWLKKGJKh6Yaiv0GLGSuhpFJe7P3SbHZ8/yjAHRQwKRoA6YZqlfjXWmVzoVSMw==",
|
||||
"dev": true,
|
||||
"bin": {
|
||||
"tsc": "bin/tsc",
|
||||
@ -1415,9 +1473,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/vscode-oniguruma": {
|
||||
"version": "1.6.1",
|
||||
"resolved": "https://registry.npmjs.org/vscode-oniguruma/-/vscode-oniguruma-1.6.1.tgz",
|
||||
"integrity": "sha512-vc4WhSIaVpgJ0jJIejjYxPvURJavX6QG41vu0mGhqywMkQqulezEqEQ3cO3gc8GvcOpX6ycmKGqRoROEMBNXTQ==",
|
||||
"version": "1.6.2",
|
||||
"resolved": "https://registry.npmjs.org/vscode-oniguruma/-/vscode-oniguruma-1.6.2.tgz",
|
||||
"integrity": "sha512-KH8+KKov5eS/9WhofZR8M8dMHWN2gTxjMsG4jd04YhpbPR91fUj7rYQ2/XjeHCJWbg7X++ApRIU9NUwM2vTvLA==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/vscode-textmate": {
|
||||
@ -1485,9 +1543,9 @@
|
||||
}
|
||||
},
|
||||
"@types/node": {
|
||||
"version": "17.0.21",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.21.tgz",
|
||||
"integrity": "sha512-DBZCJbhII3r90XbQxI8Y9IjjiiOGlZ0Hr32omXIZvwwZ7p4DMMXGrKXVyPfuoBOri9XNtL0UK69jYIBIsRX3QQ==",
|
||||
"version": "17.0.23",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.23.tgz",
|
||||
"integrity": "sha512-UxDxWn7dl97rKVeVS61vErvw086aCYhDLyvRQZ5Rk65rZKepaFdm53GeqXaKBuOhED4e9uWq34IC3TdSdJJ2Gw==",
|
||||
"dev": true
|
||||
},
|
||||
"any-promise": {
|
||||
@ -1616,154 +1674,170 @@
|
||||
}
|
||||
},
|
||||
"esbuild": {
|
||||
"version": "0.14.16",
|
||||
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.14.16.tgz",
|
||||
"integrity": "sha512-niiWy7nesZFGCiDr0NR9/JLEhtZPYHG/ABYTqveNWvocw/gGI5rKHOj3+5yUv3yH10/geTlZiyVaNvjJWL9Xbw==",
|
||||
"version": "0.14.29",
|
||||
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.14.29.tgz",
|
||||
"integrity": "sha512-SQS8cO8xFEqevYlrHt6exIhK853Me4nZ4aMW6ieysInLa0FMAL+AKs87HYNRtR2YWRcEIqoXAHh+Ytt5/66qpg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"esbuild-android-arm64": "0.14.16",
|
||||
"esbuild-darwin-64": "0.14.16",
|
||||
"esbuild-darwin-arm64": "0.14.16",
|
||||
"esbuild-freebsd-64": "0.14.16",
|
||||
"esbuild-freebsd-arm64": "0.14.16",
|
||||
"esbuild-linux-32": "0.14.16",
|
||||
"esbuild-linux-64": "0.14.16",
|
||||
"esbuild-linux-arm": "0.14.16",
|
||||
"esbuild-linux-arm64": "0.14.16",
|
||||
"esbuild-linux-mips64le": "0.14.16",
|
||||
"esbuild-linux-ppc64le": "0.14.16",
|
||||
"esbuild-linux-s390x": "0.14.16",
|
||||
"esbuild-netbsd-64": "0.14.16",
|
||||
"esbuild-openbsd-64": "0.14.16",
|
||||
"esbuild-sunos-64": "0.14.16",
|
||||
"esbuild-windows-32": "0.14.16",
|
||||
"esbuild-windows-64": "0.14.16",
|
||||
"esbuild-windows-arm64": "0.14.16"
|
||||
"esbuild-android-64": "0.14.29",
|
||||
"esbuild-android-arm64": "0.14.29",
|
||||
"esbuild-darwin-64": "0.14.29",
|
||||
"esbuild-darwin-arm64": "0.14.29",
|
||||
"esbuild-freebsd-64": "0.14.29",
|
||||
"esbuild-freebsd-arm64": "0.14.29",
|
||||
"esbuild-linux-32": "0.14.29",
|
||||
"esbuild-linux-64": "0.14.29",
|
||||
"esbuild-linux-arm": "0.14.29",
|
||||
"esbuild-linux-arm64": "0.14.29",
|
||||
"esbuild-linux-mips64le": "0.14.29",
|
||||
"esbuild-linux-ppc64le": "0.14.29",
|
||||
"esbuild-linux-riscv64": "0.14.29",
|
||||
"esbuild-linux-s390x": "0.14.29",
|
||||
"esbuild-netbsd-64": "0.14.29",
|
||||
"esbuild-openbsd-64": "0.14.29",
|
||||
"esbuild-sunos-64": "0.14.29",
|
||||
"esbuild-windows-32": "0.14.29",
|
||||
"esbuild-windows-64": "0.14.29",
|
||||
"esbuild-windows-arm64": "0.14.29"
|
||||
}
|
||||
},
|
||||
"esbuild-android-64": {
|
||||
"version": "0.14.29",
|
||||
"resolved": "https://registry.npmjs.org/esbuild-android-64/-/esbuild-android-64-0.14.29.tgz",
|
||||
"integrity": "sha512-tJuaN33SVZyiHxRaVTo1pwW+rn3qetJX/SRuc/83rrKYtyZG0XfsQ1ao1nEudIt9w37ZSNXR236xEfm2C43sbw==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"esbuild-android-arm64": {
|
||||
"version": "0.14.16",
|
||||
"resolved": "https://registry.npmjs.org/esbuild-android-arm64/-/esbuild-android-arm64-0.14.16.tgz",
|
||||
"integrity": "sha512-9qRiUXiV0qIa4Dfv+GLKsk/HHOq3U9qh8yZK9iX0awlzLPFb38NJrNTGtb/TeI6AyyZqsGgwLm/JeJ1UtEN9Aw==",
|
||||
"version": "0.14.29",
|
||||
"resolved": "https://registry.npmjs.org/esbuild-android-arm64/-/esbuild-android-arm64-0.14.29.tgz",
|
||||
"integrity": "sha512-D74dCv6yYnMTlofVy1JKiLM5JdVSQd60/rQfJSDP9qvRAI0laPXIG/IXY1RG6jobmFMUfL38PbFnCqyI/6fPXg==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"esbuild-darwin-64": {
|
||||
"version": "0.14.16",
|
||||
"resolved": "https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-0.14.16.tgz",
|
||||
"integrity": "sha512-1Xa86DpTJFRffA7go0pqUdC0ggxxGxjsrnrvA2nHBVHNf9Ix/cgGuPfxZwf3fRZxDDAT2RdqF5SRZzLYvUCtZQ==",
|
||||
"version": "0.14.29",
|
||||
"resolved": "https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-0.14.29.tgz",
|
||||
"integrity": "sha512-+CJaRvfTkzs9t+CjGa0Oa28WoXa7EeLutQhxus+fFcu0MHhsBhlmeWHac3Cc/Sf/xPi1b2ccDFfzGYJCfV0RrA==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"esbuild-darwin-arm64": {
|
||||
"version": "0.14.16",
|
||||
"resolved": "https://registry.npmjs.org/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.14.16.tgz",
|
||||
"integrity": "sha512-a0Tp0tec/s5hYT6OiJ2zvfH/6IfXFCH406yqFfXe5u8Nfo6l6IG33L7nqCYCEPnBLF7oYfZk6Re0VDwpgK18kQ==",
|
||||
"version": "0.14.29",
|
||||
"resolved": "https://registry.npmjs.org/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.14.29.tgz",
|
||||
"integrity": "sha512-5Wgz/+zK+8X2ZW7vIbwoZ613Vfr4A8HmIs1XdzRmdC1kG0n5EG5fvKk/jUxhNlrYPx1gSY7XadQ3l4xAManPSw==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"esbuild-freebsd-64": {
|
||||
"version": "0.14.16",
|
||||
"resolved": "https://registry.npmjs.org/esbuild-freebsd-64/-/esbuild-freebsd-64-0.14.16.tgz",
|
||||
"integrity": "sha512-FqEdOphRS5kJ8MFqQ21Y0yducmwcFHmpkceLkup1kpsGChr3PGO7DfzXmF5fECNnMxRpk/jgk7e6nV4zXTau/A==",
|
||||
"version": "0.14.29",
|
||||
"resolved": "https://registry.npmjs.org/esbuild-freebsd-64/-/esbuild-freebsd-64-0.14.29.tgz",
|
||||
"integrity": "sha512-VTfS7Bm9QA12JK1YXF8+WyYOfvD7WMpbArtDj6bGJ5Sy5xp01c/q70Arkn596aGcGj0TvQRplaaCIrfBG1Wdtg==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"esbuild-freebsd-arm64": {
|
||||
"version": "0.14.16",
|
||||
"resolved": "https://registry.npmjs.org/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.14.16.tgz",
|
||||
"integrity": "sha512-4Au4zR0//Df1v6FuWJEMZFRzaF69FvxHgSmKjikq7x6Ect+h4TbJKkblC3eDrfTA8L6l5bB1vhh0dbKq4zBy5Q==",
|
||||
"version": "0.14.29",
|
||||
"resolved": "https://registry.npmjs.org/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.14.29.tgz",
|
||||
"integrity": "sha512-WP5L4ejwLWWvd3Fo2J5mlXvG3zQHaw5N1KxFGnUc4+2ZFZknP0ST63i0IQhpJLgEJwnQpXv2uZlU1iWZjFqEIg==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"esbuild-linux-32": {
|
||||
"version": "0.14.16",
|
||||
"resolved": "https://registry.npmjs.org/esbuild-linux-32/-/esbuild-linux-32-0.14.16.tgz",
|
||||
"integrity": "sha512-HundAiQCa0ut7PXq3lmRZY7H3/OYh27wkJ97S7jjCgWmcd5To6Bs8UBVB7I4Qi9lNk/Yty0INnqq9on1WR8JUA==",
|
||||
"version": "0.14.29",
|
||||
"resolved": "https://registry.npmjs.org/esbuild-linux-32/-/esbuild-linux-32-0.14.29.tgz",
|
||||
"integrity": "sha512-4myeOvFmQBWdI2U1dEBe2DCSpaZyjdQtmjUY11Zu2eQg4ynqLb8Y5mNjNU9UN063aVsCYYfbs8jbken/PjyidA==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"esbuild-linux-64": {
|
||||
"version": "0.14.16",
|
||||
"resolved": "https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-0.14.16.tgz",
|
||||
"integrity": "sha512-fG8MgVmQknIuYCHFOq+9iKLyygjPun+VkNH9ZIdRQrSzb3CFdEkNm+Suq5w8W+WjA/P0OIdrQ/mXXCoHCQTWSQ==",
|
||||
"version": "0.14.29",
|
||||
"resolved": "https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-0.14.29.tgz",
|
||||
"integrity": "sha512-iaEuLhssReAKE7HMwxwFJFn7D/EXEs43fFy5CJeA4DGmU6JHh0qVJD2p/UP46DvUXLRKXsXw0i+kv5TdJ1w5pg==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"esbuild-linux-arm": {
|
||||
"version": "0.14.16",
|
||||
"resolved": "https://registry.npmjs.org/esbuild-linux-arm/-/esbuild-linux-arm-0.14.16.tgz",
|
||||
"integrity": "sha512-0NDVeuvWska0d4Rd8R3+lWEyKaIbAxDuRAeeU6a2xaUXrTG2IPhGNLWc4NbVMbnkGqRqKB4PLdk/YaTUZjKFHQ==",
|
||||
"version": "0.14.29",
|
||||
"resolved": "https://registry.npmjs.org/esbuild-linux-arm/-/esbuild-linux-arm-0.14.29.tgz",
|
||||
"integrity": "sha512-OXa9D9QL1hwrAnYYAHt/cXAuSCmoSqYfTW/0CEY0LgJNyTxJKtqc5mlwjAZAvgyjmha0auS/sQ0bXfGf2wAokQ==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"esbuild-linux-arm64": {
|
||||
"version": "0.14.16",
|
||||
"resolved": "https://registry.npmjs.org/esbuild-linux-arm64/-/esbuild-linux-arm64-0.14.16.tgz",
|
||||
"integrity": "sha512-7WF1rHsPVXhme2B6ceZZABxFwCiZfMRIJO7yRiLahIdDkwfhSTR6M0a6OwO/NsLJH9fax5GdwBOIBoG5Hkz4gA==",
|
||||
"version": "0.14.29",
|
||||
"resolved": "https://registry.npmjs.org/esbuild-linux-arm64/-/esbuild-linux-arm64-0.14.29.tgz",
|
||||
"integrity": "sha512-KYf7s8wDfUy+kjKymW3twyGT14OABjGHRkm9gPJ0z4BuvqljfOOUbq9qT3JYFnZJHOgkr29atT//hcdD0Pi7Mw==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"esbuild-linux-mips64le": {
|
||||
"version": "0.14.16",
|
||||
"resolved": "https://registry.npmjs.org/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.14.16.tgz",
|
||||
"integrity": "sha512-RLNaTRdcQ81QckeIjbk1hCrgmrL6VoZBsYT8ak9ObNQzXEJNMlxOBixaF6rhW8UUYRpTpFuoYHeNya8xY884/A==",
|
||||
"version": "0.14.29",
|
||||
"resolved": "https://registry.npmjs.org/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.14.29.tgz",
|
||||
"integrity": "sha512-05jPtWQMsZ1aMGfHOvnR5KrTvigPbU35BtuItSSWLI2sJu5VrM8Pr9Owym4wPvA4153DFcOJ1EPN/2ujcDt54g==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"esbuild-linux-ppc64le": {
|
||||
"version": "0.14.16",
|
||||
"resolved": "https://registry.npmjs.org/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.14.16.tgz",
|
||||
"integrity": "sha512-ky0Ii2Jmyc00FzGT2audU0UmnBVrVevYmKW10DXLPcHGhbhzJdFRemXLvvzhDM8WD9IMJK3uV6ifJzkKrv8IQA==",
|
||||
"version": "0.14.29",
|
||||
"resolved": "https://registry.npmjs.org/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.14.29.tgz",
|
||||
"integrity": "sha512-FYhBqn4Ir9xG+f6B5VIQVbRuM4S6qwy29dDNYFPoxLRnwTEKToIYIUESN1qHyUmIbfO0YB4phG2JDV2JDN9Kgw==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"esbuild-linux-riscv64": {
|
||||
"version": "0.14.29",
|
||||
"resolved": "https://registry.npmjs.org/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.14.29.tgz",
|
||||
"integrity": "sha512-eqZMqPehkb4nZcffnuOpXJQdGURGd6GXQ4ZsDHSWyIUaA+V4FpMBe+5zMPtXRD2N4BtyzVvnBko6K8IWWr36ew==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"esbuild-linux-s390x": {
|
||||
"version": "0.14.16",
|
||||
"resolved": "https://registry.npmjs.org/esbuild-linux-s390x/-/esbuild-linux-s390x-0.14.16.tgz",
|
||||
"integrity": "sha512-DuW9MPGJAzUUBPI/olMkMMepCasTbPN1Xr2cKZZEEDIibcdRnuFrMYVk3G3I8/Qb6SZBNTSnZMAyhvYFrwAkqw==",
|
||||
"version": "0.14.29",
|
||||
"resolved": "https://registry.npmjs.org/esbuild-linux-s390x/-/esbuild-linux-s390x-0.14.29.tgz",
|
||||
"integrity": "sha512-o7EYajF1rC/4ho7kpSG3gENVx0o2SsHm7cJ5fvewWB/TEczWU7teDgusGSujxCYcMottE3zqa423VTglNTYhjg==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"esbuild-netbsd-64": {
|
||||
"version": "0.14.16",
|
||||
"resolved": "https://registry.npmjs.org/esbuild-netbsd-64/-/esbuild-netbsd-64-0.14.16.tgz",
|
||||
"integrity": "sha512-l8+mnz8iVsV0iL5v5JCuP0UTv2LwO1ORdJ/scMkGUl8WrC6cBmUrrHhg+pwREqjbD8TxjfUJVM1Vvt5E8SaTsg==",
|
||||
"version": "0.14.29",
|
||||
"resolved": "https://registry.npmjs.org/esbuild-netbsd-64/-/esbuild-netbsd-64-0.14.29.tgz",
|
||||
"integrity": "sha512-/esN6tb6OBSot6+JxgeOZeBk6P8V/WdR3GKBFeFpSqhgw4wx7xWUqPrdx4XNpBVO7X4Ipw9SAqgBrWHlXfddww==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"esbuild-openbsd-64": {
|
||||
"version": "0.14.16",
|
||||
"resolved": "https://registry.npmjs.org/esbuild-openbsd-64/-/esbuild-openbsd-64-0.14.16.tgz",
|
||||
"integrity": "sha512-8SbZNAV902FmcGnc+j86HWY8PyTD1H7T39RsPXXS5IC1psi3yzFr2d8NoOxb6cQd5XUVHmHT1naJsbtEAyKIPA==",
|
||||
"version": "0.14.29",
|
||||
"resolved": "https://registry.npmjs.org/esbuild-openbsd-64/-/esbuild-openbsd-64-0.14.29.tgz",
|
||||
"integrity": "sha512-jUTdDzhEKrD0pLpjmk0UxwlfNJNg/D50vdwhrVcW/D26Vg0hVbthMfb19PJMatzclbK7cmgk1Nu0eNS+abzoHw==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"esbuild-sunos-64": {
|
||||
"version": "0.14.16",
|
||||
"resolved": "https://registry.npmjs.org/esbuild-sunos-64/-/esbuild-sunos-64-0.14.16.tgz",
|
||||
"integrity": "sha512-pMhe4uOaGjA/5YgeNoB0PRZi1V73D8sx876uFzuAxaZcYzLA5BsSbQeEccH182X6cBybE4Pm79kYedTSGOfwog==",
|
||||
"version": "0.14.29",
|
||||
"resolved": "https://registry.npmjs.org/esbuild-sunos-64/-/esbuild-sunos-64-0.14.29.tgz",
|
||||
"integrity": "sha512-EfhQN/XO+TBHTbkxwsxwA7EfiTHFe+MNDfxcf0nj97moCppD9JHPq48MLtOaDcuvrTYOcrMdJVeqmmeQ7doTcg==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"esbuild-windows-32": {
|
||||
"version": "0.14.16",
|
||||
"resolved": "https://registry.npmjs.org/esbuild-windows-32/-/esbuild-windows-32-0.14.16.tgz",
|
||||
"integrity": "sha512-M68/EFCgji0DI+DgULx2ytUUSxwwODJDpiVc0YsiWKdyB4umKTu1GGxFfdZhXrWtPxB4aZFoIgJyDhsFxnHC4g==",
|
||||
"version": "0.14.29",
|
||||
"resolved": "https://registry.npmjs.org/esbuild-windows-32/-/esbuild-windows-32-0.14.29.tgz",
|
||||
"integrity": "sha512-uoyb0YAJ6uWH4PYuYjfGNjvgLlb5t6b3zIaGmpWPOjgpr1Nb3SJtQiK4YCPGhONgfg2v6DcJgSbOteuKXhwqAw==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"esbuild-windows-64": {
|
||||
"version": "0.14.16",
|
||||
"resolved": "https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-0.14.16.tgz",
|
||||
"integrity": "sha512-rmSal1Co749CXSNyFJ62J5Fz/nZiFWhwMfYN9SwZazutKZ6s0QDRIhnupa93bJmzMzz4C2dqUV/VL1tqOI3y9g==",
|
||||
"version": "0.14.29",
|
||||
"resolved": "https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-0.14.29.tgz",
|
||||
"integrity": "sha512-X9cW/Wl95QjsH8WUyr3NqbmfdU72jCp71cH3pwPvI4CgBM2IeOUDdbt6oIGljPu2bf5eGDIo8K3Y3vvXCCTd8A==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"esbuild-windows-arm64": {
|
||||
"version": "0.14.16",
|
||||
"resolved": "https://registry.npmjs.org/esbuild-windows-arm64/-/esbuild-windows-arm64-0.14.16.tgz",
|
||||
"integrity": "sha512-VMfEf+MDgO+rulAuSeu3HNebSHa1TDn0lJp+QRk7E2WVg9OCSwuXUEkSbqIbkif3ZjASy7h9sTCGyHcqgKQTrg==",
|
||||
"version": "0.14.29",
|
||||
"resolved": "https://registry.npmjs.org/esbuild-windows-arm64/-/esbuild-windows-arm64-0.14.29.tgz",
|
||||
"integrity": "sha512-+O/PI+68fbUZPpl3eXhqGHTGK7DjLcexNnyJqtLZXOFwoAjaXlS5UBCvVcR3o2va+AqZTj8o6URaz8D2K+yfQQ==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
@ -1996,9 +2070,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"marked": {
|
||||
"version": "4.0.10",
|
||||
"resolved": "https://registry.npmjs.org/marked/-/marked-4.0.10.tgz",
|
||||
"integrity": "sha512-+QvuFj0nGgO970fySghXGmuw+Fd0gD2x3+MqCWLIPf5oxdv1Ka6b2q+z9RP01P/IaKPMEramy+7cNy/Lw8c3hw==",
|
||||
"version": "4.0.12",
|
||||
"resolved": "https://registry.npmjs.org/marked/-/marked-4.0.12.tgz",
|
||||
"integrity": "sha512-hgibXWrEDNBWgGiK18j/4lkS6ihTe9sxtV4Q1OQppb/0zzyPSzoFANBa5MfsG/zgsWklmNnhm0XACZOH/0HBiQ==",
|
||||
"dev": true
|
||||
},
|
||||
"merge-stream": {
|
||||
@ -2141,9 +2215,9 @@
|
||||
}
|
||||
},
|
||||
"prettier": {
|
||||
"version": "2.5.1",
|
||||
"resolved": "https://registry.npmjs.org/prettier/-/prettier-2.5.1.tgz",
|
||||
"integrity": "sha512-vBZcPRUR5MZJwoyi3ZoyQlc1rXeEck8KgeC9AwwOn+exuxLxq5toTRDTSaVrXHxelDMHy9zlicw8u66yxoSUFg==",
|
||||
"version": "2.6.1",
|
||||
"resolved": "https://registry.npmjs.org/prettier/-/prettier-2.6.1.tgz",
|
||||
"integrity": "sha512-8UVbTBYGwN37Bs9LERmxCPjdvPxlEowx2urIL6urHzdb3SDq4B/Z6xLFCblrSnE4iKWcS6ziJ3aOYrc1kz/E2A==",
|
||||
"dev": true
|
||||
},
|
||||
"queue-microtask": {
|
||||
@ -2207,9 +2281,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"shiki": {
|
||||
"version": "0.10.0",
|
||||
"resolved": "https://registry.npmjs.org/shiki/-/shiki-0.10.0.tgz",
|
||||
"integrity": "sha512-iczxaIYeBFHTFrQPb9DVy2SKgYxC4Wo7Iucm7C17cCh2Ge/refnvHscUOxM85u57MfLoNOtjoEFUWt9gBexblA==",
|
||||
"version": "0.10.1",
|
||||
"resolved": "https://registry.npmjs.org/shiki/-/shiki-0.10.1.tgz",
|
||||
"integrity": "sha512-VsY7QJVzU51j5o1+DguUd+6vmCmZ5v/6gYu4vyYAhzjuNQU6P/vmSy4uQaOhvje031qQMiW0d2BwgMH52vqMng==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"jsonc-parser": "^3.0.0",
|
||||
@ -2311,16 +2385,16 @@
|
||||
"dev": true
|
||||
},
|
||||
"tsup": {
|
||||
"version": "5.11.13",
|
||||
"resolved": "https://registry.npmjs.org/tsup/-/tsup-5.11.13.tgz",
|
||||
"integrity": "sha512-NVMK01gVmojZn7+iZwxRK1CzW2BIabaVMyEjs7Nm9lm4DrSf7IAqs2F3fg0vT7rH72x1cIBsW9U/TlWrCvHVQQ==",
|
||||
"version": "5.12.2",
|
||||
"resolved": "https://registry.npmjs.org/tsup/-/tsup-5.12.2.tgz",
|
||||
"integrity": "sha512-CZcM4UGYlKcdQzDIJbrwgpn4sQe8zobnHRgAF6C8RpMGvfRov9ipSQY3mjjnZRAkEZQO1+Jr3cxeaQJjY/iVTg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"bundle-require": "^3.0.2",
|
||||
"cac": "^6.7.12",
|
||||
"chokidar": "^3.5.1",
|
||||
"debug": "^4.3.1",
|
||||
"esbuild": "^0.14.2",
|
||||
"esbuild": "^0.14.25",
|
||||
"execa": "^5.0.0",
|
||||
"globby": "^11.0.3",
|
||||
"joycon": "^3.0.1",
|
||||
@ -2333,16 +2407,36 @@
|
||||
}
|
||||
},
|
||||
"typedoc": {
|
||||
"version": "0.22.12",
|
||||
"resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.22.12.tgz",
|
||||
"integrity": "sha512-FcyC+YuaOpr3rB9QwA1IHOi9KnU2m50sPJW5vcNRPCIdecp+3bFkh7Rq5hBU1Fyn29UR2h4h/H7twZHWDhL0sw==",
|
||||
"version": "0.22.13",
|
||||
"resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.22.13.tgz",
|
||||
"integrity": "sha512-NHNI7Dr6JHa/I3+c62gdRNXBIyX7P33O9TafGLd07ur3MqzcKgwTvpg18EtvCLHJyfeSthAtCLpM7WkStUmDuQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"glob": "^7.2.0",
|
||||
"lunr": "^2.3.9",
|
||||
"marked": "^4.0.10",
|
||||
"minimatch": "^3.0.4",
|
||||
"shiki": "^0.10.0"
|
||||
"marked": "^4.0.12",
|
||||
"minimatch": "^5.0.1",
|
||||
"shiki": "^0.10.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"brace-expansion": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
|
||||
"integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"balanced-match": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"minimatch": {
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.0.1.tgz",
|
||||
"integrity": "sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"brace-expansion": "^2.0.1"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"typedoc-plugin-extras": {
|
||||
@ -2360,15 +2454,15 @@
|
||||
"requires": {}
|
||||
},
|
||||
"typescript": {
|
||||
"version": "4.6.2",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.6.2.tgz",
|
||||
"integrity": "sha512-HM/hFigTBHZhLXshn9sN37H085+hQGeJHJ/X7LpBWLID/fbc2acUMfU+lGD98X81sKP+pFa9f0DZmCwB9GnbAg==",
|
||||
"version": "4.6.3",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.6.3.tgz",
|
||||
"integrity": "sha512-yNIatDa5iaofVozS/uQJEl3JRWLKKGJKh6Yaiv0GLGSuhpFJe7P3SbHZ8/yjAHRQwKRoA6YZqlfjXWmVzoVSMw==",
|
||||
"dev": true
|
||||
},
|
||||
"vscode-oniguruma": {
|
||||
"version": "1.6.1",
|
||||
"resolved": "https://registry.npmjs.org/vscode-oniguruma/-/vscode-oniguruma-1.6.1.tgz",
|
||||
"integrity": "sha512-vc4WhSIaVpgJ0jJIejjYxPvURJavX6QG41vu0mGhqywMkQqulezEqEQ3cO3gc8GvcOpX6ycmKGqRoROEMBNXTQ==",
|
||||
"version": "1.6.2",
|
||||
"resolved": "https://registry.npmjs.org/vscode-oniguruma/-/vscode-oniguruma-1.6.2.tgz",
|
||||
"integrity": "sha512-KH8+KKov5eS/9WhofZR8M8dMHWN2gTxjMsG4jd04YhpbPR91fUj7rYQ2/XjeHCJWbg7X++ApRIU9NUwM2vTvLA==",
|
||||
"dev": true
|
||||
},
|
||||
"vscode-textmate": {
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "play-dl",
|
||||
"version": "1.9.3",
|
||||
"version": "1.9.4",
|
||||
"description": "YouTube, SoundCloud, Spotify, Deezer searching and streaming for discord-js bots",
|
||||
"main": "dist/index.js",
|
||||
"typings": "dist/index.d.ts",
|
||||
|
||||
@ -1,12 +1,12 @@
|
||||
[
|
||||
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.99 Safari/537.36",
|
||||
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.80 Safari/537.36 Edg/98.0.1108.50",
|
||||
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.102 Safari/537.36",
|
||||
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.102 Safari/537.36",
|
||||
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.102 Safari/537.36",
|
||||
"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.80 Safari/537.36",
|
||||
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.102 Safari/537.36",
|
||||
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.102 Safari/537.36 Edg/98.0.1108.62",
|
||||
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.102 Safari/537.36",
|
||||
"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.51 Safari/537.36",
|
||||
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.119 YaBrowser/22.3.0.2430 Yowser/2.5 Safari/537.36",
|
||||
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.82 Safari/537.36",
|
||||
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.84 Safari/537.36",
|
||||
"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.74 Safari/537.36",
|
||||
"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.84 Safari/537.36",
|
||||
"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.82 Safari/537.36",
|
||||
"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) QtWebEngine/5.15.3 Chrome/87.0.4280.144 Safari/537.36",
|
||||
"Mozilla/5.0 (Windows NT 6.1; ) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.129 Safari/537.36",
|
||||
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.102 Safari/537.36"
|
||||
]
|
||||
@ -1,855 +0,0 @@
|
||||
import { request } from './../../Request/index';
|
||||
import { format_decipher } from './cipher';
|
||||
import { VideoChapter, YouTubeVideo } from '../classes/Video';
|
||||
import { YouTubePlayList } from '../classes/Playlist';
|
||||
import { InfoData, StreamInfoData } from './constants';
|
||||
import { URL, URLSearchParams } from 'node:url';
|
||||
import { parseAudioFormats } from '../stream';
|
||||
|
||||
interface InfoOptions {
|
||||
htmldata?: boolean;
|
||||
language?: string;
|
||||
}
|
||||
|
||||
interface PlaylistOptions {
|
||||
incomplete?: boolean;
|
||||
language?: string;
|
||||
}
|
||||
|
||||
const video_id_pattern = /^[a-zA-Z\d_-]{11,12}$/;
|
||||
const playlist_id_pattern = /^(PL|UU|LL|RD|OL)[a-zA-Z\d_-]{10,}$/;
|
||||
const DEFAULT_API_KEY = 'AIzaSyAO_FJ2SlqU8Q4STEHLGCilw_Y9_11qcW8';
|
||||
const video_pattern =
|
||||
/^((?:https?:)?\/\/)?(?:(?:www|m|music)\.)?((?:youtube\.com|youtu.be))(\/(?:[\w\-]+\?v=|shorts\/|embed\/|v\/)?)([\w\-]+)(\S+)?$/;
|
||||
const playlist_pattern =
|
||||
/^((?:https?:)?\/\/)?(?:(?:www|m|music)\.)?((?:youtube\.com|youtu.be))\/(?:(playlist|watch))?(.*)?((\?|\&)list=)(PL|UU|LL|RD|OL)[a-zA-Z\d_-]{10,}(&.*)?$/;
|
||||
/**
|
||||
* Validate YouTube URL or ID.
|
||||
*
|
||||
* **CAUTION :** If your search word is 11 or 12 characters long, you might get it validated as video ID.
|
||||
*
|
||||
* To avoid above, add one more condition to yt_validate
|
||||
* ```ts
|
||||
* if (url.startsWith('https') && yt_validate(url) === 'video') {
|
||||
* // YouTube Video Url.
|
||||
* }
|
||||
* ```
|
||||
* @param url YouTube URL OR ID
|
||||
* @returns
|
||||
* ```
|
||||
* 'playlist' | 'video' | 'search' | false
|
||||
* ```
|
||||
*/
|
||||
export function yt_validate(url: string): 'playlist' | 'video' | 'search' | false {
|
||||
const url_ = url.trim();
|
||||
if (url_.indexOf('list=') === -1) {
|
||||
if (url_.startsWith('https')) {
|
||||
if (url_.match(video_pattern)) {
|
||||
let id: string;
|
||||
if (url_.includes('youtu.be/')) id = url_.split('youtu.be/')[1].split(/(\?|\/|&)/)[0];
|
||||
else if (url_.includes('youtube.com/embed/'))
|
||||
id = url_.split('youtube.com/embed/')[1].split(/(\?|\/|&)/)[0];
|
||||
else if (url_.includes('youtube.com/shorts/'))
|
||||
id = url_.split('youtube.com/shorts/')[1].split(/(\?|\/|&)/)[0];
|
||||
else id = url_.split('watch?v=')[1]?.split(/(\?|\/|&)/)[0];
|
||||
if (id?.match(video_id_pattern)) return 'video';
|
||||
else return false;
|
||||
} else return false;
|
||||
} else {
|
||||
if (url_.match(video_id_pattern)) return 'video';
|
||||
else if (url_.match(playlist_id_pattern)) return 'playlist';
|
||||
else return 'search';
|
||||
}
|
||||
} else {
|
||||
if (!url_.match(playlist_pattern)) return yt_validate(url_.replace(/(\?|\&)list=[^&]+/, ''));
|
||||
else return 'playlist';
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Extracts the video ID from a YouTube URL.
|
||||
*
|
||||
* Will return the value of `urlOrId` if it looks like a video ID.
|
||||
* @param urlOrId A YouTube URL or video ID
|
||||
* @returns the video ID or `false` if it can't find a video ID.
|
||||
*/
|
||||
function extractVideoId(urlOrId: string): string | false {
|
||||
if (urlOrId.startsWith('https://') && urlOrId.match(video_pattern)) {
|
||||
let id: string;
|
||||
if (urlOrId.includes('youtu.be/')) {
|
||||
id = urlOrId.split('youtu.be/')[1].split(/(\?|\/|&)/)[0];
|
||||
} else if (urlOrId.includes('youtube.com/embed/')) {
|
||||
id = urlOrId.split('youtube.com/embed/')[1].split(/(\?|\/|&)/)[0];
|
||||
} else if (urlOrId.includes('youtube.com/shorts/')) {
|
||||
id = urlOrId.split('youtube.com/shorts/')[1].split(/(\?|\/|&)/)[0];
|
||||
} else {
|
||||
id = (urlOrId.split('watch?v=')[1] ?? urlOrId.split('&v=')[1]).split(/(\?|\/|&)/)[0];
|
||||
}
|
||||
|
||||
if (id.match(video_id_pattern)) return id;
|
||||
} else if (urlOrId.match(video_id_pattern)) {
|
||||
return urlOrId;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
/**
|
||||
* Extract ID of YouTube url.
|
||||
* @param url ID or url of YouTube
|
||||
* @returns ID of video or playlist.
|
||||
*/
|
||||
export function extractID(url: string): string {
|
||||
const check = yt_validate(url);
|
||||
if (!check || check === 'search') throw new Error('This is not a YouTube url or videoId or PlaylistID');
|
||||
const url_ = url.trim();
|
||||
if (url_.startsWith('https')) {
|
||||
if (url_.indexOf('list=') === -1) {
|
||||
const video_id = extractVideoId(url_);
|
||||
if (!video_id) throw new Error('This is not a YouTube url or videoId or PlaylistID');
|
||||
return video_id;
|
||||
} else {
|
||||
return url_.split('list=')[1].split('&')[0];
|
||||
}
|
||||
} else return url_;
|
||||
}
|
||||
/**
|
||||
* Basic function to get data from a YouTube url or ID.
|
||||
*
|
||||
* Example
|
||||
* ```ts
|
||||
* const video = await play.video_basic_info('youtube video url')
|
||||
*
|
||||
* const res = ... // Any https package get function.
|
||||
*
|
||||
* const video = await play.video_basic_info(res.body, { htmldata : true })
|
||||
* ```
|
||||
* @param url YouTube url or ID or html body data
|
||||
* @param options Video Info Options
|
||||
* - `boolean` htmldata : given data is html data or not
|
||||
* @returns Video Basic Info {@link InfoData}.
|
||||
*/
|
||||
export async function video_basic_info(url: string, options: InfoOptions = {}): Promise<InfoData> {
|
||||
if (typeof url !== 'string') throw new Error('url parameter is not a URL string or a string of HTML');
|
||||
const url_ = url.trim();
|
||||
let body: string;
|
||||
const cookieJar = {};
|
||||
if (options.htmldata) {
|
||||
body = url_;
|
||||
} else {
|
||||
const video_id = extractVideoId(url_);
|
||||
if (!video_id) throw new Error('This is not a YouTube Watch URL');
|
||||
const new_url = `https://www.youtube.com/watch?v=${video_id}&has_verified=1`;
|
||||
body = await request(new_url, {
|
||||
headers: {
|
||||
'accept-language': options.language || 'en-US;q=0.9'
|
||||
},
|
||||
cookies: true,
|
||||
cookieJar
|
||||
});
|
||||
}
|
||||
if (body.indexOf('Our systems have detected unusual traffic from your computer network.') !== -1)
|
||||
throw new Error('Captcha page: YouTube has detected that you are a bot!');
|
||||
const player_data = body
|
||||
.split('var ytInitialPlayerResponse = ')?.[1]
|
||||
?.split(';</script>')[0]
|
||||
.split(/;\s*(var|const|let)\s/)[0];
|
||||
if (!player_data) throw new Error('Initial Player Response Data is undefined.');
|
||||
const initial_data = body
|
||||
.split('var ytInitialData = ')?.[1]
|
||||
?.split(';</script>')[0]
|
||||
.split(/;\s*(var|const|let)\s/)[0];
|
||||
if (!initial_data) throw new Error('Initial Response Data is undefined.');
|
||||
const player_response = JSON.parse(player_data);
|
||||
const initial_response = JSON.parse(initial_data);
|
||||
const vid = player_response.videoDetails;
|
||||
|
||||
let discretionAdvised = false;
|
||||
let upcoming = false;
|
||||
if (player_response.playabilityStatus.status !== 'OK') {
|
||||
if (player_response.playabilityStatus.status === 'CONTENT_CHECK_REQUIRED') {
|
||||
if (options.htmldata)
|
||||
throw new Error(
|
||||
`Accepting the viewer discretion is not supported when using htmldata, video: ${vid.videoId}`
|
||||
);
|
||||
discretionAdvised = true;
|
||||
const cookies =
|
||||
initial_response.topbar.desktopTopbarRenderer.interstitial?.consentBumpV2Renderer.agreeButton
|
||||
.buttonRenderer.command.saveConsentAction;
|
||||
if (cookies) {
|
||||
Object.assign(cookieJar, {
|
||||
VISITOR_INFO1_LIVE: cookies.visitorCookie,
|
||||
CONSENT: cookies.consentCookie
|
||||
});
|
||||
}
|
||||
|
||||
const updatedValues = await acceptViewerDiscretion(vid.videoId, cookieJar, body, true);
|
||||
player_response.streamingData = updatedValues.streamingData;
|
||||
initial_response.contents.twoColumnWatchNextResults.secondaryResults = updatedValues.relatedVideos;
|
||||
} else if (player_response.playabilityStatus.status === 'LIVE_STREAM_OFFLINE') upcoming = true;
|
||||
else
|
||||
throw new Error(
|
||||
`While getting info from url\n${
|
||||
player_response.playabilityStatus.errorScreen.playerErrorMessageRenderer?.reason.simpleText ??
|
||||
player_response.playabilityStatus.errorScreen.playerKavRenderer?.reason.simpleText
|
||||
}`
|
||||
);
|
||||
}
|
||||
const ownerInfo =
|
||||
initial_response.contents.twoColumnWatchNextResults.results?.results?.contents[1]?.videoSecondaryInfoRenderer
|
||||
?.owner?.videoOwnerRenderer;
|
||||
const badge = ownerInfo?.badges?.[0]?.metadataBadgeRenderer?.style?.toLowerCase();
|
||||
const html5player = `https://www.youtube.com${body.split('"jsUrl":"')[1].split('"')[0]}`;
|
||||
const related: string[] = [];
|
||||
initial_response.contents.twoColumnWatchNextResults.secondaryResults.secondaryResults.results.forEach(
|
||||
(res: any) => {
|
||||
if (res.compactVideoRenderer)
|
||||
related.push(`https://www.youtube.com/watch?v=${res.compactVideoRenderer.videoId}`);
|
||||
if (res.itemSectionRenderer?.contents)
|
||||
res.itemSectionRenderer.contents.forEach((x: any) => {
|
||||
if (x.compactVideoRenderer)
|
||||
related.push(`https://www.youtube.com/watch?v=${x.compactVideoRenderer.videoId}`);
|
||||
});
|
||||
}
|
||||
);
|
||||
const microformat = player_response.microformat.playerMicroformatRenderer;
|
||||
const musicInfo =
|
||||
initial_response.contents.twoColumnWatchNextResults.results.results.contents?.[1]?.videoSecondaryInfoRenderer
|
||||
?.metadataRowContainer?.metadataRowContainerRenderer?.rows;
|
||||
const music: any[] = [];
|
||||
if (musicInfo) {
|
||||
musicInfo.forEach((x: any) => {
|
||||
if (!x.metadataRowRenderer) return;
|
||||
const title = x.metadataRowRenderer.title.simpleText ?? x.metadataRowRenderer.title.runs[0].text;
|
||||
let text = x.metadataRowRenderer.contents[0].simpleText ?? x.metadataRowRenderer.contents[0]?.runs?.[0]?.text;
|
||||
let url = x.metadataRowRenderer.contents[0]?.runs?.[0]?.navigationEndpoint?.commandMetadata?.webCommandMetadata.url;
|
||||
if (title.toLowerCase() === 'song') {
|
||||
music.push({});
|
||||
music[music.length - 1].song = {text, url: url ? `https://www.youtube.com${url}` : undefined};
|
||||
} else if (music.length === 0) return;
|
||||
else {
|
||||
music[music.length - 1][title.toLowerCase()] = url ? {text, url: `https://www.youtube.com${url}`} : text;
|
||||
}
|
||||
});
|
||||
}
|
||||
const rawChapters =
|
||||
initial_response.playerOverlays.playerOverlayRenderer.decoratedPlayerBarRenderer.decoratedPlayerBarRenderer.playerBar?.multiMarkersPlayerBarRenderer.markersMap.find(
|
||||
(m: any) => m.key === 'DESCRIPTION_CHAPTERS'
|
||||
)?.value?.chapters;
|
||||
const chapters: VideoChapter[] = [];
|
||||
if (rawChapters) {
|
||||
for (const { chapterRenderer } of rawChapters) {
|
||||
chapters.push({
|
||||
title: chapterRenderer.title.simpleText,
|
||||
timestamp: parseSeconds(chapterRenderer.timeRangeStartMillis / 1000),
|
||||
seconds: chapterRenderer.timeRangeStartMillis / 1000,
|
||||
thumbnails: chapterRenderer.thumbnail.thumbnails
|
||||
});
|
||||
}
|
||||
}
|
||||
let upcomingDate;
|
||||
if (upcoming) {
|
||||
if (microformat.liveBroadcastDetails.startTimestamp)
|
||||
upcomingDate = new Date(microformat.liveBroadcastDetails.startTimestamp);
|
||||
else {
|
||||
const timestamp =
|
||||
player_response.playabilityStatus.liveStreamability.liveStreamabilityRenderer.offlineSlate
|
||||
.liveStreamOfflineSlateRenderer.scheduledStartTime;
|
||||
upcomingDate = new Date(parseInt(timestamp) * 1000);
|
||||
}
|
||||
}
|
||||
const video_details = new YouTubeVideo({
|
||||
id: vid.videoId,
|
||||
title: vid.title,
|
||||
description: vid.shortDescription,
|
||||
duration: Number(vid.lengthSeconds),
|
||||
duration_raw: parseSeconds(vid.lengthSeconds),
|
||||
uploadedAt: microformat.publishDate,
|
||||
liveAt: microformat.liveBroadcastDetails?.startTimestamp,
|
||||
upcoming: upcomingDate,
|
||||
thumbnails: vid.thumbnail.thumbnails,
|
||||
channel: {
|
||||
name: vid.author,
|
||||
id: vid.channelId,
|
||||
url: `https://www.youtube.com/channel/${vid.channelId}`,
|
||||
verified: Boolean(badge?.includes('verified')),
|
||||
artist: Boolean(badge?.includes('artist')),
|
||||
icons: ownerInfo?.thumbnail?.thumbnails || undefined
|
||||
},
|
||||
views: vid.viewCount,
|
||||
tags: vid.keywords,
|
||||
likes: parseInt(
|
||||
initial_response.contents.twoColumnWatchNextResults.results.results.contents
|
||||
.find((content: any) => content.videoPrimaryInfoRenderer)
|
||||
?.videoPrimaryInfoRenderer.videoActions.menuRenderer.topLevelButtons?.find(
|
||||
(button: any) => button.toggleButtonRenderer.defaultIcon.iconType === 'LIKE'
|
||||
)
|
||||
?.toggleButtonRenderer.defaultText.accessibility?.accessibilityData.label.replace(/\D+/g, '') ?? 0
|
||||
),
|
||||
live: vid.isLiveContent,
|
||||
private: vid.isPrivate,
|
||||
discretionAdvised,
|
||||
music,
|
||||
chapters
|
||||
});
|
||||
let format = [];
|
||||
if (!upcoming) {
|
||||
format.push(...(player_response.streamingData.formats ?? []));
|
||||
format.push(...(player_response.streamingData.adaptiveFormats ?? []));
|
||||
|
||||
// get the formats for the android player for legacy videos
|
||||
// fixes the stream being closed because not enough data
|
||||
// arrived in time for ffmpeg to be able to extract audio data
|
||||
if (parseAudioFormats(format).length === 0 && !options.htmldata) {
|
||||
format = await getAndroidFormats(vid.videoId, cookieJar, body);
|
||||
}
|
||||
}
|
||||
const LiveStreamData = {
|
||||
isLive: video_details.live,
|
||||
dashManifestUrl: player_response.streamingData?.dashManifestUrl ?? null,
|
||||
hlsManifestUrl: player_response.streamingData?.hlsManifestUrl ?? null
|
||||
};
|
||||
return {
|
||||
LiveStreamData,
|
||||
html5player,
|
||||
format,
|
||||
video_details,
|
||||
related_videos: related
|
||||
};
|
||||
}
|
||||
/**
|
||||
* Gets the data required for streaming from YouTube url, ID or html body data and deciphers it.
|
||||
*
|
||||
* Internal function used by {@link stream} instead of {@link video_info}
|
||||
* because it only extracts the information required for streaming.
|
||||
*
|
||||
* @param url YouTube url or ID or html body data
|
||||
* @param options Video Info Options
|
||||
* - `boolean` htmldata : given data is html data or not
|
||||
* @returns Deciphered Video Info {@link StreamInfoData}.
|
||||
*/
|
||||
export async function video_stream_info(url: string, options: InfoOptions = {}): Promise<StreamInfoData> {
|
||||
if (typeof url !== 'string') throw new Error('url parameter is not a URL string or a string of HTML');
|
||||
let body: string;
|
||||
const cookieJar = {};
|
||||
if (options.htmldata) {
|
||||
body = url;
|
||||
} else {
|
||||
const video_id = extractVideoId(url);
|
||||
if (!video_id) throw new Error('This is not a YouTube Watch URL');
|
||||
const new_url = `https://www.youtube.com/watch?v=${video_id}&has_verified=1`;
|
||||
body = await request(new_url, {
|
||||
headers: { 'accept-language': 'en-US,en;q=0.9' },
|
||||
cookies: true,
|
||||
cookieJar
|
||||
});
|
||||
}
|
||||
if (body.indexOf('Our systems have detected unusual traffic from your computer network.') !== -1)
|
||||
throw new Error('Captcha page: YouTube has detected that you are a bot!');
|
||||
const player_data = body
|
||||
.split('var ytInitialPlayerResponse = ')?.[1]
|
||||
?.split(';</script>')[0]
|
||||
.split(/;\s*(var|const|let)\s/)[0];
|
||||
if (!player_data) throw new Error('Initial Player Response Data is undefined.');
|
||||
const player_response = JSON.parse(player_data);
|
||||
let upcoming = false;
|
||||
if (player_response.playabilityStatus.status !== 'OK') {
|
||||
if (player_response.playabilityStatus.status === 'CONTENT_CHECK_REQUIRED') {
|
||||
if (options.htmldata)
|
||||
throw new Error(
|
||||
`Accepting the viewer discretion is not supported when using htmldata, video: ${player_response.videoDetails.videoId}`
|
||||
);
|
||||
|
||||
const initial_data = body
|
||||
.split('var ytInitialData = ')?.[1]
|
||||
?.split(';</script>')[0]
|
||||
.split(/;\s*(var|const|let)\s/)[0];
|
||||
if (!initial_data) throw new Error('Initial Response Data is undefined.');
|
||||
|
||||
const cookies =
|
||||
JSON.parse(initial_data).topbar.desktopTopbarRenderer.interstitial?.consentBumpV2Renderer.agreeButton
|
||||
.buttonRenderer.command.saveConsentAction;
|
||||
if (cookies) {
|
||||
Object.assign(cookieJar, {
|
||||
VISITOR_INFO1_LIVE: cookies.visitorCookie,
|
||||
CONSENT: cookies.consentCookie
|
||||
});
|
||||
}
|
||||
|
||||
const updatedValues = await acceptViewerDiscretion(
|
||||
player_response.videoDetails.videoId,
|
||||
cookieJar,
|
||||
body,
|
||||
false
|
||||
);
|
||||
player_response.streamingData = updatedValues.streamingData;
|
||||
} else if (player_response.playabilityStatus.status === 'LIVE_STREAM_OFFLINE') upcoming = true;
|
||||
else
|
||||
throw new Error(
|
||||
`While getting info from url\n${
|
||||
player_response.playabilityStatus.errorScreen.playerErrorMessageRenderer?.reason.simpleText ??
|
||||
player_response.playabilityStatus.errorScreen.playerKavRenderer?.reason.simpleText
|
||||
}`
|
||||
);
|
||||
}
|
||||
const html5player = `https://www.youtube.com${body.split('"jsUrl":"')[1].split('"')[0]}`;
|
||||
const duration = Number(player_response.videoDetails.lengthSeconds);
|
||||
const video_details = {
|
||||
url: `https://www.youtube.com/watch?v=${player_response.videoDetails.videoId}`,
|
||||
durationInSec: (duration < 0 ? 0 : duration) || 0
|
||||
};
|
||||
let format = [];
|
||||
if (!upcoming) {
|
||||
format.push(...(player_response.streamingData.formats ?? []));
|
||||
format.push(...(player_response.streamingData.adaptiveFormats ?? []));
|
||||
|
||||
// get the formats for the android player for legacy videos
|
||||
// fixes the stream being closed because not enough data
|
||||
// arrived in time for ffmpeg to be able to extract audio data
|
||||
if (parseAudioFormats(format).length === 0 && !options.htmldata) {
|
||||
format = await getAndroidFormats(player_response.videoDetails.videoId, cookieJar, body);
|
||||
}
|
||||
}
|
||||
|
||||
const LiveStreamData = {
|
||||
isLive: player_response.videoDetails.isLiveContent,
|
||||
dashManifestUrl: player_response.streamingData?.dashManifestUrl ?? null,
|
||||
hlsManifestUrl: player_response.streamingData?.hlsManifestUrl ?? null
|
||||
};
|
||||
return await decipher_info(
|
||||
{
|
||||
LiveStreamData,
|
||||
html5player,
|
||||
format,
|
||||
video_details
|
||||
},
|
||||
true
|
||||
);
|
||||
}
|
||||
/**
|
||||
* Function to convert seconds to [hour : minutes : seconds] format
|
||||
* @param seconds seconds to convert
|
||||
* @returns [hour : minutes : seconds] format
|
||||
*/
|
||||
function parseSeconds(seconds: number): string {
|
||||
const d = Number(seconds);
|
||||
const h = Math.floor(d / 3600);
|
||||
const m = Math.floor((d % 3600) / 60);
|
||||
const s = Math.floor((d % 3600) % 60);
|
||||
|
||||
const hDisplay = h > 0 ? (h < 10 ? `0${h}` : h) + ':' : '';
|
||||
const mDisplay = m > 0 ? (m < 10 ? `0${m}` : m) + ':' : '00:';
|
||||
const sDisplay = s > 0 ? (s < 10 ? `0${s}` : s) : '00';
|
||||
return hDisplay + mDisplay + sDisplay;
|
||||
}
|
||||
/**
|
||||
* Gets data from YouTube url or ID or html body data and deciphers it.
|
||||
* ```
|
||||
* video_basic_info + decipher_info = video_info
|
||||
* ```
|
||||
*
|
||||
* Example
|
||||
* ```ts
|
||||
* const video = await play.video_info('youtube video url')
|
||||
*
|
||||
* const res = ... // Any https package get function.
|
||||
*
|
||||
* const video = await play.video_info(res.body, { htmldata : true })
|
||||
* ```
|
||||
* @param url YouTube url or ID or html body data
|
||||
* @param options Video Info Options
|
||||
* - `boolean` htmldata : given data is html data or not
|
||||
* @returns Deciphered Video Info {@link InfoData}.
|
||||
*/
|
||||
export async function video_info(url: string, options: InfoOptions = {}): Promise<InfoData> {
|
||||
const data = await video_basic_info(url.trim(), options);
|
||||
return await decipher_info(data);
|
||||
}
|
||||
/**
|
||||
* Function uses data from video_basic_info and deciphers it if it contains signatures.
|
||||
* @param data Data - {@link InfoData}
|
||||
* @param audio_only `boolean` - To decipher only audio formats only.
|
||||
* @returns Deciphered Video Info {@link InfoData}
|
||||
*/
|
||||
export async function decipher_info<T extends InfoData | StreamInfoData>(
|
||||
data: T,
|
||||
audio_only: boolean = false
|
||||
): Promise<T> {
|
||||
if (
|
||||
data.LiveStreamData.isLive === true &&
|
||||
data.LiveStreamData.dashManifestUrl !== null &&
|
||||
data.video_details.durationInSec === 0
|
||||
) {
|
||||
return data;
|
||||
} else if (data.format.length > 0 && (data.format[0].signatureCipher || data.format[0].cipher)) {
|
||||
if (audio_only) data.format = parseAudioFormats(data.format);
|
||||
data.format = await format_decipher(data.format, data.html5player);
|
||||
return data;
|
||||
} else return data;
|
||||
}
|
||||
/**
|
||||
* Gets YouTube playlist info from a playlist url.
|
||||
*
|
||||
* Example
|
||||
* ```ts
|
||||
* const playlist = await play.playlist_info('youtube playlist url')
|
||||
*
|
||||
* const playlist = await play.playlist_info('youtube playlist url', { incomplete : true })
|
||||
* ```
|
||||
* @param url Playlist URL
|
||||
* @param options Playlist Info Options
|
||||
* - `boolean` incomplete : When this is set to `false` (default) this function will throw an error
|
||||
* if the playlist contains hidden videos.
|
||||
* If it is set to `true`, it parses the playlist skipping the hidden videos,
|
||||
* only visible videos are included in the resulting {@link YouTubePlaylist}.
|
||||
*
|
||||
* @returns YouTube Playlist
|
||||
*/
|
||||
export async function playlist_info(url: string, options: PlaylistOptions = {}): Promise<YouTubePlayList> {
|
||||
if (!url || typeof url !== 'string') throw new Error(`Expected playlist url, received ${typeof url}!`);
|
||||
let url_ = url.trim();
|
||||
if (!url_.startsWith('https')) url_ = `https://www.youtube.com/playlist?list=${url_}`;
|
||||
if (url_.indexOf('list=') === -1) throw new Error('This is not a Playlist URL');
|
||||
|
||||
if (url_.includes('music.youtube.com')) {
|
||||
const urlObj = new URL(url_);
|
||||
urlObj.hostname = 'www.youtube.com';
|
||||
url_ = urlObj.toString();
|
||||
}
|
||||
|
||||
const body = await request(url_, {
|
||||
headers: {
|
||||
'accept-language': options.language || 'en-US;q=0.9'
|
||||
}
|
||||
});
|
||||
if (body.indexOf('Our systems have detected unusual traffic from your computer network.') !== -1)
|
||||
throw new Error('Captcha page: YouTube has detected that you are a bot!');
|
||||
const response = JSON.parse(
|
||||
body
|
||||
.split('var ytInitialData = ')[1]
|
||||
.split(';</script>')[0]
|
||||
.split(/;\s*(var|const|let)\s/)[0]
|
||||
);
|
||||
if (response.alerts) {
|
||||
if (response.alerts[0].alertWithButtonRenderer?.type === 'INFO') {
|
||||
if (!options.incomplete)
|
||||
throw new Error(
|
||||
`While parsing playlist url\n${response.alerts[0].alertWithButtonRenderer.text.simpleText}`
|
||||
);
|
||||
} else if (response.alerts[0].alertRenderer?.type === 'ERROR')
|
||||
throw new Error(`While parsing playlist url\n${response.alerts[0].alertRenderer.text.runs[0].text}`);
|
||||
else throw new Error('While parsing playlist url\nUnknown Playlist Error');
|
||||
}
|
||||
if (url_.indexOf('watch?v=') !== -1) {
|
||||
return getWatchPlaylist(response, body, url_);
|
||||
} else return getNormalPlaylist(response, body);
|
||||
}
|
||||
/**
|
||||
* Function to parse Playlist from YouTube search
|
||||
* @param data html data of that request
|
||||
* @param limit No. of videos to parse
|
||||
* @returns Array of YouTubeVideo.
|
||||
*/
|
||||
export function getPlaylistVideos(data: any, limit = Infinity): YouTubeVideo[] {
|
||||
const videos = [];
|
||||
|
||||
for (let i = 0; i < data.length; i++) {
|
||||
if (limit === videos.length) break;
|
||||
const info = data[i].playlistVideoRenderer;
|
||||
if (!info || !info.shortBylineText) continue;
|
||||
|
||||
videos.push(
|
||||
new YouTubeVideo({
|
||||
id: info.videoId,
|
||||
duration: parseInt(info.lengthSeconds) || 0,
|
||||
duration_raw: info.lengthText?.simpleText ?? '0:00',
|
||||
thumbnails: info.thumbnail.thumbnails,
|
||||
title: info.title.runs[0].text,
|
||||
upcoming: info.upcomingEventData?.startTime
|
||||
? new Date(parseInt(info.upcomingEventData.startTime) * 1000)
|
||||
: undefined,
|
||||
channel: {
|
||||
id: info.shortBylineText.runs[0].navigationEndpoint.browseEndpoint.browseId || undefined,
|
||||
name: info.shortBylineText.runs[0].text || undefined,
|
||||
url: `https://www.youtube.com${
|
||||
info.shortBylineText.runs[0].navigationEndpoint.browseEndpoint.canonicalBaseUrl ||
|
||||
info.shortBylineText.runs[0].navigationEndpoint.commandMetadata.webCommandMetadata.url
|
||||
}`,
|
||||
icon: undefined
|
||||
}
|
||||
})
|
||||
);
|
||||
}
|
||||
return videos;
|
||||
}
|
||||
/**
|
||||
* Function to get Continuation Token
|
||||
* @param data html data of playlist url
|
||||
* @returns token
|
||||
*/
|
||||
export function getContinuationToken(data: any): string {
|
||||
return data.find((x: any) => Object.keys(x)[0] === 'continuationItemRenderer')?.continuationItemRenderer
|
||||
.continuationEndpoint?.continuationCommand?.token;
|
||||
}
|
||||
|
||||
async function acceptViewerDiscretion(
|
||||
videoId: string,
|
||||
cookieJar: { [key: string]: string },
|
||||
body: string,
|
||||
extractRelated: boolean
|
||||
): Promise<{ streamingData: any; relatedVideos?: any }> {
|
||||
const apiKey =
|
||||
body.split('INNERTUBE_API_KEY":"')[1]?.split('"')[0] ??
|
||||
body.split('innertubeApiKey":"')[1]?.split('"')[0] ??
|
||||
DEFAULT_API_KEY;
|
||||
const sessionToken =
|
||||
body.split('"XSRF_TOKEN":"')[1]?.split('"')[0].replaceAll('\\u003d', '=') ??
|
||||
body.split('"xsrf_token":"')[1]?.split('"')[0].replaceAll('\\u003d', '=');
|
||||
if (!sessionToken)
|
||||
throw new Error(`Unable to extract XSRF_TOKEN to accept the viewer discretion popup for video: ${videoId}.`);
|
||||
|
||||
const verificationResponse = await request(`https://www.youtube.com/youtubei/v1/verify_age?key=${apiKey}`, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify({
|
||||
context: {
|
||||
client: {
|
||||
utcOffsetMinutes: 0,
|
||||
gl: 'US',
|
||||
hl: 'en',
|
||||
clientName: 'WEB',
|
||||
clientVersion:
|
||||
body.split('"INNERTUBE_CONTEXT_CLIENT_VERSION":"')[1]?.split('"')[0] ??
|
||||
body.split('"innertube_context_client_version":"')[1]?.split('"')[0] ??
|
||||
'<some version>'
|
||||
},
|
||||
user: {},
|
||||
request: {}
|
||||
},
|
||||
nextEndpoint: {
|
||||
urlEndpoint: {
|
||||
url: `watch?v=${videoId}`
|
||||
}
|
||||
},
|
||||
setControvercy: true
|
||||
}),
|
||||
cookies: true,
|
||||
cookieJar
|
||||
});
|
||||
|
||||
const endpoint = JSON.parse(verificationResponse).actions[0].navigateAction.endpoint;
|
||||
|
||||
const videoPage = await request(`https://www.youtube.com/${endpoint.urlEndpoint.url}&pbj=1`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/x-www-form-urlencoded'
|
||||
},
|
||||
body: new URLSearchParams([
|
||||
['command', JSON.stringify(endpoint)],
|
||||
['session_token', sessionToken]
|
||||
]).toString(),
|
||||
cookies: true,
|
||||
cookieJar
|
||||
});
|
||||
|
||||
if (videoPage.includes('<h1>Something went wrong</h1>'))
|
||||
throw new Error(`Unable to accept the viewer discretion popup for video: ${videoId}`);
|
||||
|
||||
const videoPageData = JSON.parse(videoPage);
|
||||
|
||||
if (videoPageData[2].playerResponse.playabilityStatus.status !== 'OK')
|
||||
throw new Error(
|
||||
`While getting info from url after trying to accept the discretion popup for video ${videoId}\n${
|
||||
videoPageData[2].playerResponse.playabilityStatus.errorScreen.playerErrorMessageRenderer?.reason
|
||||
.simpleText ??
|
||||
videoPageData[2].playerResponse.playabilityStatus.errorScreen.playerKavRenderer?.reason.simpleText
|
||||
}`
|
||||
);
|
||||
|
||||
const streamingData = videoPageData[2].playerResponse.streamingData;
|
||||
|
||||
if (extractRelated)
|
||||
return {
|
||||
streamingData,
|
||||
relatedVideos: videoPageData[3].response.contents.twoColumnWatchNextResults.secondaryResults
|
||||
};
|
||||
|
||||
return { streamingData };
|
||||
}
|
||||
|
||||
async function getAndroidFormats(videoId: string, cookieJar: { [key: string]: string }, body: string): Promise<any[]> {
|
||||
const apiKey =
|
||||
body.split('INNERTUBE_API_KEY":"')[1]?.split('"')[0] ??
|
||||
body.split('innertubeApiKey":"')[1]?.split('"')[0] ??
|
||||
DEFAULT_API_KEY;
|
||||
|
||||
const response = await request(`https://www.youtube.com/youtubei/v1/player?key=${apiKey}`, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify({
|
||||
context: {
|
||||
client: {
|
||||
clientName: 'ANDROID',
|
||||
clientVersion: '16.49',
|
||||
hl: 'en',
|
||||
timeZone: 'UTC',
|
||||
utcOffsetMinutes: 0
|
||||
}
|
||||
},
|
||||
videoId: videoId,
|
||||
playbackContext: { contentPlaybackContext: { html5Preference: 'HTML5_PREF_WANTS' } },
|
||||
contentCheckOk: true,
|
||||
racyCheckOk: true
|
||||
}),
|
||||
cookies: true,
|
||||
cookieJar
|
||||
});
|
||||
|
||||
return JSON.parse(response).streamingData.formats;
|
||||
}
|
||||
|
||||
function getWatchPlaylist(response: any, body: any, url: string): YouTubePlayList {
|
||||
const playlist_details = response.contents.twoColumnWatchNextResults.playlist.playlist;
|
||||
|
||||
const videos = getWatchPlaylistVideos(playlist_details.contents);
|
||||
const API_KEY =
|
||||
body.split('INNERTUBE_API_KEY":"')[1]?.split('"')[0] ??
|
||||
body.split('innertubeApiKey":"')[1]?.split('"')[0] ??
|
||||
DEFAULT_API_KEY;
|
||||
|
||||
const videoCount = playlist_details.totalVideos;
|
||||
const channel = playlist_details.shortBylineText?.runs?.[0];
|
||||
const badge = playlist_details.badges?.[0]?.metadataBadgeRenderer?.style.toLowerCase();
|
||||
|
||||
return new YouTubePlayList({
|
||||
continuation: {
|
||||
api: API_KEY,
|
||||
token: getContinuationToken(playlist_details.contents),
|
||||
clientVersion:
|
||||
body.split('"INNERTUBE_CONTEXT_CLIENT_VERSION":"')[1]?.split('"')[0] ??
|
||||
body.split('"innertube_context_client_version":"')[1]?.split('"')[0] ??
|
||||
'<some version>'
|
||||
},
|
||||
id: playlist_details.playlistId || '',
|
||||
title: playlist_details.title || '',
|
||||
videoCount: parseInt(videoCount) || 0,
|
||||
videos: videos,
|
||||
url: url,
|
||||
channel: {
|
||||
id: channel?.navigationEndpoint?.browseEndpoint?.browseId || null,
|
||||
name: channel?.text || null,
|
||||
url: `https://www.youtube.com${
|
||||
channel?.navigationEndpoint?.browseEndpoint?.canonicalBaseUrl ||
|
||||
channel?.navigationEndpoint?.commandMetadata?.webCommandMetadata?.url
|
||||
}`,
|
||||
verified: Boolean(badge?.includes('verified')),
|
||||
artist: Boolean(badge?.includes('artist'))
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function getNormalPlaylist(response: any, body: any): YouTubePlayList {
|
||||
const json_data =
|
||||
response.contents.twoColumnBrowseResultsRenderer.tabs[0].tabRenderer.content.sectionListRenderer.contents[0]
|
||||
.itemSectionRenderer.contents[0].playlistVideoListRenderer.contents;
|
||||
const playlist_details = response.sidebar.playlistSidebarRenderer.items;
|
||||
|
||||
const API_KEY =
|
||||
body.split('INNERTUBE_API_KEY":"')[1]?.split('"')[0] ??
|
||||
body.split('innertubeApiKey":"')[1]?.split('"')[0] ??
|
||||
DEFAULT_API_KEY;
|
||||
const videos = getPlaylistVideos(json_data, 100);
|
||||
|
||||
const data = playlist_details[0].playlistSidebarPrimaryInfoRenderer;
|
||||
if (!data.title.runs || !data.title.runs.length) throw new Error('Failed to Parse Playlist info.');
|
||||
|
||||
const author = playlist_details[1]?.playlistSidebarSecondaryInfoRenderer.videoOwner;
|
||||
const views = data.stats.length === 3 ? data.stats[1].simpleText.replace(/\D/g, '') : 0;
|
||||
const lastUpdate =
|
||||
data.stats
|
||||
.find((x: any) => 'runs' in x && x['runs'].find((y: any) => y.text.toLowerCase().includes('last update')))
|
||||
?.runs.pop()?.text ?? null;
|
||||
const videosCount = data.stats[0].runs[0].text.replace(/\D/g, '') || 0;
|
||||
|
||||
const res = new YouTubePlayList({
|
||||
continuation: {
|
||||
api: API_KEY,
|
||||
token: getContinuationToken(json_data),
|
||||
clientVersion:
|
||||
body.split('"INNERTUBE_CONTEXT_CLIENT_VERSION":"')[1]?.split('"')[0] ??
|
||||
body.split('"innertube_context_client_version":"')[1]?.split('"')[0] ??
|
||||
'<some version>'
|
||||
},
|
||||
id: data.title.runs[0].navigationEndpoint.watchEndpoint.playlistId,
|
||||
title: data.title.runs[0].text,
|
||||
videoCount: parseInt(videosCount) || 0,
|
||||
lastUpdate: lastUpdate,
|
||||
views: parseInt(views) || 0,
|
||||
videos: videos,
|
||||
url: `https://www.youtube.com/playlist?list=${data.title.runs[0].navigationEndpoint.watchEndpoint.playlistId}`,
|
||||
link: `https://www.youtube.com${data.title.runs[0].navigationEndpoint.commandMetadata.webCommandMetadata.url}`,
|
||||
channel: author
|
||||
? {
|
||||
name: author.videoOwnerRenderer.title.runs[0].text,
|
||||
id: author.videoOwnerRenderer.title.runs[0].navigationEndpoint.browseEndpoint.browseId,
|
||||
url: `https://www.youtube.com${
|
||||
author.videoOwnerRenderer.navigationEndpoint.commandMetadata.webCommandMetadata.url ||
|
||||
author.videoOwnerRenderer.navigationEndpoint.browseEndpoint.canonicalBaseUrl
|
||||
}`,
|
||||
icons: author.videoOwnerRenderer.thumbnail.thumbnails ?? []
|
||||
}
|
||||
: {},
|
||||
thumbnail: data.thumbnailRenderer.playlistVideoThumbnailRenderer?.thumbnail.thumbnails.length
|
||||
? data.thumbnailRenderer.playlistVideoThumbnailRenderer.thumbnail.thumbnails[
|
||||
data.thumbnailRenderer.playlistVideoThumbnailRenderer.thumbnail.thumbnails.length - 1
|
||||
]
|
||||
: null
|
||||
});
|
||||
return res;
|
||||
}
|
||||
|
||||
function getWatchPlaylistVideos(data: any, limit = Infinity): YouTubeVideo[] {
|
||||
const videos: YouTubeVideo[] = [];
|
||||
|
||||
for (let i = 0; i < data.length; i++) {
|
||||
if (limit === videos.length) break;
|
||||
const info = data[i].playlistPanelVideoRenderer;
|
||||
if (!info || !info.shortBylineText) continue;
|
||||
const channel_info = info.shortBylineText.runs[0];
|
||||
|
||||
videos.push(
|
||||
new YouTubeVideo({
|
||||
id: info.videoId,
|
||||
duration: parseDuration(info.lengthText?.simpleText) || 0,
|
||||
duration_raw: info.lengthText?.simpleText ?? '0:00',
|
||||
thumbnails: info.thumbnail.thumbnails,
|
||||
title: info.title.simpleText,
|
||||
upcoming:
|
||||
info.thumbnailOverlays[0].thumbnailOverlayTimeStatusRenderer.style === 'UPCOMING' || undefined,
|
||||
channel: {
|
||||
id: channel_info.navigationEndpoint.browseEndpoint.browseId || undefined,
|
||||
name: channel_info.text || undefined,
|
||||
url: `https://www.youtube.com${
|
||||
channel_info.navigationEndpoint.browseEndpoint.canonicalBaseUrl ||
|
||||
channel_info.navigationEndpoint.commandMetadata.webCommandMetadata.url
|
||||
}`,
|
||||
icon: undefined
|
||||
}
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
return videos;
|
||||
}
|
||||
|
||||
function parseDuration(text: string): number {
|
||||
if (!text) return 0;
|
||||
const split = text.split(':');
|
||||
|
||||
switch (split.length) {
|
||||
case 2:
|
||||
return parseInt(split[0]) * 60 + parseInt(split[1]);
|
||||
|
||||
case 3:
|
||||
return parseInt(split[0]) * 60 * 60 + parseInt(split[1]) * 60 + parseInt(split[2]);
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user