New logging architecture for better debugging

This commit is contained in:
Kingkor Roy Tirtho 2021-12-28 23:03:22 +06:00
parent 7024da3fed
commit d0fde48971
21 changed files with 3302 additions and 186 deletions

1
.gitignore vendored
View File

@ -19,3 +19,4 @@ aur-struct/*.zip*
aur-struct/*.zst aur-struct/*.zst
*.tsbuildinfo *.tsbuildinfo
tsconfig.tsbuildinfo

387
package-lock.json generated
View File

@ -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",

View File

@ -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": {

View File

@ -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);
} }
} }

View File

@ -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);
}); });

View File

@ -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);
} }
} }

View File

@ -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);
} }
})(); })();
}, },

View File

@ -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);
} }

View File

@ -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);
} }
} }

View File

@ -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);
}); });
} }

View File

@ -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);
} }
}; };

View File

@ -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";
} }
} }

View File

@ -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;
} }
} }

View File

@ -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;
} }
} }

View File

@ -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
View File

@ -0,0 +1,6 @@
import { useMemo } from "react";
import { Logger } from "../initializations/logger";
export function useLogger(module: string) {
return useMemo(() => new Logger(module), []);
}

View File

@ -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);

View File

@ -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);
} }
} }
}; };

View 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");
}
}

View File

@ -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": [
"**/*" "**/*"

File diff suppressed because it is too large Load Diff