mirror of
https://github.com/KRTirtho/spotube.git
synced 2025-09-13 07:55:18 +00:00
New logging architecture for better debugging
This commit is contained in:
parent
7024da3fed
commit
d0fde48971
1
.gitignore
vendored
1
.gitignore
vendored
@ -19,3 +19,4 @@ aur-struct/*.zip*
|
|||||||
aur-struct/*.zst
|
aur-struct/*.zst
|
||||||
|
|
||||||
*.tsbuildinfo
|
*.tsbuildinfo
|
||||||
|
tsconfig.tsbuildinfo
|
||||||
|
387
package-lock.json
generated
387
package-lock.json
generated
@ -5,6 +5,7 @@
|
|||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
|
"name": "spotube",
|
||||||
"version": "0.0.3",
|
"version": "0.0.3",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@ -30,6 +31,8 @@
|
|||||||
"scrape-yt": "^1.4.7",
|
"scrape-yt": "^1.4.7",
|
||||||
"spotify-web-api-node": "^5.0.2",
|
"spotify-web-api-node": "^5.0.2",
|
||||||
"uuid": "^8.3.2",
|
"uuid": "^8.3.2",
|
||||||
|
"winston": "^3.3.3",
|
||||||
|
"youtubei": "^0.0.1-rc.27",
|
||||||
"ytdl-core": "^4.5.0"
|
"ytdl-core": "^4.5.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
@ -534,6 +537,16 @@
|
|||||||
"to-fast-properties": "^2.0.0"
|
"to-fast-properties": "^2.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@dabh/diagnostics": {
|
||||||
|
"version": "2.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@dabh/diagnostics/-/diagnostics-2.0.2.tgz",
|
||||||
|
"integrity": "sha512-+A1YivoVDNNVCdfozHSR8v/jyuuLTMXwjWuxPFlFlUapXoGc+Gj9mDlTDDfrwl7rXCl2tNZ0kE8sIBO6YOn96Q==",
|
||||||
|
"dependencies": {
|
||||||
|
"colorspace": "1.1.x",
|
||||||
|
"enabled": "2.0.x",
|
||||||
|
"kuler": "^2.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@discoveryjs/json-ext": {
|
"node_modules/@discoveryjs/json-ext": {
|
||||||
"version": "0.5.2",
|
"version": "0.5.2",
|
||||||
"resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.2.tgz",
|
"resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.2.tgz",
|
||||||
@ -2194,6 +2207,11 @@
|
|||||||
"node": ">=8"
|
"node": ">=8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/async": {
|
||||||
|
"version": "3.2.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/async/-/async-3.2.2.tgz",
|
||||||
|
"integrity": "sha512-H0E+qZaDEfx/FY4t7iLRv1W2fFI6+pyCeTw1uN20AQPiwqwM6ojPxHxdLv4z8hi2DtnW9BOckSspLucW7pIE5g=="
|
||||||
|
},
|
||||||
"node_modules/asynckit": {
|
"node_modules/asynckit": {
|
||||||
"version": "0.4.0",
|
"version": "0.4.0",
|
||||||
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
|
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
|
||||||
@ -2619,6 +2637,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/bufferutil/-/bufferutil-4.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/bufferutil/-/bufferutil-4.0.3.tgz",
|
||||||
"integrity": "sha512-yEYTwGndELGvfXsImMBLop58eaGW+YdONi1fNjTINSY98tmMmFijBG6WXgdkfuLNt4imzQNtIE+eBp1PVpMCSw==",
|
"integrity": "sha512-yEYTwGndELGvfXsImMBLop58eaGW+YdONi1fNjTINSY98tmMmFijBG6WXgdkfuLNt4imzQNtIE+eBp1PVpMCSw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"hasInstallScript": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"node-gyp-build": "^4.2.0"
|
"node-gyp-build": "^4.2.0"
|
||||||
}
|
}
|
||||||
@ -3058,6 +3077,23 @@
|
|||||||
"integrity": "sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w==",
|
"integrity": "sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"node_modules/colors": {
|
||||||
|
"version": "1.4.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz",
|
||||||
|
"integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.1.90"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/colorspace": {
|
||||||
|
"version": "1.1.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/colorspace/-/colorspace-1.1.4.tgz",
|
||||||
|
"integrity": "sha512-BgvKJiuVu1igBUF2kEjRCZXol6wiiGbY5ipL/oVPwm0BL9sIpMIzM8IK7vwuxIIzOXMV3Ey5w+vxhm0rR/TN8w==",
|
||||||
|
"dependencies": {
|
||||||
|
"color": "^3.1.3",
|
||||||
|
"text-hex": "1.0.x"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/combined-stream": {
|
"node_modules/combined-stream": {
|
||||||
"version": "1.0.8",
|
"version": "1.0.8",
|
||||||
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
|
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
|
||||||
@ -3772,6 +3808,11 @@
|
|||||||
"node": ">= 4"
|
"node": ">= 4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/enabled": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/enabled/-/enabled-2.0.0.tgz",
|
||||||
|
"integrity": "sha512-AKrN98kuwOzMIdAizXGI86UFBoo26CL21UM763y1h/GMSJ4/OHU9k2YlsmBpyScFo/wbLzWQJBMCW4+IO3/+OQ=="
|
||||||
|
},
|
||||||
"node_modules/encodeurl": {
|
"node_modules/encodeurl": {
|
||||||
"version": "1.0.2",
|
"version": "1.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
|
||||||
@ -4920,6 +4961,11 @@
|
|||||||
"reusify": "^1.0.4"
|
"reusify": "^1.0.4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/fecha": {
|
||||||
|
"version": "4.2.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/fecha/-/fecha-4.2.1.tgz",
|
||||||
|
"integrity": "sha512-MMMQ0ludy/nBs1/o0zVOiKTpG7qMbonKUzjJgQFEuvq6INZ1OraKPRAWkBq5vlKLOUMpmNYG1JoN3oDPUQ9m3Q=="
|
||||||
|
},
|
||||||
"node_modules/file-entry-cache": {
|
"node_modules/file-entry-cache": {
|
||||||
"version": "6.0.1",
|
"version": "6.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz",
|
||||||
@ -5070,6 +5116,11 @@
|
|||||||
"integrity": "sha512-zAoAQiudy+r5SvnSw3KJy5os/oRJYHzrzja/tBDqrZtNhUw8bt6y8OBzMWcjWr+8liV8Eb6yOhw8WZ7VFZ5ZzA==",
|
"integrity": "sha512-zAoAQiudy+r5SvnSw3KJy5os/oRJYHzrzja/tBDqrZtNhUw8bt6y8OBzMWcjWr+8liV8Eb6yOhw8WZ7VFZ5ZzA==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"node_modules/fn.name": {
|
||||||
|
"version": "1.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/fn.name/-/fn.name-1.1.0.tgz",
|
||||||
|
"integrity": "sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw=="
|
||||||
|
},
|
||||||
"node_modules/follow-redirects": {
|
"node_modules/follow-redirects": {
|
||||||
"version": "1.13.2",
|
"version": "1.13.2",
|
||||||
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.13.2.tgz",
|
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.13.2.tgz",
|
||||||
@ -6415,6 +6466,11 @@
|
|||||||
"node": ">=0.10.0"
|
"node": ">=0.10.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/kuler": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/kuler/-/kuler-2.0.0.tgz",
|
||||||
|
"integrity": "sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A=="
|
||||||
|
},
|
||||||
"node_modules/language-subtag-registry": {
|
"node_modules/language-subtag-registry": {
|
||||||
"version": "0.3.21",
|
"version": "0.3.21",
|
||||||
"resolved": "https://registry.npmjs.org/language-subtag-registry/-/language-subtag-registry-0.3.21.tgz",
|
"resolved": "https://registry.npmjs.org/language-subtag-registry/-/language-subtag-registry-0.3.21.tgz",
|
||||||
@ -6630,6 +6686,18 @@
|
|||||||
"integrity": "sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM=",
|
"integrity": "sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM=",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"node_modules/logform": {
|
||||||
|
"version": "2.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/logform/-/logform-2.3.0.tgz",
|
||||||
|
"integrity": "sha512-graeoWUH2knKbGthMtuG1EfaSPMZFZBIrhuJHhkS5ZseFBrc7DupCzihOQAzsK/qIKPQaPJ/lFQFctILUY5ARQ==",
|
||||||
|
"dependencies": {
|
||||||
|
"colors": "^1.2.1",
|
||||||
|
"fecha": "^4.2.0",
|
||||||
|
"ms": "^2.1.1",
|
||||||
|
"safe-stable-stringify": "^1.1.0",
|
||||||
|
"triple-beam": "^1.3.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/loose-envify": {
|
"node_modules/loose-envify": {
|
||||||
"version": "1.4.0",
|
"version": "1.4.0",
|
||||||
"resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
|
"resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
|
||||||
@ -7276,6 +7344,14 @@
|
|||||||
"wrappy": "1"
|
"wrappy": "1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/one-time": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/one-time/-/one-time-1.0.0.tgz",
|
||||||
|
"integrity": "sha512-5DXOiRKwuSEcQ/l0kGCF6Q3jcADFv5tSmRaJck/OqkVFcOzutB134KRSfF0xDrL39MNnqxbHBbUUcjZIhTgb2g==",
|
||||||
|
"dependencies": {
|
||||||
|
"fn.name": "1.x.x"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/onetime": {
|
"node_modules/onetime": {
|
||||||
"version": "5.1.2",
|
"version": "5.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz",
|
||||||
@ -8612,6 +8688,11 @@
|
|||||||
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
|
||||||
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
|
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
|
||||||
},
|
},
|
||||||
|
"node_modules/safe-stable-stringify": {
|
||||||
|
"version": "1.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-1.1.1.tgz",
|
||||||
|
"integrity": "sha512-ERq4hUjKDbJfE4+XtZLFPCDi8Vb1JqaxAPTxWFLBx8XcAlf9Bda/ZJdVezs/NAfsMQScyIlUMx+Yeu7P7rx5jw=="
|
||||||
|
},
|
||||||
"node_modules/safer-buffer": {
|
"node_modules/safer-buffer": {
|
||||||
"version": "2.1.2",
|
"version": "2.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
|
||||||
@ -9001,6 +9082,14 @@
|
|||||||
"node": ">=0.10.0"
|
"node": ">=0.10.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/stack-trace": {
|
||||||
|
"version": "0.0.10",
|
||||||
|
"resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz",
|
||||||
|
"integrity": "sha1-VHxws0fo0ytOEI6hoqFZ5f3eGcA=",
|
||||||
|
"engines": {
|
||||||
|
"node": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/statuses": {
|
"node_modules/statuses": {
|
||||||
"version": "1.5.0",
|
"version": "1.5.0",
|
||||||
"resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz",
|
"resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz",
|
||||||
@ -9460,6 +9549,11 @@
|
|||||||
"node": ">= 8"
|
"node": ">= 8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/text-hex": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/text-hex/-/text-hex-1.0.0.tgz",
|
||||||
|
"integrity": "sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg=="
|
||||||
|
},
|
||||||
"node_modules/text-table": {
|
"node_modules/text-table": {
|
||||||
"version": "0.2.0",
|
"version": "0.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
|
||||||
@ -9565,6 +9659,11 @@
|
|||||||
"tree-kill": "cli.js"
|
"tree-kill": "cli.js"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/triple-beam": {
|
||||||
|
"version": "1.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/triple-beam/-/triple-beam-1.3.0.tgz",
|
||||||
|
"integrity": "sha512-XrHUvV5HpdLmIj4uVMxHggLbFSZYIn7HEWsqePZcI50pco+MPqJ50wMGY794X7AOOhxOBAjbkqfAbEe/QMp2Lw=="
|
||||||
|
},
|
||||||
"node_modules/tsconfig-paths": {
|
"node_modules/tsconfig-paths": {
|
||||||
"version": "3.9.0",
|
"version": "3.9.0",
|
||||||
"resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.9.0.tgz",
|
"resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.9.0.tgz",
|
||||||
@ -9864,6 +9963,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-5.0.4.tgz",
|
"resolved": "https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-5.0.4.tgz",
|
||||||
"integrity": "sha512-MEF05cPSq3AwJ2C7B7sHAA6i53vONoZbMGX8My5auEVm6W+dJ2Jd/TZPyGJ5CH42V2XtbI5FD28HeHeqlPzZ3Q==",
|
"integrity": "sha512-MEF05cPSq3AwJ2C7B7sHAA6i53vONoZbMGX8My5auEVm6W+dJ2Jd/TZPyGJ5CH42V2XtbI5FD28HeHeqlPzZ3Q==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"hasInstallScript": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"node-gyp-build": "^4.2.0"
|
"node-gyp-build": "^4.2.0"
|
||||||
}
|
}
|
||||||
@ -10197,6 +10297,118 @@
|
|||||||
"node": ">= 0.10.0"
|
"node": ">= 0.10.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/winston": {
|
||||||
|
"version": "3.3.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/winston/-/winston-3.3.3.tgz",
|
||||||
|
"integrity": "sha512-oEXTISQnC8VlSAKf1KYSSd7J6IWuRPQqDdo8eoRNaYKLvwSb5+79Z3Yi1lrl6KDpU6/VWaxpakDAtb1oQ4n9aw==",
|
||||||
|
"dependencies": {
|
||||||
|
"@dabh/diagnostics": "^2.0.2",
|
||||||
|
"async": "^3.1.0",
|
||||||
|
"is-stream": "^2.0.0",
|
||||||
|
"logform": "^2.2.0",
|
||||||
|
"one-time": "^1.0.0",
|
||||||
|
"readable-stream": "^3.4.0",
|
||||||
|
"stack-trace": "0.0.x",
|
||||||
|
"triple-beam": "^1.3.0",
|
||||||
|
"winston-transport": "^4.4.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 6.4.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/winston-transport": {
|
||||||
|
"version": "4.4.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/winston-transport/-/winston-transport-4.4.1.tgz",
|
||||||
|
"integrity": "sha512-ciZRlU4CSjHqHe8RQG1iPxKMRVwv6ZJ0RC7DxStKWd0KjpAhPDy5gVYSCpIUq+5CUsP+IyNOTZy1X0tO2QZqjg==",
|
||||||
|
"dependencies": {
|
||||||
|
"logform": "^2.2.0",
|
||||||
|
"readable-stream": "^3.4.0",
|
||||||
|
"triple-beam": "^1.2.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 6.4.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/winston-transport/node_modules/readable-stream": {
|
||||||
|
"version": "3.6.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
|
||||||
|
"integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
|
||||||
|
"dependencies": {
|
||||||
|
"inherits": "^2.0.3",
|
||||||
|
"string_decoder": "^1.1.1",
|
||||||
|
"util-deprecate": "^1.0.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/winston-transport/node_modules/safe-buffer": {
|
||||||
|
"version": "5.2.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
|
||||||
|
"integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"type": "github",
|
||||||
|
"url": "https://github.com/sponsors/feross"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "patreon",
|
||||||
|
"url": "https://www.patreon.com/feross"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "consulting",
|
||||||
|
"url": "https://feross.org/support"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"node_modules/winston-transport/node_modules/string_decoder": {
|
||||||
|
"version": "1.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
|
||||||
|
"integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
|
||||||
|
"dependencies": {
|
||||||
|
"safe-buffer": "~5.2.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/winston/node_modules/readable-stream": {
|
||||||
|
"version": "3.6.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
|
||||||
|
"integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
|
||||||
|
"dependencies": {
|
||||||
|
"inherits": "^2.0.3",
|
||||||
|
"string_decoder": "^1.1.1",
|
||||||
|
"util-deprecate": "^1.0.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/winston/node_modules/safe-buffer": {
|
||||||
|
"version": "5.2.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
|
||||||
|
"integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"type": "github",
|
||||||
|
"url": "https://github.com/sponsors/feross"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "patreon",
|
||||||
|
"url": "https://www.patreon.com/feross"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "consulting",
|
||||||
|
"url": "https://feross.org/support"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"node_modules/winston/node_modules/string_decoder": {
|
||||||
|
"version": "1.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
|
||||||
|
"integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
|
||||||
|
"dependencies": {
|
||||||
|
"safe-buffer": "~5.2.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/word-wrap": {
|
"node_modules/word-wrap": {
|
||||||
"version": "1.2.3",
|
"version": "1.2.3",
|
||||||
"resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz",
|
"resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz",
|
||||||
@ -10376,6 +10588,11 @@
|
|||||||
"node": ">=10"
|
"node": ">=10"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/youtubei": {
|
||||||
|
"version": "0.0.1-rc.27",
|
||||||
|
"resolved": "https://registry.npmjs.org/youtubei/-/youtubei-0.0.1-rc.27.tgz",
|
||||||
|
"integrity": "sha512-4pbKr6F9RpWQ/XLstD9KNTBd5dGkzXNm8sx2ooQFleCka/wknZQhu9HEoGbvJMb4izvfSs2e5TAAK+l6fYwxJQ=="
|
||||||
|
},
|
||||||
"node_modules/ytdl-core": {
|
"node_modules/ytdl-core": {
|
||||||
"version": "4.5.0",
|
"version": "4.5.0",
|
||||||
"resolved": "https://registry.npmjs.org/ytdl-core/-/ytdl-core-4.5.0.tgz",
|
"resolved": "https://registry.npmjs.org/ytdl-core/-/ytdl-core-4.5.0.tgz",
|
||||||
@ -10831,6 +11048,16 @@
|
|||||||
"to-fast-properties": "^2.0.0"
|
"to-fast-properties": "^2.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"@dabh/diagnostics": {
|
||||||
|
"version": "2.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@dabh/diagnostics/-/diagnostics-2.0.2.tgz",
|
||||||
|
"integrity": "sha512-+A1YivoVDNNVCdfozHSR8v/jyuuLTMXwjWuxPFlFlUapXoGc+Gj9mDlTDDfrwl7rXCl2tNZ0kE8sIBO6YOn96Q==",
|
||||||
|
"requires": {
|
||||||
|
"colorspace": "1.1.x",
|
||||||
|
"enabled": "2.0.x",
|
||||||
|
"kuler": "^2.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"@discoveryjs/json-ext": {
|
"@discoveryjs/json-ext": {
|
||||||
"version": "0.5.2",
|
"version": "0.5.2",
|
||||||
"resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.2.tgz",
|
"resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.2.tgz",
|
||||||
@ -12283,6 +12510,11 @@
|
|||||||
"integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==",
|
"integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"async": {
|
||||||
|
"version": "3.2.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/async/-/async-3.2.2.tgz",
|
||||||
|
"integrity": "sha512-H0E+qZaDEfx/FY4t7iLRv1W2fFI6+pyCeTw1uN20AQPiwqwM6ojPxHxdLv4z8hi2DtnW9BOckSspLucW7pIE5g=="
|
||||||
|
},
|
||||||
"asynckit": {
|
"asynckit": {
|
||||||
"version": "0.4.0",
|
"version": "0.4.0",
|
||||||
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
|
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
|
||||||
@ -13008,6 +13240,20 @@
|
|||||||
"integrity": "sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w==",
|
"integrity": "sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"colors": {
|
||||||
|
"version": "1.4.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz",
|
||||||
|
"integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA=="
|
||||||
|
},
|
||||||
|
"colorspace": {
|
||||||
|
"version": "1.1.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/colorspace/-/colorspace-1.1.4.tgz",
|
||||||
|
"integrity": "sha512-BgvKJiuVu1igBUF2kEjRCZXol6wiiGbY5ipL/oVPwm0BL9sIpMIzM8IK7vwuxIIzOXMV3Ey5w+vxhm0rR/TN8w==",
|
||||||
|
"requires": {
|
||||||
|
"color": "^3.1.3",
|
||||||
|
"text-hex": "1.0.x"
|
||||||
|
}
|
||||||
|
},
|
||||||
"combined-stream": {
|
"combined-stream": {
|
||||||
"version": "1.0.8",
|
"version": "1.0.8",
|
||||||
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
|
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
|
||||||
@ -13566,6 +13812,11 @@
|
|||||||
"integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==",
|
"integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"enabled": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/enabled/-/enabled-2.0.0.tgz",
|
||||||
|
"integrity": "sha512-AKrN98kuwOzMIdAizXGI86UFBoo26CL21UM763y1h/GMSJ4/OHU9k2YlsmBpyScFo/wbLzWQJBMCW4+IO3/+OQ=="
|
||||||
|
},
|
||||||
"encodeurl": {
|
"encodeurl": {
|
||||||
"version": "1.0.2",
|
"version": "1.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
|
||||||
@ -14445,6 +14696,11 @@
|
|||||||
"reusify": "^1.0.4"
|
"reusify": "^1.0.4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"fecha": {
|
||||||
|
"version": "4.2.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/fecha/-/fecha-4.2.1.tgz",
|
||||||
|
"integrity": "sha512-MMMQ0ludy/nBs1/o0zVOiKTpG7qMbonKUzjJgQFEuvq6INZ1OraKPRAWkBq5vlKLOUMpmNYG1JoN3oDPUQ9m3Q=="
|
||||||
|
},
|
||||||
"file-entry-cache": {
|
"file-entry-cache": {
|
||||||
"version": "6.0.1",
|
"version": "6.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz",
|
||||||
@ -14568,6 +14824,11 @@
|
|||||||
"integrity": "sha512-zAoAQiudy+r5SvnSw3KJy5os/oRJYHzrzja/tBDqrZtNhUw8bt6y8OBzMWcjWr+8liV8Eb6yOhw8WZ7VFZ5ZzA==",
|
"integrity": "sha512-zAoAQiudy+r5SvnSw3KJy5os/oRJYHzrzja/tBDqrZtNhUw8bt6y8OBzMWcjWr+8liV8Eb6yOhw8WZ7VFZ5ZzA==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"fn.name": {
|
||||||
|
"version": "1.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/fn.name/-/fn.name-1.1.0.tgz",
|
||||||
|
"integrity": "sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw=="
|
||||||
|
},
|
||||||
"follow-redirects": {
|
"follow-redirects": {
|
||||||
"version": "1.13.2",
|
"version": "1.13.2",
|
||||||
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.13.2.tgz",
|
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.13.2.tgz",
|
||||||
@ -15606,6 +15867,11 @@
|
|||||||
"integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==",
|
"integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"kuler": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/kuler/-/kuler-2.0.0.tgz",
|
||||||
|
"integrity": "sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A=="
|
||||||
|
},
|
||||||
"language-subtag-registry": {
|
"language-subtag-registry": {
|
||||||
"version": "0.3.21",
|
"version": "0.3.21",
|
||||||
"resolved": "https://registry.npmjs.org/language-subtag-registry/-/language-subtag-registry-0.3.21.tgz",
|
"resolved": "https://registry.npmjs.org/language-subtag-registry/-/language-subtag-registry-0.3.21.tgz",
|
||||||
@ -15791,6 +16057,18 @@
|
|||||||
"integrity": "sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM=",
|
"integrity": "sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM=",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"logform": {
|
||||||
|
"version": "2.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/logform/-/logform-2.3.0.tgz",
|
||||||
|
"integrity": "sha512-graeoWUH2knKbGthMtuG1EfaSPMZFZBIrhuJHhkS5ZseFBrc7DupCzihOQAzsK/qIKPQaPJ/lFQFctILUY5ARQ==",
|
||||||
|
"requires": {
|
||||||
|
"colors": "^1.2.1",
|
||||||
|
"fecha": "^4.2.0",
|
||||||
|
"ms": "^2.1.1",
|
||||||
|
"safe-stable-stringify": "^1.1.0",
|
||||||
|
"triple-beam": "^1.3.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"loose-envify": {
|
"loose-envify": {
|
||||||
"version": "1.4.0",
|
"version": "1.4.0",
|
||||||
"resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
|
"resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
|
||||||
@ -16295,6 +16573,14 @@
|
|||||||
"wrappy": "1"
|
"wrappy": "1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"one-time": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/one-time/-/one-time-1.0.0.tgz",
|
||||||
|
"integrity": "sha512-5DXOiRKwuSEcQ/l0kGCF6Q3jcADFv5tSmRaJck/OqkVFcOzutB134KRSfF0xDrL39MNnqxbHBbUUcjZIhTgb2g==",
|
||||||
|
"requires": {
|
||||||
|
"fn.name": "1.x.x"
|
||||||
|
}
|
||||||
|
},
|
||||||
"onetime": {
|
"onetime": {
|
||||||
"version": "5.1.2",
|
"version": "5.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz",
|
||||||
@ -17346,6 +17632,11 @@
|
|||||||
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
|
||||||
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
|
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
|
||||||
},
|
},
|
||||||
|
"safe-stable-stringify": {
|
||||||
|
"version": "1.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-1.1.1.tgz",
|
||||||
|
"integrity": "sha512-ERq4hUjKDbJfE4+XtZLFPCDi8Vb1JqaxAPTxWFLBx8XcAlf9Bda/ZJdVezs/NAfsMQScyIlUMx+Yeu7P7rx5jw=="
|
||||||
|
},
|
||||||
"safer-buffer": {
|
"safer-buffer": {
|
||||||
"version": "2.1.2",
|
"version": "2.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
|
||||||
@ -17685,6 +17976,11 @@
|
|||||||
"tweetnacl": "~0.14.0"
|
"tweetnacl": "~0.14.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"stack-trace": {
|
||||||
|
"version": "0.0.10",
|
||||||
|
"resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz",
|
||||||
|
"integrity": "sha1-VHxws0fo0ytOEI6hoqFZ5f3eGcA="
|
||||||
|
},
|
||||||
"statuses": {
|
"statuses": {
|
||||||
"version": "1.5.0",
|
"version": "1.5.0",
|
||||||
"resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz",
|
"resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz",
|
||||||
@ -18055,6 +18351,11 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"text-hex": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/text-hex/-/text-hex-1.0.0.tgz",
|
||||||
|
"integrity": "sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg=="
|
||||||
|
},
|
||||||
"text-table": {
|
"text-table": {
|
||||||
"version": "0.2.0",
|
"version": "0.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
|
||||||
@ -18136,6 +18437,11 @@
|
|||||||
"integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==",
|
"integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"triple-beam": {
|
||||||
|
"version": "1.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/triple-beam/-/triple-beam-1.3.0.tgz",
|
||||||
|
"integrity": "sha512-XrHUvV5HpdLmIj4uVMxHggLbFSZYIn7HEWsqePZcI50pco+MPqJ50wMGY794X7AOOhxOBAjbkqfAbEe/QMp2Lw=="
|
||||||
|
},
|
||||||
"tsconfig-paths": {
|
"tsconfig-paths": {
|
||||||
"version": "3.9.0",
|
"version": "3.9.0",
|
||||||
"resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.9.0.tgz",
|
"resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.9.0.tgz",
|
||||||
@ -18663,6 +18969,82 @@
|
|||||||
"resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.4.tgz",
|
"resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.4.tgz",
|
||||||
"integrity": "sha1-+OGqHuWlPsW/FR/6CXQqatdpeHY="
|
"integrity": "sha1-+OGqHuWlPsW/FR/6CXQqatdpeHY="
|
||||||
},
|
},
|
||||||
|
"winston": {
|
||||||
|
"version": "3.3.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/winston/-/winston-3.3.3.tgz",
|
||||||
|
"integrity": "sha512-oEXTISQnC8VlSAKf1KYSSd7J6IWuRPQqDdo8eoRNaYKLvwSb5+79Z3Yi1lrl6KDpU6/VWaxpakDAtb1oQ4n9aw==",
|
||||||
|
"requires": {
|
||||||
|
"@dabh/diagnostics": "^2.0.2",
|
||||||
|
"async": "^3.1.0",
|
||||||
|
"is-stream": "^2.0.0",
|
||||||
|
"logform": "^2.2.0",
|
||||||
|
"one-time": "^1.0.0",
|
||||||
|
"readable-stream": "^3.4.0",
|
||||||
|
"stack-trace": "0.0.x",
|
||||||
|
"triple-beam": "^1.3.0",
|
||||||
|
"winston-transport": "^4.4.0"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"readable-stream": {
|
||||||
|
"version": "3.6.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
|
||||||
|
"integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
|
||||||
|
"requires": {
|
||||||
|
"inherits": "^2.0.3",
|
||||||
|
"string_decoder": "^1.1.1",
|
||||||
|
"util-deprecate": "^1.0.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"safe-buffer": {
|
||||||
|
"version": "5.2.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
|
||||||
|
"integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="
|
||||||
|
},
|
||||||
|
"string_decoder": {
|
||||||
|
"version": "1.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
|
||||||
|
"integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
|
||||||
|
"requires": {
|
||||||
|
"safe-buffer": "~5.2.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"winston-transport": {
|
||||||
|
"version": "4.4.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/winston-transport/-/winston-transport-4.4.1.tgz",
|
||||||
|
"integrity": "sha512-ciZRlU4CSjHqHe8RQG1iPxKMRVwv6ZJ0RC7DxStKWd0KjpAhPDy5gVYSCpIUq+5CUsP+IyNOTZy1X0tO2QZqjg==",
|
||||||
|
"requires": {
|
||||||
|
"logform": "^2.2.0",
|
||||||
|
"readable-stream": "^3.4.0",
|
||||||
|
"triple-beam": "^1.2.0"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"readable-stream": {
|
||||||
|
"version": "3.6.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
|
||||||
|
"integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
|
||||||
|
"requires": {
|
||||||
|
"inherits": "^2.0.3",
|
||||||
|
"string_decoder": "^1.1.1",
|
||||||
|
"util-deprecate": "^1.0.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"safe-buffer": {
|
||||||
|
"version": "5.2.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
|
||||||
|
"integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="
|
||||||
|
},
|
||||||
|
"string_decoder": {
|
||||||
|
"version": "1.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
|
||||||
|
"integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
|
||||||
|
"requires": {
|
||||||
|
"safe-buffer": "~5.2.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"word-wrap": {
|
"word-wrap": {
|
||||||
"version": "1.2.3",
|
"version": "1.2.3",
|
||||||
"resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz",
|
"resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz",
|
||||||
@ -18797,6 +19179,11 @@
|
|||||||
"integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==",
|
"integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"youtubei": {
|
||||||
|
"version": "0.0.1-rc.27",
|
||||||
|
"resolved": "https://registry.npmjs.org/youtubei/-/youtubei-0.0.1-rc.27.tgz",
|
||||||
|
"integrity": "sha512-4pbKr6F9RpWQ/XLstD9KNTBd5dGkzXNm8sx2ooQFleCka/wknZQhu9HEoGbvJMb4izvfSs2e5TAAK+l6fYwxJQ=="
|
||||||
|
},
|
||||||
"ytdl-core": {
|
"ytdl-core": {
|
||||||
"version": "4.5.0",
|
"version": "4.5.0",
|
||||||
"resolved": "https://registry.npmjs.org/ytdl-core/-/ytdl-core-4.5.0.tgz",
|
"resolved": "https://registry.npmjs.org/ytdl-core/-/ytdl-core-4.5.0.tgz",
|
||||||
|
@ -43,6 +43,8 @@
|
|||||||
"scrape-yt": "^1.4.7",
|
"scrape-yt": "^1.4.7",
|
||||||
"spotify-web-api-node": "^5.0.2",
|
"spotify-web-api-node": "^5.0.2",
|
||||||
"uuid": "^8.3.2",
|
"uuid": "^8.3.2",
|
||||||
|
"winston": "^3.3.3",
|
||||||
|
"youtubei": "^0.0.1-rc.27",
|
||||||
"ytdl-core": "^4.5.0"
|
"ytdl-core": "^4.5.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
39
src/app.tsx
39
src/app.tsx
@ -18,7 +18,6 @@ import { QueryClient, QueryClientProvider } from "react-query";
|
|||||||
import express from "express";
|
import express from "express";
|
||||||
import open from "open";
|
import open from "open";
|
||||||
import spotifyApi from "./initializations/spotifyApi";
|
import spotifyApi from "./initializations/spotifyApi";
|
||||||
import showError from "./helpers/showError";
|
|
||||||
import fs from "fs";
|
import fs from "fs";
|
||||||
import path from "path";
|
import path from "path";
|
||||||
import { confDir, LocalStorageKeys } from "./conf";
|
import { confDir, LocalStorageKeys } from "./conf";
|
||||||
@ -26,6 +25,8 @@ import spotubeIcon from "../assets/icon.svg";
|
|||||||
import preferencesContext, {
|
import preferencesContext, {
|
||||||
PreferencesContextProperties,
|
PreferencesContextProperties,
|
||||||
} from "./context/preferencesContext";
|
} from "./context/preferencesContext";
|
||||||
|
import { useLogger } from "./hooks/useLogger";
|
||||||
|
import { Logger } from "./initializations/logger";
|
||||||
|
|
||||||
export interface Credentials {
|
export interface Credentials {
|
||||||
clientId: string;
|
clientId: string;
|
||||||
@ -40,8 +41,9 @@ global.localStorage = new LocalStorage(localStorageDir);
|
|||||||
const queryClient = new QueryClient({
|
const queryClient = new QueryClient({
|
||||||
defaultOptions: {
|
defaultOptions: {
|
||||||
queries: {
|
queries: {
|
||||||
onError(error) {
|
onError(error: any) {
|
||||||
showError(error);
|
const logger = new Logger(QueryClient.name);
|
||||||
|
logger.error(error);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -54,6 +56,7 @@ const initialCredentials: Credentials = { clientId: "", clientSecret: "" };
|
|||||||
|
|
||||||
//* Application start
|
//* Application start
|
||||||
function RootApp() {
|
function RootApp() {
|
||||||
|
const logger = useLogger(RootApp.name);
|
||||||
const windowRef = useRef<QMainWindow>();
|
const windowRef = useRef<QMainWindow>();
|
||||||
const [currentTrack, setCurrentTrack] = useState<CurrentTrack>();
|
const [currentTrack, setCurrentTrack] = useState<CurrentTrack>();
|
||||||
// cache
|
// cache
|
||||||
@ -110,14 +113,14 @@ function RootApp() {
|
|||||||
);
|
);
|
||||||
setIsLoggedIn(true);
|
setIsLoggedIn(true);
|
||||||
return res.end();
|
return res.end();
|
||||||
} catch (error) {
|
} catch (error: any) {
|
||||||
console.error("Failed to fullfil code grant flow: ", error);
|
logger.error("Failed to fullfil code grant flow", error);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
const server = app.listen(4304, () => {
|
const server = app.listen(4304, () => {
|
||||||
console.log("Server is running");
|
logger.info("Server is running");
|
||||||
spotifyApi.setClientId(credentials.clientId);
|
spotifyApi.setClientId(credentials.clientId);
|
||||||
spotifyApi.setClientSecret(credentials.clientSecret);
|
spotifyApi.setClientSecret(credentials.clientSecret);
|
||||||
open(
|
open(
|
||||||
@ -132,11 +135,11 @@ function RootApp() {
|
|||||||
"xxxyyysssddd",
|
"xxxyyysssddd",
|
||||||
),
|
),
|
||||||
).catch((e) =>
|
).catch((e) =>
|
||||||
console.error("Opening IPC connection with browser failed: ", e),
|
logger.error("Opening IPC connection with browser failed", e),
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
return () => {
|
return () => {
|
||||||
server.close(() => console.log("Closed server"));
|
server.close(() => logger.info("Closed server"));
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}, [credentials]);
|
}, [credentials]);
|
||||||
@ -152,7 +155,7 @@ function RootApp() {
|
|||||||
if (audioPlayer.isRunning()) {
|
if (audioPlayer.isRunning()) {
|
||||||
audioPlayer
|
audioPlayer
|
||||||
.stop()
|
.stop()
|
||||||
.catch((e) => console.error("Failed to quit MPV player: ", e));
|
.catch((e) => logger.error("Failed to quit MPV player", e));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -183,9 +186,9 @@ function RootApp() {
|
|||||||
(await audioPlayer.isPaused())
|
(await audioPlayer.isPaused())
|
||||||
? await audioPlayer.play()
|
? await audioPlayer.play()
|
||||||
: await audioPlayer.pause();
|
: await audioPlayer.pause();
|
||||||
console.log("You pressed SPACE");
|
logger.info("You pressed SPACE");
|
||||||
} catch (error) {
|
} catch (error: any) {
|
||||||
showError(error, "[Failed to play/pause audioPlayer]: ");
|
logger.error("Failed to play/pause audioPlayer", error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
async function rightAction() {
|
async function rightAction() {
|
||||||
@ -194,9 +197,9 @@ function RootApp() {
|
|||||||
audioPlayer.isRunning() &&
|
audioPlayer.isRunning() &&
|
||||||
(await audioPlayer.isSeekable()) &&
|
(await audioPlayer.isSeekable()) &&
|
||||||
(await audioPlayer.seek(+5));
|
(await audioPlayer.seek(+5));
|
||||||
console.log("You pressed RIGHT");
|
logger.info("You pressed RIGHT");
|
||||||
} catch (error) {
|
} catch (error: any) {
|
||||||
showError(error, "[Failed to seek audioPlayer]: ");
|
logger.error("Failed to seek audioPlayer", error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
async function leftAction() {
|
async function leftAction() {
|
||||||
@ -205,9 +208,9 @@ function RootApp() {
|
|||||||
audioPlayer.isRunning() &&
|
audioPlayer.isRunning() &&
|
||||||
(await audioPlayer.isSeekable()) &&
|
(await audioPlayer.isSeekable()) &&
|
||||||
(await audioPlayer.seek(-5));
|
(await audioPlayer.seek(-5));
|
||||||
console.log("You pressed LEFT");
|
logger.info("You pressed LEFT");
|
||||||
} catch (error) {
|
} catch (error: any) {
|
||||||
showError(error, "[Failed to seek audioPlayer]: ");
|
logger.error("Failed to seek audioPlayer", error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,8 +8,8 @@ import {
|
|||||||
TextFormat,
|
TextFormat,
|
||||||
} from "@nodegui/nodegui";
|
} from "@nodegui/nodegui";
|
||||||
import React, { PropsWithChildren, useEffect, useState } from "react";
|
import React, { PropsWithChildren, useEffect, useState } from "react";
|
||||||
import showError from "../helpers/showError";
|
|
||||||
import fetchLyrics from "../helpers/fetchLyrics";
|
import fetchLyrics from "../helpers/fetchLyrics";
|
||||||
|
import { useLogger } from "../hooks/useLogger";
|
||||||
|
|
||||||
interface ManualLyricDialogProps extends PropsWithChildren<unknown> {
|
interface ManualLyricDialogProps extends PropsWithChildren<unknown> {
|
||||||
open: boolean;
|
open: boolean;
|
||||||
@ -18,6 +18,8 @@ interface ManualLyricDialogProps extends PropsWithChildren<unknown> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function ManualLyricDialog({ open, track }: ManualLyricDialogProps) {
|
function ManualLyricDialog({ open, track }: ManualLyricDialogProps) {
|
||||||
|
const logger = useLogger(ManualLyricDialog.name);
|
||||||
|
|
||||||
const dialog = new QDialog();
|
const dialog = new QDialog();
|
||||||
const areaContainer = new QWidget();
|
const areaContainer = new QWidget();
|
||||||
const retryButton = new QPushButton();
|
const retryButton = new QPushButton();
|
||||||
@ -31,11 +33,11 @@ function ManualLyricDialog({ open, track }: ManualLyricDialogProps) {
|
|||||||
async function handleBtnClick() {
|
async function handleBtnClick() {
|
||||||
try {
|
try {
|
||||||
const lyrics = await fetchLyrics(artists, track.name);
|
const lyrics = await fetchLyrics(artists, track.name);
|
||||||
console.log("lyrics:", lyrics);
|
logger.info("lyrics", lyrics);
|
||||||
setLyrics(lyrics);
|
setLyrics(lyrics);
|
||||||
setLyricNotFound(lyrics === "Not Found");
|
setLyricNotFound(lyrics === "Not Found");
|
||||||
} catch (error) {
|
} catch (error: any) {
|
||||||
showError(error, `[Finding lyrics for ${track.name} failed]: `);
|
logger.error(`Finding lyrics for ${track.name} failed`, error);
|
||||||
setLyrics("No lyrics found, rare track :)");
|
setLyrics("No lyrics found, rare track :)");
|
||||||
setLyricNotFound(true);
|
setLyricNotFound(true);
|
||||||
}
|
}
|
||||||
@ -77,7 +79,7 @@ function ManualLyricDialog({ open, track }: ManualLyricDialogProps) {
|
|||||||
setLyricNotFound(lyrics === "Not Found");
|
setLyricNotFound(lyrics === "Not Found");
|
||||||
})
|
})
|
||||||
.catch((e: Error) => {
|
.catch((e: Error) => {
|
||||||
showError(e, `[Finding lyrics for ${track.name} failed]: `);
|
logger.error(`Finding lyrics for ${track.name} failed `, e);
|
||||||
setLyrics("No lyrics found, rare track :)");
|
setLyrics("No lyrics found, rare track :)");
|
||||||
setLyricNotFound(true);
|
setLyricNotFound(true);
|
||||||
});
|
});
|
||||||
|
@ -27,11 +27,11 @@ import {
|
|||||||
download,
|
download,
|
||||||
} from "../icons";
|
} from "../icons";
|
||||||
import IconButton from "./shared/IconButton";
|
import IconButton from "./shared/IconButton";
|
||||||
import showError from "../helpers/showError";
|
|
||||||
import useTrackReaction from "../hooks/useTrackReaction";
|
import useTrackReaction from "../hooks/useTrackReaction";
|
||||||
import ManualLyricDialog from "./ManualLyricDialog";
|
import ManualLyricDialog from "./ManualLyricDialog";
|
||||||
import { LocalStorageKeys } from "../conf";
|
import { LocalStorageKeys } from "../conf";
|
||||||
import useDownloadQueue from "../hooks/useDownloadQueue";
|
import useDownloadQueue from "../hooks/useDownloadQueue";
|
||||||
|
import { useLogger } from "../hooks/useLogger";
|
||||||
|
|
||||||
export const audioPlayer = new NodeMpv(
|
export const audioPlayer = new NodeMpv(
|
||||||
{
|
{
|
||||||
@ -45,6 +45,8 @@ export const audioPlayer = new NodeMpv(
|
|||||||
["--ytdl-raw-options-set=format=140,http-chunk-size=300000"],
|
["--ytdl-raw-options-set=format=140,http-chunk-size=300000"],
|
||||||
);
|
);
|
||||||
function Player(): ReactElement {
|
function Player(): ReactElement {
|
||||||
|
const logger = useLogger(Player.name);
|
||||||
|
|
||||||
const { currentTrack, currentPlaylist, setCurrentTrack, setCurrentPlaylist } =
|
const { currentTrack, currentPlaylist, setCurrentTrack, setCurrentPlaylist } =
|
||||||
useContext(playerContext);
|
useContext(playerContext);
|
||||||
const { reactToTrack, isFavorite } = useTrackReaction();
|
const { reactToTrack, isFavorite } = useTrackReaction();
|
||||||
@ -87,8 +89,8 @@ function Player(): ReactElement {
|
|||||||
await audioPlayer.start();
|
await audioPlayer.start();
|
||||||
await audioPlayer.volume(volume);
|
await audioPlayer.volume(volume);
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error: any) {
|
||||||
showError(error, "[Failed starting audio player]: ");
|
logger.error("Failed starting audio player", error);
|
||||||
}
|
}
|
||||||
})().then(() => {
|
})().then(() => {
|
||||||
if (cachedPlaylist && !currentPlaylist) {
|
if (cachedPlaylist && !currentPlaylist) {
|
||||||
@ -101,7 +103,7 @@ function Player(): ReactElement {
|
|||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
if (playerRunning) {
|
if (playerRunning) {
|
||||||
audioPlayer.quit().catch((e: unknown) => console.log(e));
|
audioPlayer.quit().catch((e: any) => logger.error(e));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}, []);
|
}, []);
|
||||||
@ -126,12 +128,12 @@ function Player(): ReactElement {
|
|||||||
setIsPaused(false);
|
setIsPaused(false);
|
||||||
}
|
}
|
||||||
setIsStopped(false);
|
setIsStopped(false);
|
||||||
} catch (error) {
|
} catch (error: any) {
|
||||||
if (error.errcode !== 5) {
|
if (error.errcode !== 5) {
|
||||||
setIsStopped(true);
|
setIsStopped(true);
|
||||||
setIsPaused(true);
|
setIsPaused(true);
|
||||||
}
|
}
|
||||||
showError(error, "[Failure at track change]: ");
|
logger.error("Failure at track change", error);
|
||||||
}
|
}
|
||||||
})();
|
})();
|
||||||
}, [currentTrack]);
|
}, [currentTrack]);
|
||||||
@ -223,8 +225,8 @@ function Player(): ReactElement {
|
|||||||
setIsStopped(true);
|
setIsStopped(true);
|
||||||
setIsPaused(true);
|
setIsPaused(true);
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error: any) {
|
||||||
showError(error, "[Track control failed]: ");
|
logger.error("Track control failed", error);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -250,8 +252,8 @@ function Player(): ReactElement {
|
|||||||
setCurrentPlaylist(undefined);
|
setCurrentPlaylist(undefined);
|
||||||
await audioPlayer.stop();
|
await audioPlayer.stop();
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error: any) {
|
||||||
showError(error, "[Failed at audio-player stop]: ");
|
logger.error("Failed at audio-player stop", error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,6 +3,7 @@ import { BoxView, Slider, Text, useEventHandler } from "@nodegui/react-nodegui";
|
|||||||
import NodeMpv from "node-mpv";
|
import NodeMpv from "node-mpv";
|
||||||
import React, { useContext, useEffect, useState } from "react";
|
import React, { useContext, useEffect, useState } from "react";
|
||||||
import playerContext from "../context/playerContext";
|
import playerContext from "../context/playerContext";
|
||||||
|
import { useLogger } from "../hooks/useLogger";
|
||||||
|
|
||||||
interface PlayerProgressBarProps {
|
interface PlayerProgressBarProps {
|
||||||
audioPlayer: NodeMpv;
|
audioPlayer: NodeMpv;
|
||||||
@ -10,6 +11,7 @@ interface PlayerProgressBarProps {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function PlayerProgressBar({ audioPlayer, totalDuration }: PlayerProgressBarProps) {
|
function PlayerProgressBar({ audioPlayer, totalDuration }: PlayerProgressBarProps) {
|
||||||
|
const logger = useLogger(PlayerProgressBar.name);
|
||||||
const { currentTrack } = useContext(playerContext);
|
const { currentTrack } = useContext(playerContext);
|
||||||
const [trackTime, setTrackTime] = useState<number>(0);
|
const [trackTime, setTrackTime] = useState<number>(0);
|
||||||
const trackSliderEvents = useEventHandler<QAbstractSliderSignals>(
|
const trackSliderEvents = useEventHandler<QAbstractSliderSignals>(
|
||||||
@ -24,8 +26,8 @@ function PlayerProgressBar({ audioPlayer, totalDuration }: PlayerProgressBarProp
|
|||||||
(async () => {
|
(async () => {
|
||||||
try {
|
try {
|
||||||
await audioPlayer.goToPosition(trackTime);
|
await audioPlayer.goToPosition(trackTime);
|
||||||
} catch (error) {
|
} catch (error: any) {
|
||||||
console.error(error);
|
logger.error(error);
|
||||||
}
|
}
|
||||||
})();
|
})();
|
||||||
},
|
},
|
||||||
|
@ -12,6 +12,7 @@ import useSpotifyQuery from "../hooks/useSpotifyQuery";
|
|||||||
import usePlaylistReaction from "../hooks/usePlaylistReaction";
|
import usePlaylistReaction from "../hooks/usePlaylistReaction";
|
||||||
import { TrackButton } from "./shared/TrackButton";
|
import { TrackButton } from "./shared/TrackButton";
|
||||||
import PlaceholderApplet from "./shared/PlaceholderApplet";
|
import PlaceholderApplet from "./shared/PlaceholderApplet";
|
||||||
|
import { useLogger } from "../hooks/useLogger";
|
||||||
|
|
||||||
export interface PlaylistTrackRes {
|
export interface PlaylistTrackRes {
|
||||||
name: string;
|
name: string;
|
||||||
@ -20,6 +21,8 @@ export interface PlaylistTrackRes {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const PlaylistView: FC = () => {
|
const PlaylistView: FC = () => {
|
||||||
|
const logger = useLogger(PlaylistView.name);
|
||||||
|
|
||||||
const { setCurrentTrack, currentPlaylist, setCurrentPlaylist } =
|
const { setCurrentTrack, currentPlaylist, setCurrentPlaylist } =
|
||||||
useContext(playerContext);
|
useContext(playerContext);
|
||||||
const params = useParams<{ id: string }>();
|
const params = useParams<{ id: string }>();
|
||||||
@ -50,7 +53,7 @@ const PlaylistView: FC = () => {
|
|||||||
} else {
|
} else {
|
||||||
audioPlayer
|
audioPlayer
|
||||||
.stop()
|
.stop()
|
||||||
.catch((error) => console.error("Failed to stop audio player: ", error));
|
.catch((error) => logger.error("Failed to stop audio player", error));
|
||||||
setCurrentTrack(undefined);
|
setCurrentTrack(undefined);
|
||||||
setCurrentPlaylist(undefined);
|
setCurrentPlaylist(undefined);
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,7 @@ import { LineEdit, ScrollArea, Text, View } from "@nodegui/react-nodegui";
|
|||||||
import React, { useState } from "react";
|
import React, { useState } from "react";
|
||||||
import { useHistory } from "react-router";
|
import { useHistory } from "react-router";
|
||||||
import { QueryCacheKeys } from "../conf";
|
import { QueryCacheKeys } from "../conf";
|
||||||
import showError from "../helpers/showError";
|
import { useLogger } from "../hooks/useLogger";
|
||||||
import useSpotifyQuery from "../hooks/useSpotifyQuery";
|
import useSpotifyQuery from "../hooks/useSpotifyQuery";
|
||||||
import { search } from "../icons";
|
import { search } from "../icons";
|
||||||
import { TrackTableIndex } from "./PlaylistView";
|
import { TrackTableIndex } from "./PlaylistView";
|
||||||
@ -13,6 +13,7 @@ import PlaylistCard from "./shared/PlaylistCard";
|
|||||||
import { TrackButton } from "./shared/TrackButton";
|
import { TrackButton } from "./shared/TrackButton";
|
||||||
|
|
||||||
function Search() {
|
function Search() {
|
||||||
|
const logger = useLogger(Search.name);
|
||||||
const history = useHistory<{ searchQuery: string }>();
|
const history = useHistory<{ searchQuery: string }>();
|
||||||
const [searchQuery, setSearchQuery] = useState<string>("");
|
const [searchQuery, setSearchQuery] = useState<string>("");
|
||||||
const {
|
const {
|
||||||
@ -32,8 +33,8 @@ function Search() {
|
|||||||
async function handleSearch() {
|
async function handleSearch() {
|
||||||
try {
|
try {
|
||||||
await refetch();
|
await refetch();
|
||||||
} catch (error) {
|
} catch (error: any) {
|
||||||
showError(error, "[Failed to search through spotify]: ");
|
logger.error("Failed to search through spotify", error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@ import { Text, View } from "@nodegui/react-nodegui";
|
|||||||
import { QLabel, QPixmap } from "@nodegui/nodegui";
|
import { QLabel, QPixmap } from "@nodegui/nodegui";
|
||||||
import { ImageProps } from "@nodegui/react-nodegui/dist/components/Image/RNImage";
|
import { ImageProps } from "@nodegui/react-nodegui/dist/components/Image/RNImage";
|
||||||
import { getCachedImageBuffer } from "../../helpers/getCachedImageBuffer";
|
import { getCachedImageBuffer } from "../../helpers/getCachedImageBuffer";
|
||||||
import showError from "../../helpers/showError";
|
import { useLogger } from "../../hooks/useLogger";
|
||||||
|
|
||||||
interface CachedImageProps extends Omit<ImageProps, "buffer"> {
|
interface CachedImageProps extends Omit<ImageProps, "buffer"> {
|
||||||
src: string;
|
src: string;
|
||||||
@ -11,6 +11,7 @@ interface CachedImageProps extends Omit<ImageProps, "buffer"> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function CachedImage({ src, alt, size, maxSize, ...props }: CachedImageProps) {
|
function CachedImage({ src, alt, size, maxSize, ...props }: CachedImageProps) {
|
||||||
|
const logger = useLogger(CachedImage.name);
|
||||||
const labelRef = useRef<QLabel>();
|
const labelRef = useRef<QLabel>();
|
||||||
const [imageBuffer, setImageBuffer] = useState<Buffer>();
|
const [imageBuffer, setImageBuffer] = useState<Buffer>();
|
||||||
const [imageProcessError, setImageProcessError] = useState<boolean>(false);
|
const [imageProcessError, setImageProcessError] = useState<boolean>(false);
|
||||||
@ -22,7 +23,7 @@ function CachedImage({ src, alt, size, maxSize, ...props }: CachedImageProps) {
|
|||||||
.then((buffer) => setImageBuffer(buffer))
|
.then((buffer) => setImageBuffer(buffer))
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
setImageProcessError(false);
|
setImageProcessError(false);
|
||||||
showError(error, "[Cached Image Error]: ");
|
logger.error("Cached Image Error", error);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,7 +6,7 @@ import { QueryCacheKeys } from "../../conf";
|
|||||||
import playerContext from "../../context/playerContext";
|
import playerContext from "../../context/playerContext";
|
||||||
import preferencesContext from "../../context/preferencesContext";
|
import preferencesContext from "../../context/preferencesContext";
|
||||||
import { generateRandomColor, getDarkenForeground } from "../../helpers/RandomColor";
|
import { generateRandomColor, getDarkenForeground } from "../../helpers/RandomColor";
|
||||||
import showError from "../../helpers/showError";
|
import { useLogger } from "../../hooks/useLogger";
|
||||||
import usePlaylistReaction from "../../hooks/usePlaylistReaction";
|
import usePlaylistReaction from "../../hooks/usePlaylistReaction";
|
||||||
import useSpotifyQuery from "../../hooks/useSpotifyQuery";
|
import useSpotifyQuery from "../../hooks/useSpotifyQuery";
|
||||||
import { heart, heartRegular, pause, play } from "../../icons";
|
import { heart, heartRegular, pause, play } from "../../icons";
|
||||||
@ -19,6 +19,7 @@ interface PlaylistCardProps {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const PlaylistCard = ({ playlist }: PlaylistCardProps) => {
|
const PlaylistCard = ({ playlist }: PlaylistCardProps) => {
|
||||||
|
const logger = useLogger(PlaylistCard.name);
|
||||||
const preferences = useContext(preferencesContext);
|
const preferences = useContext(preferencesContext);
|
||||||
const thumbnail = playlist.images[0].url;
|
const thumbnail = playlist.images[0].url;
|
||||||
const { id, description, name } = playlist;
|
const { id, description, name } = playlist;
|
||||||
@ -48,8 +49,8 @@ const PlaylistCard = ({ playlist }: PlaylistCardProps) => {
|
|||||||
setCurrentTrack(undefined);
|
setCurrentTrack(undefined);
|
||||||
setCurrentPlaylist(undefined);
|
setCurrentPlaylist(undefined);
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error: any) {
|
||||||
showError(error, "[Failed adding playlist to queue]: ");
|
logger.error("Failed adding playlist to queue", error);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,17 +1,19 @@
|
|||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
import htmlToText from "html-to-text";
|
import htmlToText from "html-to-text";
|
||||||
import showError from "./showError";
|
import { Logger } from "../initializations/logger";
|
||||||
const delim1 =
|
const delim1 =
|
||||||
'</div></div></div></div><div class="hwc"><div class="BNeawe tAd8D AP7Wnd"><div><div class="BNeawe tAd8D AP7Wnd">';
|
'</div></div></div></div><div class="hwc"><div class="BNeawe tAd8D AP7Wnd"><div><div class="BNeawe tAd8D AP7Wnd">';
|
||||||
const delim2 =
|
const delim2 =
|
||||||
'</div></div></div></div></div><div><span class="hwc"><div class="BNeawe uEec3 AP7Wnd">';
|
'</div></div></div></div></div><div><span class="hwc"><div class="BNeawe uEec3 AP7Wnd">';
|
||||||
const url = "https://www.google.com/search?q=";
|
const url = "https://www.google.com/search?q=";
|
||||||
|
|
||||||
|
const logger = new Logger("FetchLyrics");
|
||||||
|
|
||||||
export default async function fetchLyrics(artists: string, title: string) {
|
export default async function fetchLyrics(artists: string, title: string) {
|
||||||
let lyrics;
|
let lyrics;
|
||||||
try {
|
try {
|
||||||
console.log(
|
logger.info(
|
||||||
"[lyric query]:",
|
"Lyric Query",
|
||||||
`${url}${encodeURIComponent(title + " " + artists)}+lyrics`,
|
`${url}${encodeURIComponent(title + " " + artists)}+lyrics`,
|
||||||
);
|
);
|
||||||
lyrics = (
|
lyrics = (
|
||||||
@ -22,11 +24,11 @@ export default async function fetchLyrics(artists: string, title: string) {
|
|||||||
).data;
|
).data;
|
||||||
[, lyrics] = lyrics.split(delim1);
|
[, lyrics] = lyrics.split(delim1);
|
||||||
[lyrics] = lyrics.split(delim2);
|
[lyrics] = lyrics.split(delim2);
|
||||||
} catch (err) {
|
} catch (err: any) {
|
||||||
showError(err, "[Lyric Query Error]: ");
|
logger.error("Lyric Query Error", err);
|
||||||
try {
|
try {
|
||||||
console.log(
|
logger.info(
|
||||||
"[lyric query]:",
|
"Lyric Query",
|
||||||
`${url}${encodeURIComponent(title + " " + artists)}+song+lyrics`,
|
`${url}${encodeURIComponent(title + " " + artists)}+song+lyrics`,
|
||||||
);
|
);
|
||||||
lyrics = (
|
lyrics = (
|
||||||
@ -36,11 +38,11 @@ export default async function fetchLyrics(artists: string, title: string) {
|
|||||||
).data;
|
).data;
|
||||||
[, lyrics] = lyrics.split(delim1);
|
[, lyrics] = lyrics.split(delim1);
|
||||||
[lyrics] = lyrics.split(delim2);
|
[lyrics] = lyrics.split(delim2);
|
||||||
} catch (err_1) {
|
} catch (err_1: any) {
|
||||||
showError(err_1, "[Lyric Query Error]: ");
|
logger.error("Lyric Query Error", err_1);
|
||||||
try {
|
try {
|
||||||
console.log(
|
logger.info(
|
||||||
"[lyric query]:",
|
"Lyric Query",
|
||||||
`${url}${encodeURIComponent(title + " " + artists)}+song`,
|
`${url}${encodeURIComponent(title + " " + artists)}+song`,
|
||||||
);
|
);
|
||||||
lyrics = (
|
lyrics = (
|
||||||
@ -50,11 +52,11 @@ export default async function fetchLyrics(artists: string, title: string) {
|
|||||||
).data;
|
).data;
|
||||||
[, lyrics] = lyrics.split(delim1);
|
[, lyrics] = lyrics.split(delim1);
|
||||||
[lyrics] = lyrics.split(delim2);
|
[lyrics] = lyrics.split(delim2);
|
||||||
} catch (err_2) {
|
} catch (err_2: any) {
|
||||||
showError(err_2, "[Lyric Query Error]: ");
|
logger.error("Lyric Query Error", err_2);
|
||||||
try {
|
try {
|
||||||
console.log(
|
logger.info(
|
||||||
"[lyric query]:",
|
"Lyric Query",
|
||||||
`${url}${encodeURIComponent(title + " " + artists)}`,
|
`${url}${encodeURIComponent(title + " " + artists)}`,
|
||||||
);
|
);
|
||||||
lyrics = (
|
lyrics = (
|
||||||
@ -64,8 +66,8 @@ export default async function fetchLyrics(artists: string, title: string) {
|
|||||||
).data;
|
).data;
|
||||||
[, lyrics] = lyrics.split(delim1);
|
[, lyrics] = lyrics.split(delim1);
|
||||||
[lyrics] = lyrics.split(delim2);
|
[lyrics] = lyrics.split(delim2);
|
||||||
} catch (err_3) {
|
} catch (err_3: any) {
|
||||||
showError(err_3, "[Lyric Query Error]: ");
|
logger.error("Lyric Query Error", err_3);
|
||||||
lyrics = "Not Found";
|
lyrics = "Not Found";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,7 @@ import { streamToBuffer } from "./streamToBuffer";
|
|||||||
import Jimp from "jimp";
|
import Jimp from "jimp";
|
||||||
import du from "du";
|
import du from "du";
|
||||||
import { cacheDir } from "../conf";
|
import { cacheDir } from "../conf";
|
||||||
|
import { Logger } from "../initializations/logger";
|
||||||
|
|
||||||
interface ImageDimensions {
|
interface ImageDimensions {
|
||||||
height: number;
|
height: number;
|
||||||
@ -15,6 +16,8 @@ interface ImageDimensions {
|
|||||||
|
|
||||||
const fsm = fs.promises;
|
const fsm = fs.promises;
|
||||||
|
|
||||||
|
const logger = new Logger("GetCachedImageBuffer");
|
||||||
|
|
||||||
export async function getCachedImageBuffer(
|
export async function getCachedImageBuffer(
|
||||||
name: string,
|
name: string,
|
||||||
dims?: ImageDimensions,
|
dims?: ImageDimensions,
|
||||||
@ -68,8 +71,8 @@ export async function getCachedImageBuffer(
|
|||||||
await fsm.writeFile(path.join(cacheImgFolder, cacheName), resImgBuf);
|
await fsm.writeFile(path.join(cacheImgFolder, cacheName), resImgBuf);
|
||||||
return resImgBuf;
|
return resImgBuf;
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error: any) {
|
||||||
console.error("[Error in Image Cache]: ", error);
|
logger.error("Error in Image Cache ", error);
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,8 @@
|
|||||||
import scrapYt from "scrape-yt";
|
|
||||||
import { CurrentTrack } from "../context/playerContext";
|
import { CurrentTrack } from "../context/playerContext";
|
||||||
|
import { Client, SearchResult } from "youtubei";
|
||||||
|
import { Logger } from "../initializations/logger";
|
||||||
|
|
||||||
|
const youtube = new Client();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* returns the percentage of matched elements of a certain array(src)
|
* returns the percentage of matched elements of a certain array(src)
|
||||||
@ -25,6 +28,8 @@ export interface YoutubeTrack extends CurrentTrack {
|
|||||||
youtube_uri: string;
|
youtube_uri: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const logger = new Logger("GetYoutubeTrack");
|
||||||
|
|
||||||
export async function getYoutubeTrack(
|
export async function getYoutubeTrack(
|
||||||
track: SpotifyApi.TrackObjectFull,
|
track: SpotifyApi.TrackObjectFull,
|
||||||
): Promise<YoutubeTrack> {
|
): Promise<YoutubeTrack> {
|
||||||
@ -33,8 +38,10 @@ export async function getYoutubeTrack(
|
|||||||
const queryString = `${artistsName[0]} - ${track.name}${
|
const queryString = `${artistsName[0]} - ${track.name}${
|
||||||
artistsName.length > 1 ? ` feat. ${artistsName.slice(1).join(" ")}` : ``
|
artistsName.length > 1 ? ` feat. ${artistsName.slice(1).join(" ")}` : ``
|
||||||
}`;
|
}`;
|
||||||
console.log("Youtube Query String:", queryString);
|
logger.info(`Youtube Query String: ${queryString}`);
|
||||||
const result = await scrapYt.search(queryString, { limit: 7, type: "video" });
|
const result = (await youtube.search(queryString, {
|
||||||
|
type: "video",
|
||||||
|
})) as SearchResult<"video">;
|
||||||
const tracksWithRelevance = result
|
const tracksWithRelevance = result
|
||||||
.map((video) => {
|
.map((video) => {
|
||||||
// percentage of matched track {name, artists} matched with
|
// percentage of matched track {name, artists} matched with
|
||||||
@ -45,8 +52,8 @@ export async function getYoutubeTrack(
|
|||||||
]);
|
]);
|
||||||
// keeps only those tracks which are from the same artist channel
|
// keeps only those tracks which are from the same artist channel
|
||||||
const sameChannel =
|
const sameChannel =
|
||||||
video.channel.name.includes(artistsName[0]) ||
|
video.channel?.name.includes(artistsName[0]) ||
|
||||||
artistsName[0].includes(video.channel.name);
|
(video.channel && artistsName[0].includes(video.channel.name));
|
||||||
return {
|
return {
|
||||||
url: `http://www.youtube.com/watch?v=${video.id}`,
|
url: `http://www.youtube.com/watch?v=${video.id}`,
|
||||||
matchPercentage,
|
matchPercentage,
|
||||||
@ -71,8 +78,8 @@ export async function getYoutubeTrack(
|
|||||||
: rarestTrack)[0].url,
|
: rarestTrack)[0].url,
|
||||||
};
|
};
|
||||||
return finalTrack;
|
return finalTrack;
|
||||||
} catch (error) {
|
} catch (error: any) {
|
||||||
console.error("Failed to resolve track's youtube url: ", error);
|
logger.error(error);
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,9 +5,10 @@ import { YoutubeTrack } from "../helpers/getYoutubeTrack";
|
|||||||
import { join } from "path";
|
import { join } from "path";
|
||||||
import os from "os";
|
import os from "os";
|
||||||
import playerContext from "../context/playerContext";
|
import playerContext from "../context/playerContext";
|
||||||
import showError from "../helpers/showError";
|
import { useLogger } from "./useLogger";
|
||||||
|
|
||||||
function useDownloadQueue() {
|
function useDownloadQueue() {
|
||||||
|
const logger = useLogger(useDownloadQueue.name);
|
||||||
const [downloadQueue, setDownloadQueue] = useState<YoutubeTrack[]>([]);
|
const [downloadQueue, setDownloadQueue] = useState<YoutubeTrack[]>([]);
|
||||||
const [completedQueue, setCompletedQueue] = useState<YoutubeTrack[]>([]);
|
const [completedQueue, setCompletedQueue] = useState<YoutubeTrack[]>([]);
|
||||||
const { currentTrack } = useContext(playerContext);
|
const { currentTrack } = useContext(playerContext);
|
||||||
@ -45,7 +46,7 @@ function useDownloadQueue() {
|
|||||||
),
|
),
|
||||||
)
|
)
|
||||||
.on("error", (err) => {
|
.on("error", (err) => {
|
||||||
showError(err, `[failed to download ${el.name}]: `);
|
logger.error(`failed to download ${el.name}`, err);
|
||||||
})
|
})
|
||||||
.on("finish", () => {
|
.on("finish", () => {
|
||||||
setCompletedQueue([...completedQueue, el]);
|
setCompletedQueue([...completedQueue, el]);
|
||||||
|
6
src/hooks/useLogger.ts
Normal file
6
src/hooks/useLogger.ts
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
import { useMemo } from "react";
|
||||||
|
import { Logger } from "../initializations/logger";
|
||||||
|
|
||||||
|
export function useLogger(module: string) {
|
||||||
|
return useMemo(() => new Logger(module), []);
|
||||||
|
}
|
@ -1,10 +1,11 @@
|
|||||||
import { useContext, useEffect } from "react";
|
import { useContext, useEffect } from "react";
|
||||||
import { LocalStorageKeys } from "../conf";
|
import { LocalStorageKeys } from "../conf";
|
||||||
import authContext from "../context/authContext";
|
import authContext from "../context/authContext";
|
||||||
import showError from "../helpers/showError";
|
|
||||||
import spotifyApi from "../initializations/spotifyApi";
|
import spotifyApi from "../initializations/spotifyApi";
|
||||||
|
import { useLogger } from "./useLogger";
|
||||||
|
|
||||||
function useSpotifyApi() {
|
function useSpotifyApi() {
|
||||||
|
const logger = useLogger(useSpotifyApi.name);
|
||||||
const { access_token, clientId, clientSecret, isLoggedIn, setAccess_token } =
|
const { access_token, clientId, clientSecret, isLoggedIn, setAccess_token } =
|
||||||
useContext(authContext);
|
useContext(authContext);
|
||||||
const refreshToken = localStorage.getItem(LocalStorageKeys.refresh_token);
|
const refreshToken = localStorage.getItem(LocalStorageKeys.refresh_token);
|
||||||
@ -21,7 +22,7 @@ function useSpotifyApi() {
|
|||||||
setAccess_token(token.body.access_token);
|
setAccess_token(token.body.access_token);
|
||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
showError(error);
|
logger.error(error);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
spotifyApi.setAccessToken(access_token);
|
spotifyApi.setAccessToken(access_token);
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
import chalk from "chalk";
|
|
||||||
import { useContext } from "react";
|
import { useContext } from "react";
|
||||||
import SpotifyWebApi from "spotify-web-api-node";
|
import SpotifyWebApi from "spotify-web-api-node";
|
||||||
import authContext from "../context/authContext";
|
import authContext from "../context/authContext";
|
||||||
import showError from "../helpers/showError";
|
import { useLogger } from "./useLogger";
|
||||||
|
|
||||||
function useSpotifyApiError(spotifyApi: SpotifyWebApi) {
|
function useSpotifyApiError(spotifyApi: SpotifyWebApi) {
|
||||||
|
const logger = useLogger(useSpotifyApiError.name);
|
||||||
const { setAccess_token, isLoggedIn } = useContext(authContext);
|
const { setAccess_token, isLoggedIn } = useContext(authContext);
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
return async (error: SpotifyApi.ErrorObject | any) => {
|
return async (error: SpotifyApi.ErrorObject | any) => {
|
||||||
@ -18,13 +18,13 @@ function useSpotifyApiError(spotifyApi: SpotifyWebApi) {
|
|||||||
((noToken || expiredToken) && bodyStatus401)
|
((noToken || expiredToken) && bodyStatus401)
|
||||||
) {
|
) {
|
||||||
try {
|
try {
|
||||||
console.log(chalk.bgYellow.blackBright("Refreshing Access token"));
|
logger.info("Refreshing Access token");
|
||||||
const {
|
const {
|
||||||
body: { access_token: refreshedAccessToken },
|
body: { access_token: refreshedAccessToken },
|
||||||
} = await spotifyApi.refreshAccessToken();
|
} = await spotifyApi.refreshAccessToken();
|
||||||
setAccess_token(refreshedAccessToken);
|
setAccess_token(refreshedAccessToken);
|
||||||
} catch (error) {
|
} catch (error: any) {
|
||||||
showError(error, "[Authorization Failure]: ");
|
logger.error("Authorization Failure", error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
74
src/initializations/logger.ts
Normal file
74
src/initializations/logger.ts
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
import winston from "winston";
|
||||||
|
import chalk from "chalk";
|
||||||
|
import util from "util";
|
||||||
|
|
||||||
|
function safeStringify(arg: string | Record<any, any>): string {
|
||||||
|
return typeof arg === "object" ? JSON.stringify(arg, null, 2) : arg;
|
||||||
|
}
|
||||||
|
|
||||||
|
const spotubeLogFormat = winston.format.printf(({ level, message, label, prefix }) => {
|
||||||
|
if (!prefix && !label && typeof message === "object") {
|
||||||
|
return util.inspect(message, { colors: true, sorted: true, depth: 5 });
|
||||||
|
}
|
||||||
|
const safeMsg = safeStringify(message);
|
||||||
|
const safePrefix = safeStringify(prefix) ?? "";
|
||||||
|
|
||||||
|
const colors = {
|
||||||
|
info: "skyblue",
|
||||||
|
error: "red",
|
||||||
|
debug: "orange",
|
||||||
|
warn: "yellow",
|
||||||
|
};
|
||||||
|
const colorize = chalk.bold.keyword(colors[level as keyof typeof colors]);
|
||||||
|
return `${colorize(level)} [${chalk.bold.green(label)}]: ${colorize(
|
||||||
|
safePrefix,
|
||||||
|
)} ${safeMsg}`;
|
||||||
|
});
|
||||||
|
|
||||||
|
const baseLogger = winston.createLogger({
|
||||||
|
level: "info",
|
||||||
|
format: winston.format.combine(
|
||||||
|
winston.format.prettyPrint({ colorize: true }),
|
||||||
|
spotubeLogFormat,
|
||||||
|
),
|
||||||
|
transports: [new winston.transports.Console()],
|
||||||
|
});
|
||||||
|
|
||||||
|
type LogMessage = string | Record<any, any> | number;
|
||||||
|
|
||||||
|
export class Logger {
|
||||||
|
logger: winston.Logger = baseLogger;
|
||||||
|
|
||||||
|
constructor(public module: string, logger?: winston.Logger) {
|
||||||
|
if (logger) this.logger = logger;
|
||||||
|
}
|
||||||
|
|
||||||
|
log(message: LogMessage, level = "debug", prefix?: LogMessage) {
|
||||||
|
if (typeof message === "object") {
|
||||||
|
this.logger.log(level, { label: this.module, prefix, message: "" });
|
||||||
|
this.logger.log(level, { message });
|
||||||
|
} else {
|
||||||
|
this.logger.log(level, { label: this.module, message, prefix });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
info(msg: LogMessage, msg2?: LogMessage): void {
|
||||||
|
if (msg2) this.log(msg2, "info", msg);
|
||||||
|
else this.log(msg, "info");
|
||||||
|
}
|
||||||
|
|
||||||
|
warn(msg: LogMessage, msg2?: LogMessage): void {
|
||||||
|
if (msg2) this.log(msg2, "warn", msg);
|
||||||
|
else this.log(msg, "warn");
|
||||||
|
}
|
||||||
|
|
||||||
|
error(msg: LogMessage, msg2?: LogMessage): void {
|
||||||
|
if (msg2) this.log(msg2, "error", msg);
|
||||||
|
else this.log(msg, "error");
|
||||||
|
}
|
||||||
|
|
||||||
|
debug(msg: LogMessage, msg2?: LogMessage): void {
|
||||||
|
if (msg2) this.log(msg2, "debug", msg);
|
||||||
|
else this.log(msg, "debug");
|
||||||
|
}
|
||||||
|
}
|
@ -12,7 +12,10 @@
|
|||||||
"moduleResolution": "node",
|
"moduleResolution": "node",
|
||||||
"esModuleInterop": true,
|
"esModuleInterop": true,
|
||||||
"skipLibCheck": true,
|
"skipLibCheck": true,
|
||||||
"incremental": true
|
"incremental": true,
|
||||||
|
"downlevelIteration": true,
|
||||||
|
"declaration": true,
|
||||||
|
"sourceMap": true
|
||||||
},
|
},
|
||||||
"include": [
|
"include": [
|
||||||
"**/*"
|
"**/*"
|
||||||
|
2824
tsconfig.tsbuildinfo
2824
tsconfig.tsbuildinfo
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user