diff --git a/.gitignore b/.gitignore index 993ff72..390869e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ # files .vscode/ .idea/ +json.sqlite .env .env.local diff --git a/package.json b/package.json index 119a73b..f5d99b6 100644 --- a/package.json +++ b/package.json @@ -15,8 +15,11 @@ "dependencies": { "@discordx/importer": "^1.3.0", "@discordx/pagination": "^3.5.1", + "better-sqlite3": "^11.0.0", "discord.js": "^14.15.3", - "discordx": "^11.9.2" + "discordx": "^11.9.2", + "dotenv": "^16.4.5", + "quick.db": "^9.1.7" }, "devDependencies": { "@types/node": "^20.14.1", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 89eff04..2bb31cf 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -14,12 +14,21 @@ importers: '@discordx/pagination': specifier: ^3.5.1 version: 3.5.1(discord.js@14.15.3) + better-sqlite3: + specifier: ^11.0.0 + version: 11.0.0 discord.js: specifier: ^14.15.3 version: 14.15.3 discordx: specifier: ^11.9.2 version: 11.9.2(discord.js@14.15.3) + dotenv: + specifier: ^16.4.5 + version: 16.4.5 + quick.db: + specifier: ^9.1.7 + version: 9.1.7 devDependencies: '@types/node': specifier: ^20.14.1 @@ -175,10 +184,22 @@ packages: balanced-match@1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + base64-js@1.5.1: + resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} + + better-sqlite3@11.0.0: + resolution: {integrity: sha512-1NnNhmT3EZTsKtofJlMox1jkMxdedILury74PwUbQBjWgo4tL4kf7uTAjU55mgQwjdzqakSTjkf+E1imrFwjnA==} + binary-extensions@2.3.0: resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} engines: {node: '>=8'} + bindings@1.5.0: + resolution: {integrity: sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==} + + bl@4.1.0: + resolution: {integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==} + brace-expansion@1.1.11: resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} @@ -189,10 +210,16 @@ packages: resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} engines: {node: '>=8'} + buffer@5.7.1: + resolution: {integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==} + chokidar@3.6.0: resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} engines: {node: '>= 8.10.0'} + chownr@1.1.4: + resolution: {integrity: sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==} + color-convert@2.0.1: resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} engines: {node: '>=7.0.0'} @@ -219,6 +246,18 @@ packages: supports-color: optional: true + decompress-response@6.0.0: + resolution: {integrity: sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==} + engines: {node: '>=10'} + + deep-extend@0.6.0: + resolution: {integrity: sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==} + engines: {node: '>=4.0.0'} + + detect-libc@2.0.3: + resolution: {integrity: sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==} + engines: {node: '>=8'} + diff@4.0.2: resolution: {integrity: sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==} engines: {node: '>=0.3.1'} @@ -236,6 +275,10 @@ packages: peerDependencies: discord.js: '>=14 || ^14.0.0-dev' + dotenv@16.4.5: + resolution: {integrity: sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==} + engines: {node: '>=12'} + eastasianwidth@0.2.0: resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} @@ -245,9 +288,19 @@ packages: emoji-regex@9.2.2: resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} + end-of-stream@1.4.4: + resolution: {integrity: sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==} + + expand-template@2.0.3: + resolution: {integrity: sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==} + engines: {node: '>=6'} + fast-deep-equal@3.1.3: resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + file-uri-to-path@1.0.0: + resolution: {integrity: sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==} + fill-range@7.1.1: resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} engines: {node: '>=8'} @@ -256,11 +309,17 @@ packages: resolution: {integrity: sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==} engines: {node: '>=14'} + fs-constants@1.0.0: + resolution: {integrity: sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==} + fsevents@2.3.3: resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} os: [darwin] + github-from-package@0.0.0: + resolution: {integrity: sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==} + glob-parent@5.1.2: resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} engines: {node: '>= 6'} @@ -274,9 +333,18 @@ packages: resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==} engines: {node: '>=4'} + ieee754@1.2.1: + resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} + ignore-by-default@1.0.1: resolution: {integrity: sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==} + inherits@2.0.4: + resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + + ini@1.3.8: + resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==} + is-binary-path@2.1.0: resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} engines: {node: '>=8'} @@ -320,6 +388,10 @@ packages: make-error@1.3.6: resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==} + mimic-response@3.1.0: + resolution: {integrity: sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==} + engines: {node: '>=10'} + minimatch@3.1.2: resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} @@ -327,13 +399,26 @@ packages: resolution: {integrity: sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==} engines: {node: '>=16 || 14 >=14.17'} + minimist@1.2.8: + resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} + minipass@7.1.2: resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==} engines: {node: '>=16 || 14 >=14.17'} + mkdirp-classic@0.5.3: + resolution: {integrity: sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==} + ms@2.1.2: resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} + napi-build-utils@1.0.2: + resolution: {integrity: sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==} + + node-abi@3.63.0: + resolution: {integrity: sha512-vAszCsOUrUxjGAmdnM/pq7gUgie0IRteCQMX6d4A534fQCR93EJU5qgzBvU6EkFfK27s0T3HEV3BOyJIr7OMYw==} + engines: {node: '>=10'} + nodemon@3.1.3: resolution: {integrity: sha512-m4Vqs+APdKzDFpuaL9F9EVOF85+h070FnkHVEoU4+rmT6Vw0bmNl7s61VEkY/cJkL7RCv1p4urnUDUMrS5rk2w==} engines: {node: '>=10'} @@ -343,6 +428,9 @@ packages: resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} engines: {node: '>=0.10.0'} + once@1.4.0: + resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} + path-key@3.1.1: resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} engines: {node: '>=8'} @@ -355,6 +443,11 @@ packages: resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} engines: {node: '>=8.6'} + prebuild-install@7.1.2: + resolution: {integrity: sha512-UnNke3IQb6sgarcZIDU3gbMeTp/9SSU1DAIkil7PrqG1vZlBtY5msYccSKSHDqa3hNg436IXK+SNImReuA1wEQ==} + engines: {node: '>=10'} + hasBin: true + prettier@3.3.1: resolution: {integrity: sha512-7CAwy5dRsxs8PHXT3twixW9/OEll8MLE0VRPCJyl7CkS6VHGPSlsVaWTiASPTyGyYRyApxlaWTzwUxVNrhcwDg==} engines: {node: '>=14'} @@ -363,10 +456,27 @@ packages: pstree.remy@1.1.8: resolution: {integrity: sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==} + pump@3.0.0: + resolution: {integrity: sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==} + + quick.db@9.1.7: + resolution: {integrity: sha512-ZLPVLVFZtvFRLHqIK99iyrLDUznOTpnp5tB+QpGErT+reDSvgBELuVsMkGSSiqKT9R2YSOhO+096Wb0xTaOHMA==} + + rc@1.2.8: + resolution: {integrity: sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==} + hasBin: true + + readable-stream@3.6.2: + resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} + engines: {node: '>= 6'} + readdirp@3.6.0: resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} engines: {node: '>=8.10.0'} + safe-buffer@5.2.1: + resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} + semver@7.6.2: resolution: {integrity: sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==} engines: {node: '>=10'} @@ -384,6 +494,12 @@ packages: resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} engines: {node: '>=14'} + simple-concat@1.0.1: + resolution: {integrity: sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==} + + simple-get@4.0.1: + resolution: {integrity: sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==} + simple-update-notifier@2.0.0: resolution: {integrity: sha512-a2B9Y0KlNXl9u/vsW6sTIu9vGEpfKu2wRV6l1H3XEas/0gUIzGzBoP/IouTcUQbm9JWZLH3COxyn03TYlFax6w==} engines: {node: '>=10'} @@ -396,6 +512,9 @@ packages: resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} engines: {node: '>=12'} + string_decoder@1.3.0: + resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} + strip-ansi@6.0.1: resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} engines: {node: '>=8'} @@ -404,10 +523,21 @@ packages: resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==} engines: {node: '>=12'} + strip-json-comments@2.0.1: + resolution: {integrity: sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==} + engines: {node: '>=0.10.0'} + supports-color@5.5.0: resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} engines: {node: '>=4'} + tar-fs@2.1.1: + resolution: {integrity: sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==} + + tar-stream@2.2.0: + resolution: {integrity: sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==} + engines: {node: '>=6'} + to-regex-range@5.0.1: resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} engines: {node: '>=8.0'} @@ -446,6 +576,9 @@ packages: resolution: {integrity: sha512-YB1FG+axdxADa3ncEtRnQCFq/M0lALGLxSZeVNbTU8NqhOVc51nnv2CISTcvc1kyv6EGPtXVr0v6lWeDxiijOA==} engines: {node: '>= 6.0.0'} + tunnel-agent@0.6.0: + resolution: {integrity: sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==} + typedi@0.10.0: resolution: {integrity: sha512-v3UJF8xm68BBj6AF4oQML3ikrfK2c9EmZUyLOfShpJuItAqVBHWP/KtpGinkSsIiP6EZyyb6Z3NXyW9dgS9X1w==} @@ -464,6 +597,9 @@ packages: resolution: {integrity: sha512-Q2rtqmZWrbP8nePMq7mOJIN98M0fYvSgV89vwl/BQRT4mDOeY2GXZngfGpcBBhtky3woM7G24wZV3Q304Bv6cw==} engines: {node: '>=18.0'} + util-deprecate@1.0.2: + resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + v8-compile-cache-lib@3.0.1: resolution: {integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==} @@ -480,6 +616,9 @@ packages: resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==} engines: {node: '>=12'} + wrappy@1.0.2: + resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} + ws@8.17.0: resolution: {integrity: sha512-uJq6108EgZMAl20KagGkzCKfMEjxmKvZHG7Tlq0Z6nOky7YF7aq4mOx6xK8TJ/i1LeK4Qus7INktacctDgY8Ow==} engines: {node: '>=10.0.0'} @@ -640,8 +779,25 @@ snapshots: balanced-match@1.0.2: {} + base64-js@1.5.1: {} + + better-sqlite3@11.0.0: + dependencies: + bindings: 1.5.0 + prebuild-install: 7.1.2 + binary-extensions@2.3.0: {} + bindings@1.5.0: + dependencies: + file-uri-to-path: 1.0.0 + + bl@4.1.0: + dependencies: + buffer: 5.7.1 + inherits: 2.0.4 + readable-stream: 3.6.2 + brace-expansion@1.1.11: dependencies: balanced-match: 1.0.2 @@ -655,6 +811,11 @@ snapshots: dependencies: fill-range: 7.1.1 + buffer@5.7.1: + dependencies: + base64-js: 1.5.1 + ieee754: 1.2.1 + chokidar@3.6.0: dependencies: anymatch: 3.1.3 @@ -667,6 +828,8 @@ snapshots: optionalDependencies: fsevents: 2.3.3 + chownr@1.1.4: {} + color-convert@2.0.1: dependencies: color-name: 1.1.4 @@ -689,6 +852,14 @@ snapshots: optionalDependencies: supports-color: 5.5.0 + decompress-response@6.0.0: + dependencies: + mimic-response: 3.1.0 + + deep-extend@0.6.0: {} + + detect-libc@2.0.3: {} + diff@4.0.2: {} discord-api-types@0.37.83: {} @@ -719,14 +890,24 @@ snapshots: lodash: 4.17.21 tslib: 2.6.3 + dotenv@16.4.5: {} + eastasianwidth@0.2.0: {} emoji-regex@8.0.0: {} emoji-regex@9.2.2: {} + end-of-stream@1.4.4: + dependencies: + once: 1.4.0 + + expand-template@2.0.3: {} + fast-deep-equal@3.1.3: {} + file-uri-to-path@1.0.0: {} + fill-range@7.1.1: dependencies: to-regex-range: 5.0.1 @@ -736,9 +917,13 @@ snapshots: cross-spawn: 7.0.3 signal-exit: 4.1.0 + fs-constants@1.0.0: {} + fsevents@2.3.3: optional: true + github-from-package@0.0.0: {} + glob-parent@5.1.2: dependencies: is-glob: 4.0.3 @@ -753,8 +938,14 @@ snapshots: has-flag@3.0.0: {} + ieee754@1.2.1: {} + ignore-by-default@1.0.1: {} + inherits@2.0.4: {} + + ini@1.3.8: {} + is-binary-path@2.1.0: dependencies: binary-extensions: 2.3.0 @@ -787,6 +978,8 @@ snapshots: make-error@1.3.6: {} + mimic-response@3.1.0: {} + minimatch@3.1.2: dependencies: brace-expansion: 1.1.11 @@ -795,10 +988,20 @@ snapshots: dependencies: brace-expansion: 2.0.1 + minimist@1.2.8: {} + minipass@7.1.2: {} + mkdirp-classic@0.5.3: {} + ms@2.1.2: {} + napi-build-utils@1.0.2: {} + + node-abi@3.63.0: + dependencies: + semver: 7.6.2 + nodemon@3.1.3: dependencies: chokidar: 3.6.0 @@ -814,6 +1017,10 @@ snapshots: normalize-path@3.0.0: {} + once@1.4.0: + dependencies: + wrappy: 1.0.2 + path-key@3.1.1: {} path-scurry@1.11.1: @@ -823,14 +1030,53 @@ snapshots: picomatch@2.3.1: {} + prebuild-install@7.1.2: + dependencies: + detect-libc: 2.0.3 + expand-template: 2.0.3 + github-from-package: 0.0.0 + minimist: 1.2.8 + mkdirp-classic: 0.5.3 + napi-build-utils: 1.0.2 + node-abi: 3.63.0 + pump: 3.0.0 + rc: 1.2.8 + simple-get: 4.0.1 + tar-fs: 2.1.1 + tunnel-agent: 0.6.0 + prettier@3.3.1: {} pstree.remy@1.1.8: {} + pump@3.0.0: + dependencies: + end-of-stream: 1.4.4 + once: 1.4.0 + + quick.db@9.1.7: + dependencies: + lodash: 4.17.21 + + rc@1.2.8: + dependencies: + deep-extend: 0.6.0 + ini: 1.3.8 + minimist: 1.2.8 + strip-json-comments: 2.0.1 + + readable-stream@3.6.2: + dependencies: + inherits: 2.0.4 + string_decoder: 1.3.0 + util-deprecate: 1.0.2 + readdirp@3.6.0: dependencies: picomatch: 2.3.1 + safe-buffer@5.2.1: {} + semver@7.6.2: {} shebang-command@2.0.0: @@ -841,6 +1087,14 @@ snapshots: signal-exit@4.1.0: {} + simple-concat@1.0.1: {} + + simple-get@4.0.1: + dependencies: + decompress-response: 6.0.0 + once: 1.4.0 + simple-concat: 1.0.1 + simple-update-notifier@2.0.0: dependencies: semver: 7.6.2 @@ -857,6 +1111,10 @@ snapshots: emoji-regex: 9.2.2 strip-ansi: 7.1.0 + string_decoder@1.3.0: + dependencies: + safe-buffer: 5.2.1 + strip-ansi@6.0.1: dependencies: ansi-regex: 5.0.1 @@ -865,10 +1123,27 @@ snapshots: dependencies: ansi-regex: 6.0.1 + strip-json-comments@2.0.1: {} + supports-color@5.5.0: dependencies: has-flag: 3.0.0 + tar-fs@2.1.1: + dependencies: + chownr: 1.1.4 + mkdirp-classic: 0.5.3 + pump: 3.0.0 + tar-stream: 2.2.0 + + tar-stream@2.2.0: + dependencies: + bl: 4.1.0 + end-of-stream: 1.4.4 + fs-constants: 1.0.0 + inherits: 2.0.4 + readable-stream: 3.6.2 + to-regex-range@5.0.1: dependencies: is-number: 7.0.0 @@ -905,6 +1180,10 @@ snapshots: dependencies: tslib: 1.14.1 + tunnel-agent@0.6.0: + dependencies: + safe-buffer: 5.2.1 + typedi@0.10.0: {} typescript@5.4.5: {} @@ -915,6 +1194,8 @@ snapshots: undici@6.13.0: {} + util-deprecate@1.0.2: {} + v8-compile-cache-lib@3.0.1: {} which@2.0.2: @@ -933,6 +1214,8 @@ snapshots: string-width: 5.1.2 strip-ansi: 7.1.0 + wrappy@1.0.2: {} + ws@8.17.0: {} yn@3.1.1: {} diff --git a/src/commands/choices.ts b/src/commands/choices.ts deleted file mode 100644 index 3b90c65..0000000 --- a/src/commands/choices.ts +++ /dev/null @@ -1,37 +0,0 @@ -import type { CommandInteraction } from "discord.js"; -import { ApplicationCommandOptionType } from "discord.js"; -import { Discord, Slash, SlashChoice, SlashOption } from "discordx"; - -@Discord() -export class Example { - @Slash({ description: "choose" }) - async choose( - @SlashChoice("Human", "Astronaut", "Dev") - @SlashOption({ - description: "What are you?", - name: "what", - required: true, - type: ApplicationCommandOptionType.String, - }) - what: string, - interaction: CommandInteraction, - ): Promise { - await interaction.reply(what); - } - - @Slash({ description: "choose1" }) - async choose1( - @SlashChoice({ name: "are you okay?", value: "okay" }) - @SlashChoice({ name: "are you good?", value: "good" }) - @SlashOption({ - description: "what1", - name: "what1", - required: true, - type: ApplicationCommandOptionType.String, - }) - what: string, - interaction: CommandInteraction, - ): Promise { - await interaction.reply(what); - } -} diff --git a/src/commands/context.ts b/src/commands/context.ts deleted file mode 100644 index 0d75868..0000000 --- a/src/commands/context.ts +++ /dev/null @@ -1,26 +0,0 @@ -import type { - MessageContextMenuCommandInteraction, - UserContextMenuCommandInteraction, -} from "discord.js"; -import { ApplicationCommandType } from "discord.js"; -import { ContextMenu, Discord } from "discordx"; - -@Discord() -export class Example { - @ContextMenu({ - name: "message context", - type: ApplicationCommandType.Message, - }) - async messageHandler( - interaction: MessageContextMenuCommandInteraction, - ): Promise { - await interaction.reply("I am user context handler"); - } - - @ContextMenu({ name: "user context", type: ApplicationCommandType.User }) - async userHandler( - interaction: UserContextMenuCommandInteraction, - ): Promise { - await interaction.reply("I am user context handler"); - } -} diff --git a/src/commands/menu.ts b/src/commands/menu.ts deleted file mode 100644 index e60c5a6..0000000 --- a/src/commands/menu.ts +++ /dev/null @@ -1,59 +0,0 @@ -import type { - CommandInteraction, - MessageActionRowComponentBuilder, - StringSelectMenuInteraction, -} from "discord.js"; -import { ActionRowBuilder, StringSelectMenuBuilder } from "discord.js"; -import { Discord, SelectMenuComponent, Slash } from "discordx"; - -const roles = [ - { label: "Principal", value: "principal" }, - { label: "Teacher", value: "teacher" }, - { label: "Student", value: "student" }, -]; - -@Discord() -export class Example { - @SelectMenuComponent({ id: "role-menu" }) - async handle(interaction: StringSelectMenuInteraction): Promise { - await interaction.deferReply(); - - // extract selected value by member - const roleValue = interaction.values[0]; - - // if value not found - if (!roleValue) { - return interaction.followUp("invalid role id, select again"); - } - - await interaction.followUp( - `you have selected role: ${ - roles.find((r) => r.value === roleValue)?.label ?? "unknown" - }`, - ); - return; - } - - @Slash({ description: "roles menu", name: "my_roles" }) - async myRoles(interaction: CommandInteraction): Promise { - await interaction.deferReply(); - - // create menu for roles - const menu = new StringSelectMenuBuilder() - .addOptions(roles) - .setCustomId("role-menu"); - - // create a row for message actions - const buttonRow = - new ActionRowBuilder().addComponents( - menu, - ); - - // send it - await interaction.editReply({ - components: [buttonRow], - content: "select your role!", - }); - return; - } -} diff --git a/src/commands/set-banner-url.ts b/src/commands/set-banner-url.ts new file mode 100644 index 0000000..6a81ffd --- /dev/null +++ b/src/commands/set-banner-url.ts @@ -0,0 +1,28 @@ +import { Discord, Slash, SlashOption } from 'discordx' +import { + ApplicationCommandOptionType, + CommandInteraction, + TextChannel, +} from 'discord.js' +import { db, DBTableEnum } from '../db.ts' + +@Discord() +export class SetFeedbackChannel { + @Slash({ + description: 'Set banner url', + name: 'set-banner-url', + }) + async setBannerUrl( + @SlashOption({ + name: 'url', + description: 'Provide banner url with extension on the end', + type: ApplicationCommandOptionType.String, + required: true, + }) + url: string, + interaction: CommandInteraction, + ) { + await db.set(DBTableEnum.BANNER_URL, url) + await interaction.reply({ ephemeral: true, content: 'Success.' }) + } +} diff --git a/src/commands/set-feedback-channel.ts b/src/commands/set-feedback-channel.ts new file mode 100644 index 0000000..11d0ea0 --- /dev/null +++ b/src/commands/set-feedback-channel.ts @@ -0,0 +1,28 @@ +import { Discord, Slash, SlashOption } from 'discordx' +import { + ApplicationCommandOptionType, + CommandInteraction, + TextChannel, +} from 'discord.js' +import { db, DBTableEnum } from '../db.ts' + +@Discord() +export class SetFeedbackChannel { + @Slash({ + description: 'Set feedback channel', + name: 'set-feedback-channel', + }) + async setFeedbackChannel( + @SlashOption({ + name: 'channel', + description: 'channel description', + type: ApplicationCommandOptionType.Channel, + required: true, + }) + channel: TextChannel, + interaction: CommandInteraction, + ) { + await db.set(DBTableEnum.FEEDBACK_CHANNEL, channel.id) + await interaction.reply({ ephemeral: true, content: 'Success.' }) + } +} diff --git a/src/commands/set-order-channel.ts b/src/commands/set-order-channel.ts new file mode 100644 index 0000000..01e0c2b --- /dev/null +++ b/src/commands/set-order-channel.ts @@ -0,0 +1,28 @@ +import { Discord, Slash, SlashOption } from 'discordx' +import { + ApplicationCommandOptionType, + CommandInteraction, + TextChannel, +} from 'discord.js' +import { db, DBTableEnum } from '../db.ts' + +@Discord() +export class SetOrderChannel { + @Slash({ + description: 'Set a make an order channel', + name: 'set-order-channel', + }) + async setOrderChannel( + @SlashOption({ + name: 'channel', + description: 'channel description', + type: ApplicationCommandOptionType.Channel, + required: true, + }) + channel: TextChannel, + interaction: CommandInteraction, + ) { + await db.set(DBTableEnum.MAKE_AN_ORDER_CHANNEL, channel.id) + await interaction.reply({ ephemeral: true, content: 'Success.' }) + } +} diff --git a/src/commands/set-portfolio-channel.ts b/src/commands/set-portfolio-channel.ts new file mode 100644 index 0000000..982bc5a --- /dev/null +++ b/src/commands/set-portfolio-channel.ts @@ -0,0 +1,28 @@ +import { Discord, Slash, SlashOption } from 'discordx' +import { + ApplicationCommandOptionType, + CommandInteraction, + TextChannel, +} from 'discord.js' +import { db, DBTableEnum } from '../db.ts' + +@Discord() +export class SetPortfolioChannel { + @Slash({ + description: 'Set portfolio channel', + name: 'set-portfolio-channel', + }) + async setPortfolioChannel( + @SlashOption({ + name: 'channel', + description: 'channel description', + type: ApplicationCommandOptionType.Channel, + required: true, + }) + channel: TextChannel, + interaction: CommandInteraction, + ) { + await db.set(DBTableEnum.PORTFOLIO_CHANNEL, channel.id) + await interaction.reply({ ephemeral: true, content: 'Success.' }) + } +} diff --git a/src/commands/set-price-channel.ts b/src/commands/set-price-channel.ts new file mode 100644 index 0000000..c162c96 --- /dev/null +++ b/src/commands/set-price-channel.ts @@ -0,0 +1,28 @@ +import { Discord, Slash, SlashOption } from 'discordx' +import { + ApplicationCommandOptionType, + CommandInteraction, + TextChannel, +} from 'discord.js' +import { db, DBTableEnum } from '../db.ts' + +@Discord() +export class SetPriceChannel { + @Slash({ + description: 'Set price channel', + name: 'set-price-channel', + }) + async setPriceChannel( + @SlashOption({ + name: 'channel', + description: 'channel description', + type: ApplicationCommandOptionType.Channel, + required: true, + }) + channel: TextChannel, + interaction: CommandInteraction, + ) { + await db.set(DBTableEnum.PRICE_CHANNEL, channel.id) + await interaction.reply({ ephemeral: true, content: 'Success.' }) + } +} diff --git a/src/commands/set-welcome-channel.ts b/src/commands/set-welcome-channel.ts new file mode 100644 index 0000000..1dde907 --- /dev/null +++ b/src/commands/set-welcome-channel.ts @@ -0,0 +1,25 @@ +import { Discord, Slash, SlashOption } from 'discordx' +import { + ApplicationCommandOptionType, + CommandInteraction, + TextChannel, +} from 'discord.js' +import { db, DBTableEnum } from '../db.ts' + +@Discord() +export class SetWelcomeChannel { + @Slash({ description: 'Set welcome channel', name: 'set-welcome-channel' }) + async setWelcomeChannel( + @SlashOption({ + name: 'channel', + description: 'channel description', + type: ApplicationCommandOptionType.Channel, + required: true, + }) + channel: TextChannel, + interaction: CommandInteraction, + ) { + await db.set(DBTableEnum.WELCOME_CHANNEL, channel.id) + await interaction.reply({ ephemeral: true, content: 'Success.' }) + } +} diff --git a/src/commands/simple command.ts b/src/commands/simple command.ts deleted file mode 100644 index 1b3decb..0000000 --- a/src/commands/simple command.ts +++ /dev/null @@ -1,53 +0,0 @@ -import type { CommandInteraction, Message } from "discord.js"; -import type { SimpleCommandMessage } from "discordx"; -import { - Discord, - SimpleCommand, - SimpleCommandOption, - SimpleCommandOptionType, - Slash, -} from "discordx"; - -@Discord() -export class Example { - @SimpleCommand({ aliases: ["hi"] }) - async hello(command: SimpleCommandMessage): Promise { - const member = command.message.member; - if (member) { - await command.message.reply(`👋 ${member.toString()}`); - } else { - await command.message.reply("👋 hello"); - } - } - - @SimpleCommand({ argSplitter: "+" }) - async sum( - @SimpleCommandOption({ name: "num1", type: SimpleCommandOptionType.Number }) - num1: number | undefined, - @SimpleCommandOption({ name: "num2", type: SimpleCommandOptionType.Number }) - num2: number | undefined, - command: SimpleCommandMessage, - ): Promise { - if (!num1 || !num2) { - await command.sendUsageSyntax(); - return; - } - - await command.message.reply(`total = ${String(num1 + num2)}`); - } - - // make single handler for simple and slash command - async likeIt(command: CommandInteraction | Message): Promise { - await command.reply("I like it, Thanks"); - } - - @SimpleCommand({ name: "like-it" }) - async simpleLikeIt(command: SimpleCommandMessage): Promise { - await this.likeIt(command.message); - } - - @Slash({ description: "like-ite", name: "like-it" }) - async slashLikeIt(command: CommandInteraction): Promise { - await this.likeIt(command); - } -} diff --git a/src/commands/slash + button.ts b/src/commands/slash + button.ts deleted file mode 100644 index a97fdb5..0000000 --- a/src/commands/slash + button.ts +++ /dev/null @@ -1,60 +0,0 @@ -import type { - ButtonInteraction, - CommandInteraction, - MessageActionRowComponentBuilder, - User, -} from "discord.js"; -import { - ActionRowBuilder, - ApplicationCommandOptionType, - ButtonBuilder, - ButtonStyle, - GuildMember, -} from "discord.js"; -import { ButtonComponent, Discord, Slash, SlashOption } from "discordx"; - -@Discord() -export class Example { - @Slash({ description: "hello", name: "hello-btn" }) - async hello( - @SlashOption({ - description: "user", - name: "user", - required: true, - type: ApplicationCommandOptionType.User, - }) - user: User | GuildMember | undefined, - interaction: CommandInteraction, - ): Promise { - if (!user) { - return; - } - - await interaction.deferReply(); - - const helloBtn = new ButtonBuilder() - .setLabel("Hello") - .setEmoji("👋") - .setStyle(ButtonStyle.Primary) - .setCustomId("hello-btn"); - - const row = - new ActionRowBuilder().addComponents( - helloBtn, - ); - - await interaction.editReply({ - components: [row], - content: `${user.toString()}, Say hello to bot`, - }); - } - - @ButtonComponent({ id: "hello-btn" }) - async helloBtn(interaction: ButtonInteraction): Promise { - if (!(interaction.member instanceof GuildMember)) { - return; - } - - await interaction.reply(`👋 ${interaction.member.toString()}`); - } -} diff --git a/src/commands/slash group.ts b/src/commands/slash group.ts deleted file mode 100644 index 46feb2c..0000000 --- a/src/commands/slash group.ts +++ /dev/null @@ -1,67 +0,0 @@ -import type { CommandInteraction } from "discord.js"; -import { ApplicationCommandOptionType } from "discord.js"; -import { Discord, Slash, SlashGroup, SlashOption } from "discordx"; - -@Discord() -@SlashGroup({ description: "testing", name: "testing" }) -@SlashGroup({ description: "maths", name: "maths", root: "testing" }) -export class GroupExample { - @Slash({ description: "add" }) - @SlashGroup("maths", "testing") - async add( - @SlashOption({ - description: "x value", - name: "x", - required: true, - type: ApplicationCommandOptionType.Number, - }) - x: number, - @SlashOption({ - description: "y value", - name: "y", - required: true, - type: ApplicationCommandOptionType.Number, - }) - y: number, - interaction: CommandInteraction, - ): Promise { - await interaction.reply(String(x + y)); - } - - @Slash({ description: "multiply" }) - @SlashGroup("maths", "testing") - async multiply( - @SlashOption({ - description: "x value", - name: "x", - required: true, - type: ApplicationCommandOptionType.Number, - }) - x: number, - @SlashOption({ - description: "y value", - name: "y", - required: true, - type: ApplicationCommandOptionType.Number, - }) - y: number, - interaction: CommandInteraction, - ): Promise { - await interaction.reply(String(x * y)); - } - - @Slash({ description: "root" }) - @SlashGroup("testing") - async root( - @SlashOption({ - description: "text", - name: "text", - required: true, - type: ApplicationCommandOptionType.String, - }) - text: string, - interaction: CommandInteraction, - ): Promise { - await interaction.reply(text); - } -} diff --git a/src/commands/slashes.ts b/src/commands/slashes.ts deleted file mode 100644 index a97d612..0000000 --- a/src/commands/slashes.ts +++ /dev/null @@ -1,36 +0,0 @@ -import { Pagination } from "@discordx/pagination"; -import type { CommandInteraction } from "discord.js"; -import { EmbedBuilder } from "discord.js"; -import { Discord, MetadataStorage, Slash } from "discordx"; - -@Discord() -export class SlashExample { - // example: pagination for all slash command - @Slash({ - description: "Pagination for all slash command", - name: "all-commands", - }) - async pages(interaction: CommandInteraction): Promise { - const commands = MetadataStorage.instance.applicationCommands.map((cmd) => { - return { description: cmd.description, name: cmd.name }; - }); - - const pages = commands.map((cmd, i) => { - const embed = new EmbedBuilder() - .setFooter({ - text: `Page ${String(i + 1)} of ${String(commands.length)}`, - }) - .setTitle("**Slash command info**") - .addFields({ name: "Name", value: cmd.name }) - .addFields({ - name: "Description", - value: cmd.description, - }); - - return { embeds: [embed] }; - }); - - const pagination = new Pagination(interaction, pages); - await pagination.send(); - } -} diff --git a/src/db.ts b/src/db.ts new file mode 100644 index 0000000..28d9087 --- /dev/null +++ b/src/db.ts @@ -0,0 +1,12 @@ +import { QuickDB } from 'quick.db' +export const db = new QuickDB() + +export enum DBTableEnum { + WELCOME_CHANNEL = 'WELCOME_CHANNEL', + TICKET_CHANNEL = 'TICKET_CHANNEL', + FEEDBACK_CHANNEL = 'FEEDBACK_CHANNEL', + PORTFOLIO_CHANNEL = 'PORTFOLIO_CHANNEL', + MAKE_AN_ORDER_CHANNEL = 'MAKE_AN_ORDER_CHANNEL', + PRICE_CHANNEL = 'PRICE_CHANNEL', + BANNER_URL = 'BANNER_URL', +} diff --git a/src/events/common.ts b/src/events/common.ts deleted file mode 100644 index 3a4e946..0000000 --- a/src/events/common.ts +++ /dev/null @@ -1,10 +0,0 @@ -import type { ArgsOf, Client } from "discordx"; -import { Discord, On } from "discordx"; - -@Discord() -export class Example { - @On() - messageDelete([message]: ArgsOf<"messageDelete">, client: Client): void { - console.log("Message Deleted", client.user?.username, message.content); - } -} diff --git a/src/events/guildMemberAdd.ts b/src/events/guildMemberAdd.ts new file mode 100644 index 0000000..ee06727 --- /dev/null +++ b/src/events/guildMemberAdd.ts @@ -0,0 +1,35 @@ +import { ArgsOf, Discord, On } from 'discordx' +import { EmbedBuilder } from 'discord.js' +import { db, DBTableEnum } from '../db.ts' + +@Discord() +export class GuildMemberAdd { + @On({ event: 'guildMemberAdd' }) + async guildMemberAdd([member]: ArgsOf<'guildMemberAdd'>) { + const portfolioChannelID = await db.get(DBTableEnum.PORTFOLIO_CHANNEL) + const makeAnOrderChannelID = await db.get( + DBTableEnum.MAKE_AN_ORDER_CHANNEL, + ) + const welcomeChannelID = await db.get(DBTableEnum.WELCOME_CHANNEL) + const imageURL = await db.get(DBTableEnum.BANNER_URL) + + let embed = new EmbedBuilder() + .setTitle( + `I'm glad to see you on my server. Let me give you a little tour.`, + ) + .setDescription( + `> 1. In the https://discord.com/channels/1248048650886578247/${portfolioChannelID} - you can see my previous works. + > 2. Here https://discord.com/channels/1248048650886578247/${makeAnOrderChannelID} you might open a ticket.`, + ) + .setImage(imageURL) + + const channel = await member.guild.channels.fetch(welcomeChannelID) + + if (channel?.isTextBased()) { + channel.send({ + embeds: [embed], + content: `What's up, <@${member.id}>`, + }) + } + } +} diff --git a/src/main.ts b/src/main.ts index 681d97c..11cb044 100644 --- a/src/main.ts +++ b/src/main.ts @@ -2,6 +2,7 @@ import { dirname, importx } from "@discordx/importer"; import type { Interaction, Message } from "discord.js"; import { IntentsBitField } from "discord.js"; import { Client } from "discordx"; +import 'dotenv/config' export const bot = new Client({ // To use only guild command diff --git a/tsconfig.json b/tsconfig.json index f5de8d5..3392544 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -10,6 +10,7 @@ "experimentalDecorators": true, "emitDecoratorMetadata": false, + "allowImportingTsExtensions": true, "skipLibCheck": true, "forceConsistentCasingInFileNames": true