commit a3fdeba6be93e278655e4d2daa34b9a47c8d1785 Author: Oleksandr Honcharov <0976053529@ukr.net> Date: Thu Jun 6 02:04:52 2024 +0300 init diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..7764f1a --- /dev/null +++ b/.gitignore @@ -0,0 +1,11 @@ +# files +.vscode +.env +.env.local +package-lock.json +yarn.lock +.idea + +# folders +build +node_modules \ No newline at end of file diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..b58b603 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,5 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ diff --git a/.idea/discord-ticket-bot.iml b/.idea/discord-ticket-bot.iml new file mode 100644 index 0000000..24643cc --- /dev/null +++ b/.idea/discord-ticket-bot.iml @@ -0,0 +1,12 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/discord.xml b/.idea/discord.xml new file mode 100644 index 0000000..3aef922 --- /dev/null +++ b/.idea/discord.xml @@ -0,0 +1,12 @@ + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..5b6e9d2 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..35eb1dd --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..566555f --- /dev/null +++ b/Dockerfile @@ -0,0 +1,36 @@ +## build runner +FROM node:lts-alpine as build-runner + +# Set temp directory +WORKDIR /tmp/app + +# Move package.json +COPY package.json . + +# Install dependencies +RUN npm install + +# Move source files +COPY src ./src +COPY tsconfig.json . + +# Build project +RUN npm run build + +## production runner +FROM node:lts-alpine as prod-runner + +# Set work directory +WORKDIR /app + +# Copy package.json from build-runner +COPY --from=build-runner /tmp/app/package.json /app/package.json + +# Install dependencies +RUN npm install --omit=dev + +# Move build files +COPY --from=build-runner /tmp/app/build /app/build + +# Start bot +CMD [ "npm", "run", "start" ] diff --git a/README.md b/README.md new file mode 100644 index 0000000..86947a7 --- /dev/null +++ b/README.md @@ -0,0 +1,99 @@ +
+

+ + + +

+

+ Discord server + NPM version + NPM downloads + Build status + paypal +

+

+ Create a discord bot with TypeScript and Decorators! +

+
+ +# 📖 Introduction + +A starter template equipped with several interaction commands and one event. + +# 🏗 Development + +``` +npm install +npm run dev +``` + +If you want to use [Nodemon](https://nodemon.io/) to auto-reload while in development: + +``` +npm run watch +``` + +# 💻 Production + +``` +npm install --production +npm run build +npm run start +``` + +# 🐋 Docker + +To start your application: + +``` +docker-compose up -d +``` + +To shut down your application: + +``` +docker-compose down +``` + +To view your application's logs: + +``` +docker-compose logs +``` + +For the full command list please view the [Docker Documentation](https://docs.docker.com/engine/reference/commandline/cli/). + +# 📜 Documentation + +- [discordx.js.org](https://discordx.js.org) +- [Tutorials (dev.to)](https://dev.to/samarmeena/series/14317) + +# ☎️ Need help? + +- [Check frequently asked questions](https://discordx.js.org/docs/faq) +- [Check examples](https://github.com/discordx-ts/discordx/tree/main/packages/discordx/examples) +- Ask in the community [Discord server](https://discordx.js.org/discord) + +# 💖 Thank you + +You can support [discordx](https://www.npmjs.com/package/discordx) by giving it a [GitHub](https://github.com/discordx-ts/discordx) star. diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..becb204 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,7 @@ +version: "3" +services: + app: + build: . + command: node build/main.js + environment: + - BOT_TOKEN=${BOT_TOKEN} diff --git a/package.json b/package.json new file mode 100644 index 0000000..119a73b --- /dev/null +++ b/package.json @@ -0,0 +1,32 @@ +{ + "name": "fedotov-bot", + "version": "1.0.0", + "private": true, + "license": "MIT", + "type": "module", + "main": "build/main.js", + "scripts": { + "build": "tsc", + "build:changelog": "npx @discordx/changelog --src src", + "dev": "node --loader ts-node/esm/transpile-only src/main.ts", + "start": "node build/main.js", + "watch": "nodemon --exec npm run dev --watch src --ext ts" + }, + "dependencies": { + "@discordx/importer": "^1.3.0", + "@discordx/pagination": "^3.5.1", + "discord.js": "^14.15.3", + "discordx": "^11.9.2" + }, + "devDependencies": { + "@types/node": "^20.14.1", + "nodemon": "^3.1.3", + "prettier": "^3.3.0", + "ts-node": "^10.9.2", + "typescript": "5.4.5" + }, + "engines": { + "node": ">=16.0.0", + "npm": ">=7.0.0" + } +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml new file mode 100644 index 0000000..89eff04 --- /dev/null +++ b/pnpm-lock.yaml @@ -0,0 +1,938 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: + dependencies: + '@discordx/importer': + specifier: ^1.3.0 + version: 1.3.0 + '@discordx/pagination': + specifier: ^3.5.1 + version: 3.5.1(discord.js@14.15.3) + discord.js: + specifier: ^14.15.3 + version: 14.15.3 + discordx: + specifier: ^11.9.2 + version: 11.9.2(discord.js@14.15.3) + devDependencies: + '@types/node': + specifier: ^20.14.1 + version: 20.14.2 + nodemon: + specifier: ^3.1.3 + version: 3.1.3 + prettier: + specifier: ^3.3.0 + version: 3.3.1 + ts-node: + specifier: ^10.9.2 + version: 10.9.2(@types/node@20.14.2)(typescript@5.4.5) + typescript: + specifier: 5.4.5 + version: 5.4.5 + +packages: + + '@cspotcode/source-map-support@0.8.1': + resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==} + engines: {node: '>=12'} + + '@discordjs/builders@1.8.2': + resolution: {integrity: sha512-6wvG3QaCjtMu0xnle4SoOIeFB4y6fKMN6WZfy3BMKJdQQtPLik8KGzDwBVL/+wTtcE/ZlFjgEk74GublyEVZ7g==} + engines: {node: '>=16.11.0'} + + '@discordjs/collection@1.5.3': + resolution: {integrity: sha512-SVb428OMd3WO1paV3rm6tSjM4wC+Kecaa1EUGX7vc6/fddvw/6lg90z4QtCqm21zvVe92vMMDt9+DkIvjXImQQ==} + engines: {node: '>=16.11.0'} + + '@discordjs/collection@2.1.0': + resolution: {integrity: sha512-mLcTACtXUuVgutoznkh6hS3UFqYirDYAg5Dc1m8xn6OvPjetnUlf/xjtqnnc47OwWdaoCQnHmHh9KofhD6uRqw==} + engines: {node: '>=18'} + + '@discordjs/formatters@0.4.0': + resolution: {integrity: sha512-fJ06TLC1NiruF35470q3Nr1bi95BdvKFAF+T5bNfZJ4bNdqZ3VZ+Ttg6SThqTxm6qumSG3choxLBHMC69WXNXQ==} + engines: {node: '>=16.11.0'} + + '@discordjs/rest@2.3.0': + resolution: {integrity: sha512-C1kAJK8aSYRv3ZwMG8cvrrW4GN0g5eMdP8AuN8ODH5DyOCbHgJspze1my3xHOAgwLJdKUbWNVyAeJ9cEdduqIg==} + engines: {node: '>=16.11.0'} + + '@discordjs/util@1.1.0': + resolution: {integrity: sha512-IndcI5hzlNZ7GS96RV3Xw1R2kaDuXEp7tRIy/KlhidpN/BQ1qh1NZt3377dMLTa44xDUNKT7hnXkA/oUAzD/lg==} + engines: {node: '>=16.11.0'} + + '@discordjs/ws@1.1.1': + resolution: {integrity: sha512-PZ+vLpxGCRtmr2RMkqh8Zp+BenUaJqlS6xhgWKEZcgC/vfHLEzpHtKkB0sl3nZWpwtcKk6YWy+pU3okL2I97FA==} + engines: {node: '>=16.11.0'} + + '@discordx/di@3.3.0': + resolution: {integrity: sha512-0QZ71bHeM15OG/U32/i1hDAknIpFSg6jm/OsI817BUJwwpdr8CNuB1bLQ5SfOUndoXAr7BiLEthtnXhs4DtQng==} + engines: {node: '>=16.0.0', npm: '>=7.0.0'} + + '@discordx/importer@1.3.0': + resolution: {integrity: sha512-RlvGi0vLnXXWFK7g/qTcJ33R64tIOwkX6pPVDw9JOPAbmfOoBE2pZT0uEuUxH5y/VvYwumdc0IwwcsCcQrMulw==} + + '@discordx/internal@1.1.0': + resolution: {integrity: sha512-C2o6LxzhTLbR8t74a6m/3YWLpkt2SjXvUMqfUIgLFjDn6nN3qKxeDJo+e83jNC8VFCcWbxKTzMLbnm+h9B8frg==} + engines: {node: '>=16.0.0', npm: '>=7.0.0'} + + '@discordx/pagination@3.5.1': + resolution: {integrity: sha512-Rq6Oj5cUJY8duzQV6ARpIpGErQ/W8lh7ZXj9MfEnKaWcDCDzSidHhpQ5hKDhgFPLzwv+wyQeh6ck9Q3i4PtQPQ==} + engines: {node: '>=16.0.0', npm: '>=7.0.0'} + peerDependencies: + discord.js: '>=14 || ^14.0.0-dev' + + '@isaacs/cliui@8.0.2': + resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} + engines: {node: '>=12'} + + '@jridgewell/resolve-uri@3.1.2': + resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} + engines: {node: '>=6.0.0'} + + '@jridgewell/sourcemap-codec@1.4.15': + resolution: {integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==} + + '@jridgewell/trace-mapping@0.3.9': + resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==} + + '@pkgjs/parseargs@0.11.0': + resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} + engines: {node: '>=14'} + + '@sapphire/async-queue@1.5.2': + resolution: {integrity: sha512-7X7FFAA4DngXUl95+hYbUF19bp1LGiffjJtu7ygrZrbdCSsdDDBaSjB7Akw0ZbOu6k0xpXyljnJ6/RZUvLfRdg==} + engines: {node: '>=v14.0.0', npm: '>=7.0.0'} + + '@sapphire/shapeshift@3.9.7': + resolution: {integrity: sha512-4It2mxPSr4OGn4HSQWGmhFMsNFGfFVhWeRPCRwbH972Ek2pzfGRZtb0pJ4Ze6oIzcyh2jw7nUDa6qGlWofgd9g==} + engines: {node: '>=v16'} + + '@sapphire/snowflake@3.5.3': + resolution: {integrity: sha512-jjmJywLAFoWeBi1W7994zZyiNWPIiqRRNAmSERxyg93xRGzNYvGjlZ0gR6x0F4gPRi2+0O6S71kOZYyr3cxaIQ==} + engines: {node: '>=v14.0.0', npm: '>=7.0.0'} + + '@tsconfig/node10@1.0.11': + resolution: {integrity: sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==} + + '@tsconfig/node12@1.0.11': + resolution: {integrity: sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==} + + '@tsconfig/node14@1.0.3': + resolution: {integrity: sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==} + + '@tsconfig/node16@1.0.4': + resolution: {integrity: sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==} + + '@types/node@20.14.2': + resolution: {integrity: sha512-xyu6WAMVwv6AKFLB+e/7ySZVr/0zLCzOa7rSpq6jNwpqOrUbcACDWC+53d4n2QHOnDou0fbIsg8wZu/sxrnI4Q==} + + '@types/ws@8.5.10': + resolution: {integrity: sha512-vmQSUcfalpIq0R9q7uTo2lXs6eGIpt9wtnLdMv9LVpIjCA/+ufZRozlVoVelIYixx1ugCBKDhn89vnsEGOCx9A==} + + '@vladfrangu/async_event_emitter@2.2.4': + resolution: {integrity: sha512-ButUPz9E9cXMLgvAW8aLAKKJJsPu1dY1/l/E8xzLFuysowXygs6GBcyunK9rnGC4zTsnIc2mQo71rGw9U+Ykug==} + engines: {node: '>=v14.0.0', npm: '>=7.0.0'} + + acorn-walk@8.3.2: + resolution: {integrity: sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A==} + engines: {node: '>=0.4.0'} + + acorn@8.11.3: + resolution: {integrity: sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==} + engines: {node: '>=0.4.0'} + hasBin: true + + ansi-regex@5.0.1: + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} + engines: {node: '>=8'} + + ansi-regex@6.0.1: + resolution: {integrity: sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==} + engines: {node: '>=12'} + + ansi-styles@4.3.0: + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} + engines: {node: '>=8'} + + ansi-styles@6.2.1: + resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} + engines: {node: '>=12'} + + anymatch@3.1.3: + resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} + engines: {node: '>= 8'} + + arg@4.1.3: + resolution: {integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==} + + balanced-match@1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + + binary-extensions@2.3.0: + resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} + engines: {node: '>=8'} + + brace-expansion@1.1.11: + resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} + + brace-expansion@2.0.1: + resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} + + braces@3.0.3: + resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} + engines: {node: '>=8'} + + chokidar@3.6.0: + resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} + engines: {node: '>= 8.10.0'} + + color-convert@2.0.1: + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} + engines: {node: '>=7.0.0'} + + color-name@1.1.4: + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + + concat-map@0.0.1: + resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + + create-require@1.1.1: + resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==} + + cross-spawn@7.0.3: + resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} + engines: {node: '>= 8'} + + debug@4.3.5: + resolution: {integrity: sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + diff@4.0.2: + resolution: {integrity: sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==} + engines: {node: '>=0.3.1'} + + discord-api-types@0.37.83: + resolution: {integrity: sha512-urGGYeWtWNYMKnYlZnOnDHm8fVRffQs3U0SpE8RHeiuLKb/u92APS8HoQnPTFbnXmY1vVnXjXO4dOxcAn3J+DA==} + + discord.js@14.15.3: + resolution: {integrity: sha512-/UJDQO10VuU6wQPglA4kz2bw2ngeeSbogiIPx/TsnctfzV/tNf+q+i1HlgtX1OGpeOBpJH9erZQNO5oRM2uAtQ==} + engines: {node: '>=16.11.0'} + + discordx@11.9.2: + resolution: {integrity: sha512-O/Dk2OY1rmgqlOX1zNLnBkpZrnl+XHBOv+SU0+ajAweehKDy36KMCcK0fZhneo2uGJeFcwUOoQRyeAzl6F1WMA==} + engines: {node: '>=16.0.0', npm: '>=7.0.0'} + peerDependencies: + discord.js: '>=14 || ^14.0.0-dev' + + eastasianwidth@0.2.0: + resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} + + emoji-regex@8.0.0: + resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + + emoji-regex@9.2.2: + resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} + + fast-deep-equal@3.1.3: + resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + + fill-range@7.1.1: + resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} + engines: {node: '>=8'} + + foreground-child@3.1.1: + resolution: {integrity: sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==} + engines: {node: '>=14'} + + fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + + glob-parent@5.1.2: + resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} + engines: {node: '>= 6'} + + glob@10.4.1: + resolution: {integrity: sha512-2jelhlq3E4ho74ZyVLN03oKdAZVUa6UDZzFLVH1H7dnoax+y9qyaq8zBkfDIggjniU19z0wU18y16jMB2eyVIw==} + engines: {node: '>=16 || 14 >=14.18'} + hasBin: true + + has-flag@3.0.0: + resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==} + engines: {node: '>=4'} + + ignore-by-default@1.0.1: + resolution: {integrity: sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==} + + is-binary-path@2.1.0: + resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} + engines: {node: '>=8'} + + is-extglob@2.1.1: + resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} + engines: {node: '>=0.10.0'} + + is-fullwidth-code-point@3.0.0: + resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} + engines: {node: '>=8'} + + is-glob@4.0.3: + resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} + engines: {node: '>=0.10.0'} + + is-number@7.0.0: + resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} + engines: {node: '>=0.12.0'} + + isexe@2.0.0: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + + jackspeak@3.4.0: + resolution: {integrity: sha512-JVYhQnN59LVPFCEcVa2C3CrEKYacvjRfqIQl+h8oi91aLYQVWRYbxjPcv1bUiUy/kLmQaANrYfNMCO3kuEDHfw==} + engines: {node: '>=14'} + + lodash.snakecase@4.1.1: + resolution: {integrity: sha512-QZ1d4xoBHYUeuouhEq3lk3Uq7ldgyFXGBhg04+oRLnIz8o9T65Eh+8YdroUwn846zchkA9yDsDl5CVVaV2nqYw==} + + lodash@4.17.21: + resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} + + lru-cache@10.2.2: + resolution: {integrity: sha512-9hp3Vp2/hFQUiIwKo8XCeFVnrg8Pk3TYNPIR7tJADKi5YfcF7vEaK7avFHTlSy3kOKYaJQaalfEo6YuXdceBOQ==} + engines: {node: 14 || >=16.14} + + magic-bytes.js@1.10.0: + resolution: {integrity: sha512-/k20Lg2q8LE5xiaaSkMXk4sfvI+9EGEykFS4b0CHHGWqDYU0bGUFSwchNOMA56D7TCs9GwVTkqe9als1/ns8UQ==} + + make-error@1.3.6: + resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==} + + minimatch@3.1.2: + resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} + + minimatch@9.0.4: + resolution: {integrity: sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==} + engines: {node: '>=16 || 14 >=14.17'} + + minipass@7.1.2: + resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==} + engines: {node: '>=16 || 14 >=14.17'} + + ms@2.1.2: + resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} + + nodemon@3.1.3: + resolution: {integrity: sha512-m4Vqs+APdKzDFpuaL9F9EVOF85+h070FnkHVEoU4+rmT6Vw0bmNl7s61VEkY/cJkL7RCv1p4urnUDUMrS5rk2w==} + engines: {node: '>=10'} + hasBin: true + + normalize-path@3.0.0: + resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} + engines: {node: '>=0.10.0'} + + path-key@3.1.1: + resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} + engines: {node: '>=8'} + + path-scurry@1.11.1: + resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==} + engines: {node: '>=16 || 14 >=14.18'} + + picomatch@2.3.1: + resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} + engines: {node: '>=8.6'} + + prettier@3.3.1: + resolution: {integrity: sha512-7CAwy5dRsxs8PHXT3twixW9/OEll8MLE0VRPCJyl7CkS6VHGPSlsVaWTiASPTyGyYRyApxlaWTzwUxVNrhcwDg==} + engines: {node: '>=14'} + hasBin: true + + pstree.remy@1.1.8: + resolution: {integrity: sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==} + + readdirp@3.6.0: + resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} + engines: {node: '>=8.10.0'} + + semver@7.6.2: + resolution: {integrity: sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==} + engines: {node: '>=10'} + hasBin: true + + shebang-command@2.0.0: + resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} + engines: {node: '>=8'} + + shebang-regex@3.0.0: + resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} + engines: {node: '>=8'} + + signal-exit@4.1.0: + resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} + engines: {node: '>=14'} + + simple-update-notifier@2.0.0: + resolution: {integrity: sha512-a2B9Y0KlNXl9u/vsW6sTIu9vGEpfKu2wRV6l1H3XEas/0gUIzGzBoP/IouTcUQbm9JWZLH3COxyn03TYlFax6w==} + engines: {node: '>=10'} + + string-width@4.2.3: + resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} + engines: {node: '>=8'} + + string-width@5.1.2: + resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} + engines: {node: '>=12'} + + strip-ansi@6.0.1: + resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} + engines: {node: '>=8'} + + strip-ansi@7.1.0: + resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==} + engines: {node: '>=12'} + + supports-color@5.5.0: + resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} + engines: {node: '>=4'} + + to-regex-range@5.0.1: + resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} + engines: {node: '>=8.0'} + + touch@3.1.1: + resolution: {integrity: sha512-r0eojU4bI8MnHr8c5bNo7lJDdI2qXlWWJk6a9EAFG7vbhTjElYhBVS3/miuE0uOuoLdb8Mc/rVfsmm6eo5o9GA==} + hasBin: true + + ts-mixer@6.0.4: + resolution: {integrity: sha512-ufKpbmrugz5Aou4wcr5Wc1UUFWOLhq+Fm6qa6P0w0K5Qw2yhaUoiWszhCVuNQyNwrlGiscHOmqYoAox1PtvgjA==} + + ts-node@10.9.2: + resolution: {integrity: sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==} + hasBin: true + peerDependencies: + '@swc/core': '>=1.2.50' + '@swc/wasm': '>=1.2.50' + '@types/node': '*' + typescript: '>=2.7' + peerDependenciesMeta: + '@swc/core': + optional: true + '@swc/wasm': + optional: true + + tslib@1.14.1: + resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==} + + tslib@2.6.2: + resolution: {integrity: sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==} + + tslib@2.6.3: + resolution: {integrity: sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==} + + tsyringe@4.8.0: + resolution: {integrity: sha512-YB1FG+axdxADa3ncEtRnQCFq/M0lALGLxSZeVNbTU8NqhOVc51nnv2CISTcvc1kyv6EGPtXVr0v6lWeDxiijOA==} + engines: {node: '>= 6.0.0'} + + typedi@0.10.0: + resolution: {integrity: sha512-v3UJF8xm68BBj6AF4oQML3ikrfK2c9EmZUyLOfShpJuItAqVBHWP/KtpGinkSsIiP6EZyyb6Z3NXyW9dgS9X1w==} + + typescript@5.4.5: + resolution: {integrity: sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==} + engines: {node: '>=14.17'} + hasBin: true + + undefsafe@2.0.5: + resolution: {integrity: sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==} + + undici-types@5.26.5: + resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} + + undici@6.13.0: + resolution: {integrity: sha512-Q2rtqmZWrbP8nePMq7mOJIN98M0fYvSgV89vwl/BQRT4mDOeY2GXZngfGpcBBhtky3woM7G24wZV3Q304Bv6cw==} + engines: {node: '>=18.0'} + + v8-compile-cache-lib@3.0.1: + resolution: {integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==} + + which@2.0.2: + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} + engines: {node: '>= 8'} + hasBin: true + + wrap-ansi@7.0.0: + resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} + engines: {node: '>=10'} + + wrap-ansi@8.1.0: + resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==} + engines: {node: '>=12'} + + ws@8.17.0: + resolution: {integrity: sha512-uJq6108EgZMAl20KagGkzCKfMEjxmKvZHG7Tlq0Z6nOky7YF7aq4mOx6xK8TJ/i1LeK4Qus7INktacctDgY8Ow==} + engines: {node: '>=10.0.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: '>=5.0.2' + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + + yn@3.1.1: + resolution: {integrity: sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==} + engines: {node: '>=6'} + +snapshots: + + '@cspotcode/source-map-support@0.8.1': + dependencies: + '@jridgewell/trace-mapping': 0.3.9 + + '@discordjs/builders@1.8.2': + dependencies: + '@discordjs/formatters': 0.4.0 + '@discordjs/util': 1.1.0 + '@sapphire/shapeshift': 3.9.7 + discord-api-types: 0.37.83 + fast-deep-equal: 3.1.3 + ts-mixer: 6.0.4 + tslib: 2.6.2 + + '@discordjs/collection@1.5.3': {} + + '@discordjs/collection@2.1.0': {} + + '@discordjs/formatters@0.4.0': + dependencies: + discord-api-types: 0.37.83 + + '@discordjs/rest@2.3.0': + dependencies: + '@discordjs/collection': 2.1.0 + '@discordjs/util': 1.1.0 + '@sapphire/async-queue': 1.5.2 + '@sapphire/snowflake': 3.5.3 + '@vladfrangu/async_event_emitter': 2.2.4 + discord-api-types: 0.37.83 + magic-bytes.js: 1.10.0 + tslib: 2.6.2 + undici: 6.13.0 + + '@discordjs/util@1.1.0': {} + + '@discordjs/ws@1.1.1': + dependencies: + '@discordjs/collection': 2.1.0 + '@discordjs/rest': 2.3.0 + '@discordjs/util': 1.1.0 + '@sapphire/async-queue': 1.5.2 + '@types/ws': 8.5.10 + '@vladfrangu/async_event_emitter': 2.2.4 + discord-api-types: 0.37.83 + tslib: 2.6.2 + ws: 8.17.0 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + + '@discordx/di@3.3.0': + dependencies: + tsyringe: 4.8.0 + typedi: 0.10.0 + + '@discordx/importer@1.3.0': + dependencies: + glob: 10.4.1 + tslib: 2.6.3 + + '@discordx/internal@1.1.0': + dependencies: + tslib: 2.6.3 + + '@discordx/pagination@3.5.1(discord.js@14.15.3)': + dependencies: + discord.js: 14.15.3 + lodash: 4.17.21 + tslib: 2.6.3 + + '@isaacs/cliui@8.0.2': + dependencies: + string-width: 5.1.2 + string-width-cjs: string-width@4.2.3 + strip-ansi: 7.1.0 + strip-ansi-cjs: strip-ansi@6.0.1 + wrap-ansi: 8.1.0 + wrap-ansi-cjs: wrap-ansi@7.0.0 + + '@jridgewell/resolve-uri@3.1.2': {} + + '@jridgewell/sourcemap-codec@1.4.15': {} + + '@jridgewell/trace-mapping@0.3.9': + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.4.15 + + '@pkgjs/parseargs@0.11.0': + optional: true + + '@sapphire/async-queue@1.5.2': {} + + '@sapphire/shapeshift@3.9.7': + dependencies: + fast-deep-equal: 3.1.3 + lodash: 4.17.21 + + '@sapphire/snowflake@3.5.3': {} + + '@tsconfig/node10@1.0.11': {} + + '@tsconfig/node12@1.0.11': {} + + '@tsconfig/node14@1.0.3': {} + + '@tsconfig/node16@1.0.4': {} + + '@types/node@20.14.2': + dependencies: + undici-types: 5.26.5 + + '@types/ws@8.5.10': + dependencies: + '@types/node': 20.14.2 + + '@vladfrangu/async_event_emitter@2.2.4': {} + + acorn-walk@8.3.2: {} + + acorn@8.11.3: {} + + ansi-regex@5.0.1: {} + + ansi-regex@6.0.1: {} + + ansi-styles@4.3.0: + dependencies: + color-convert: 2.0.1 + + ansi-styles@6.2.1: {} + + anymatch@3.1.3: + dependencies: + normalize-path: 3.0.0 + picomatch: 2.3.1 + + arg@4.1.3: {} + + balanced-match@1.0.2: {} + + binary-extensions@2.3.0: {} + + brace-expansion@1.1.11: + dependencies: + balanced-match: 1.0.2 + concat-map: 0.0.1 + + brace-expansion@2.0.1: + dependencies: + balanced-match: 1.0.2 + + braces@3.0.3: + dependencies: + fill-range: 7.1.1 + + chokidar@3.6.0: + dependencies: + anymatch: 3.1.3 + braces: 3.0.3 + glob-parent: 5.1.2 + is-binary-path: 2.1.0 + is-glob: 4.0.3 + normalize-path: 3.0.0 + readdirp: 3.6.0 + optionalDependencies: + fsevents: 2.3.3 + + color-convert@2.0.1: + dependencies: + color-name: 1.1.4 + + color-name@1.1.4: {} + + concat-map@0.0.1: {} + + create-require@1.1.1: {} + + cross-spawn@7.0.3: + dependencies: + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 + + debug@4.3.5(supports-color@5.5.0): + dependencies: + ms: 2.1.2 + optionalDependencies: + supports-color: 5.5.0 + + diff@4.0.2: {} + + discord-api-types@0.37.83: {} + + discord.js@14.15.3: + dependencies: + '@discordjs/builders': 1.8.2 + '@discordjs/collection': 1.5.3 + '@discordjs/formatters': 0.4.0 + '@discordjs/rest': 2.3.0 + '@discordjs/util': 1.1.0 + '@discordjs/ws': 1.1.1 + '@sapphire/snowflake': 3.5.3 + discord-api-types: 0.37.83 + fast-deep-equal: 3.1.3 + lodash.snakecase: 4.1.1 + tslib: 2.6.2 + undici: 6.13.0 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + + discordx@11.9.2(discord.js@14.15.3): + dependencies: + '@discordx/di': 3.3.0 + '@discordx/internal': 1.1.0 + discord.js: 14.15.3 + lodash: 4.17.21 + tslib: 2.6.3 + + eastasianwidth@0.2.0: {} + + emoji-regex@8.0.0: {} + + emoji-regex@9.2.2: {} + + fast-deep-equal@3.1.3: {} + + fill-range@7.1.1: + dependencies: + to-regex-range: 5.0.1 + + foreground-child@3.1.1: + dependencies: + cross-spawn: 7.0.3 + signal-exit: 4.1.0 + + fsevents@2.3.3: + optional: true + + glob-parent@5.1.2: + dependencies: + is-glob: 4.0.3 + + glob@10.4.1: + dependencies: + foreground-child: 3.1.1 + jackspeak: 3.4.0 + minimatch: 9.0.4 + minipass: 7.1.2 + path-scurry: 1.11.1 + + has-flag@3.0.0: {} + + ignore-by-default@1.0.1: {} + + is-binary-path@2.1.0: + dependencies: + binary-extensions: 2.3.0 + + is-extglob@2.1.1: {} + + is-fullwidth-code-point@3.0.0: {} + + is-glob@4.0.3: + dependencies: + is-extglob: 2.1.1 + + is-number@7.0.0: {} + + isexe@2.0.0: {} + + jackspeak@3.4.0: + dependencies: + '@isaacs/cliui': 8.0.2 + optionalDependencies: + '@pkgjs/parseargs': 0.11.0 + + lodash.snakecase@4.1.1: {} + + lodash@4.17.21: {} + + lru-cache@10.2.2: {} + + magic-bytes.js@1.10.0: {} + + make-error@1.3.6: {} + + minimatch@3.1.2: + dependencies: + brace-expansion: 1.1.11 + + minimatch@9.0.4: + dependencies: + brace-expansion: 2.0.1 + + minipass@7.1.2: {} + + ms@2.1.2: {} + + nodemon@3.1.3: + dependencies: + chokidar: 3.6.0 + debug: 4.3.5(supports-color@5.5.0) + ignore-by-default: 1.0.1 + minimatch: 3.1.2 + pstree.remy: 1.1.8 + semver: 7.6.2 + simple-update-notifier: 2.0.0 + supports-color: 5.5.0 + touch: 3.1.1 + undefsafe: 2.0.5 + + normalize-path@3.0.0: {} + + path-key@3.1.1: {} + + path-scurry@1.11.1: + dependencies: + lru-cache: 10.2.2 + minipass: 7.1.2 + + picomatch@2.3.1: {} + + prettier@3.3.1: {} + + pstree.remy@1.1.8: {} + + readdirp@3.6.0: + dependencies: + picomatch: 2.3.1 + + semver@7.6.2: {} + + shebang-command@2.0.0: + dependencies: + shebang-regex: 3.0.0 + + shebang-regex@3.0.0: {} + + signal-exit@4.1.0: {} + + simple-update-notifier@2.0.0: + dependencies: + semver: 7.6.2 + + string-width@4.2.3: + dependencies: + emoji-regex: 8.0.0 + is-fullwidth-code-point: 3.0.0 + strip-ansi: 6.0.1 + + string-width@5.1.2: + dependencies: + eastasianwidth: 0.2.0 + emoji-regex: 9.2.2 + strip-ansi: 7.1.0 + + strip-ansi@6.0.1: + dependencies: + ansi-regex: 5.0.1 + + strip-ansi@7.1.0: + dependencies: + ansi-regex: 6.0.1 + + supports-color@5.5.0: + dependencies: + has-flag: 3.0.0 + + to-regex-range@5.0.1: + dependencies: + is-number: 7.0.0 + + touch@3.1.1: {} + + ts-mixer@6.0.4: {} + + ts-node@10.9.2(@types/node@20.14.2)(typescript@5.4.5): + dependencies: + '@cspotcode/source-map-support': 0.8.1 + '@tsconfig/node10': 1.0.11 + '@tsconfig/node12': 1.0.11 + '@tsconfig/node14': 1.0.3 + '@tsconfig/node16': 1.0.4 + '@types/node': 20.14.2 + acorn: 8.11.3 + acorn-walk: 8.3.2 + arg: 4.1.3 + create-require: 1.1.1 + diff: 4.0.2 + make-error: 1.3.6 + typescript: 5.4.5 + v8-compile-cache-lib: 3.0.1 + yn: 3.1.1 + + tslib@1.14.1: {} + + tslib@2.6.2: {} + + tslib@2.6.3: {} + + tsyringe@4.8.0: + dependencies: + tslib: 1.14.1 + + typedi@0.10.0: {} + + typescript@5.4.5: {} + + undefsafe@2.0.5: {} + + undici-types@5.26.5: {} + + undici@6.13.0: {} + + v8-compile-cache-lib@3.0.1: {} + + which@2.0.2: + dependencies: + isexe: 2.0.0 + + wrap-ansi@7.0.0: + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + + wrap-ansi@8.1.0: + dependencies: + ansi-styles: 6.2.1 + string-width: 5.1.2 + strip-ansi: 7.1.0 + + ws@8.17.0: {} + + yn@3.1.1: {} diff --git a/src/commands/choices.ts b/src/commands/choices.ts new file mode 100644 index 0000000..3b90c65 --- /dev/null +++ b/src/commands/choices.ts @@ -0,0 +1,37 @@ +import type { CommandInteraction } from "discord.js"; +import { ApplicationCommandOptionType } from "discord.js"; +import { Discord, Slash, SlashChoice, SlashOption } from "discordx"; + +@Discord() +export class Example { + @Slash({ description: "choose" }) + async choose( + @SlashChoice("Human", "Astronaut", "Dev") + @SlashOption({ + description: "What are you?", + name: "what", + required: true, + type: ApplicationCommandOptionType.String, + }) + what: string, + interaction: CommandInteraction, + ): Promise { + await interaction.reply(what); + } + + @Slash({ description: "choose1" }) + async choose1( + @SlashChoice({ name: "are you okay?", value: "okay" }) + @SlashChoice({ name: "are you good?", value: "good" }) + @SlashOption({ + description: "what1", + name: "what1", + required: true, + type: ApplicationCommandOptionType.String, + }) + what: string, + interaction: CommandInteraction, + ): Promise { + await interaction.reply(what); + } +} diff --git a/src/commands/context.ts b/src/commands/context.ts new file mode 100644 index 0000000..0d75868 --- /dev/null +++ b/src/commands/context.ts @@ -0,0 +1,26 @@ +import type { + MessageContextMenuCommandInteraction, + UserContextMenuCommandInteraction, +} from "discord.js"; +import { ApplicationCommandType } from "discord.js"; +import { ContextMenu, Discord } from "discordx"; + +@Discord() +export class Example { + @ContextMenu({ + name: "message context", + type: ApplicationCommandType.Message, + }) + async messageHandler( + interaction: MessageContextMenuCommandInteraction, + ): Promise { + await interaction.reply("I am user context handler"); + } + + @ContextMenu({ name: "user context", type: ApplicationCommandType.User }) + async userHandler( + interaction: UserContextMenuCommandInteraction, + ): Promise { + await interaction.reply("I am user context handler"); + } +} diff --git a/src/commands/menu.ts b/src/commands/menu.ts new file mode 100644 index 0000000..e60c5a6 --- /dev/null +++ b/src/commands/menu.ts @@ -0,0 +1,59 @@ +import type { + CommandInteraction, + MessageActionRowComponentBuilder, + StringSelectMenuInteraction, +} from "discord.js"; +import { ActionRowBuilder, StringSelectMenuBuilder } from "discord.js"; +import { Discord, SelectMenuComponent, Slash } from "discordx"; + +const roles = [ + { label: "Principal", value: "principal" }, + { label: "Teacher", value: "teacher" }, + { label: "Student", value: "student" }, +]; + +@Discord() +export class Example { + @SelectMenuComponent({ id: "role-menu" }) + async handle(interaction: StringSelectMenuInteraction): Promise { + await interaction.deferReply(); + + // extract selected value by member + const roleValue = interaction.values[0]; + + // if value not found + if (!roleValue) { + return interaction.followUp("invalid role id, select again"); + } + + await interaction.followUp( + `you have selected role: ${ + roles.find((r) => r.value === roleValue)?.label ?? "unknown" + }`, + ); + return; + } + + @Slash({ description: "roles menu", name: "my_roles" }) + async myRoles(interaction: CommandInteraction): Promise { + await interaction.deferReply(); + + // create menu for roles + const menu = new StringSelectMenuBuilder() + .addOptions(roles) + .setCustomId("role-menu"); + + // create a row for message actions + const buttonRow = + new ActionRowBuilder().addComponents( + menu, + ); + + // send it + await interaction.editReply({ + components: [buttonRow], + content: "select your role!", + }); + return; + } +} diff --git a/src/commands/simple command.ts b/src/commands/simple command.ts new file mode 100644 index 0000000..1b3decb --- /dev/null +++ b/src/commands/simple command.ts @@ -0,0 +1,53 @@ +import type { CommandInteraction, Message } from "discord.js"; +import type { SimpleCommandMessage } from "discordx"; +import { + Discord, + SimpleCommand, + SimpleCommandOption, + SimpleCommandOptionType, + Slash, +} from "discordx"; + +@Discord() +export class Example { + @SimpleCommand({ aliases: ["hi"] }) + async hello(command: SimpleCommandMessage): Promise { + const member = command.message.member; + if (member) { + await command.message.reply(`👋 ${member.toString()}`); + } else { + await command.message.reply("👋 hello"); + } + } + + @SimpleCommand({ argSplitter: "+" }) + async sum( + @SimpleCommandOption({ name: "num1", type: SimpleCommandOptionType.Number }) + num1: number | undefined, + @SimpleCommandOption({ name: "num2", type: SimpleCommandOptionType.Number }) + num2: number | undefined, + command: SimpleCommandMessage, + ): Promise { + if (!num1 || !num2) { + await command.sendUsageSyntax(); + return; + } + + await command.message.reply(`total = ${String(num1 + num2)}`); + } + + // make single handler for simple and slash command + async likeIt(command: CommandInteraction | Message): Promise { + await command.reply("I like it, Thanks"); + } + + @SimpleCommand({ name: "like-it" }) + async simpleLikeIt(command: SimpleCommandMessage): Promise { + await this.likeIt(command.message); + } + + @Slash({ description: "like-ite", name: "like-it" }) + async slashLikeIt(command: CommandInteraction): Promise { + await this.likeIt(command); + } +} diff --git a/src/commands/slash + button.ts b/src/commands/slash + button.ts new file mode 100644 index 0000000..a97fdb5 --- /dev/null +++ b/src/commands/slash + button.ts @@ -0,0 +1,60 @@ +import type { + ButtonInteraction, + CommandInteraction, + MessageActionRowComponentBuilder, + User, +} from "discord.js"; +import { + ActionRowBuilder, + ApplicationCommandOptionType, + ButtonBuilder, + ButtonStyle, + GuildMember, +} from "discord.js"; +import { ButtonComponent, Discord, Slash, SlashOption } from "discordx"; + +@Discord() +export class Example { + @Slash({ description: "hello", name: "hello-btn" }) + async hello( + @SlashOption({ + description: "user", + name: "user", + required: true, + type: ApplicationCommandOptionType.User, + }) + user: User | GuildMember | undefined, + interaction: CommandInteraction, + ): Promise { + if (!user) { + return; + } + + await interaction.deferReply(); + + const helloBtn = new ButtonBuilder() + .setLabel("Hello") + .setEmoji("👋") + .setStyle(ButtonStyle.Primary) + .setCustomId("hello-btn"); + + const row = + new ActionRowBuilder().addComponents( + helloBtn, + ); + + await interaction.editReply({ + components: [row], + content: `${user.toString()}, Say hello to bot`, + }); + } + + @ButtonComponent({ id: "hello-btn" }) + async helloBtn(interaction: ButtonInteraction): Promise { + if (!(interaction.member instanceof GuildMember)) { + return; + } + + await interaction.reply(`👋 ${interaction.member.toString()}`); + } +} diff --git a/src/commands/slash group.ts b/src/commands/slash group.ts new file mode 100644 index 0000000..46feb2c --- /dev/null +++ b/src/commands/slash group.ts @@ -0,0 +1,67 @@ +import type { CommandInteraction } from "discord.js"; +import { ApplicationCommandOptionType } from "discord.js"; +import { Discord, Slash, SlashGroup, SlashOption } from "discordx"; + +@Discord() +@SlashGroup({ description: "testing", name: "testing" }) +@SlashGroup({ description: "maths", name: "maths", root: "testing" }) +export class GroupExample { + @Slash({ description: "add" }) + @SlashGroup("maths", "testing") + async add( + @SlashOption({ + description: "x value", + name: "x", + required: true, + type: ApplicationCommandOptionType.Number, + }) + x: number, + @SlashOption({ + description: "y value", + name: "y", + required: true, + type: ApplicationCommandOptionType.Number, + }) + y: number, + interaction: CommandInteraction, + ): Promise { + await interaction.reply(String(x + y)); + } + + @Slash({ description: "multiply" }) + @SlashGroup("maths", "testing") + async multiply( + @SlashOption({ + description: "x value", + name: "x", + required: true, + type: ApplicationCommandOptionType.Number, + }) + x: number, + @SlashOption({ + description: "y value", + name: "y", + required: true, + type: ApplicationCommandOptionType.Number, + }) + y: number, + interaction: CommandInteraction, + ): Promise { + await interaction.reply(String(x * y)); + } + + @Slash({ description: "root" }) + @SlashGroup("testing") + async root( + @SlashOption({ + description: "text", + name: "text", + required: true, + type: ApplicationCommandOptionType.String, + }) + text: string, + interaction: CommandInteraction, + ): Promise { + await interaction.reply(text); + } +} diff --git a/src/commands/slashes.ts b/src/commands/slashes.ts new file mode 100644 index 0000000..a97d612 --- /dev/null +++ b/src/commands/slashes.ts @@ -0,0 +1,36 @@ +import { Pagination } from "@discordx/pagination"; +import type { CommandInteraction } from "discord.js"; +import { EmbedBuilder } from "discord.js"; +import { Discord, MetadataStorage, Slash } from "discordx"; + +@Discord() +export class SlashExample { + // example: pagination for all slash command + @Slash({ + description: "Pagination for all slash command", + name: "all-commands", + }) + async pages(interaction: CommandInteraction): Promise { + const commands = MetadataStorage.instance.applicationCommands.map((cmd) => { + return { description: cmd.description, name: cmd.name }; + }); + + const pages = commands.map((cmd, i) => { + const embed = new EmbedBuilder() + .setFooter({ + text: `Page ${String(i + 1)} of ${String(commands.length)}`, + }) + .setTitle("**Slash command info**") + .addFields({ name: "Name", value: cmd.name }) + .addFields({ + name: "Description", + value: cmd.description, + }); + + return { embeds: [embed] }; + }); + + const pagination = new Pagination(interaction, pages); + await pagination.send(); + } +} diff --git a/src/events/common.ts b/src/events/common.ts new file mode 100644 index 0000000..3a4e946 --- /dev/null +++ b/src/events/common.ts @@ -0,0 +1,10 @@ +import type { ArgsOf, Client } from "discordx"; +import { Discord, On } from "discordx"; + +@Discord() +export class Example { + @On() + messageDelete([message]: ArgsOf<"messageDelete">, client: Client): void { + console.log("Message Deleted", client.user?.username, message.content); + } +} diff --git a/src/main.ts b/src/main.ts new file mode 100644 index 0000000..681d97c --- /dev/null +++ b/src/main.ts @@ -0,0 +1,72 @@ +import { dirname, importx } from "@discordx/importer"; +import type { Interaction, Message } from "discord.js"; +import { IntentsBitField } from "discord.js"; +import { Client } from "discordx"; + +export const bot = new Client({ + // To use only guild command + // botGuilds: [(client) => client.guilds.cache.map((guild) => guild.id)], + + // Discord intents + intents: [ + IntentsBitField.Flags.Guilds, + IntentsBitField.Flags.GuildMembers, + IntentsBitField.Flags.GuildMessages, + IntentsBitField.Flags.GuildMessageReactions, + IntentsBitField.Flags.GuildVoiceStates, + IntentsBitField.Flags.MessageContent, + ], + + // Debug logs are disabled in silent mode + silent: false, + + // Configuration for @SimpleCommand + simpleCommand: { + prefix: "!", + }, +}); + +bot.once("ready", async () => { + // Make sure all guilds are cached + // await bot.guilds.fetch(); + + // Synchronize applications commands with Discord + await bot.initApplicationCommands(); + + // To clear all guild commands, uncomment this line, + // This is useful when moving from guild commands to global commands + // It must only be executed once + // + // await bot.clearApplicationCommands( + // ...bot.guilds.cache.map((g) => g.id) + // ); + + console.log("Bot started"); +}); + +bot.on("interactionCreate", (interaction: Interaction) => { + bot.executeInteraction(interaction); +}); + +bot.on("messageCreate", async (message: Message) => { + await bot.executeCommand(message); +}); + +async function run() { + // The following syntax should be used in the commonjs environment + // + // await importx(__dirname + "/{events,commands}/**/*.{ts,js}"); + + // The following syntax should be used in the ECMAScript environment + await importx(`${dirname(import.meta.url)}/{events,commands}/**/*.{ts,js}`); + + // Let's start the bot + if (!process.env.BOT_TOKEN) { + throw Error("Could not find BOT_TOKEN in your environment"); + } + + // Log in with your bot token + await bot.login(process.env.BOT_TOKEN); +} + +void run(); diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..f5de8d5 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,18 @@ +{ + "compilerOptions": { + "target": "ESNext", + "module": "ESNext", + "outDir": "build", + "rootDir": "src", + "strict": true, + "moduleResolution": "Node", + "allowSyntheticDefaultImports": true, + + "experimentalDecorators": true, + "emitDecoratorMetadata": false, + + "skipLibCheck": true, + "forceConsistentCasingInFileNames": true + }, + "exclude": ["build", "node_modules"] +}