diff --git a/.gitignore b/.gitignore index cf17e17..ef58427 100644 --- a/.gitignore +++ b/.gitignore @@ -8,4 +8,7 @@ config.js json.sqlite # VSCode -.vscode \ No newline at end of file +.vscode + +# Environment variables +.env \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 8e2b92b..d969c79 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,71 +1,87 @@ { "name": "o-codex", - "version": "1.2.0", + "version": "2.0.0", "lockfileVersion": 2, "requires": true, "packages": { "": { - "name": "neobot", - "version": "1.2.0", + "name": "o-codex", + "version": "2.0.0", "license": "ISC", "dependencies": { - "@iamtraction/google-translate": "^2.0.0", - "colors": "^1.4.0", - "discord.js": "^14.7.1", - "erela.js": "^2.4.0", - "node-fetch": "^3.2.10", - "openai": "^3.1.0" + "@iamtraction/google-translate": "^2.0.1", + "chalk": "^5.2.0", + "discord.js": "^14.9.0", + "dotenv": "^16.0.3", + "mongoose": "^7.0.4" } }, "node_modules/@discordjs/builders": { - "version": "1.4.0", - "license": "Apache-2.0", + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/@discordjs/builders/-/builders-1.6.1.tgz", + "integrity": "sha512-CCcLwn/8ANhlAbhlE18fcaN0hfXTen53/JiwZs1t9oE/Cqa9maA8ZRarkCIsXF4J7J/MYnd0J6IsxeKsq+f6mw==", "dependencies": { - "@discordjs/util": "^0.1.0", - "@sapphire/shapeshift": "^3.7.1", - "discord-api-types": "^0.37.20", + "@discordjs/formatters": "^0.3.0", + "@discordjs/util": "^0.2.0", + "@sapphire/shapeshift": "^3.8.1", + "discord-api-types": "^0.37.37", "fast-deep-equal": "^3.1.3", - "ts-mixer": "^6.0.2", - "tslib": "^2.4.1" + "ts-mixer": "^6.0.3", + "tslib": "^2.5.0" }, "engines": { "node": ">=16.9.0" } }, "node_modules/@discordjs/collection": { - "version": "1.3.0", - "license": "Apache-2.0", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@discordjs/collection/-/collection-1.5.0.tgz", + "integrity": "sha512-suyVndkEAAWrGxyw/CPGdtXoRRU6AUNkibtnbJevQzpelkJh3Q1gQqWDpqf5i39CnAn5+LrN0YS+cULeEjq2Yw==", + "engines": { + "node": ">=16.9.0" + } + }, + "node_modules/@discordjs/formatters": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@discordjs/formatters/-/formatters-0.3.0.tgz", + "integrity": "sha512-Fc4MomalbP8HMKEMor3qUiboAKDtR7PSBoPjwm7WYghVRwgJlj5WYvUsriLsxeKk8+Qq2oy+HJlGTUkGvX0YnA==", + "dependencies": { + "discord-api-types": "^0.37.37" + }, "engines": { "node": ">=16.9.0" } }, "node_modules/@discordjs/rest": { - "version": "1.4.0", - "license": "Apache-2.0", + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@discordjs/rest/-/rest-1.7.0.tgz", + "integrity": "sha512-r2HzmznRIo8IDGYBWqQfkEaGN1LrFfWQd3dSyC4tOpMU8nuVvFUEw6V/lwnG44jyOq+vgyDny2fxeUDMt9I4aQ==", "dependencies": { - "@discordjs/collection": "^1.3.0", - "@discordjs/util": "^0.1.0", + "@discordjs/collection": "^1.5.0", + "@discordjs/util": "^0.2.0", "@sapphire/async-queue": "^1.5.0", - "@sapphire/snowflake": "^3.2.2", - "discord-api-types": "^0.37.20", - "file-type": "^18.0.0", - "tslib": "^2.4.1", - "undici": "^5.13.0" + "@sapphire/snowflake": "^3.4.0", + "discord-api-types": "^0.37.37", + "file-type": "^18.2.1", + "tslib": "^2.5.0", + "undici": "^5.21.0" }, "engines": { "node": ">=16.9.0" } }, "node_modules/@discordjs/util": { - "version": "0.1.0", - "license": "Apache-2.0", + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@discordjs/util/-/util-0.2.0.tgz", + "integrity": "sha512-/8qNbebFzLWKOOg+UV+RB8itp4SmU5jw0tBUD3ifElW6rYNOj1Ku5JaSW7lLl/WgjjxF01l/1uQPCzkwr110vg==", "engines": { "node": ">=16.9.0" } }, "node_modules/@iamtraction/google-translate": { "version": "2.0.1", - "license": "MIT", + "resolved": "https://registry.npmjs.org/@iamtraction/google-translate/-/google-translate-2.0.1.tgz", + "integrity": "sha512-kOTkt23zflxpgxLIe9tLvDU8IvNscXYbgMSXydNkZGWDtJ75YJiU3v7EBz+t7h/gSiY7sT5r4dlFkMrHCl+N6A==", "dependencies": { "undici": "^5.12.0" }, @@ -75,18 +91,20 @@ }, "node_modules/@sapphire/async-queue": { "version": "1.5.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/@sapphire/async-queue/-/async-queue-1.5.0.tgz", + "integrity": "sha512-JkLdIsP8fPAdh9ZZjrbHWR/+mZj0wvKS5ICibcLrRI1j84UmLMshx5n9QmL8b95d4onJ2xxiyugTgSAX7AalmA==", "engines": { "node": ">=v14.0.0", "npm": ">=7.0.0" } }, "node_modules/@sapphire/shapeshift": { - "version": "3.7.1", - "license": "MIT", + "version": "3.8.2", + "resolved": "https://registry.npmjs.org/@sapphire/shapeshift/-/shapeshift-3.8.2.tgz", + "integrity": "sha512-NXpnJAsxN3/h9TqQPntOeVWZrpIuucqXI3IWF6tj2fWCoRLCuVK5wx7Dtg7pRrtkYfsMUbDqgKoX26vrC5iYfA==", "dependencies": { "fast-deep-equal": "^3.1.3", - "lodash.uniqwith": "^4.5.0" + "lodash": "^4.17.21" }, "engines": { "node": ">=v14.0.0", @@ -94,8 +112,9 @@ } }, "node_modules/@sapphire/snowflake": { - "version": "3.2.2", - "license": "MIT", + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/@sapphire/snowflake/-/snowflake-3.4.2.tgz", + "integrity": "sha512-KJwlv5gkGjs1uFV7/xx81n3tqgBwBJvH94n1xDyH3q+JSmtsMeSleJffarEBfG2yAFeJiFA4BnGOK6FFPHc19g==", "engines": { "node": ">=v14.0.0", "npm": ">=7.0.0" @@ -103,30 +122,42 @@ }, "node_modules/@tokenizer/token": { "version": "0.3.0", - "license": "MIT" + "resolved": "https://registry.npmjs.org/@tokenizer/token/-/token-0.3.0.tgz", + "integrity": "sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A==" }, "node_modules/@types/node": { - "version": "18.11.9", - "license": "MIT" + "version": "18.15.11", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.15.11.tgz", + "integrity": "sha512-E5Kwq2n4SbMzQOn6wnmBjuK9ouqlURrcZDVfbo9ftDDTFt3nk7ZKK4GMOzoYgnpQJKcxwQw+lGaBvvlMo0qN/Q==" + }, + "node_modules/@types/webidl-conversions": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@types/webidl-conversions/-/webidl-conversions-7.0.0.tgz", + "integrity": "sha512-xTE1E+YF4aWPJJeUzaZI5DRntlkY3+BCVJi0axFptnjGmAoWxkyREIh/XMrfxVLejwQxMCfDXdICo0VLxThrog==" + }, + "node_modules/@types/whatwg-url": { + "version": "8.2.2", + "resolved": "https://registry.npmjs.org/@types/whatwg-url/-/whatwg-url-8.2.2.tgz", + "integrity": "sha512-FtQu10RWgn3D9U4aazdwIE2yzphmTJREDqNdODHrbrZmmMqI0vMheC/6NE/J1Yveaj8H+ela+YwWTjq5PGmuhA==", + "dependencies": { + "@types/node": "*", + "@types/webidl-conversions": "*" + } }, "node_modules/@types/ws": { - "version": "8.5.3", - "license": "MIT", + "version": "8.5.4", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.4.tgz", + "integrity": "sha512-zdQDHKUgcX/zBc4GrwsE/7dVdAD8JR4EuiAXiiUhhfyIJXXb2+PrGshFyeXWQPMmmZ2XxgaqclgpIC7eTXc1mg==", "dependencies": { "@types/node": "*" } }, - "node_modules/asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" - }, - "node_modules/axios": { - "version": "0.26.1", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.26.1.tgz", - "integrity": "sha512-fPwcX4EvnSHuInCMItEhAGnaSEXRBjtzh9fOtsE6E1G6p7vl7edEeZe11QHf18+6+9gR5PbKV/sGKNaD8YaMeA==", - "dependencies": { - "follow-redirects": "^1.14.8" + "node_modules/bson": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/bson/-/bson-5.2.0.tgz", + "integrity": "sha512-HevkSpDbpUfsrHWmWiAsNavANKYIErV2ePXllp1bwq5CDreAaFVj6RVlZpJnxK4WWDCJ/5jMUpaY6G526q3Hjg==", + "engines": { + "node": ">=14.20.1" } }, "node_modules/busboy": { @@ -138,108 +169,83 @@ "node": ">=10.16.0" } }, - "node_modules/colors": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", - "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==", + "node_modules/chalk": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.2.0.tgz", + "integrity": "sha512-ree3Gqw/nazQAPuJJEy+avdl7QfZMcUvmHIKgEZkGL+xOBzRvup5Hxo6LHuMceSxOabuJLJm5Yp/92R9eMmMvA==", "engines": { - "node": ">=0.1.90" + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", "dependencies": { - "delayed-stream": "~1.0.0" + "ms": "2.1.2" }, "engines": { - "node": ">= 0.8" - } - }, - "node_modules/data-uri-to-buffer": { - "version": "4.0.0", - "license": "MIT", - "engines": { - "node": ">= 12" + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } } }, - "node_modules/delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", - "engines": { - "node": ">=0.4.0" - } + "node_modules/debug/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, "node_modules/discord-api-types": { - "version": "0.37.20", - "license": "MIT" + "version": "0.37.39", + "resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.37.39.tgz", + "integrity": "sha512-hkhQsQyzsTJITp311WXvHZh9j4RAMfIk2hPmsWeOTN50QTpg6zqmJNfel9D/8lYNvsU01wzw9281Yke8NhYyHg==" }, "node_modules/discord.js": { - "version": "14.7.1", - "resolved": "https://registry.npmjs.org/discord.js/-/discord.js-14.7.1.tgz", - "integrity": "sha512-1FECvqJJjjeYcjSm0IGMnPxLqja/pmG1B0W2l3lUY2Gi4KXiyTeQmU1IxWcbXHn2k+ytP587mMWqva2IA87EbA==", + "version": "14.9.0", + "resolved": "https://registry.npmjs.org/discord.js/-/discord.js-14.9.0.tgz", + "integrity": "sha512-ygGms5xP4hG+QrrY9k7d/OYCzMltSMtdl/2Snzq/nLCiZo+Sna91Ulv9l0+B5Jd/Czcq37B7wJAnmja7GOa+bg==", "dependencies": { - "@discordjs/builders": "^1.4.0", - "@discordjs/collection": "^1.3.0", - "@discordjs/rest": "^1.4.0", - "@discordjs/util": "^0.1.0", - "@sapphire/snowflake": "^3.2.2", - "@types/ws": "^8.5.3", - "discord-api-types": "^0.37.20", + "@discordjs/builders": "^1.6.0", + "@discordjs/collection": "^1.5.0", + "@discordjs/formatters": "^0.3.0", + "@discordjs/rest": "^1.7.0", + "@discordjs/util": "^0.2.0", + "@sapphire/snowflake": "^3.4.0", + "@types/ws": "^8.5.4", + "discord-api-types": "^0.37.37", "fast-deep-equal": "^3.1.3", "lodash.snakecase": "^4.1.1", - "tslib": "^2.4.1", - "undici": "^5.13.0", - "ws": "^8.11.0" + "tslib": "^2.5.0", + "undici": "^5.21.0", + "ws": "^8.13.0" }, "engines": { "node": ">=16.9.0" } }, - "node_modules/erela.js": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/erela.js/-/erela.js-2.4.0.tgz", - "integrity": "sha512-wLfPvfzbDZTDV0zwJYXGkjO9Q6mkXi3PNf984apdv58Ktt0cv1Zp8og3hmp7Ose4C4iwAKitHxV/yiP+pt3FRQ==", - "dependencies": { - "@discordjs/collection": "^1.1.0", - "tslib": "^2.4.0", - "undici": "^5.10.0", - "ws": "^8.8.1" - }, + "node_modules/dotenv": { + "version": "16.0.3", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.0.3.tgz", + "integrity": "sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ==", "engines": { - "node": ">=16.0.0" + "node": ">=12" } }, "node_modules/fast-deep-equal": { "version": "3.1.3", - "license": "MIT" - }, - "node_modules/fetch-blob": { - "version": "3.2.0", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/jimmywarting" - }, - { - "type": "paypal", - "url": "https://paypal.me/jimmywarting" - } - ], - "license": "MIT", - "dependencies": { - "node-domexception": "^1.0.0", - "web-streams-polyfill": "^3.0.3" - }, - "engines": { - "node": "^12.20 || >= 14.13" - } + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" }, "node_modules/file-type": { - "version": "18.0.0", - "license": "MIT", + "version": "18.2.1", + "resolved": "https://registry.npmjs.org/file-type/-/file-type-18.2.1.tgz", + "integrity": "sha512-Yw5MtnMv7vgD2/6Bjmmuegc8bQEVA9GmAyaR18bMYWKqsWDG9wgYZ1j4I6gNMF5Y5JBDcUcjRQqNQx7Y8uotcg==", "dependencies": { "readable-web-to-node-stream": "^3.0.2", "strtok3": "^7.0.0", @@ -252,50 +258,10 @@ "url": "https://github.com/sindresorhus/file-type?sponsor=1" } }, - "node_modules/follow-redirects": { - "version": "1.15.2", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", - "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==", - "funding": [ - { - "type": "individual", - "url": "https://github.com/sponsors/RubenVerborgh" - } - ], - "engines": { - "node": ">=4.0" - }, - "peerDependenciesMeta": { - "debug": { - "optional": true - } - } - }, - "node_modules/form-data": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", - "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", - "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/formdata-polyfill": { - "version": "4.0.10", - "license": "MIT", - "dependencies": { - "fetch-blob": "^3.1.2" - }, - "engines": { - "node": ">=12.20.0" - } - }, "node_modules/ieee754": { "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", "funding": [ { "type": "github", @@ -309,85 +275,131 @@ "type": "consulting", "url": "https://feross.org/support" } - ], - "license": "BSD-3-Clause" + ] }, "node_modules/inherits": { "version": "2.0.4", - "license": "ISC" + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "node_modules/ip": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ip/-/ip-2.0.0.tgz", + "integrity": "sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ==" + }, + "node_modules/kareem": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/kareem/-/kareem-2.5.1.tgz", + "integrity": "sha512-7jFxRVm+jD+rkq3kY0iZDJfsO2/t4BBPeEb2qKn2lR/9KhuksYk5hxzfRYWMPV8P/x2d0kHD306YyWLzjjH+uA==", + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" }, "node_modules/lodash.snakecase": { "version": "4.1.1", "license": "MIT" }, - "node_modules/lodash.uniqwith": { - "version": "4.5.0", - "license": "MIT" - }, - "node_modules/mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "node_modules/memory-pager": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/memory-pager/-/memory-pager-1.5.0.tgz", + "integrity": "sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==", + "optional": true + }, + "node_modules/mongodb": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-5.1.0.tgz", + "integrity": "sha512-qgKb7y+EI90y4weY3z5+lIgm8wmexbonz0GalHkSElQXVKtRuwqXuhXKccyvIjXCJVy9qPV82zsinY0W1FBnJw==", "dependencies": { - "mime-db": "1.52.0" + "bson": "^5.0.1", + "mongodb-connection-string-url": "^2.6.0", + "socks": "^2.7.1" }, "engines": { - "node": ">= 0.6" - } - }, - "node_modules/node-domexception": { - "version": "1.0.0", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/jimmywarting" + "node": ">=14.20.1" + }, + "optionalDependencies": { + "saslprep": "^1.0.3" + }, + "peerDependencies": { + "@aws-sdk/credential-providers": "^3.201.0", + "mongodb-client-encryption": "^2.3.0", + "snappy": "^7.2.2" + }, + "peerDependenciesMeta": { + "@aws-sdk/credential-providers": { + "optional": true }, - { - "type": "github", - "url": "https://paypal.me/jimmywarting" + "mongodb-client-encryption": { + "optional": true + }, + "snappy": { + "optional": true } - ], - "license": "MIT", - "engines": { - "node": ">=10.5.0" } }, - "node_modules/node-fetch": { - "version": "3.3.0", - "license": "MIT", + "node_modules/mongodb-connection-string-url": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/mongodb-connection-string-url/-/mongodb-connection-string-url-2.6.0.tgz", + "integrity": "sha512-WvTZlI9ab0QYtTYnuMLgobULWhokRjtC7db9LtcVfJ+Hsnyr5eo6ZtNAt3Ly24XZScGMelOcGtm7lSn0332tPQ==", + "dependencies": { + "@types/whatwg-url": "^8.2.1", + "whatwg-url": "^11.0.0" + } + }, + "node_modules/mongoose": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-7.0.4.tgz", + "integrity": "sha512-MEmQOOqQUvW1PJcji64NtA2EFGHrEvk9o4g//isVYSJW2+8Y8u49C2qFBKzn1t6/l9onQn012o/PcFqR6ixQpQ==", "dependencies": { - "data-uri-to-buffer": "^4.0.0", - "fetch-blob": "^3.1.4", - "formdata-polyfill": "^4.0.10" + "bson": "^5.0.1", + "kareem": "2.5.1", + "mongodb": "5.1.0", + "mpath": "0.9.0", + "mquery": "5.0.0", + "ms": "2.1.3", + "sift": "16.0.1" }, "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + "node": ">=14.0.0" }, "funding": { "type": "opencollective", - "url": "https://opencollective.com/node-fetch" + "url": "https://opencollective.com/mongoose" + } + }, + "node_modules/mpath": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/mpath/-/mpath-0.9.0.tgz", + "integrity": "sha512-ikJRQTk8hw5DEoFVxHG1Gn9T/xcjtdnOKIU1JTmGjZZlg9LST2mBLmcX3/ICIbgJydT2GOc15RnNy5mHmzfSew==", + "engines": { + "node": ">=4.0.0" } }, - "node_modules/openai": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/openai/-/openai-3.1.0.tgz", - "integrity": "sha512-v5kKFH5o+8ld+t0arudj833Mgm3GcgBnbyN9946bj6u7bvel4Yg6YFz2A4HLIYDzmMjIo0s6vSG9x73kOwvdCg==", + "node_modules/mquery": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/mquery/-/mquery-5.0.0.tgz", + "integrity": "sha512-iQMncpmEK8R8ncT8HJGsGc9Dsp8xcgYMVSbs5jgnm1lFHTZqMJTUWTDx1LBO8+mK3tPNZWFLBghQEIOULSTHZg==", "dependencies": { - "axios": "^0.26.0", - "form-data": "^4.0.0" + "debug": "4.x" + }, + "engines": { + "node": ">=14.0.0" } }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, "node_modules/peek-readable": { "version": "5.0.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/peek-readable/-/peek-readable-5.0.0.tgz", + "integrity": "sha512-YtCKvLUOvwtMGmrniQPdO7MwPjgkFBtFIrmfSbYmYuq3tKDV/mcfAhBth1+C3ru7uXIZasc/pHnb+YDYNkkj4A==", "engines": { "node": ">=14.16" }, @@ -396,9 +408,18 @@ "url": "https://github.com/sponsors/Borewit" } }, + "node_modules/punycode": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", + "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==", + "engines": { + "node": ">=6" + } + }, "node_modules/readable-stream": { - "version": "3.6.0", - "license": "MIT", + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", @@ -410,7 +431,8 @@ }, "node_modules/readable-web-to-node-stream": { "version": "3.0.2", - "license": "MIT", + "resolved": "https://registry.npmjs.org/readable-web-to-node-stream/-/readable-web-to-node-stream-3.0.2.tgz", + "integrity": "sha512-ePeK6cc1EcKLEhJFt/AebMCLL+GgSKhuygrZ/GLaKZYEecIgIECf4UaUuaByiGtzckwR4ain9VzUh95T1exYGw==", "dependencies": { "readable-stream": "^3.6.0" }, @@ -424,6 +446,8 @@ }, "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", @@ -437,8 +461,55 @@ "type": "consulting", "url": "https://feross.org/support" } - ], - "license": "MIT" + ] + }, + "node_modules/saslprep": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/saslprep/-/saslprep-1.0.3.tgz", + "integrity": "sha512-/MY/PEMbk2SuY5sScONwhUDsV2p77Znkb/q3nSVstq/yQzYJOH/Azh29p9oJLsl3LnQwSvZDKagDGBsBwSooag==", + "optional": true, + "dependencies": { + "sparse-bitfield": "^3.0.3" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/sift": { + "version": "16.0.1", + "resolved": "https://registry.npmjs.org/sift/-/sift-16.0.1.tgz", + "integrity": "sha512-Wv6BjQ5zbhW7VFefWusVP33T/EM0vYikCaQ2qR8yULbsilAT8/wQaXvuQ3ptGLpoKx+lihJE3y2UTgKDyyNHZQ==" + }, + "node_modules/smart-buffer": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", + "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==", + "engines": { + "node": ">= 6.0.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/socks": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/socks/-/socks-2.7.1.tgz", + "integrity": "sha512-7maUZy1N7uo6+WVEX6psASxtNlKaNVMlGQKkG/63nEDdLOWNbiUMoLK7X4uYoLhQstau72mLgfEWcXcwsaHbYQ==", + "dependencies": { + "ip": "^2.0.0", + "smart-buffer": "^4.2.0" + }, + "engines": { + "node": ">= 10.13.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/sparse-bitfield": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz", + "integrity": "sha512-kvzhi7vqKTfkh0PZU+2D2PIllw2ymqJKujUcyPMd9Y75Nv4nPbGJZXNhxsgdQab2BmlDct1YnfQCguEvHr7VsQ==", + "optional": true, + "dependencies": { + "memory-pager": "^1.0.2" + } }, "node_modules/streamsearch": { "version": "1.1.0", @@ -448,14 +519,16 @@ }, "node_modules/string_decoder": { "version": "1.3.0", - "license": "MIT", + "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/strtok3": { "version": "7.0.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/strtok3/-/strtok3-7.0.0.tgz", + "integrity": "sha512-pQ+V+nYQdC5H3Q7qBZAz/MO6lwGhoC2gOAjuouGf/VO0m7vQRh8QNMl2Uf6SwAtzZ9bOw3UIeBukEGNJl5dtXQ==", "dependencies": { "@tokenizer/token": "^0.3.0", "peek-readable": "^5.0.0" @@ -470,7 +543,8 @@ }, "node_modules/token-types": { "version": "5.0.1", - "license": "MIT", + "resolved": "https://registry.npmjs.org/token-types/-/token-types-5.0.1.tgz", + "integrity": "sha512-Y2fmSnZjQdDb9W4w4r1tswlMHylzWIeOKpx0aZH9BgGtACHhrk3OkT52AzwcuqTRBZtvvnTjDBh8eynMulu8Vg==", "dependencies": { "@tokenizer/token": "^0.3.0", "ieee754": "^1.2.1" @@ -483,18 +557,31 @@ "url": "https://github.com/sponsors/Borewit" } }, + "node_modules/tr46": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-3.0.0.tgz", + "integrity": "sha512-l7FvfAHlcmulp8kr+flpQZmVwtu7nfRV7NZujtN0OqES8EL4O4e0qqzL0DC5gAvx/ZC/9lk6rhcUwYvkBnBnYA==", + "dependencies": { + "punycode": "^2.1.1" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/ts-mixer": { - "version": "6.0.2", - "license": "MIT" + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/ts-mixer/-/ts-mixer-6.0.3.tgz", + "integrity": "sha512-k43M7uCG1AkTyxgnmI5MPwKoUvS/bRvLvUb7+Pgpdlmok8AoqmUaZxUUw8zKM5B1lqZrt41GjYgnvAi0fppqgQ==" }, "node_modules/tslib": { - "version": "2.4.1", - "license": "0BSD" + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.0.tgz", + "integrity": "sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg==" }, "node_modules/undici": { - "version": "5.19.1", - "resolved": "https://registry.npmjs.org/undici/-/undici-5.19.1.tgz", - "integrity": "sha512-YiZ61LPIgY73E7syxCDxxa3LV2yl3sN8spnIuTct60boiiRaE1J8mNWHO8Im2Zi/sFrPusjLlmRPrsyraSqX6A==", + "version": "5.21.2", + "resolved": "https://registry.npmjs.org/undici/-/undici-5.21.2.tgz", + "integrity": "sha512-f6pTQ9RF4DQtwoWSaC42P/NKlUjvezVvd9r155ohqkwFNRyBKM3f3pcty3ouusefNRyM25XhIQEbeQ46sZDJfQ==", "dependencies": { "busboy": "^1.6.0" }, @@ -504,24 +591,39 @@ }, "node_modules/util-deprecate": { "version": "1.0.2", - "license": "MIT" + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" }, - "node_modules/web-streams-polyfill": { - "version": "3.2.1", - "license": "MIT", + "node_modules/webidl-conversions": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", + "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==", "engines": { - "node": ">= 8" + "node": ">=12" + } + }, + "node_modules/whatwg-url": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-11.0.0.tgz", + "integrity": "sha512-RKT8HExMpoYx4igMiVMY83lN6UeITKJlBQ+vR/8ZJ8OCdSiN3RwCq+9gH0+Xzj0+5IrM6i4j/6LuvzbZIQgEcQ==", + "dependencies": { + "tr46": "^3.0.0", + "webidl-conversions": "^7.0.0" + }, + "engines": { + "node": ">=12" } }, "node_modules/ws": { - "version": "8.11.0", - "license": "MIT", + "version": "8.13.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.13.0.tgz", + "integrity": "sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA==", "engines": { "node": ">=10.0.0" }, "peerDependencies": { "bufferutil": "^4.0.1", - "utf-8-validate": "^5.0.2" + "utf-8-validate": ">=5.0.2" }, "peerDependenciesMeta": { "bufferutil": { @@ -535,228 +637,287 @@ }, "dependencies": { "@discordjs/builders": { - "version": "1.4.0", + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/@discordjs/builders/-/builders-1.6.1.tgz", + "integrity": "sha512-CCcLwn/8ANhlAbhlE18fcaN0hfXTen53/JiwZs1t9oE/Cqa9maA8ZRarkCIsXF4J7J/MYnd0J6IsxeKsq+f6mw==", "requires": { - "@discordjs/util": "^0.1.0", - "@sapphire/shapeshift": "^3.7.1", - "discord-api-types": "^0.37.20", + "@discordjs/formatters": "^0.3.0", + "@discordjs/util": "^0.2.0", + "@sapphire/shapeshift": "^3.8.1", + "discord-api-types": "^0.37.37", "fast-deep-equal": "^3.1.3", - "ts-mixer": "^6.0.2", - "tslib": "^2.4.1" + "ts-mixer": "^6.0.3", + "tslib": "^2.5.0" } }, "@discordjs/collection": { - "version": "1.3.0" + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@discordjs/collection/-/collection-1.5.0.tgz", + "integrity": "sha512-suyVndkEAAWrGxyw/CPGdtXoRRU6AUNkibtnbJevQzpelkJh3Q1gQqWDpqf5i39CnAn5+LrN0YS+cULeEjq2Yw==" + }, + "@discordjs/formatters": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@discordjs/formatters/-/formatters-0.3.0.tgz", + "integrity": "sha512-Fc4MomalbP8HMKEMor3qUiboAKDtR7PSBoPjwm7WYghVRwgJlj5WYvUsriLsxeKk8+Qq2oy+HJlGTUkGvX0YnA==", + "requires": { + "discord-api-types": "^0.37.37" + } }, "@discordjs/rest": { - "version": "1.4.0", + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@discordjs/rest/-/rest-1.7.0.tgz", + "integrity": "sha512-r2HzmznRIo8IDGYBWqQfkEaGN1LrFfWQd3dSyC4tOpMU8nuVvFUEw6V/lwnG44jyOq+vgyDny2fxeUDMt9I4aQ==", "requires": { - "@discordjs/collection": "^1.3.0", - "@discordjs/util": "^0.1.0", + "@discordjs/collection": "^1.5.0", + "@discordjs/util": "^0.2.0", "@sapphire/async-queue": "^1.5.0", - "@sapphire/snowflake": "^3.2.2", - "discord-api-types": "^0.37.20", - "file-type": "^18.0.0", - "tslib": "^2.4.1", - "undici": "^5.13.0" + "@sapphire/snowflake": "^3.4.0", + "discord-api-types": "^0.37.37", + "file-type": "^18.2.1", + "tslib": "^2.5.0", + "undici": "^5.21.0" } }, "@discordjs/util": { - "version": "0.1.0" + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@discordjs/util/-/util-0.2.0.tgz", + "integrity": "sha512-/8qNbebFzLWKOOg+UV+RB8itp4SmU5jw0tBUD3ifElW6rYNOj1Ku5JaSW7lLl/WgjjxF01l/1uQPCzkwr110vg==" }, "@iamtraction/google-translate": { "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@iamtraction/google-translate/-/google-translate-2.0.1.tgz", + "integrity": "sha512-kOTkt23zflxpgxLIe9tLvDU8IvNscXYbgMSXydNkZGWDtJ75YJiU3v7EBz+t7h/gSiY7sT5r4dlFkMrHCl+N6A==", "requires": { "undici": "^5.12.0" } }, "@sapphire/async-queue": { - "version": "1.5.0" + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@sapphire/async-queue/-/async-queue-1.5.0.tgz", + "integrity": "sha512-JkLdIsP8fPAdh9ZZjrbHWR/+mZj0wvKS5ICibcLrRI1j84UmLMshx5n9QmL8b95d4onJ2xxiyugTgSAX7AalmA==" }, "@sapphire/shapeshift": { - "version": "3.7.1", + "version": "3.8.2", + "resolved": "https://registry.npmjs.org/@sapphire/shapeshift/-/shapeshift-3.8.2.tgz", + "integrity": "sha512-NXpnJAsxN3/h9TqQPntOeVWZrpIuucqXI3IWF6tj2fWCoRLCuVK5wx7Dtg7pRrtkYfsMUbDqgKoX26vrC5iYfA==", "requires": { "fast-deep-equal": "^3.1.3", - "lodash.uniqwith": "^4.5.0" + "lodash": "^4.17.21" } }, "@sapphire/snowflake": { - "version": "3.2.2" + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/@sapphire/snowflake/-/snowflake-3.4.2.tgz", + "integrity": "sha512-KJwlv5gkGjs1uFV7/xx81n3tqgBwBJvH94n1xDyH3q+JSmtsMeSleJffarEBfG2yAFeJiFA4BnGOK6FFPHc19g==" }, "@tokenizer/token": { - "version": "0.3.0" + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@tokenizer/token/-/token-0.3.0.tgz", + "integrity": "sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A==" }, "@types/node": { - "version": "18.11.9" + "version": "18.15.11", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.15.11.tgz", + "integrity": "sha512-E5Kwq2n4SbMzQOn6wnmBjuK9ouqlURrcZDVfbo9ftDDTFt3nk7ZKK4GMOzoYgnpQJKcxwQw+lGaBvvlMo0qN/Q==" }, - "@types/ws": { - "version": "8.5.3", + "@types/webidl-conversions": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@types/webidl-conversions/-/webidl-conversions-7.0.0.tgz", + "integrity": "sha512-xTE1E+YF4aWPJJeUzaZI5DRntlkY3+BCVJi0axFptnjGmAoWxkyREIh/XMrfxVLejwQxMCfDXdICo0VLxThrog==" + }, + "@types/whatwg-url": { + "version": "8.2.2", + "resolved": "https://registry.npmjs.org/@types/whatwg-url/-/whatwg-url-8.2.2.tgz", + "integrity": "sha512-FtQu10RWgn3D9U4aazdwIE2yzphmTJREDqNdODHrbrZmmMqI0vMheC/6NE/J1Yveaj8H+ela+YwWTjq5PGmuhA==", "requires": { - "@types/node": "*" + "@types/node": "*", + "@types/webidl-conversions": "*" } }, - "asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" - }, - "axios": { - "version": "0.26.1", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.26.1.tgz", - "integrity": "sha512-fPwcX4EvnSHuInCMItEhAGnaSEXRBjtzh9fOtsE6E1G6p7vl7edEeZe11QHf18+6+9gR5PbKV/sGKNaD8YaMeA==", + "@types/ws": { + "version": "8.5.4", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.4.tgz", + "integrity": "sha512-zdQDHKUgcX/zBc4GrwsE/7dVdAD8JR4EuiAXiiUhhfyIJXXb2+PrGshFyeXWQPMmmZ2XxgaqclgpIC7eTXc1mg==", "requires": { - "follow-redirects": "^1.14.8" + "@types/node": "*" } }, + "bson": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/bson/-/bson-5.2.0.tgz", + "integrity": "sha512-HevkSpDbpUfsrHWmWiAsNavANKYIErV2ePXllp1bwq5CDreAaFVj6RVlZpJnxK4WWDCJ/5jMUpaY6G526q3Hjg==" + }, "busboy": { "version": "1.6.0", "requires": { "streamsearch": "^1.1.0" } }, - "colors": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", - "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==" + "chalk": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.2.0.tgz", + "integrity": "sha512-ree3Gqw/nazQAPuJJEy+avdl7QfZMcUvmHIKgEZkGL+xOBzRvup5Hxo6LHuMceSxOabuJLJm5Yp/92R9eMmMvA==" }, - "combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", "requires": { - "delayed-stream": "~1.0.0" + "ms": "2.1.2" + }, + "dependencies": { + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + } } }, - "data-uri-to-buffer": { - "version": "4.0.0" - }, - "delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==" - }, "discord-api-types": { - "version": "0.37.20" + "version": "0.37.39", + "resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.37.39.tgz", + "integrity": "sha512-hkhQsQyzsTJITp311WXvHZh9j4RAMfIk2hPmsWeOTN50QTpg6zqmJNfel9D/8lYNvsU01wzw9281Yke8NhYyHg==" }, "discord.js": { - "version": "14.7.1", - "resolved": "https://registry.npmjs.org/discord.js/-/discord.js-14.7.1.tgz", - "integrity": "sha512-1FECvqJJjjeYcjSm0IGMnPxLqja/pmG1B0W2l3lUY2Gi4KXiyTeQmU1IxWcbXHn2k+ytP587mMWqva2IA87EbA==", + "version": "14.9.0", + "resolved": "https://registry.npmjs.org/discord.js/-/discord.js-14.9.0.tgz", + "integrity": "sha512-ygGms5xP4hG+QrrY9k7d/OYCzMltSMtdl/2Snzq/nLCiZo+Sna91Ulv9l0+B5Jd/Czcq37B7wJAnmja7GOa+bg==", "requires": { - "@discordjs/builders": "^1.4.0", - "@discordjs/collection": "^1.3.0", - "@discordjs/rest": "^1.4.0", - "@discordjs/util": "^0.1.0", - "@sapphire/snowflake": "^3.2.2", - "@types/ws": "^8.5.3", - "discord-api-types": "^0.37.20", + "@discordjs/builders": "^1.6.0", + "@discordjs/collection": "^1.5.0", + "@discordjs/formatters": "^0.3.0", + "@discordjs/rest": "^1.7.0", + "@discordjs/util": "^0.2.0", + "@sapphire/snowflake": "^3.4.0", + "@types/ws": "^8.5.4", + "discord-api-types": "^0.37.37", "fast-deep-equal": "^3.1.3", "lodash.snakecase": "^4.1.1", - "tslib": "^2.4.1", - "undici": "^5.13.0", - "ws": "^8.11.0" + "tslib": "^2.5.0", + "undici": "^5.21.0", + "ws": "^8.13.0" } }, - "erela.js": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/erela.js/-/erela.js-2.4.0.tgz", - "integrity": "sha512-wLfPvfzbDZTDV0zwJYXGkjO9Q6mkXi3PNf984apdv58Ktt0cv1Zp8og3hmp7Ose4C4iwAKitHxV/yiP+pt3FRQ==", - "requires": { - "@discordjs/collection": "^1.1.0", - "tslib": "^2.4.0", - "undici": "^5.10.0", - "ws": "^8.8.1" - } + "dotenv": { + "version": "16.0.3", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.0.3.tgz", + "integrity": "sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ==" }, "fast-deep-equal": { - "version": "3.1.3" - }, - "fetch-blob": { - "version": "3.2.0", - "requires": { - "node-domexception": "^1.0.0", - "web-streams-polyfill": "^3.0.3" - } + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" }, "file-type": { - "version": "18.0.0", + "version": "18.2.1", + "resolved": "https://registry.npmjs.org/file-type/-/file-type-18.2.1.tgz", + "integrity": "sha512-Yw5MtnMv7vgD2/6Bjmmuegc8bQEVA9GmAyaR18bMYWKqsWDG9wgYZ1j4I6gNMF5Y5JBDcUcjRQqNQx7Y8uotcg==", "requires": { "readable-web-to-node-stream": "^3.0.2", "strtok3": "^7.0.0", "token-types": "^5.0.1" } }, - "follow-redirects": { - "version": "1.15.2", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", - "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==" + "ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==" }, - "form-data": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", - "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" - } + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" }, - "formdata-polyfill": { - "version": "4.0.10", - "requires": { - "fetch-blob": "^3.1.2" - } + "ip": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ip/-/ip-2.0.0.tgz", + "integrity": "sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ==" }, - "ieee754": { - "version": "1.2.1" + "kareem": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/kareem/-/kareem-2.5.1.tgz", + "integrity": "sha512-7jFxRVm+jD+rkq3kY0iZDJfsO2/t4BBPeEb2qKn2lR/9KhuksYk5hxzfRYWMPV8P/x2d0kHD306YyWLzjjH+uA==" }, - "inherits": { - "version": "2.0.4" + "lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" }, "lodash.snakecase": { "version": "4.1.1" }, - "lodash.uniqwith": { - "version": "4.5.0" - }, - "mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==" - }, - "mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "memory-pager": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/memory-pager/-/memory-pager-1.5.0.tgz", + "integrity": "sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==", + "optional": true + }, + "mongodb": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-5.1.0.tgz", + "integrity": "sha512-qgKb7y+EI90y4weY3z5+lIgm8wmexbonz0GalHkSElQXVKtRuwqXuhXKccyvIjXCJVy9qPV82zsinY0W1FBnJw==", "requires": { - "mime-db": "1.52.0" + "bson": "^5.0.1", + "mongodb-connection-string-url": "^2.6.0", + "saslprep": "^1.0.3", + "socks": "^2.7.1" } }, - "node-domexception": { - "version": "1.0.0" + "mongodb-connection-string-url": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/mongodb-connection-string-url/-/mongodb-connection-string-url-2.6.0.tgz", + "integrity": "sha512-WvTZlI9ab0QYtTYnuMLgobULWhokRjtC7db9LtcVfJ+Hsnyr5eo6ZtNAt3Ly24XZScGMelOcGtm7lSn0332tPQ==", + "requires": { + "@types/whatwg-url": "^8.2.1", + "whatwg-url": "^11.0.0" + } }, - "node-fetch": { - "version": "3.3.0", + "mongoose": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-7.0.4.tgz", + "integrity": "sha512-MEmQOOqQUvW1PJcji64NtA2EFGHrEvk9o4g//isVYSJW2+8Y8u49C2qFBKzn1t6/l9onQn012o/PcFqR6ixQpQ==", "requires": { - "data-uri-to-buffer": "^4.0.0", - "fetch-blob": "^3.1.4", - "formdata-polyfill": "^4.0.10" + "bson": "^5.0.1", + "kareem": "2.5.1", + "mongodb": "5.1.0", + "mpath": "0.9.0", + "mquery": "5.0.0", + "ms": "2.1.3", + "sift": "16.0.1" } }, - "openai": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/openai/-/openai-3.1.0.tgz", - "integrity": "sha512-v5kKFH5o+8ld+t0arudj833Mgm3GcgBnbyN9946bj6u7bvel4Yg6YFz2A4HLIYDzmMjIo0s6vSG9x73kOwvdCg==", + "mpath": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/mpath/-/mpath-0.9.0.tgz", + "integrity": "sha512-ikJRQTk8hw5DEoFVxHG1Gn9T/xcjtdnOKIU1JTmGjZZlg9LST2mBLmcX3/ICIbgJydT2GOc15RnNy5mHmzfSew==" + }, + "mquery": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/mquery/-/mquery-5.0.0.tgz", + "integrity": "sha512-iQMncpmEK8R8ncT8HJGsGc9Dsp8xcgYMVSbs5jgnm1lFHTZqMJTUWTDx1LBO8+mK3tPNZWFLBghQEIOULSTHZg==", "requires": { - "axios": "^0.26.0", - "form-data": "^4.0.0" + "debug": "4.x" } }, + "ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, "peek-readable": { - "version": "5.0.0" + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/peek-readable/-/peek-readable-5.0.0.tgz", + "integrity": "sha512-YtCKvLUOvwtMGmrniQPdO7MwPjgkFBtFIrmfSbYmYuq3tKDV/mcfAhBth1+C3ru7uXIZasc/pHnb+YDYNkkj4A==" + }, + "punycode": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", + "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==" }, "readable-stream": { - "version": "3.6.0", + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", "requires": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", @@ -765,24 +926,69 @@ }, "readable-web-to-node-stream": { "version": "3.0.2", + "resolved": "https://registry.npmjs.org/readable-web-to-node-stream/-/readable-web-to-node-stream-3.0.2.tgz", + "integrity": "sha512-ePeK6cc1EcKLEhJFt/AebMCLL+GgSKhuygrZ/GLaKZYEecIgIECf4UaUuaByiGtzckwR4ain9VzUh95T1exYGw==", "requires": { "readable-stream": "^3.6.0" } }, "safe-buffer": { - "version": "5.2.1" + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" + }, + "saslprep": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/saslprep/-/saslprep-1.0.3.tgz", + "integrity": "sha512-/MY/PEMbk2SuY5sScONwhUDsV2p77Znkb/q3nSVstq/yQzYJOH/Azh29p9oJLsl3LnQwSvZDKagDGBsBwSooag==", + "optional": true, + "requires": { + "sparse-bitfield": "^3.0.3" + } + }, + "sift": { + "version": "16.0.1", + "resolved": "https://registry.npmjs.org/sift/-/sift-16.0.1.tgz", + "integrity": "sha512-Wv6BjQ5zbhW7VFefWusVP33T/EM0vYikCaQ2qR8yULbsilAT8/wQaXvuQ3ptGLpoKx+lihJE3y2UTgKDyyNHZQ==" + }, + "smart-buffer": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", + "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==" + }, + "socks": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/socks/-/socks-2.7.1.tgz", + "integrity": "sha512-7maUZy1N7uo6+WVEX6psASxtNlKaNVMlGQKkG/63nEDdLOWNbiUMoLK7X4uYoLhQstau72mLgfEWcXcwsaHbYQ==", + "requires": { + "ip": "^2.0.0", + "smart-buffer": "^4.2.0" + } + }, + "sparse-bitfield": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz", + "integrity": "sha512-kvzhi7vqKTfkh0PZU+2D2PIllw2ymqJKujUcyPMd9Y75Nv4nPbGJZXNhxsgdQab2BmlDct1YnfQCguEvHr7VsQ==", + "optional": true, + "requires": { + "memory-pager": "^1.0.2" + } }, "streamsearch": { "version": "1.1.0" }, "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" } }, "strtok3": { "version": "7.0.0", + "resolved": "https://registry.npmjs.org/strtok3/-/strtok3-7.0.0.tgz", + "integrity": "sha512-pQ+V+nYQdC5H3Q7qBZAz/MO6lwGhoC2gOAjuouGf/VO0m7vQRh8QNMl2Uf6SwAtzZ9bOw3UIeBukEGNJl5dtXQ==", "requires": { "@tokenizer/token": "^0.3.0", "peek-readable": "^5.0.0" @@ -790,33 +996,62 @@ }, "token-types": { "version": "5.0.1", + "resolved": "https://registry.npmjs.org/token-types/-/token-types-5.0.1.tgz", + "integrity": "sha512-Y2fmSnZjQdDb9W4w4r1tswlMHylzWIeOKpx0aZH9BgGtACHhrk3OkT52AzwcuqTRBZtvvnTjDBh8eynMulu8Vg==", "requires": { "@tokenizer/token": "^0.3.0", "ieee754": "^1.2.1" } }, + "tr46": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-3.0.0.tgz", + "integrity": "sha512-l7FvfAHlcmulp8kr+flpQZmVwtu7nfRV7NZujtN0OqES8EL4O4e0qqzL0DC5gAvx/ZC/9lk6rhcUwYvkBnBnYA==", + "requires": { + "punycode": "^2.1.1" + } + }, "ts-mixer": { - "version": "6.0.2" + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/ts-mixer/-/ts-mixer-6.0.3.tgz", + "integrity": "sha512-k43M7uCG1AkTyxgnmI5MPwKoUvS/bRvLvUb7+Pgpdlmok8AoqmUaZxUUw8zKM5B1lqZrt41GjYgnvAi0fppqgQ==" }, "tslib": { - "version": "2.4.1" + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.0.tgz", + "integrity": "sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg==" }, "undici": { - "version": "5.19.1", - "resolved": "https://registry.npmjs.org/undici/-/undici-5.19.1.tgz", - "integrity": "sha512-YiZ61LPIgY73E7syxCDxxa3LV2yl3sN8spnIuTct60boiiRaE1J8mNWHO8Im2Zi/sFrPusjLlmRPrsyraSqX6A==", + "version": "5.21.2", + "resolved": "https://registry.npmjs.org/undici/-/undici-5.21.2.tgz", + "integrity": "sha512-f6pTQ9RF4DQtwoWSaC42P/NKlUjvezVvd9r155ohqkwFNRyBKM3f3pcty3ouusefNRyM25XhIQEbeQ46sZDJfQ==", "requires": { "busboy": "^1.6.0" } }, "util-deprecate": { - "version": "1.0.2" + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" + }, + "webidl-conversions": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", + "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==" }, - "web-streams-polyfill": { - "version": "3.2.1" + "whatwg-url": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-11.0.0.tgz", + "integrity": "sha512-RKT8HExMpoYx4igMiVMY83lN6UeITKJlBQ+vR/8ZJ8OCdSiN3RwCq+9gH0+Xzj0+5IrM6i4j/6LuvzbZIQgEcQ==", + "requires": { + "tr46": "^3.0.0", + "webidl-conversions": "^7.0.0" + } }, "ws": { - "version": "8.11.0", + "version": "8.13.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.13.0.tgz", + "integrity": "sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA==", "requires": {} } } diff --git a/package.json b/package.json index b430eda..5c47241 100644 --- a/package.json +++ b/package.json @@ -1,30 +1,29 @@ { "name": "o-codex", - "version": "1.2.0", - "description": "Minesa Hub's Bot", + "version": "2.0.0", + "description": "A Discord bot is doing unique things.", "main": "index.js", "type": "module", "scripts": { "test": "echo \"Error: no test specified\" && exit 1", - "start": "node index.js" + "start": "node src/index.js" }, "repository": { "type": "git", - "url": "git+https://github.com/minesa-hub/Neobot.git" + "url": "git+https://github.com/minesa-hub/O-codex.git" }, "keywords": [], "author": "", "license": "ISC", "bugs": { - "url": "https://github.com/minesa-hub/Neobot/issues" + "url": "https://github.com/minesa-hub/O-codex/issues" }, - "homepage": "https://github.com/minesa-hub/Neobot#readme", + "homepage": "https://github.com/minesa-hub/o-codex#readme", "dependencies": { - "@iamtraction/google-translate": "^2.0.0", - "colors": "^1.4.0", - "discord.js": "^14.7.1", - "erela.js": "^2.4.0", - "node-fetch": "^3.2.10", - "openai": "^3.1.0" + "@iamtraction/google-translate": "^2.0.1", + "chalk": "^5.2.0", + "discord.js": "^14.9.0", + "dotenv": "^16.0.3", + "mongoose": "^7.0.4" } } diff --git a/src/commands/context menus/user-avatar.js b/src/commands/context menus/user-avatar.js deleted file mode 100644 index 65ac7d6..0000000 --- a/src/commands/context menus/user-avatar.js +++ /dev/null @@ -1,51 +0,0 @@ -import { - ContextMenuCommandBuilder, - ApplicationCommandType, - ButtonBuilder, - ButtonStyle, - ActionRowBuilder, - EmbedBuilder, -} from 'discord.js'; - -export default { - data: new ContextMenuCommandBuilder() - .setName('User Avatar') - .setNameLocalizations({ - tr: 'Kullanıcı Avatarı', - it: 'Avatar Utente', - ChineseCN: '用户头像', - }) - .setType(ApplicationCommandType.User), - async execute({ interaction }) { - // Deferring the reply - await interaction.deferReply({ ephemeral: true }); - - // Getting the user from the context menu - const target = interaction.guild.members.cache.get(interaction.targetId); - const targetAvatar = target.user.avatarURL({ - dynamic: true, - size: 4096, - }); - - // Creating an embed - const embed = new EmbedBuilder() - .setTitle(`${target.user.username}'s Avatar`) - .setImage(targetAvatar) - - - // Creating a new button - const button = new ActionRowBuilder().addComponents( - new ButtonBuilder() - .setCustomId(`ShowMemberAvatar_${target.id}`) - .setLabel('See Their Member Avatar!') - .setStyle(ButtonStyle.Secondary) - .setEmoji('<:git_eye:992920314172424242>'), - ); - - // Creating the reply - await interaction.followUp({ - embeds: [embed], - components: [button], - }); - }, -}; diff --git a/src/commands/context menus/user-banner.js b/src/commands/context menus/user-banner.js deleted file mode 100644 index dc97ef0..0000000 --- a/src/commands/context menus/user-banner.js +++ /dev/null @@ -1,35 +0,0 @@ -import { ContextMenuCommandBuilder, ApplicationCommandType } from 'discord.js'; - -export default { - data: new ContextMenuCommandBuilder() - .setName('User Banner') - .setNameLocalizations({ - tr: 'Kullanıcı Afişi', - it: 'Banner Utente', - ChineseCN: '用户横幅', - }) - .setType(ApplicationCommandType.User), - async execute({ interaction, client }) { - // Getting the user from the context menu - let user = client.users.fetch(interaction.targetId, { force: true }); - - // Creating the reply - user.then(async (res) => { - // Save the banner URL in a variable - var imgURL = res.bannerURL({ size: 4096, dynamic: true }); - - // If the user has no banner, return message, else return the banner - if (imgURL == null) { - await interaction.reply({ - content: ">>> This user doesn't have a banner.", - ephemeral: true, - }); - } else { - await interaction.reply({ - content: `>>> ${imgURL}`, - ephemeral: true, - }); - } - }); - }, -}; diff --git a/src/commands/context menus/translate.js b/src/commands/contextMenu/messageTranslate.js similarity index 57% rename from src/commands/context menus/translate.js rename to src/commands/contextMenu/messageTranslate.js index bcc67f1..f727a80 100644 --- a/src/commands/context menus/translate.js +++ b/src/commands/contextMenu/messageTranslate.js @@ -3,40 +3,40 @@ import { ApplicationCommandType, ContextMenuCommandBuilder } from 'discord.js'; export default { data: new ContextMenuCommandBuilder() - .setName('Translate') + .setName('Translate Message') .setNameLocalizations({ - tr: 'Çevir', - it: 'Tradurre', - ChineseCN: '翻译', + ChineseCN: '翻译消息', + it: 'Traduci Messaggio', + tr: 'Mesajı Çevir', }) .setType(ApplicationCommandType.Message), - async execute({ interaction }) { - // Getting the message from the context menu - const message = interaction.options.getMessage('message', true); + execute: async ({ interaction }) => { await interaction.deferReply({ ephemeral: true }); - // Getting the language from the command arguments + const message = interaction.options.getMessage('message'); + if (!message.content) - return interaction.editReply({ content: 'There is no text in this message.' }); + interaction.editReply({ + content: 'Message has no content to translate.', + ephemeral: true, + }); try { - // Translating the message const locale = !['zh-CN', 'zh-TW'].includes(interaction.locale) ? new Intl.Locale(interaction.locale).language : interaction.locale; const translated = await translate( message.content.replace(/()?/g, ''), - { - to: locale, - }, + { to: locale }, ); - // Sending the translated message - return interaction.editReply({ content: translated.text }); + interaction.editReply({ + content: translated.text, + }); } catch (error) { - // Sending an error message - return interaction.editReply({ + interaction.editReply({ content: 'An error occurred while translating the message.', + ephemeral: true, }); } }, diff --git a/src/commands/contextMenu/userAvatar.js b/src/commands/contextMenu/userAvatar.js new file mode 100644 index 0000000..42e5c93 --- /dev/null +++ b/src/commands/contextMenu/userAvatar.js @@ -0,0 +1,34 @@ +import { + ContextMenuCommandBuilder, + ApplicationCommandType, + EmbedBuilder, + ButtonBuilder, + ButtonStyle, + ActionRowBuilder, +} from 'discord.js'; + +export default { + data: new ContextMenuCommandBuilder() + .setName('User Avatar') + .setNameLocalizations({ + ChineseCN: '用户头像', + it: 'Avatar Utente', + tr: 'Kullanıcı Avatarı-', + }) + .setType(ApplicationCommandType.User), + execute: async ({ interaction }) => { + await interaction.deferReply({ ephemeral: true }); + + const target = interaction.guild.members.cache.get(interaction.targetId); + const avatar = target.user.displayAvatarURL({ dynamic: true, size: 4096 }); + + const embed = new EmbedBuilder() + .setTitle(`${target.user.tag}'s Avatar`) + .setImage(avatar) + .setColor(0x1e1e1e); + + await interaction.editReply({ + embeds: [embed], + }); + }, +}; diff --git a/src/commands/contextMenu/userBanner.js b/src/commands/contextMenu/userBanner.js new file mode 100644 index 0000000..979d759 --- /dev/null +++ b/src/commands/contextMenu/userBanner.js @@ -0,0 +1,34 @@ +import { ContextMenuCommandBuilder, ApplicationCommandType, EmbedBuilder } from 'discord.js'; + +export default { + data: new ContextMenuCommandBuilder() + .setName('User Banner') + .setNameLocalizations({ + ChineseCN: '用户横幅', + it: 'Banner Utente', + tr: 'Kullanıcı Afişi', + }) + .setType(ApplicationCommandType.User), + execute: async ({ interaction, client }) => { + await interaction.deferReply({ ephemeral: true }); + + const user = client.users.fetch(interaction.targetId, { force: true }); + + user.then(async (resolved) => { + const imageURI = resolved.bannerURL({ dynamic: true, size: 4096 }); + const embed = new EmbedBuilder() + .setTitle(`${resolved.tag}'s Banner`) + .setImage(imageURI) + .setColor(0x1e1e1e); + + if (imageURI === null) { + await interaction.editReply({ + content: 'User has no banner set.', + ephemeral: true, + }); + } else { + await interaction.editReply({ embeds: [embed] }); + } + }); + }, +}; diff --git a/src/commands/general/generate-image.js b/src/commands/general/generate-image.js deleted file mode 100644 index c73836c..0000000 --- a/src/commands/general/generate-image.js +++ /dev/null @@ -1,57 +0,0 @@ -// Importing openai -import { SlashCommandBuilder } from 'discord.js'; -import { Configuration, OpenAIApi } from 'openai'; -import config from '../../../config.js'; - -// Creating the command -export default { - data: new SlashCommandBuilder() - .setName('generate-image') - .setDescription('— Generate images with A.I.!') - .setNameLocalizations({ - tr: 'görüntü-oluştur', - it: 'generare-immagine', - ChineseCN: '生成图像', - }) - .setDescriptionLocalizations({ - tr: '— Y.Z. ile görüntüler oluşturun!', - it: "— Genera immagini con l'intelligenza artificiale!", - ChineseCN: '— 用人工智能生成图像!', - }) - .addStringOption((option) => - option - .setName('text') - .setDescription('What is your imagination? 👀') - .setRequired(true) - .setNameLocalizations({ tr: 'konu' }) - .setDescriptionLocalizations({ tr: '• Hayal gücünde neler var? 👀' }), - ), - async execute({ interaction }) { - // Configuration of openai - const configuration = new Configuration({ - apiKey: config.openai.apiKey, - organization: config.openai.organization, - }); - const openai = new OpenAIApi(configuration); - - if (interaction.channel.id === '1071856982748844124') { - if (interaction.author.bot) return; - - try { - const imageUrl = await openai.createImage({ - prompt: interaction.content, - n: 1, - size: '1024x1024', - }); - interaction.reply({ content: `${imageUrl.data.data[0].url}` }); - } catch (error) { - interaction.reply({ - content: - "Couldn't generate that image... Am I the problem or you? Can't decide...", - ephemeral: true, - }); - console.log(error); - } - } - }, -}; diff --git a/src/commands/general/generate-meme.js b/src/commands/general/generate-meme.js deleted file mode 100644 index 0affe81..0000000 --- a/src/commands/general/generate-meme.js +++ /dev/null @@ -1,33 +0,0 @@ -import { SlashCommandBuilder } from 'discord.js'; -import { fetch } from 'undici'; - -export default { - data: new SlashCommandBuilder() - .setName('meme') - .setDescription('— Sends a random meme from somewhere.') - .setNameLocalizations({ tr: 'meme', it: 'meme', ChineseCN: '梗图' }) - .setDescriptionLocalizations({ - tr: '— Bir yerden rastgele bir meme gönderir.', - it: '— Invia un meme casuale da qualche parte.', - ChineseCN: '— 从某处发送一个随机梗图。', - }), - async execute({ interaction }) { - // Deferring the reply - await interaction.deferReply(); - - try { - // Fetching the meme - const raw = await fetch('https://apis.duncte123.me/meme', { method: 'GET' }); - const response = await raw.json(); - - // Sending the meme - return interaction.editReply({ content: response.data.image }); - } catch (error) { - // Sending an error message - return interaction.editReply({ - content: 'An error occurred while fetching the meme.', - ephemeral: true, - }); - } - }, -}; diff --git a/src/commands/general/generate-nsfw.js b/src/commands/general/generate-nsfw.js deleted file mode 100644 index 5146b5c..0000000 --- a/src/commands/general/generate-nsfw.js +++ /dev/null @@ -1,87 +0,0 @@ -import { ActionRowBuilder, ButtonBuilder, ButtonStyle, SlashCommandBuilder } from 'discord.js'; -import { fetch } from 'undici'; - -export default { - data: new SlashCommandBuilder() - .setName('nsfw') - .setDescription('— Access to NSFW images.') - .setNameLocalizations({ tr: 'nsfw', it: 'nsfw', ChineseCN: 'nsfw' }) - .setDescriptionLocalizations({ - tr: '— NSFW resimlere erişim.', - it: '— Accesso alle immagini NSFW.', - ChineseCN: '— 访问NSFW图像。', - }) - .addStringOption((option) => - option - .setName('category') - .setDescription('• The category to see.') - .setRequired(true) - .setNameLocalizations({ tr: 'kategori' }) - .setDescriptionLocalizations({ tr: '• Seçmek istediğiniz kategori.' }) - .addChoices( - { name: 'driff', value: 'hmidriff' }, - { name: 'porn gif', value: 'pgif' }, - { name: '4k', value: '4k' }, - { name: 'hentai', value: 'hentai' }, - { name: 'holo', value: 'holo' }, - { name: 'hneko', value: 'hneko' }, - { name: 'hkitsune', value: 'hkitsune' }, - { name: 'kemonomimi', value: 'kemonomimi' }, - { name: 'anal', value: 'anal' }, - { name: 'hanal', value: 'hanal' }, - { name: 'gonewild', value: 'gonewild' }, - { name: 'ass', value: 'ass' }, - { name: 'pussy', value: 'pussy' }, - { name: 'thigh', value: 'thigh' }, - { name: 'hthigh', value: 'hthigh' }, - { name: 'paizuri', value: 'paizuri' }, - { name: 'tentacle', value: 'tentacle' }, - { name: 'boobs', value: 'boobs' }, - { name: 'yaoi', value: 'yaoi' }, - ), - ) - .addBooleanOption((option) => - option - .setName('ephemeral') - .setDescription('• Display the response as ephemeral or not?') - .setRequired(true) - .setNameLocalizations({ tr: 'kısmı_görünüm' }) - .setDescriptionLocalizations({ - tr: 'Resmi kısmi mesaj olarak göster veya gösterme, seçim senin?', - }), - ), - async execute({ interaction }) { - // Adding "category" and "ephemeral" options for the slash - const category = interaction.options.getString('category'); - const ephemeral = interaction.options.getBoolean('ephemeral'); - - try { - // Fetching the url to get an image of the category - const raw = await fetch(`https://nekobot.xyz/api/image?type=${category}`, { - method: 'GET', - }); - const response = await raw.json(); - - // Building a button - const button = new ActionRowBuilder().addComponents( - new ButtonBuilder() - .setLabel('Display in Browser') - .setURL(response.message) - .setStyle(ButtonStyle.Link), - ); - - // Sending the response - return interaction.reply({ - content: response.message, - components: [button], - ephemeral, - }); - } catch (error) { - // Sending the error - return interaction.reply({ - content: 'Nothing found for this search.', - ephemeral: true, - }); - } - }, -}; diff --git a/src/commands/general/give-me.js b/src/commands/general/give-me.js deleted file mode 100644 index 0a1654e..0000000 --- a/src/commands/general/give-me.js +++ /dev/null @@ -1,37 +0,0 @@ -import { SlashCommandBuilder } from 'discord.js'; - -export default { - data: new SlashCommandBuilder() - .setName('give-me') - .setDescription('— Take the key and lock yourself in the top of all roles.') - .setNameLocalizations({ tr: 'bana-ver', it: 'dami-mi', ChineseCN: '给我' }) - .setDescriptionLocalizations({ - tr: '— Anahtarı al ve tüm rollerin en üstünde kendini kilitle.', - it: '— Prendi la chiave e bloccati in cima a tutti i ruoli.', - ChineseCN: '— 拿起钥匙,把自己锁在所有角色的顶部。', - }), - async execute({ interaction, client }) { - // Declaring the role - const role = '805451556081500220'; - // Declaring the guild - const guild = client.guilds.cache.get('697039582922801182'); - - // Get all members with the role - let members = await guild.members.fetch(); - members = members.filter((m) => m.roles.cache.has(role)); - - // Take role from all members - for (const member of members.values()) { - await member.roles.remove(role); - } - - // Give role to the command executor - await interaction.member.roles.add(role); - - // Send interaction reply - return interaction.reply({ - content: 'You have taken the key!', - ephemeral: true, - }); - }, -}; diff --git a/src/commands/general/text-to-ai.js b/src/commands/general/text-to-ai.js deleted file mode 100644 index 732621f..0000000 --- a/src/commands/general/text-to-ai.js +++ /dev/null @@ -1,66 +0,0 @@ -import { SlashCommandBuilder } from 'discord.js'; -import { Configuration, OpenAIApi } from 'openai'; -import config from '../../../config.js'; - -// Creating the command -export default { - data: new SlashCommandBuilder() - .setName('ask-ai') - .setDescription('— Ask to artificial intelligence anything in your mind!') - .setNameLocalizations({ - tr: 'yapay-zekaya-sor', - it: "chiedi-ai", - 'zh-CN': '问人工智能', - }) - .setDescriptionLocalizations({ - tr: '— Aklınızdaki her şeyi yapay zekaya sorun!', - it: "— Chiedi all'intelligenza artificiale qualsiasi cosa nella tua mente!", - 'zh-CN': '— 向人工智能询问您的想法!', - }) - .addStringOption((option) => - option - .setName('text') - .setDescription('• So... What is it?') - .setRequired(true) - .setNameLocalizations({ tr: 'konu', it: 'soggetto', 'zh-CN': '主题' }) - .setDescriptionLocalizations({ - tr: '• Ehm... Ne soracaksın?', - 'zh-CN': '• 嗯……你会问什么?', - it: '• Ehm... Cosa chiederai?', - }), - ), - async execute({ interaction }) { - // Configuration of openai - const configuration = new Configuration({ - apiKey: config.openai.apiKey, - organization: config.openai.organization, - }); - const openai = new OpenAIApi(configuration); - - // OpenAI - if (interaction.channel.id === '795473337697697837') { - if (interaction.author.bot) return; - - try { - const completion = await openai.createCompletion({ - model: 'text-davinci-003', - prompt: interaction.content, - temperature: 0.5, - max_tokens: 400, - top_p: 1.0, - frequency_penalty: 0.5, - presence_penalty: 0.0, - stop: ['You:'], - }); - - interaction.reply(`${completion.data.choices[0].text}`); - } catch (error) { - interaction.reply({ - content: `Sorry, couldn't answer that. I don't want to...`, - ephemeral: true, - }); - console.log(error); - } - } - }, -}; diff --git a/src/commands/misc/add-emoji.js b/src/commands/misc/add-emoji.js deleted file mode 100644 index bf0e1cf..0000000 --- a/src/commands/misc/add-emoji.js +++ /dev/null @@ -1,71 +0,0 @@ -import { SlashCommandBuilder, parseEmoji } from 'discord.js'; - -export default { - data: new SlashCommandBuilder() - .setName('addemoji') - .setDescription('— Adds an emoji to the server.') - .setNameLocalizations({ tr: 'emojiekle', it: 'aggiungiemoji', ChineseCN: '添加表情' }) - .setDescriptionLocalizations({ - tr: '— Sunucuya bir emoji ekler.', - it: '— Aggiunge un emoji al server.', - ChineseCN: '— 将表情添加到服务器。', - }) - .addStringOption((option) => - option - .setName('name') - .setDescription('• The name of the emoji.') - .setRequired(true) - .setNameLocalizations({ tr: 'isim', it: 'nome', ChineseCN: '名称' }) - .setDescriptionLocalizations({ - tr: '• Emojinin adı.', - it: "• Il nome dell'emoji.", - ChineseCN: '• 表情的名称。', - }), - ) - .addStringOption((option) => - option - .setName('emoji') - .setDescription('• The emoji.') - .setRequired(true) - .setNameLocalizations({ tr: 'emoji', it: 'emoji', ChineseCN: '表情' }) - .setDescriptionLocalizations({ - tr: '• Emoji.', - it: '• Emoji.', - ChineseCN: '• 表情。', - }), - ), - async execute({ interaction }) { - // Adding "name" and "emoji" options for the slash - const name = interaction.options.getString('name'); - const emoji = interaction.options.getString('emoji'); - - // Regex - const regex = RegExp(/(https?:\/\/[^\s]+)/g); - - // Parsing the emoji - const parse = parseEmoji(emoji); - - try { - let emojis; - if (emoji.match(regex)) { - emojis = await interaction.guild.emojis.create({ attachment: emoji, name }); - } else if (parse.id) { - const link = `https://cdn.discordapp.com/emojis/${parse.id}.${ - parse.animated ? 'gif' : 'png' - }`; - emojis = await interaction.guild.emojis.create({ attachment: link, name }); - } - - return interaction.reply({ - content: `Emoji \`:${emojis.name}:\` ${emojis} was successfully added.`, - }); - } catch (err) { - console.error(err); - - return interaction.reply({ - content: "The emoji is invalid or we don't have more space.", - ephemeral: true, - }); - } - }, -}; diff --git a/src/commands/misc/create-event.js b/src/commands/misc/create-event.js deleted file mode 100644 index 896331a..0000000 --- a/src/commands/misc/create-event.js +++ /dev/null @@ -1,72 +0,0 @@ -import moment from 'moment-timezone'; -import { SlashCommandBuilder } from 'discord.js'; - -export default { - data: new SlashCommandBuilder() - .setName('create-event') - .setDescription('Create a giveaway by events.') - .addStringOption((option) => - option.setName('name') - .setDescription('Event name.') - .setRequired(true) - ) - .addStringOption((option) => - option.setName('description') - .setDescription('Event description.') - .setRequired(true) - ) - .addStringOption((option) => - option.setName('location') - .setDescription('Write down the location.') - .setRequired(true) - ) - .addStringOption((option) => - option.setName('duration') - .setDescription('The duration of event') - .setRequired(true) - .addChoices({ name: '1 minute', value: 'min' }, { name: '1 hour', value: 'hour' }, { name: '1 day', value: 'day' }) - ), - async execute({ interaction }) { - await interaction.deferReply(); - - const eventName = interaction.options.getString('name'); - const eventDescription = interaction.options.getString('description'); - const eventLocation = interaction.options.getString('location'); - const duration = interaction.options.getString('duration'); - - let seconds; - switch (duration) { - case 'min': - seconds = 60; - break; - case 'hour': - seconds = 60 * 60; - break; - case 'day': - seconds = 24 * 60 * 60; - break; - default: - return await interaction.followUp('Invalid duration selected.'); - } - - const timezone = 'Europe/Istanbul'; - const scheduledStartTime = moment().tz(timezone).add(seconds, 'seconds'); - const scheduledEndTime = moment(scheduledStartTime).add(30, 'minutes'); - - interaction.guild.scheduledEvents.create({ - name: eventName, - description: eventDescription, - scheduledStartTime: scheduledStartTime.format(), - scheduledEndTime: scheduledEndTime.format(), - privacyLevel: 2, - entityType: 3, - entityMetadata: { - location: eventLocation - } - }); - - return interaction.editReply({ - content: `Created an event starting at ${scheduledStartTime.format('lll')} and ending at ${scheduledEndTime.format('lll')} in ${timezone}` - }); - } -} diff --git a/src/commands/misc/createDiscussion.js b/src/commands/misc/createDiscussion.js new file mode 100644 index 0000000..6aa86c3 --- /dev/null +++ b/src/commands/misc/createDiscussion.js @@ -0,0 +1,53 @@ +import { + ActionRowBuilder, + ModalBuilder, + SlashCommandBuilder, + TextInputBuilder, + TextInputStyle, +} from 'discord.js'; + +export default { + data: new SlashCommandBuilder() + .setName('create-discussion') + .setNameLocalizations({ + tr: 'tartışma-oluştur', + it: 'crea-discussione', + ChineseCN: '创建讨论', + }) + .setDescription('Create a discussion about anything!') + .setDescriptionLocalizations({ + tr: 'Herhangi bir şey hakkında tartışma oluşturun!', + it: 'Crea una discussione su qualsiasi cosa!', + ChineseCN: '创建关于任何事情的讨论!', + }), + execute: async ({ interaction }) => { + const discussionModal = new ModalBuilder() + .setCustomId('create-discussion-modal') + .setTitle('Discussion Creation'); + + const discussionTitleInput = new TextInputBuilder() + .setCustomId('discussion-title') + .setLabel('What do you want to discuss?') + .setRequired(true) + .setStyle(TextInputStyle.Short) + .setPlaceholder('I think this bot is awesome!') + .setMaxLength(100) + .setMinLength(10); + + const discussionDescriptionInput = new TextInputBuilder() + .setCustomId('discussion-description') + .setLabel('Why do you think this?') + .setRequired(true) + .setStyle(TextInputStyle.Paragraph) + .setPlaceholder("I think this bot is awesome because it's open source and it's free!") + .setMaxLength(1000) + .setMinLength(10); + + const row = new ActionRowBuilder().addComponents(discussionTitleInput); + const row2 = new ActionRowBuilder().addComponents(discussionDescriptionInput); + + discussionModal.addComponents(row, row2); + + await interaction.showModal(discussionModal).catch((e) => console.log(e)); + }, +}; diff --git a/src/commands/misc/poll.js b/src/commands/misc/poll.js deleted file mode 100644 index 2f3b407..0000000 --- a/src/commands/misc/poll.js +++ /dev/null @@ -1,57 +0,0 @@ -import { ActionRowBuilder, ButtonBuilder, ButtonStyle, SlashCommandBuilder } from 'discord.js'; - -export default { - data: new SlashCommandBuilder() - .setName('poll') - .setDescription('— Create a poll.') - .setNameLocalizations({ tr: 'oylama', it: 'sondaggio', ChineseCN: '投票' }) - .setDescriptionLocalizations({ - tr: '— Bir oylama oluştur.', - it: '— Crea un sondaggio.', - ChineseCN: '— 创建投票。', - }) - .addStringOption((option) => - option - .setName('question') - .setDescription('— The question to ask.') - .setRequired(true) - .setNameLocalizations({ tr: 'soru', it: 'domanda', ChineseCN: '问题' }) - .setDescriptionLocalizations({ - tr: '— Sorulacak soru.', - it: '— La domanda da porre.', - ChineseCN: '— 要问的问题。', - }), - ), - async execute({ interaction }) { - // Gettings the question - const question = interaction.options.getString('question'); - - // Emojis - const [thumbsup, thumbsdown, megaphone, discussion] = [ - '<:thumbsup:1020408053037793321>', - '<:thumbsdown:1020408108998197331>', - '<:megaphone:1020408969610670133>', - '<:commentdiscussion:1020408196743037039>', - ]; - - // Creating the poll button - const row = new ActionRowBuilder().addComponents( - new ButtonBuilder() - .setCustomId('poll-discussion') - .setLabel('Discuss it!') - .setStyle(ButtonStyle.Secondary) - .setEmoji(discussion), - ); - - // Creating the poll reply - const msg = await interaction.reply({ - content: `${megaphone} **${question}**\n\n>>> ${thumbsup} — Definitely!\n\n${thumbsdown} — Definitely Not!\n\nʸᵒᵘ ᶜᵃⁿ ᵃˡˢᵒ ᵈᶦˢᶜᵘˢˢ`, - components: [row], - fetchReply: true, - }); - - // Adding the reactions to fetched reply - msg.react('1020408053037793321'); - msg.react('1020408108998197331'); - }, -}; diff --git a/src/commands/music/play.js b/src/commands/music/play.js deleted file mode 100644 index 71f4a5a..0000000 --- a/src/commands/music/play.js +++ /dev/null @@ -1,48 +0,0 @@ -import { SlashCommandBuilder } from 'discord.js'; - -export default { - data: new SlashCommandBuilder() - .setName('play') - .setDescription('— Play a song.') - .addStringOption((option) => - option.setName('song').setDescription('The song you want to play.').setRequired(true), - ), - async execute({ interaction, client }) { - await interaction.deferReply(); - - const song_name = interaction.options.getString('song'); - - // Check if the user is in a voice channel - if (!interaction.member.voice.channel) { - return interaction.reply({ - content: 'You need to be in a voice channel to play music!', - ephemeral: true, - }); - } - - // Create the player - let player = client.manager.players.get(interaction.guildId); - - if (!player) { - player = client.manager.create({ - guild: interaction.guildId, - voiceChannel: interaction.member.voice.channelId, - textChannel: interaction.channelId, - selfDeafen: false, - }); - } - - const songs = await client.manager.search(song_name); - - player.connect(); - - player.queue.add(songs.tracks[0]); - - if (!player.playing) return player.play(); - - interaction.reply({ - content: `Added ${songs.tracks[0].title} to the queue.`, - ephemeral: true, - }); - }, -}; diff --git a/src/commands/utils/eval.js b/src/commands/utils/eval.js deleted file mode 100644 index 62e7451..0000000 --- a/src/commands/utils/eval.js +++ /dev/null @@ -1,85 +0,0 @@ -import { - EmbedBuilder, - WebhookClient, - ActionRowBuilder, - ButtonBuilder, - AttachmentBuilder, - SlashCommandBuilder, -} from 'discord.js'; -import fetch from 'node-fetch'; -import config from '../../../config.js'; -import { inspect } from 'util'; - -const webhook = new WebhookClient({ - id: config.webhookId, - token: config.webhookToken, -}); - -export default { - data: new SlashCommandBuilder() - .setName('eval') - .setDescription('— Developer only.') - .setNameLocalizations({ - tr: 'değerlendir', - it: 'valutare', - ChineseCN: '评估', - }) - .setDescriptionLocalizations({ - tr: '— Sadece geliştiriciler için.', - it: '— Solo per sviluppatori.', - ChineseCN: '— 仅限开发人员。', - }) - .addStringOption((option) => - option - .setName('input') - .setDescription('• Please input the code.') - .setRequired(true) - .setNameLocalizations({ - tr: 'girdi', - it: 'input', - ChineseCN: '输入', - }) - .setDescriptionLocalizations({ - tr: '• Lütfen kodu girin.', - it: '• Inserisci il codice.', - ChineseCN: '• 请输入代码。', - }), - ), - async execute({ interaction, client }) { - // Defining the client, guild, channel, member, and user - let channel = interaction.channel; - let guild = interaction.guild; - let member = interaction.member; - let user = interaction.user; - - // Emojis - const [debug_emoji, warning_emoji] = [ - '<:debug:1020403337738334208>', - '<:warning:1020401563468058664>', - ]; - - // If the user is not Neo, return nothing. - if (!'285118390031351809'.includes(interaction.member.user.id)) - return interaction.reply({ - content: `${warning_emoji} You can not use this command.`, - ephemeral: true, - }); - - // The input and output - try { - let evaluated = eval(interaction.options.getString('input')); - evaluated = - typeof evaluated === 'object' - ? inspect(evaluated, { depth: 0, showHidden: false }) - : evaluated; - - return interaction.reply({ - content: `${debug_emoji} **Output**\n\n>>> ***\`\`\`javascript\n${evaluated}\n\`\`\`***`, - }); - } catch (error) { - return interaction.reply({ - content: `${warning_emoji} An error occurred: \`${error.message}\``, - }); - } - }, -}; diff --git a/src/components/buttons/add-comment.js b/src/components/buttons/add-comment.js new file mode 100644 index 0000000..3795bb9 --- /dev/null +++ b/src/components/buttons/add-comment.js @@ -0,0 +1,45 @@ +import { + ActionRowBuilder, + ButtonBuilder, + ButtonStyle, + ChannelType, + ThreadAutoArchiveDuration, +} from 'discord.js'; + +export default { + data: { + customId: 'add-comment', + }, + execute: async ({ interaction }) => { + const [discussionEmoji] = ['<:discussion_button:1098366305947635784>']; + + if (interaction.channel.type !== ChannelType.GuildText) + return interaction.reply({ + content: `${discussionEmoji} You **can not** create a discussion in this channel.`, + ephemeral: true, + }); + + const disabledButton = new ButtonBuilder() + .setCustomId('disabled-button') + .setLabel('Created the Discussion') + .setStyle(ButtonStyle.Secondary) + .setDisabled(true) + .setEmoji(discussionEmoji); + + const row = new ActionRowBuilder().addComponents(disabledButton); + + interaction.channel.threads + .create({ + name: interaction.message.embeds[0].title.split(' ').slice(1).join(' '), + autoArchiveDuration: ThreadAutoArchiveDuration.OneDay, + type: ChannelType.PublicThread, + reason: 'For discussing', + startMessage: interaction.message.id, + }) + .then((poll) => { + poll.members.add(interaction.user); + + interaction.update({ components: [row] }); + }); + }, +}; diff --git a/src/components/buttons/create-issue.js b/src/components/buttons/create-issue.js new file mode 100644 index 0000000..9df7bc7 --- /dev/null +++ b/src/components/buttons/create-issue.js @@ -0,0 +1,23 @@ +import { ActionRowBuilder, ModalBuilder, TextInputBuilder, TextInputStyle } from 'discord.js'; + +export default { + data: { + customId: 'create-issue', + }, + async execute({ interaction }) { + const modal = new ModalBuilder() + .setCustomId('create-issue-modal') + .setTitle('Issue Creation'); + const input = new TextInputBuilder() + .setCustomId('issue-title') + .setLabel('Please explain your issue with a few words.') + .setRequired(true) + .setStyle(TextInputStyle.Short) + .setPlaceholder('Cannot post memes') + .setMaxLength(100); + + const firstActionRow = new ActionRowBuilder().addComponents(input); + modal.addComponents(firstActionRow); + await interaction.showModal(modal).catch((e) => console.log(e)); + }, +}; diff --git a/src/components/modals/create-discussion.js b/src/components/modals/create-discussion.js new file mode 100644 index 0000000..67f6294 --- /dev/null +++ b/src/components/modals/create-discussion.js @@ -0,0 +1,47 @@ +import { ActionRowBuilder, ButtonBuilder, ButtonStyle, EmbedBuilder } from 'discord.js'; + +export default { + data: { + customId: 'create-discussion-modal', + }, + execute: async ({ interaction }) => { + await interaction.deferReply(); + + const discussionTitleInput = interaction.fields.getTextInputValue('discussion-title'); + const discussionDescriptionInput = + interaction.fields.getTextInputValue('discussion-description'); + const discussionTitleCapitalized = discussionTitleInput + .split(' ') + .map((word) => word.charAt(0).toUpperCase() + word.slice(1)) + .join(' '); + + const [discussionEmoji] = ['<:discussion_button:1098366305947635784>']; + const embed = new EmbedBuilder() + .setTitle(`${discussionEmoji} ${discussionTitleCapitalized}`) + .setDescription(discussionDescriptionInput) + .setThumbnail( + 'https://media.discordapp.net/attachments/861208192121569280/1098398274714599434/8FCA1239-C15C-49CC-B854-EABD299893AF.png?width=473&height=473', + ) + .setColor(0x1e1e1e) + .setFooter({ + text: `Created by: ${interaction.user.tag}`, + iconURL: interaction.user.avatarURL(), + }); + const button = new ButtonBuilder() + .setCustomId('add-comment') + .setLabel('Create Discussion') + .setStyle(ButtonStyle.Secondary) + .setEmoji(discussionEmoji); + + const row = new ActionRowBuilder().addComponents(button); + + const pollMessage = await interaction.editReply({ + embeds: [embed], + components: [row], + fetchReply: true, + }); + + await pollMessage.react('👍'); + await pollMessage.react('👎'); + }, +}; diff --git a/src/components/selectMenus/test-menu.js b/src/components/selectMenus/test-menu.js new file mode 100644 index 0000000..1881e08 --- /dev/null +++ b/src/components/selectMenus/test-menu.js @@ -0,0 +1,8 @@ +export default { + data: { + customId: 'test-menu', + }, + execute: async ({ interaction }) => { + await interaction.reply({ content: `You selected: ${interaction.values[0]}` }); + }, +}; diff --git a/src/events/buttons.js b/src/events/buttons.js deleted file mode 100644 index 9ad84a8..0000000 --- a/src/events/buttons.js +++ /dev/null @@ -1,468 +0,0 @@ -import { - ActionRowBuilder, - ButtonBuilder, - ButtonStyle, - ChannelType, - EmbedBuilder, - StringSelectMenuBuilder, - StringSelectMenuOptionBuilder, -} from 'discord.js'; - -export default { - name: 'interactionCreate', - once: false, - async execute(interaction) { - if (interaction.isButton()) { - let client = interaction.client; - const args = interaction.customId.split('_'); - - // ———————————————[MEMBER AVATAR]——————————————— // - if (args[0] === 'ShowMemberAvatar') { - await interaction.deferUpdate(); - - const member = interaction.guild.members.cache.get(args[1]); - - const memberAvatar = member.avatarURL({ - dynamic: true, - size: 4096, - }); - - const button = new ActionRowBuilder().addComponents( - new ButtonBuilder() - .setCustomId('disabled') - .setLabel('Displaying Member Avatar') - .setStyle(ButtonStyle.Secondary) - .setEmoji('<:git_eye:992920314172424242>') - .setDisabled(true), - ); - - const nullButton = new ActionRowBuilder().addComponents( - new ButtonBuilder() - .setCustomId('disabled') - .setLabel('No Avatar Settled') - .setStyle(ButtonStyle.Secondary) - .setEmoji('<:git_eye:992920314172424242>') - .setDisabled(true), - ); - - return interaction.editReply({ - content: memberAvatar - ? `${memberAvatar}` - : 'They do not have a profile picture for this server.', - components: [memberAvatar ? button : nullButton] - }); - } - - // ———————————————[POLL BUTTON]——————————————— // - if (interaction.customId === 'poll-discussion') { - if (interaction.channel.type !== ChannelType.GuildText) - return interaction.reply({ - content: 'You **can not** create a discussion in this channel.', - ephemeral: true, - }); - - const row = new ActionRowBuilder().addComponents( - new ButtonBuilder() - .setCustomId('disabled') - .setLabel('— Created a discussion') - .setStyle(ButtonStyle.Secondary) - .setDisabled(true) - .setEmoji('<:commentdiscussion:1020408196743037039>'), - ); - - interaction.channel.threads - .create({ - name: '— Discussion', - autoArchiveDuration: 60, - type: ChannelType.PublicThread, - reason: 'For Discussing the Poll', - startMessage: interaction.message.id, - }) - .then((poll) => { - poll.members.add(interaction.user); - - interaction.update({ components: [row] }); - }); - } - - // ———————————————[RULES BUTTON]——————————————— // - if (interaction.customId === 'Rules') { - await interaction.deferReply({ ephemeral: true }); - - const embed1 = new EmbedBuilder() - .setDescription( - '<:interface:1026230825697689740> **· Age Requirements!**\n> ➜ You __must be 13+ years of the age__ to be a member of Minesa Hub. If you are under the age of 13, please let us know.', - ) - .setColor('#303136'); - - const embed2 = new EmbedBuilder() - .setDescription( - "<:interface:1026230825697689740> **· No Earrape, Troll, Spoilers or Raiding!**\n>>> ➜ It's not funny. If you do any of these you will get __kick/ban.__\n\n➜ No spamming either. This includes chains, chat flood, copy pastas, excessive keyboard spamming, large blocks of texts and spam pinging mods or members.", - ) - .setColor('#303136'); - - const embed3 = new EmbedBuilder() - .setDescription( - '<:interface:1026230825697689740> **· No NSFW Content!**\n>>> ➜ No NSFW content is allowed in any channel. This includes any form of nudity, sexual content, gore, etc. This also includes any form of sexual harassment, sexual jokes, etc.', - ) - .setColor('#303136'); - - const embed4 = new EmbedBuilder() - .setDescription( - '<:interface:1026230825697689740> **· No Advertising!**\n>>> ➜ Advertisement will result a __ban__. If you want to advertise your server, the FAIR way, is to ask **partnership managers** or **boost** the server.', - ) - .setColor('#303136'); - - const embed5 = new EmbedBuilder() - .setDescription( - "<:interface:1026230825697689740> **· Be respectful to staffs.**\n>>> ➜ If you do something that is against the rules or that isn't allowed by staff, and the staff tells you not to even though it isn't explicitly listed here, you are still __breaking the rules__, and do not try to impersonate or act as if you're a part of staff.", - ) - .setColor('#303136'); - - const embed6 = new EmbedBuilder() - .setDescription( - "<:interface:1026230825697689740> **· Following Discord Term of Service.**\n>>> ➜ Minesa Hub follows Discord's ToS. If you don't want to get ban, read those lessons before you look around.\n\n<:book:1026219326803542036>・__[Discord Terms of Service](https://discord.com/terms)__\n<:book:1026219326803542036>・__[Discord Community Guidelines](https://discord.com/guidelines)__\n\n➜ You are responsible for all actions done on your discord account, even if someone who isn’t you uses it excluding getting hacked. It is possible to provide proof that this was not you.", - ) - .setColor('#303136'); - - const row = new ActionRowBuilder().addComponents( - new ButtonBuilder() - .setLabel('Term of Service') - .setStyle(ButtonStyle.Link) - .setURL('https://discord.com/terms'), - new ButtonBuilder() - .setLabel('Guidelines') - .setStyle(ButtonStyle.Link) - .setURL('https://discord.com/guidelines'), - ); - - await interaction.followUp({ - content: - "**__Server Rules:__**\n>>> ➜ Please read rules carefully, otherwise we will take action to give you punishment. *(we hope, you're not masochist...)*\n\n ➜ If you have any questions, please contact the staffs.", - embeds: [embed1, embed2, embed3, embed4, embed5, embed6], - components: [row], - ephemeral: true, - }); - } - - // ———————————————[GET ROLES]——————————————— // - - if (interaction.customId === 'ColorRoles') { - await interaction.deferUpdate({ ephemeral: true }); - - const embed = new EmbedBuilder() - .setAuthor({ - name: 'Color Roles', - iconURL: client.user.displayAvatarURL(), - }) - .setDescription( - '<@&801612652920438784>\n<@&993254456277868544>\n<@&801613602440216617>\n<@&801615185096867871>\n<@&805430953958309908>\n<@&805433136615653416>\n<@&805435812786470932>\n<@&959044181190381609>', - ) - .setColor('#303136'); - - const row1 = new ActionRowBuilder().addComponents( - new StringSelectMenuBuilder() - .setCustomId('ColorRolesMenu') - .setPlaceholder('Select a color role') - .addOptions([ - new StringSelectMenuOptionBuilder() - .setLabel('⠀୭ sunset') - .setDescription('Red') - .setValue('801612652920438784'), - new StringSelectMenuOptionBuilder() - .setLabel('⠀୭ caramel') - .setDescription('Brown') - .setValue('993254456277868544'), - new StringSelectMenuOptionBuilder() - .setLabel('⠀୭ pineapple') - .setDescription('Orange') - .setValue('801613602440216617'), - new StringSelectMenuOptionBuilder() - .setLabel('⠀୭ banana') - .setDescription('Yellow') - .setValue('801615185096867871'), - new StringSelectMenuOptionBuilder() - .setLabel('⠀୭ palm') - .setDescription('Green') - .setValue('805430953958309908'), - new StringSelectMenuOptionBuilder() - .setLabel('⠀୭ ocean') - .setDescription('Blue') - .setValue('805433136615653416'), - new StringSelectMenuOptionBuilder() - .setLabel('⠀୭ sandy') - .setDescription('Purple') - .setValue('805435812786470932'), - new StringSelectMenuOptionBuilder() - .setLabel('⠀୭ shelly') - .setDescription('Pink') - .setValue('959044181190381609'), - ]), - ); - - const row2 = new ActionRowBuilder().addComponents( - new ButtonBuilder() - .setLabel('Back') - .setStyle(ButtonStyle.Secondary) - .setCustomId('GetRoles2'), - ); - - await interaction.editReply({ - content: - '**<:paint:1027815202571423814> Color Roles**\n>>> Pick a color role you want! Your username will change into whichever color you choose.', - embeds: [embed], - components: [row1, row2], - }); - } - - // ———————————————[GET ROLES BUTTON]——————————————— // - - if (interaction.customId === 'OtherRoles') { - await interaction.deferUpdate({ ephemeral: true }); - - // Genders - const row1 = new ActionRowBuilder().addComponents( - new StringSelectMenuBuilder() - .setCustomId('OtherRolesMenu1') - .setPlaceholder('Gender') - .addOptions([ - new StringSelectMenuOptionBuilder() - .setLabel('he/him') - .setValue('801610025558081567'), - new StringSelectMenuOptionBuilder() - .setLabel('she/her') - .setValue('801609422438006794'), - new StringSelectMenuOptionBuilder() - .setLabel('they/them') - .setValue('801610167606706186'), - ]), - ); - - // Personality - const row2 = new ActionRowBuilder().addComponents( - new StringSelectMenuBuilder() - .setCustomId('OtherRolesMenu2') - .setPlaceholder('Personality') - .addOptions([ - new StringSelectMenuOptionBuilder() - .setLabel('Introvert') - .setValue('959009541167648808'), - new StringSelectMenuOptionBuilder() - .setLabel('Extrovert') - .setValue('959009466509049896'), - ]), - ); - - // Notifications - const row3 = new ActionRowBuilder().addComponents( - new StringSelectMenuBuilder() - .setCustomId('OtherRolesMenu3') - .setPlaceholder('Notifications') - .addOptions([ - new StringSelectMenuOptionBuilder() - .setLabel('Server Updates') - .setDescription( - 'Get notified when a new post is made about the server.', - ) - .setValue('801618406817136651'), - new StringSelectMenuOptionBuilder() - .setLabel('Community Events') - .setDescription('Get notified when a new event is made.') - .setValue('801618365231398912'), - new StringSelectMenuOptionBuilder() - .setLabel('Dev Updates') - .setDescription( - 'Get notified when a new post is made about the developer.', - ) - .setValue('940881871624089600'), - new StringSelectMenuOptionBuilder() - .setLabel('Extras') - .setDescription( - 'Get notified when a new post is made about the server extras.', - ) - .setValue('836338427578286111'), - ]), - ); - - // Age - const row4 = new ActionRowBuilder().addComponents( - new StringSelectMenuBuilder() - .setCustomId('OtherRolesMenu4') - .setPlaceholder('Age') - .addOptions([ - new StringSelectMenuOptionBuilder() - .setLabel('minor') - .setValue('958997694897082418'), - new StringSelectMenuOptionBuilder() - .setLabel('adult') - .setValue('958997737439911947'), - ]), - ); - - // Back Button - const row5 = new ActionRowBuilder().addComponents( - new ButtonBuilder() - .setLabel('Back') - .setStyle(ButtonStyle.Secondary) - .setCustomId('GetRoles2'), - ); - - await interaction.editReply({ - content: - '**<:mention:1027815155804938311> Other Roles**\n>>> Pick a role you want! You can pick multiple roles.', - components: [row1, row2, row3, row4, row5], - }); - } - - // ———————————————[GET ROLES]——————————————— // - if (interaction.customId === 'GetRoles') { - await interaction.deferReply({ ephemeral: true }); - - const row = new ActionRowBuilder().addComponents( - new ButtonBuilder() - .setLabel('Color Roles') - .setStyle(ButtonStyle.Secondary) - .setCustomId('ColorRoles') - .setEmoji('<:paint:1027815202571423814>'), - new ButtonBuilder() - .setLabel('Other Roles') - .setStyle(ButtonStyle.Secondary) - .setCustomId('OtherRoles') - .setEmoji('<:mention:1027815155804938311>'), - ); - - await interaction.editReply({ - content: - '**Customize your roles!**\n>>> Use the __role-categories__ below to add the roles that apply to you to spice up your profile. It could be color roles, notification pings, or even some fun roles. Simply experiment with it as you see fit!', - components: [row], - }); - } - - // ———————————————[GET ROLES]——————————————— // - if (interaction.customId === 'GetRoles2') { - await interaction.deferUpdate({ ephemeral: true }); - - const row = new ActionRowBuilder().addComponents( - new ButtonBuilder() - .setLabel('Color Roles') - .setStyle(ButtonStyle.Secondary) - .setCustomId('ColorRoles') - .setEmoji('<:paint:1027815202571423814>'), - new ButtonBuilder() - .setLabel('Other Roles') - .setStyle(ButtonStyle.Secondary) - .setCustomId('OtherRoles') - .setEmoji('<:mention:1027815155804938311>'), - ); - - await interaction.editReply({ - content: - '**Customize your roles!**\n>>> Use the __role-categories__ below to add the roles that apply to you to spice up your profile. It could be color roles, notification pings, or even some fun roles. Simply experiment with it as you see fit!', - embeds: [], - components: [row], - }); - } - - // ———————————————[INFO OF ROLES]——————————————— // - if (interaction.customId === 'GetInfo') { - await interaction.deferReply({ ephemeral: true }); - - const row = new ActionRowBuilder().addComponents( - new ButtonBuilder() - .setCustomId('important-roles') - .setLabel('Start Guide') - .setStyle(ButtonStyle.Primary), - ); - - await interaction.editReply({ - content: `**Getting started on __MinesaHub__**\n> Refer to this guide to understand how the server works! This "Info" section was added as a means to help new members get started on the server. If you have any questions, feel free to ask in <#1019645269740097647>!\n\n> Just press the \`Start guide\` button below.`, - components: [row], - }); - } - - // Important Roles - if (interaction.customId === 'important-roles') { - await interaction.deferUpdate({ ephemeral: true }); - - const row = new ActionRowBuilder().addComponents( - new ButtonBuilder() - .setCustomId('important-roles') - .setLabel('Important Roles') - .setStyle(ButtonStyle.Primary) - .setDisabled(true), - new ButtonBuilder() - .setCustomId('important-channels') - .setLabel('Important Channels') - .setStyle(ButtonStyle.Secondary) - .setDisabled(false), - new ButtonBuilder() - .setCustomId('getting-support') - .setLabel('Getting Support') - .setStyle(ButtonStyle.Secondary) - .setDisabled(false), - ); - - await interaction.editReply({ - content: `**Important Roles**\nHere's a overview of all the important roles!\n\n> __<@&801606644001013760>__\n> Server owners, Mica-Neo-Saku.\n\n> __<@&801606706374639666>__\n> Moderators and maintainers of our server! Staff is responsible for keeping the server peaceful and user-friendly, as well as updating the server with new features as needed.\n\n> __<@&969643043059793980>__\n> Extremely helpful people who are very active in <#1019645269740097647>. The Support Team contributes equally in making this server a more user-friendly space.\n> — *Staff will assign you this role at their discretion if you are deserving.*\n\n> __<@&970996897382801438>__\n> The Youtubers who upload content about gaming, development and Discord bot developers.\n> — *Please contact a moderator for more info.*\n\n> __<@&751418618763280427>__\n> The lovely people who are helping tremendously in keeping the server alive. They're the members helping us. So, to repay back for the boosts, here are some perks that the server boosters get on boosting our server:\n> • Embed Perms\n> • A role __only for you__\n> • Image perms in <#722267447935238215>\n> • An emoji of your liking will be __added to the server__\n> \n> *These permissions are not permanent and will last as long as you're boosting the server.*\n\n`, - components: [row], - }); - } - - // Important Channels - if (interaction.customId === 'important-channels') { - await interaction.deferUpdate({ ephemeral: true }); - - const row = new ActionRowBuilder().addComponents( - new ButtonBuilder() - .setCustomId('important-roles') - .setLabel('Important Roles') - .setStyle(ButtonStyle.Secondary) - .setDisabled(false), - new ButtonBuilder() - .setCustomId('important-channels') - .setLabel('Important Channels') - .setStyle(ButtonStyle.Primary) - .setDisabled(true), - new ButtonBuilder() - .setCustomId('getting-support') - .setLabel('Getting Support') - .setStyle(ButtonStyle.Secondary) - .setDisabled(false), - ); - - await interaction.editReply({ - content: `**Important Channels**\nNavigating through the various channels on this server can be difficult. So, the channels listed below should help you better understand the server and get things started!\n\n>>> • <#722040388030038078>\n• <#722267447935238215>\n• <#1021527613598085170>\n• <#925677111782551603>\n`, - components: [row], - }); - } - - // Geting Support - if (interaction.customId === 'getting-support') { - await interaction.deferUpdate({ ephemeral: true }); - - const row = new ActionRowBuilder().addComponents( - new ButtonBuilder() - .setCustomId('important-roles') - .setLabel('Important Roles') - .setStyle(ButtonStyle.Secondary) - .setDisabled(false), - new ButtonBuilder() - .setCustomId('important-channels') - .setLabel('Important Channels') - .setStyle(ButtonStyle.Secondary) - .setDisabled(false), - new ButtonBuilder() - .setCustomId('getting-support') - .setLabel('Getting Support') - .setStyle(ButtonStyle.Primary) - .setDisabled(true), - ); - - await interaction.editReply({ - content: `**Getting Support**\n> If you need help regarding on something or need help with something else in general, coding; feel free to pop in and ask in our <#1019645269740097647> channel.`, - components: [row], - }); - } - } - }, -}; diff --git a/src/events/client/interactionCreate.js b/src/events/client/interactionCreate.js new file mode 100644 index 0000000..6de48e7 --- /dev/null +++ b/src/events/client/interactionCreate.js @@ -0,0 +1,81 @@ +import { Events, InteractionType } from 'discord.js'; + +export default { + name: Events.InteractionCreate, + once: false, + execute: async (interaction, client) => { + if (interaction.isChatInputCommand()) { + const { commands } = client; + const { commandName } = interaction; + const command = commands.get(commandName); + + if (!command) return; + + try { + await command.execute({ interaction, client }); + } catch (error) { + console.error(error); + } + } else if (interaction.isButton()) { + const { buttons } = client; + const { customId } = interaction; + const button = buttons.get(customId); + + if (!button) return new Error('Button not found.'); + + try { + await button.execute({ interaction, client }); + } catch (error) { + console.error(error); + } + } else if (interaction.isStringSelectMenu()) { + const { selectMenus } = client; + const { customId } = interaction; + const selectMenu = selectMenus.get(customId); + + if (!selectMenu) return new Error('Select menu not found.'); + + try { + await selectMenu.execute({ interaction, client }); + } catch (error) { + console.error(error); + } + } else if (interaction.type == InteractionType.ModalSubmit) { + const { modals } = client; + const { customId } = interaction; + const modal = modals.get(customId); + + if (!modal) return new Error('Modal not found.'); + + try { + await modal.execute({ interaction, client }); + } catch (error) { + console.error(error); + } + } else if (interaction.isContextMenuCommand()) { + const { commands } = client; + const { commandName } = interaction; + const contextCommand = commands.get(commandName); + + if (!contextCommand) return; + + try { + await contextCommand.execute({ interaction, client }); + } catch (error) { + console.error(error); + } + } else if (interaction.type == InteractionType.ApplicationCommandAutocomplete) { + const { commands } = client; + const { commandName } = interaction; + const autocompleteCommand = commands.get(commandName); + + if (!autocompleteCommand) return; + + try { + await autocompleteCommand.autocomplete({ interaction, client }); + } catch (error) { + console.error(error); + } + } + }, +}; diff --git a/src/events/client/ready.js b/src/events/client/ready.js new file mode 100644 index 0000000..dfa1b6c --- /dev/null +++ b/src/events/client/ready.js @@ -0,0 +1,10 @@ +import { Events } from 'discord.js'; +import chalk from 'chalk'; + +export default { + name: Events.ClientReady, + once: true, + execute: async (client) => { + console.log(chalk.greenBright(`Logged in as ${client.user.tag}!`)); + }, +}; diff --git a/src/events/interactionCreate.js b/src/events/interactionCreate.js deleted file mode 100644 index 737acd1..0000000 --- a/src/events/interactionCreate.js +++ /dev/null @@ -1,21 +0,0 @@ -export default { - name: 'interactionCreate', - once: false, - async execute(interaction) { - // Defining the client - let client = interaction.client; - - // Get the command - const command = client.commands.get(interaction.commandName); - - // If the command is not found, return nothing. - if (!command) return; - - // If the command is found, execute the command. - try { - await command.execute({ interaction, client }); - } catch (error) { - console.error(error); - } - }, -}; diff --git a/src/events/mongo/connected.js b/src/events/mongo/connected.js new file mode 100644 index 0000000..4cc8017 --- /dev/null +++ b/src/events/mongo/connected.js @@ -0,0 +1,8 @@ +import chalk from 'chalk'; + +export default { + name: 'connected', + execute() { + console.log(chalk.green('Connected to MongoDB!')); + }, +}; diff --git a/src/events/mongo/connecting.js b/src/events/mongo/connecting.js new file mode 100644 index 0000000..8668e98 --- /dev/null +++ b/src/events/mongo/connecting.js @@ -0,0 +1,8 @@ +import chalk from 'chalk'; + +export default { + name: 'connecting', + execute() { + console.log(chalk.blueBright('Connecting to MongoDB!')); + }, +}; diff --git a/src/events/mongo/disconnected.js b/src/events/mongo/disconnected.js new file mode 100644 index 0000000..034bf6b --- /dev/null +++ b/src/events/mongo/disconnected.js @@ -0,0 +1,8 @@ +import chalk from 'chalk'; + +export default { + name: 'disconnected', + execute() { + console.log(chalk.yellowBright('Disconnected from MongoDB!')); + }, +}; diff --git a/src/events/mongo/err.js b/src/events/mongo/err.js new file mode 100644 index 0000000..0d2052f --- /dev/null +++ b/src/events/mongo/err.js @@ -0,0 +1,8 @@ +import chalk from 'chalk'; + +export default { + name: 'err', + execute(err) { + console.log(chalk.red(`MongoDB Error: ${err}`)); + }, +}; diff --git a/src/events/ready.js b/src/events/ready.js deleted file mode 100644 index b58ce60..0000000 --- a/src/events/ready.js +++ /dev/null @@ -1,15 +0,0 @@ -import colors from 'colors'; - -export default { - name: "ready", - once: true, - async execute(client) { - // Initiates the manager and connects to all the nodes - client.manager.init(client.user.id); - // The bot starts, and logs in, successfully. - console.log(`[READY] Logged in as ${client.user.tag}!`.green); - - // Fetching the message on rules channel to bot does not die from restart. - client.channels.cache.get('889266702620176434').messages.fetch('1075866763616604170'); - }, -}; diff --git a/src/events/select-menus.js b/src/events/select-menus.js deleted file mode 100644 index 3fce5a0..0000000 --- a/src/events/select-menus.js +++ /dev/null @@ -1,37 +0,0 @@ -export default { - name: 'interactionCreate', - once: false, - async execute(interaction) { - if (interaction.isStringSelectMenu()) { - // Color Roles Button on the Get Color Roles - if ( - interaction.customId === 'ColorRolesMenu' || - interaction.customId === 'OtherRolesMenu1' || - interaction.customId === 'OtherRolesMenu2' || - interaction.customId === 'OtherRolesMenu3' || - interaction.customId === 'OtherRolesMenu4' - ) { - await interaction.deferUpdate({ ephemeral: true }); - - let roleId = interaction.values[0]; - const role = interaction.guild.roles.cache.get(roleId); - const memberRoles = interaction.member.roles; - const hasRole = memberRoles.cache.has(roleId); - - if (hasRole) { - memberRoles.remove(role); - await interaction.followUp({ - content: `Removed the ${role} role from you.`, - ephemeral: true, - }); - } else { - memberRoles.add(role); - await interaction.followUp({ - content: `Added the ${role} role to you.`, - ephemeral: true, - }); - } - } - } - }, -}; diff --git a/src/functions/handlers/handleCommands.js b/src/functions/handlers/handleCommands.js new file mode 100644 index 0000000..f294769 --- /dev/null +++ b/src/functions/handlers/handleCommands.js @@ -0,0 +1,44 @@ +import { REST, Routes } from 'discord.js'; +import { promises as fs } from 'fs'; +import { dirname } from 'path'; +import { fileURLToPath } from 'url'; +import chalk from 'chalk'; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = dirname(__filename); + +export default async (client) => { + client.handleCommands = async () => { + const commandFolders = await fs.readdir(`${__dirname}../../../commands`); + + for (const folder of commandFolders) { + const commandFiles = ( + await fs.readdir(`${__dirname}../../../commands/${folder}`) + ).filter((file) => file.endsWith('.js')); + + const { commands, commandArray } = client; + for (const file of commandFiles) { + const { default: command } = await import(`../../commands/${folder}/${file}`); + commands.set(command.data.name, command); + commandArray.push(command.data.toJSON()); + + console.log(chalk.green(`[Commands]: Loaded ${command.data.name} command.`)); + } + } + + const clientId = '736561919292473454'; + // const guildId = '795473336998035486'; + const rest = new REST({ version: '10' }).setToken(process.env.TOKEN); + + try { + console.log(chalk.cyan(`[Commands] Started refreshing application (/) commands.`)); + await rest.put(Routes.applicationCommands(clientId), { + body: client.commandArray, + }); + + console.log(chalk.cyan(`[Commands] Successfully reloaded application (/) commands.`)); + } catch (error) { + console.error(error); + } + }; +}; diff --git a/src/functions/handlers/handleComponents.js b/src/functions/handlers/handleComponents.js new file mode 100644 index 0000000..b7ff416 --- /dev/null +++ b/src/functions/handlers/handleComponents.js @@ -0,0 +1,58 @@ +import fs from 'fs'; +import chalk from 'chalk'; + +export default (client) => { + client.handleComponents = async () => { + const componentFolders = fs.readdirSync('./src/components'); + + for (const folder of componentFolders) { + const componentFiles = fs + .readdirSync(`./src/components/${folder}`) + .filter((file) => file.endsWith('.js')); + + const { buttons, selectMenus, modals } = client; + + switch (folder) { + case 'buttons': + for (const file of componentFiles) { + const { default: button } = await import( + `../../components/${folder}/${file}` + ); + buttons.set(button.data.customId, button); + + console.log( + chalk.green(`[Buttons]: Loaded ${button.data.customId} button.`), + ); + } + break; + case 'selectMenus': + for (const file of componentFiles) { + const { default: selectMenu } = await import( + `../../components/${folder}/${file}` + ); + selectMenus.set(selectMenu.data.customId, selectMenu); + + console.log( + chalk.green( + `[Select Menus]: Loaded ${selectMenu.data.customId} select menu.`, + ), + ); + } + break; + + case 'modals': + for (const file of componentFiles) { + const { default: modal } = await import( + `../../components/${folder}/${file}` + ); + modals.set(modal.data.customId, modal); + + console.log(chalk.green(`[Modals]: Loaded ${modal.data.customId} modal.`)); + } + + default: + break; + } + } + }; +}; diff --git a/src/functions/handlers/handleEvents.js b/src/functions/handlers/handleEvents.js new file mode 100644 index 0000000..bf86008 --- /dev/null +++ b/src/functions/handlers/handleEvents.js @@ -0,0 +1,49 @@ +import fs from 'fs'; +import chalk from 'chalk'; + +import mongoose from 'mongoose'; +const { connection } = mongoose; + +export default async (client) => { + client.handleEvents = async () => { + const eventFolders = fs.readdirSync('./src/events'); + + for (const folder of eventFolders) { + const eventFiles = fs + .readdirSync(`./src/events/${folder}`) + .filter((file) => file.endsWith('.js')); + + switch (folder) { + case 'client': + for (const file of eventFiles) { + const { default: event } = await import(`../../events/${folder}/${file}`); + if (event.once) { + client.once(event.name, (...args) => event.execute(...args, client)); + console.log(chalk.green(`[Events]: Loaded ${event.name} event.`)); + } else { + client.on(event.name, (...args) => event.execute(...args, client)); + console.log(chalk.green(`[Events]: Loaded ${event.name} event.`)); + } + } + break; + + case 'mongo': + for (const file of eventFiles) { + const { default: event } = await import(`../../events/${folder}/${file}`); + if (connection.once) { + connection.once(event.name, (...args) => + event.execute(...args, client), + ); + console.log(chalk.green(`[Events]: Loaded ${event.name} event.`)); + } else { + connection.on(event.name, (...args) => event.execute(...args, client)); + console.log(chalk.green(`[Events]: Loaded ${event.name} event.`)); + } + } + break; + default: + break; + } + } + }; +}; diff --git a/src/handlers/handleCommands.js b/src/handlers/handleCommands.js deleted file mode 100644 index 2e0928a..0000000 --- a/src/handlers/handleCommands.js +++ /dev/null @@ -1,41 +0,0 @@ -import { REST } from '@discordjs/rest'; -import { Routes } from 'discord-api-types/v10'; -import { readdirSync } from 'fs'; -import config from '../../config.js'; -import colors from 'colors'; - -// Create a new REST instance -const handleCommands = (client) => { - client.handleCommands = async (commandFolders, path) => { - client.commandArray = []; - for (const folder of commandFolders) { - const commandFiles = readdirSync(`${path}/${folder}`).filter((file) => - file.endsWith('.js'), - ); - - for (const file of commandFiles) { - const command = (await import(`../commands/${folder}/${file}`).then(command => command.default)); - - console.log(`[COMMAND] ${command.data.name} loaded.`.underline.green); - client.commandArray.push(command.data.toJSON()); - client.commands.set(command.data.name, command); - } - } - - const rest = new REST({ version: '10' }).setToken(config.token); - - (async () => { - try { - console.log('[REFRESHING] Global Application (/) commands.'); - await rest.put(Routes.applicationCommands(config.clientId), { - body: client.commandArray, - }); - console.log(`[RELOADED] ${client.commands.size} commands loaded.`.red); - } catch (error) { - console.error(error); - } - })(); - }; -}; - -export default handleCommands; diff --git a/src/handlers/handleEvents.js b/src/handlers/handleEvents.js deleted file mode 100644 index 1569449..0000000 --- a/src/handlers/handleEvents.js +++ /dev/null @@ -1,15 +0,0 @@ -// Handling Events -const handleEvents = client => { - client.handleEvents = async eventFiles => { - for (const file of eventFiles) { - const event = await import(`../events/${file}`).then(module => module.default); - if (event.once) { - client.once(event.name, (...args) => event.execute(...args, client)); - } else { - client.on(event.name, (...args) => event.execute(...args, client)); - } - } - }; -}; - -export default handleEvents; diff --git a/src/index.js b/src/index.js new file mode 100644 index 0000000..19cd1d5 --- /dev/null +++ b/src/index.js @@ -0,0 +1,50 @@ +import { ActivityType, Client, Collection, GatewayIntentBits, Partials } from 'discord.js'; +import { connect } from 'mongoose'; +import fs from 'fs'; +import { config } from 'dotenv'; +config(); + +const { TOKEN, DATABASE_URI } = process.env; +const client = new Client({ + intents: [ + GatewayIntentBits.Guilds, + GatewayIntentBits.GuildMembers, + GatewayIntentBits.GuildScheduledEvents, + ], + partials: [Partials.GuildMember, Partials.GuildScheduledEvent], + presence: { + status: 'dnd', + activities: [ + { + name: 'What is happening? 👀', + type: ActivityType.Watching, + }, + ], + }, +}); + +client.commands = new Collection(); +client.buttons = new Collection(); +client.selectMenus = new Collection(); +client.modals = new Collection(); +client.commandArray = []; + +const functionFolders = fs.readdirSync('./src/functions'); +for (const folder of functionFolders) { + const functionFiles = fs + .readdirSync(`./src/functions/${folder}`) + .filter((file) => file.endsWith('.js')); + + for (const file of functionFiles) { + const { default: func } = await import(`./functions/${folder}/${file}`); + func(client); + } +} + +client.handleCommands(); +client.handleEvents(); +client.handleComponents(); +client.login(TOKEN); +(async () => { + await connect(DATABASE_URI).catch(console.error); +})(); diff --git a/src/schemas/guild.js b/src/schemas/guild.js new file mode 100644 index 0000000..b547e1b --- /dev/null +++ b/src/schemas/guild.js @@ -0,0 +1,9 @@ +import { model, Schema } from 'mongoose'; + +const guildSchema = new Schema({ + _id: Schema.Types.ObjectId, + guildId: String, + guildName: String, +}); + +export default model('Guild', guildSchema, 'guilds');