yipee it works
This commit is contained in:
parent
e1da30687e
commit
36d373ef32
4 changed files with 3310 additions and 2555 deletions
461
package-lock.json
generated
461
package-lock.json
generated
|
|
@ -21,6 +21,7 @@
|
|||
"eslint": "^8.57.0",
|
||||
"prettier": "^3.2.5",
|
||||
"prettier-eslint": "^16.3.0",
|
||||
"tsx": "^4.7.1",
|
||||
"typescript": "^4.9.5"
|
||||
},
|
||||
"engines": {
|
||||
|
|
@ -204,6 +205,374 @@
|
|||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/aix-ppc64": {
|
||||
"version": "0.19.12",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.19.12.tgz",
|
||||
"integrity": "sha512-bmoCYyWdEL3wDQIVbcyzRyeKLgk2WtWLTWz1ZIAZF/EGbNOwSA6ew3PftJ1PqMiOOGu0OyFMzG53L0zqIpPeNA==",
|
||||
"cpu": [
|
||||
"ppc64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"aix"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/android-arm": {
|
||||
"version": "0.19.12",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.19.12.tgz",
|
||||
"integrity": "sha512-qg/Lj1mu3CdQlDEEiWrlC4eaPZ1KztwGJ9B6J+/6G+/4ewxJg7gqj8eVYWvao1bXrqGiW2rsBZFSX3q2lcW05w==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"android"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/android-arm64": {
|
||||
"version": "0.19.12",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.19.12.tgz",
|
||||
"integrity": "sha512-P0UVNGIienjZv3f5zq0DP3Nt2IE/3plFzuaS96vihvD0Hd6H/q4WXUGpCxD/E8YrSXfNyRPbpTq+T8ZQioSuPA==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"android"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/android-x64": {
|
||||
"version": "0.19.12",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.19.12.tgz",
|
||||
"integrity": "sha512-3k7ZoUW6Q6YqhdhIaq/WZ7HwBpnFBlW905Fa4s4qWJyiNOgT1dOqDiVAQFwBH7gBRZr17gLrlFCRzF6jFh7Kew==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"android"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/darwin-arm64": {
|
||||
"version": "0.19.12",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.19.12.tgz",
|
||||
"integrity": "sha512-B6IeSgZgtEzGC42jsI+YYu9Z3HKRxp8ZT3cqhvliEHovq8HSX2YX8lNocDn79gCKJXOSaEot9MVYky7AKjCs8g==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/darwin-x64": {
|
||||
"version": "0.19.12",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.19.12.tgz",
|
||||
"integrity": "sha512-hKoVkKzFiToTgn+41qGhsUJXFlIjxI/jSYeZf3ugemDYZldIXIxhvwN6erJGlX4t5h417iFuheZ7l+YVn05N3A==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/freebsd-arm64": {
|
||||
"version": "0.19.12",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.19.12.tgz",
|
||||
"integrity": "sha512-4aRvFIXmwAcDBw9AueDQ2YnGmz5L6obe5kmPT8Vd+/+x/JMVKCgdcRwH6APrbpNXsPz+K653Qg8HB/oXvXVukA==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"freebsd"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/freebsd-x64": {
|
||||
"version": "0.19.12",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.19.12.tgz",
|
||||
"integrity": "sha512-EYoXZ4d8xtBoVN7CEwWY2IN4ho76xjYXqSXMNccFSx2lgqOG/1TBPW0yPx1bJZk94qu3tX0fycJeeQsKovA8gg==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"freebsd"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-arm": {
|
||||
"version": "0.19.12",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.19.12.tgz",
|
||||
"integrity": "sha512-J5jPms//KhSNv+LO1S1TX1UWp1ucM6N6XuL6ITdKWElCu8wXP72l9MM0zDTzzeikVyqFE6U8YAV9/tFyj0ti+w==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-arm64": {
|
||||
"version": "0.19.12",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.19.12.tgz",
|
||||
"integrity": "sha512-EoTjyYyLuVPfdPLsGVVVC8a0p1BFFvtpQDB/YLEhaXyf/5bczaGeN15QkR+O4S5LeJ92Tqotve7i1jn35qwvdA==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-ia32": {
|
||||
"version": "0.19.12",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.19.12.tgz",
|
||||
"integrity": "sha512-Thsa42rrP1+UIGaWz47uydHSBOgTUnwBwNq59khgIwktK6x60Hivfbux9iNR0eHCHzOLjLMLfUMLCypBkZXMHA==",
|
||||
"cpu": [
|
||||
"ia32"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-loong64": {
|
||||
"version": "0.19.12",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.19.12.tgz",
|
||||
"integrity": "sha512-LiXdXA0s3IqRRjm6rV6XaWATScKAXjI4R4LoDlvO7+yQqFdlr1Bax62sRwkVvRIrwXxvtYEHHI4dm50jAXkuAA==",
|
||||
"cpu": [
|
||||
"loong64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-mips64el": {
|
||||
"version": "0.19.12",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.19.12.tgz",
|
||||
"integrity": "sha512-fEnAuj5VGTanfJ07ff0gOA6IPsvrVHLVb6Lyd1g2/ed67oU1eFzL0r9WL7ZzscD+/N6i3dWumGE1Un4f7Amf+w==",
|
||||
"cpu": [
|
||||
"mips64el"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-ppc64": {
|
||||
"version": "0.19.12",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.19.12.tgz",
|
||||
"integrity": "sha512-nYJA2/QPimDQOh1rKWedNOe3Gfc8PabU7HT3iXWtNUbRzXS9+vgB0Fjaqr//XNbd82mCxHzik2qotuI89cfixg==",
|
||||
"cpu": [
|
||||
"ppc64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-riscv64": {
|
||||
"version": "0.19.12",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.19.12.tgz",
|
||||
"integrity": "sha512-2MueBrlPQCw5dVJJpQdUYgeqIzDQgw3QtiAHUC4RBz9FXPrskyyU3VI1hw7C0BSKB9OduwSJ79FTCqtGMWqJHg==",
|
||||
"cpu": [
|
||||
"riscv64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-s390x": {
|
||||
"version": "0.19.12",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.19.12.tgz",
|
||||
"integrity": "sha512-+Pil1Nv3Umes4m3AZKqA2anfhJiVmNCYkPchwFJNEJN5QxmTs1uzyy4TvmDrCRNT2ApwSari7ZIgrPeUx4UZDg==",
|
||||
"cpu": [
|
||||
"s390x"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-x64": {
|
||||
"version": "0.19.12",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.19.12.tgz",
|
||||
"integrity": "sha512-B71g1QpxfwBvNrfyJdVDexenDIt1CiDN1TIXLbhOw0KhJzE78KIFGX6OJ9MrtC0oOqMWf+0xop4qEU8JrJTwCg==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/netbsd-x64": {
|
||||
"version": "0.19.12",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.19.12.tgz",
|
||||
"integrity": "sha512-3ltjQ7n1owJgFbuC61Oj++XhtzmymoCihNFgT84UAmJnxJfm4sYCiSLTXZtE00VWYpPMYc+ZQmB6xbSdVh0JWA==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"netbsd"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/openbsd-x64": {
|
||||
"version": "0.19.12",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.19.12.tgz",
|
||||
"integrity": "sha512-RbrfTB9SWsr0kWmb9srfF+L933uMDdu9BIzdA7os2t0TXhCRjrQyCeOt6wVxr79CKD4c+p+YhCj31HBkYcXebw==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"openbsd"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/sunos-x64": {
|
||||
"version": "0.19.12",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.19.12.tgz",
|
||||
"integrity": "sha512-HKjJwRrW8uWtCQnQOz9qcU3mUZhTUQvi56Q8DPTLLB+DawoiQdjsYq+j+D3s9I8VFtDr+F9CjgXKKC4ss89IeA==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"sunos"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/win32-arm64": {
|
||||
"version": "0.19.12",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.19.12.tgz",
|
||||
"integrity": "sha512-URgtR1dJnmGvX864pn1B2YUYNzjmXkuJOIqG2HdU62MVS4EHpU2946OZoTMnRUHklGtJdJZ33QfzdjGACXhn1A==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/win32-ia32": {
|
||||
"version": "0.19.12",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.19.12.tgz",
|
||||
"integrity": "sha512-+ZOE6pUkMOJfmxmBZElNOx72NKpIa/HFOMGzu8fqzQJ5kgf6aTGrcJaFsNiVMH4JKpMipyK+7k0n2UXN7a8YKQ==",
|
||||
"cpu": [
|
||||
"ia32"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/win32-x64": {
|
||||
"version": "0.19.12",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.19.12.tgz",
|
||||
"integrity": "sha512-T1QyPSDCyMXaO3pzBkF96E8xMkiRYbUEZADd29SyPGabqxMViNoii+NcK7eWJAEoU6RZyEm5lVSIjTmcdoB9HA==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@eslint-community/eslint-utils": {
|
||||
"version": "4.4.0",
|
||||
"resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz",
|
||||
|
|
@ -822,6 +1191,44 @@
|
|||
"url": "https://dotenvx.com"
|
||||
}
|
||||
},
|
||||
"node_modules/esbuild": {
|
||||
"version": "0.19.12",
|
||||
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.19.12.tgz",
|
||||
"integrity": "sha512-aARqgq8roFBj054KvQr5f1sFu0D65G+miZRCuJyJ0G13Zwx7vRar5Zhn2tkQNzIXcBrNVsv/8stehpj+GAjgbg==",
|
||||
"dev": true,
|
||||
"hasInstallScript": true,
|
||||
"bin": {
|
||||
"esbuild": "bin/esbuild"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@esbuild/aix-ppc64": "0.19.12",
|
||||
"@esbuild/android-arm": "0.19.12",
|
||||
"@esbuild/android-arm64": "0.19.12",
|
||||
"@esbuild/android-x64": "0.19.12",
|
||||
"@esbuild/darwin-arm64": "0.19.12",
|
||||
"@esbuild/darwin-x64": "0.19.12",
|
||||
"@esbuild/freebsd-arm64": "0.19.12",
|
||||
"@esbuild/freebsd-x64": "0.19.12",
|
||||
"@esbuild/linux-arm": "0.19.12",
|
||||
"@esbuild/linux-arm64": "0.19.12",
|
||||
"@esbuild/linux-ia32": "0.19.12",
|
||||
"@esbuild/linux-loong64": "0.19.12",
|
||||
"@esbuild/linux-mips64el": "0.19.12",
|
||||
"@esbuild/linux-ppc64": "0.19.12",
|
||||
"@esbuild/linux-riscv64": "0.19.12",
|
||||
"@esbuild/linux-s390x": "0.19.12",
|
||||
"@esbuild/linux-x64": "0.19.12",
|
||||
"@esbuild/netbsd-x64": "0.19.12",
|
||||
"@esbuild/openbsd-x64": "0.19.12",
|
||||
"@esbuild/sunos-x64": "0.19.12",
|
||||
"@esbuild/win32-arm64": "0.19.12",
|
||||
"@esbuild/win32-ia32": "0.19.12",
|
||||
"@esbuild/win32-x64": "0.19.12"
|
||||
}
|
||||
},
|
||||
"node_modules/escape-string-regexp": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
|
||||
|
|
@ -1104,6 +1511,32 @@
|
|||
"integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/fsevents": {
|
||||
"version": "2.3.3",
|
||||
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
|
||||
"integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
|
||||
"dev": true,
|
||||
"hasInstallScript": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
],
|
||||
"engines": {
|
||||
"node": "^8.16.0 || ^10.6.0 || >=11.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/get-tsconfig": {
|
||||
"version": "4.7.3",
|
||||
"resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.7.3.tgz",
|
||||
"integrity": "sha512-ZvkrzoUA0PQZM6fy6+/Hce561s+faD1rsNwhnO5FelNjyy7EMGJ3Rz1AQ8GYDWjhRs/7dBLOEJvhK8MiEJOAFg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"resolve-pkg-maps": "^1.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/privatenumber/get-tsconfig?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/glob": {
|
||||
"version": "7.2.3",
|
||||
"resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
|
||||
|
|
@ -1982,6 +2415,15 @@
|
|||
"node": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/resolve-pkg-maps": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz",
|
||||
"integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==",
|
||||
"dev": true,
|
||||
"funding": {
|
||||
"url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/reusify": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz",
|
||||
|
|
@ -2184,6 +2626,25 @@
|
|||
"integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/tsx": {
|
||||
"version": "4.7.1",
|
||||
"resolved": "https://registry.npmjs.org/tsx/-/tsx-4.7.1.tgz",
|
||||
"integrity": "sha512-8d6VuibXHtlN5E3zFkgY8u4DX7Y3Z27zvvPKVmLon/D4AjuKzarkUBTLDBgj9iTQ0hg5xM7c/mYiRVM+HETf0g==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"esbuild": "~0.19.10",
|
||||
"get-tsconfig": "^4.7.2"
|
||||
},
|
||||
"bin": {
|
||||
"tsx": "dist/cli.mjs"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18.0.0"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"fsevents": "~2.3.3"
|
||||
}
|
||||
},
|
||||
"node_modules/type-check": {
|
||||
"version": "0.4.0",
|
||||
"resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
|
||||
|
|
|
|||
|
|
@ -5,7 +5,8 @@
|
|||
"scripts": {
|
||||
"build": "tsc",
|
||||
"start": "node dist/index.js",
|
||||
"watch": "tsc watch"
|
||||
"watch": "tsc watch",
|
||||
"dev": "nodemon src/index.ts"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@biomejs/biome": "1.6.0",
|
||||
|
|
@ -15,6 +16,7 @@
|
|||
"eslint": "^8.57.0",
|
||||
"prettier": "^3.2.5",
|
||||
"prettier-eslint": "^16.3.0",
|
||||
"tsx": "^4.7.1",
|
||||
"typescript": "^4.9.5"
|
||||
},
|
||||
"engines": {
|
||||
|
|
|
|||
1
settings.json
Normal file
1
settings.json
Normal file
|
|
@ -0,0 +1 @@
|
|||
{"requestChannels":{"777923126981558282":{"channelId":"1219720332101943296","messageId":"1219745004659015813"}}}
|
||||
375
src/index.ts
375
src/index.ts
|
|
@ -9,22 +9,40 @@ import {
|
|||
GatewayIntentBits,
|
||||
type Message,
|
||||
SlashCommandBuilder,
|
||||
Interaction,
|
||||
} from "discord.js";
|
||||
|
||||
import { Connectors, Track } from "shoukaku";
|
||||
|
||||
import { Kazagumo, type KazagumoPlayer, type KazagumoTrack, type Payload } from "kazagumo";
|
||||
import {
|
||||
Kazagumo,
|
||||
type KazagumoPlayer,
|
||||
type KazagumoTrack,
|
||||
type Payload,
|
||||
} from "kazagumo";
|
||||
|
||||
import KazagumoPlugin from "kazagumo-spotify";
|
||||
import prettyMilliseconds from 'pretty-ms';
|
||||
import prettyMilliseconds from "pretty-ms";
|
||||
|
||||
const { Guilds, GuildVoiceStates, GuildMessages, MessageContent } = GatewayIntentBits;
|
||||
const { Guilds, GuildVoiceStates, GuildMessages, MessageContent } =
|
||||
GatewayIntentBits;
|
||||
|
||||
import * as dotenv from "dotenv";
|
||||
import { readFileSync, writeFileSync } from "fs";
|
||||
import { channel } from "process";
|
||||
|
||||
dotenv.config();
|
||||
|
||||
if (!process.env.SPOTIFY_ID || !process.env.SPOTIFY_SECRET) {
|
||||
throw "Spotfiy Credentials missing";
|
||||
throw "Spotify Credentials missing";
|
||||
}
|
||||
|
||||
let settings: settings;
|
||||
|
||||
try {
|
||||
settings = JSON.parse(readFileSync("./settings.json", "utf8")); // Load data
|
||||
} catch (e) {
|
||||
settings = { requestChannels: {} }; // Init if no data found
|
||||
}
|
||||
|
||||
const Nodes = [
|
||||
|
|
@ -59,25 +77,37 @@ const kazagumo = new Kazagumo(
|
|||
],
|
||||
},
|
||||
new Connectors.DiscordJS(client),
|
||||
Nodes,
|
||||
Nodes
|
||||
);
|
||||
|
||||
client.on("ready", () => console.log(`${client.user!.tag}·Ready!`));
|
||||
interface requestChannels {
|
||||
[guildId: string]: {
|
||||
channelId: string;
|
||||
messageId: string;
|
||||
};
|
||||
}
|
||||
interface settings {
|
||||
requestChannels: requestChannels;
|
||||
}
|
||||
|
||||
client.on("ready", () => {
|
||||
// console.log(client)
|
||||
console.log(`${client.user!.tag}·Ready!`);
|
||||
});
|
||||
|
||||
kazagumo.shoukaku.on("ready", (name: string) =>
|
||||
console.log(`Lavalink ${name}: Ready!`),
|
||||
console.log(`Lavalink ${name}: Ready!`)
|
||||
);
|
||||
kazagumo.shoukaku.on("error", (name: string, error: Error) =>
|
||||
console.error(`Lavalink ${name}: Error Caught,`, error),
|
||||
console.error(`Lavalink ${name}: Error Caught,`, error)
|
||||
);
|
||||
kazagumo.shoukaku.on("close", (name: string, code: unknown, reason: unknown) =>
|
||||
console.warn(
|
||||
`Lavalink ${name}: Closed, Code ${code}, Reason ${reason || "No reason"}`,
|
||||
),
|
||||
`Lavalink ${name}: Closed, Code ${code}, Reason ${reason || "No reason"}`
|
||||
)
|
||||
);
|
||||
kazagumo.shoukaku.on("debug", (name: string, info: string) =>
|
||||
console.debug(`Lavalink ${name}: Debug,`, info),
|
||||
console.debug(`Lavalink ${name}: Debug,`, info)
|
||||
);
|
||||
|
||||
kazagumo.shoukaku.on("disconnect", (name: string, count: number) => {
|
||||
|
|
@ -88,11 +118,18 @@ kazagumo.shoukaku.on("disconnect", (name:string, count:number) => {
|
|||
|
||||
kazagumo.on("playerStart", (player: KazagumoPlayer, track: KazagumoTrack) => {
|
||||
if (!player.textId) return;
|
||||
const channel = client.channels.cache.get(player.textId)
|
||||
const channel = client.channels.cache.get(player.textId);
|
||||
if (!channel) return;
|
||||
if (channel.type === ChannelType.GuildText)
|
||||
{ channel.send({ content: `Now playing **${track.title}** by **${track.author}**` })
|
||||
.then((x:any) => player.data.set("message", x));}
|
||||
if (channel.type === ChannelType.GuildText) {
|
||||
channel
|
||||
.send({
|
||||
content: `Now playing **${track.title}** by **${track.author}**`,
|
||||
})
|
||||
.then((x: any) => {
|
||||
player.data.set("message", x);
|
||||
setTimeout(() => x.delete(), 3000);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
kazagumo.on("playerEnd", (player: KazagumoPlayer) => {
|
||||
|
|
@ -101,30 +138,176 @@ kazagumo.on("playerEnd", (player:KazagumoPlayer) => {
|
|||
|
||||
kazagumo.on("playerEmpty", (player: KazagumoPlayer) => {
|
||||
if (!player.textId) return;
|
||||
const channel = client.channels.cache.get(player.textId)
|
||||
const channel = client.channels.cache.get(player.textId);
|
||||
if (!channel) return;
|
||||
if (channel.type === ChannelType.GuildText)
|
||||
{ channel.send({ content: "Destroyed player due to inactivity." })
|
||||
.then((x:any) => player.data.set("message", x));}
|
||||
if (channel.type === ChannelType.GuildText) {
|
||||
channel
|
||||
.send({ content: "Destroyed player due to inactivity." })
|
||||
.then((x: any) => {
|
||||
player.data.set("message", x);
|
||||
setTimeout(() => x.delete(), 3000);
|
||||
});
|
||||
}
|
||||
player.destroy();
|
||||
});
|
||||
|
||||
client.on("messageCreate", async (msg: Message) => {
|
||||
// console.log(msg.content);
|
||||
if (msg.author.bot) return;
|
||||
if (!msg.guild) return;
|
||||
if (!msg.member) return;
|
||||
if (msg.channel.type !== ChannelType.GuildText) return;
|
||||
if (msg.content.startsWith(".")) {
|
||||
let cmd = msg.content.split(".")[1];
|
||||
switch (cmd) {
|
||||
case "init":
|
||||
if (msg.guildId && msg.channelId) {
|
||||
if (!settings.requestChannels[msg.guildId]) {
|
||||
await msg.delete();
|
||||
const player = await kazagumo.createPlayer({
|
||||
guildId: msg.guild.id,
|
||||
textId: msg.channel.id,
|
||||
voiceId: msg.channel.id,
|
||||
volume: 40,
|
||||
});
|
||||
const play = new ButtonBuilder()
|
||||
.setCustomId("play")
|
||||
.setLabel("Play/Pause")
|
||||
.setStyle(ButtonStyle.Secondary)
|
||||
.setEmoji("889943073793122355");
|
||||
|
||||
const stop = new ButtonBuilder()
|
||||
.setCustomId("stop")
|
||||
.setLabel("Stop Playing")
|
||||
.setStyle(ButtonStyle.Secondary)
|
||||
.setEmoji("889943074258694184");
|
||||
|
||||
const skip = new ButtonBuilder()
|
||||
.setCustomId("skip")
|
||||
.setLabel("Skip Song")
|
||||
.setStyle(ButtonStyle.Secondary)
|
||||
.setEmoji("889943074233516072");
|
||||
|
||||
const loop = new ButtonBuilder()
|
||||
.setCustomId("loop")
|
||||
.setLabel("Loop Song")
|
||||
.setStyle(ButtonStyle.Secondary)
|
||||
.setEmoji("889943073667289099");
|
||||
|
||||
const shuffle = new ButtonBuilder()
|
||||
.setCustomId("shuffle")
|
||||
.setLabel("Shuffle Queue")
|
||||
.setStyle(ButtonStyle.Secondary)
|
||||
.setEmoji("890325437962678352");
|
||||
|
||||
const seek = new ButtonBuilder()
|
||||
.setCustomId("seek")
|
||||
.setLabel("Seek Forward")
|
||||
.setStyle(ButtonStyle.Secondary)
|
||||
.setEmoji("890325511878889504");
|
||||
|
||||
const previous = new ButtonBuilder()
|
||||
.setCustomId("previous")
|
||||
.setLabel("Previous Song")
|
||||
.setStyle(ButtonStyle.Secondary)
|
||||
.setEmoji("890325512071831562");
|
||||
|
||||
const row = new ActionRowBuilder<ButtonBuilder>().addComponents(
|
||||
play,
|
||||
stop,
|
||||
skip,
|
||||
loop
|
||||
);
|
||||
const row2 = new ActionRowBuilder<ButtonBuilder>().addComponents(
|
||||
shuffle,
|
||||
seek,
|
||||
previous
|
||||
);
|
||||
|
||||
let track_author: string;
|
||||
track_author = "None";
|
||||
let track_duration;
|
||||
track_duration = "NaN:NaN";
|
||||
|
||||
const embed = new EmbedBuilder()
|
||||
.setAuthor({
|
||||
name: "Moe",
|
||||
iconURL: "https://cdn.m3.fyi/MoeLogo.gif",
|
||||
})
|
||||
.setTitle("Nothing is being played right now")
|
||||
.setDescription("Enter message to search")
|
||||
.addFields(
|
||||
{
|
||||
name: "Author",
|
||||
value: track_author,
|
||||
inline: true,
|
||||
},
|
||||
{
|
||||
name: "Duration",
|
||||
value: track_duration,
|
||||
inline: true,
|
||||
}
|
||||
)
|
||||
.setColor("#ff0047");
|
||||
|
||||
const response = await msg.channel.send({
|
||||
embeds: [embed],
|
||||
components: [row, row2],
|
||||
});
|
||||
|
||||
settings.requestChannels[msg.guildId] = {
|
||||
channelId: msg.channelId,
|
||||
messageId: response.id,
|
||||
};
|
||||
|
||||
console.log(settings.requestChannels[msg.guildId]);
|
||||
|
||||
writeFileSync("./settings.json", JSON.stringify(settings)); // Save count to file
|
||||
return;
|
||||
} else {
|
||||
let answer = await msg.reply("Already initialized");
|
||||
console.log(answer);
|
||||
setTimeout(() => msg.delete(), 3000);
|
||||
setTimeout(() => answer.delete(), 3000);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (msg.channel.name === "moe-song-requests") {
|
||||
let controls;
|
||||
if (!settings.requestChannels[msg.guild.id]) {
|
||||
let answer = await msg.reply("Use .init first");
|
||||
console.log(answer);
|
||||
setTimeout(() => msg.delete(), 3000);
|
||||
setTimeout(() => answer.delete(), 3000);
|
||||
return;
|
||||
} else {
|
||||
let channelId = settings.requestChannels[msg.guild.id].channelId;
|
||||
let messageId = settings.requestChannels[msg.guild.id].messageId;
|
||||
let channel = msg.guild.channels.cache.get(channelId);
|
||||
if (channel && channel.type === ChannelType.GuildText) {
|
||||
controls = await channel.messages.fetch(messageId);
|
||||
}
|
||||
// let controls = msg.channel.guild
|
||||
// get(requestChannels[msg.guild.id]);
|
||||
// client.channels.fetch(requestChannels[msg.guild.id])
|
||||
}
|
||||
const query = msg.content;
|
||||
|
||||
const { channel } = msg.member.voice;
|
||||
if (!channel) {
|
||||
msg.reply(
|
||||
"You need to be in a voice channel to use this command!",
|
||||
let answer = await msg.reply(
|
||||
"You need to be in a voice channel to use this command!"
|
||||
);
|
||||
setTimeout(() => answer.delete(), 3000);
|
||||
|
||||
return;
|
||||
}
|
||||
// if (channel.type !== ChannelType.GuildVoice) {return;}
|
||||
|
||||
const player = await kazagumo.createPlayer({
|
||||
guildId: msg.guild.id,
|
||||
|
|
@ -132,9 +315,12 @@ client.on("messageCreate", async (msg:Message) => {
|
|||
voiceId: channel.id,
|
||||
volume: 40,
|
||||
});
|
||||
console.log("Player created")
|
||||
console.log("Player created");
|
||||
const result = await kazagumo.search(query, { requester: msg.author });
|
||||
if (!result.tracks.length) msg.reply("No results found!");
|
||||
if (!result.tracks.length) {
|
||||
let answer = await msg.reply("No results found!");
|
||||
setTimeout(() => answer.delete(), 3000);
|
||||
}
|
||||
|
||||
if (result.type === "PLAYLIST")
|
||||
for (const track of result.tracks) player.queue.add(track);
|
||||
|
|
@ -182,36 +368,45 @@ client.on("messageCreate", async (msg:Message) => {
|
|||
.setStyle(ButtonStyle.Secondary)
|
||||
.setEmoji("890325512071831562");
|
||||
|
||||
const row = new ActionRowBuilder<ButtonBuilder>().addComponents(play, stop, skip, loop);
|
||||
const row2 = new ActionRowBuilder<ButtonBuilder>().addComponents(shuffle, seek, previous);
|
||||
const row = new ActionRowBuilder<ButtonBuilder>().addComponents(
|
||||
play,
|
||||
stop,
|
||||
skip,
|
||||
loop
|
||||
);
|
||||
const row2 = new ActionRowBuilder<ButtonBuilder>().addComponents(
|
||||
shuffle,
|
||||
seek,
|
||||
previous
|
||||
);
|
||||
|
||||
let track_author:string
|
||||
let track_author: string;
|
||||
if (result.tracks[0].author) {
|
||||
track_author = result.tracks[0].author
|
||||
track_author = result.tracks[0].author;
|
||||
} else {
|
||||
track_author = ""
|
||||
track_author = "";
|
||||
}
|
||||
let track_duration:string
|
||||
let track_duration: string;
|
||||
if (result.tracks[0].length) {
|
||||
track_duration = prettyMilliseconds(result.tracks[0].length)
|
||||
track_duration = prettyMilliseconds(result.tracks[0].length);
|
||||
} else {
|
||||
track_duration = "NaN:NaN"
|
||||
track_duration = "NaN:NaN";
|
||||
}
|
||||
let track_thumbnail:string
|
||||
let track_thumbnail: string;
|
||||
if (result.tracks[0].thumbnail) {
|
||||
track_thumbnail = result.tracks[0].thumbnail.toString()
|
||||
track_thumbnail = result.tracks[0].thumbnail.toString();
|
||||
} else {
|
||||
track_thumbnail = "NaN:NaN"
|
||||
track_thumbnail = "NaN:NaN";
|
||||
}
|
||||
const embed = new EmbedBuilder()
|
||||
.setAuthor({
|
||||
name: "Added to queue",
|
||||
name: "Now playing",
|
||||
iconURL: "https://cdn.m3.fyi/MoeLogo.gif",
|
||||
})
|
||||
.setTitle(
|
||||
result.type === "PLAYLIST"
|
||||
? `Queued ${result.tracks.length} from ${result.playlistName}`
|
||||
: `Queued ${result.tracks[0].title}`,
|
||||
? `Playing ${result.tracks.length} from ${result.playlistName}`
|
||||
: `Playing ${result.tracks[0].title}`
|
||||
)
|
||||
.setDescription(`[${result.tracks[0].title}](${result.tracks[0].uri})`)
|
||||
.addFields(
|
||||
|
|
@ -224,20 +419,116 @@ client.on("messageCreate", async (msg:Message) => {
|
|||
name: "Duration",
|
||||
value: track_duration,
|
||||
inline: true,
|
||||
},
|
||||
}
|
||||
)
|
||||
.setThumbnail(track_thumbnail)
|
||||
.setColor("#ff0047");
|
||||
|
||||
if (!player.playing && !player.paused) player.play();
|
||||
|
||||
const response = msg.channel.send({
|
||||
if (controls) {
|
||||
const response = controls.edit({
|
||||
embeds: [embed],
|
||||
components: [row, row2],
|
||||
})
|
||||
});
|
||||
}
|
||||
setTimeout(() => msg.delete(), 3000);
|
||||
|
||||
return;
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
client.on("interactionCreate", async (interaction: Interaction) => {
|
||||
console.log(interaction.id);
|
||||
if (interaction.isButton()) {
|
||||
const guild = client.guilds.cache.get(interaction.guildId!);
|
||||
const member = guild?.members.cache.get(interaction.member!.user.id);
|
||||
let voiceId = member?.voice.channel!.id;
|
||||
let player = await kazagumo.createPlayer({
|
||||
guildId: interaction.guild!.id,
|
||||
textId: interaction.channel!.id,
|
||||
voiceId: voiceId!,
|
||||
});
|
||||
// volume: 40
|
||||
// })
|
||||
switch (interaction.customId) {
|
||||
case "play":
|
||||
player.pause(!player.paused);
|
||||
await interaction.reply({
|
||||
ephemeral: true,
|
||||
content: "Toggled Pause",
|
||||
});
|
||||
break;
|
||||
case "stop":
|
||||
// player.disconnect();
|
||||
player.destroy();
|
||||
await interaction.reply({
|
||||
ephemeral: true,
|
||||
content: "Stopped Playing",
|
||||
});
|
||||
break;
|
||||
case "skip":
|
||||
player.skip();
|
||||
await interaction.reply({
|
||||
ephemeral: true,
|
||||
content: "Skipped Song",
|
||||
});
|
||||
break;
|
||||
case "loop":
|
||||
if (player.loop != "none") {
|
||||
player.setLoop("none");
|
||||
await interaction.reply({
|
||||
ephemeral: true,
|
||||
content: "Disabled Looping",
|
||||
});
|
||||
} else {
|
||||
player.setLoop("track");
|
||||
await interaction.reply({
|
||||
ephemeral: true,
|
||||
content: "Started Looping",
|
||||
});
|
||||
}
|
||||
break;
|
||||
case "shuffle":
|
||||
player.queue.shuffle();
|
||||
await interaction.reply({
|
||||
ephemeral: true,
|
||||
content: "Shuffled Queue",
|
||||
});
|
||||
break;
|
||||
case "seek":
|
||||
// let position = player.position / 1000;
|
||||
// position = position | 0;
|
||||
// console.log(position);
|
||||
// player.seek(position + 5);
|
||||
await interaction.reply({
|
||||
ephemeral: true,
|
||||
content: "Does not work :pensive:",
|
||||
// content: "Skipped 5s forward",
|
||||
});
|
||||
break;
|
||||
case "previous":
|
||||
let track = player.getPrevious();
|
||||
await interaction.reply({
|
||||
ephemeral: true,
|
||||
content: "Queued previous song",
|
||||
});
|
||||
player.play(track[0]);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
// interaction.id
|
||||
// console.log(interaction.client.application.get(interaction.commandName))
|
||||
// switch (interaction.customID) {
|
||||
// case value:
|
||||
// break;
|
||||
|
||||
// default:
|
||||
// break;
|
||||
// }
|
||||
});
|
||||
|
||||
client.login(process.env.TOKEN);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue